commit c87842d5aed77e4f15bab3980e8cb22f18e954f8 from: Mark Jamsek date: Fri Sep 23 06:01:40 2022 UTC show file mode for new added files in work tree diffs Make work tree diffs of local changes on disk display the file mode of new added files like other versions of `got diff` currently do. ok stsp@ commit - 0e678fc8b5ec094de9fab7b1a3ab6886ecb2c95a commit + c87842d5aed77e4f15bab3980e8cb22f18e954f8 blob - 7c95dd13a7945672200a10ba9c507d183e842406 blob + 04f6245bfb7bfdc492c4818321900ff49e579289 --- got/got.c +++ got/got.c @@ -4717,7 +4717,9 @@ print_diff(void *arg, unsigned char status, unsigned c char *abspath = NULL, *label1 = NULL; struct stat sb; off_t size1 = 0; - int f2_exists = 1; + int f2_exists = 0; + + memset(&sb, 0, sizeof(sb)); if (a->diff_staged) { if (staged_status != GOT_STATUS_MODIFY && @@ -4850,8 +4852,8 @@ print_diff(void *arg, unsigned char status, unsigned c goto done; } } - if (fstat(fd, &sb) == -1) { - err = got_error_from_errno2("fstat", abspath); + if (fstatat(fd, abspath, &sb, AT_SYMLINK_NOFOLLOW) == -1) { + err = got_error_from_errno2("fstatat", abspath); goto done; } f2 = fdopen(fd, "r"); @@ -4860,9 +4862,7 @@ print_diff(void *arg, unsigned char status, unsigned c goto done; } fd = -1; - } else { - sb.st_size = 0; - f2_exists = 0; + f2_exists = 1; } if (blob1) { @@ -4873,8 +4873,8 @@ print_diff(void *arg, unsigned char status, unsigned c } err = got_diff_blob_file(blob1, a->f1, size1, label1, f2 ? f2 : a->f2, - f2_exists, sb.st_size, path, GOT_DIFF_ALGORITHM_PATIENCE, - a->diff_context, a->ignore_whitespace, a->force_text_diff, stdout); + f2_exists, &sb, path, GOT_DIFF_ALGORITHM_PATIENCE, a->diff_context, + a->ignore_whitespace, a->force_text_diff, stdout); done: if (fd1 != -1 && close(fd1) == -1 && err == NULL) err = got_error_from_errno("close"); blob - bc4bc871ee90bf32c4fd2bd3b2b452f29d5822a0 blob + 26617c2f087a790bbb5f19d32d57f83246fcb532 --- include/got_diff.h +++ include/got_diff.h @@ -74,7 +74,7 @@ const struct got_error *got_diff_blob(struct got_diff_ * Whitespace differences may optionally be ignored. */ const struct got_error *got_diff_blob_file(struct got_blob_object *, FILE *, - off_t, const char *, FILE *, int, size_t, const char *, + off_t, const char *, FILE *, int, struct stat *, const char *, enum got_diff_algorithm, int, int, int, FILE *); /* blob - ec271a03249db4f54f213d8fd71a18c6220153ef blob + 58baf2baa359d6bb49f1d7c1b7bd6af3f15bbb36 --- lib/diff.c +++ lib/diff.c @@ -221,7 +221,7 @@ got_diff_blob(struct got_diff_line **lines, size_t*nli static const struct got_error * diff_blob_file(struct got_diffreg_result **resultp, struct got_blob_object *blob1, FILE *f1, off_t size1, const char *label1, - FILE *f2, int f2_exists, size_t size2, const char *label2, + FILE *f2, int f2_exists, struct stat *sb2, const char *label2, enum got_diff_algorithm diff_algo, int diff_context, int ignore_whitespace, int force_text_diff, FILE *outfile) { @@ -239,9 +239,22 @@ diff_blob_file(struct got_diffreg_result **resultp, idstr1 = "/dev/null"; if (outfile) { + char *mode = NULL; + + /* display file mode for new added files only */ + if (f2_exists && blob1 == NULL) { + int mmask = (S_IRWXU | S_IRWXG | S_IRWXO); + + if (S_ISLNK(sb2->st_mode)) + mmask = S_IFLNK; + if (asprintf(&mode, " (mode %o)", + sb2->st_mode & mmask) == -1) + return got_error_from_errno("asprintf"); + } fprintf(outfile, "blob - %s\n", label1 ? label1 : idstr1); - fprintf(outfile, "file + %s\n", - f2_exists ? label2 : "/dev/null"); + fprintf(outfile, "file + %s%s\n", + f2_exists ? label2 : "/dev/null", mode ? mode : ""); + free(mode); } err = got_diffreg(&result, f1, f2, diff_algo, ignore_whitespace, @@ -272,13 +285,13 @@ done: const struct got_error * got_diff_blob_file(struct got_blob_object *blob1, FILE *f1, off_t size1, - const char *label1, FILE *f2, int f2_exists, size_t size2, + const char *label1, FILE *f2, int f2_exists, struct stat *sb2, const char *label2, enum got_diff_algorithm diff_algo, int diff_context, int ignore_whitespace, int force_text_diff, FILE *outfile) { return diff_blob_file(NULL, blob1, f1, size1, label1, f2, f2_exists, - size2, label2, diff_algo, diff_context, ignore_whitespace, - force_text_diff, outfile ); + sb2, label2, diff_algo, diff_context, ignore_whitespace, + force_text_diff, outfile); } static const struct got_error * blob - b01acc2d4192df91e119abcea319ac890c164de0 blob + becf27d3e00feb1fd2b32823931dc0d1b580cfb6 --- libexec/got-read-patch/got-read-patch.c +++ libexec/got-read-patch/got-read-patch.c @@ -231,7 +231,8 @@ find_diff(int *done, int *next, FILE *fp, int git, con } else if (!strncmp(line, "+++ ", 4)) { free(new); err = filename(line+4, &new); - } else if (!strncmp(line, "blob + ", 7)) { + } else if (!strncmp(line, "blob + ", 7) || + !strncmp(line, "file + ", 7)) { xbit = filexbit(line); } else if (!git && !strncmp(line, "blob - ", 7)) { free(blob); blob - 43f41172dfa14e7ca103f635f10f4b25a6f11cf8 blob + be07e3211fa6b1491159fb5458fdf2f901864d68 --- regress/cmdline/diff.sh +++ regress/cmdline/diff.sh @@ -54,7 +54,7 @@ test_diff_basic() { echo '@@ -1 +0,0 @@' >> $testroot/stdout.expected echo '-beta' >> $testroot/stdout.expected echo 'blob - /dev/null' >> $testroot/stdout.expected - echo 'file + new' >> $testroot/stdout.expected + echo 'file + new (mode 644)' >> $testroot/stdout.expected echo '--- /dev/null' >> $testroot/stdout.expected echo '+++ new' >> $testroot/stdout.expected echo '@@ -0,0 +1 @@' >> $testroot/stdout.expected @@ -148,7 +148,7 @@ test_diff_basic() { echo '-zeta' >> $testroot/stdout.expected echo '+modified zeta' >> $testroot/stdout.expected echo 'blob - /dev/null' >> $testroot/stdout.expected - echo 'file + new' >> $testroot/stdout.expected + echo 'file + new (mode 644)' >> $testroot/stdout.expected echo '--- /dev/null' >> $testroot/stdout.expected echo '+++ new' >> $testroot/stdout.expected echo '@@ -0,0 +1 @@' >> $testroot/stdout.expected @@ -269,13 +269,13 @@ test_diff_basic() { echo "commit - $head_rev" >> $testroot/stdout.expected echo "path + $testroot/wt" >> $testroot/stdout.expected echo 'blob - /dev/null' >> $testroot/stdout.expected - echo 'file + master' >> $testroot/stdout.expected + echo 'file + master (mode 644)' >> $testroot/stdout.expected echo '--- /dev/null' >> $testroot/stdout.expected echo '+++ master' >> $testroot/stdout.expected echo '@@ -0,0 +1 @@' >> $testroot/stdout.expected echo '+master' >> $testroot/stdout.expected echo 'blob - /dev/null' >> $testroot/stdout.expected - echo 'file + new' >> $testroot/stdout.expected + echo 'file + new (mode 644)' >> $testroot/stdout.expected echo '--- /dev/null' >> $testroot/stdout.expected echo '+++ new' >> $testroot/stdout.expected echo '@@ -0,0 +1 @@' >> $testroot/stdout.expected @@ -311,7 +311,7 @@ test_diff_basic() { echo "commit - $head_rev" >> $testroot/stdout.expected echo "path + $testroot/wt" >> $testroot/stdout.expected echo 'blob - /dev/null' >> $testroot/stdout.expected - echo 'file + new' >> $testroot/stdout.expected + echo 'file + new (mode 644)' >> $testroot/stdout.expected echo '--- /dev/null' >> $testroot/stdout.expected echo '+++ new' >> $testroot/stdout.expected echo '@@ -0,0 +1 @@' >> $testroot/stdout.expected @@ -365,7 +365,7 @@ test_diff_basic() { echo "commit - $head_rev" >> $testroot/stdout.expected echo "path + $testroot/wt" >> $testroot/stdout.expected echo 'blob - /dev/null' >> $testroot/stdout.expected - echo 'file + new' >> $testroot/stdout.expected + echo 'file + new (mode 644)' >> $testroot/stdout.expected echo '--- /dev/null' >> $testroot/stdout.expected echo '+++ new' >> $testroot/stdout.expected echo '@@ -0,0 +1 @@' >> $testroot/stdout.expected @@ -798,7 +798,7 @@ test_diff_symlinks_in_work_tree() { echo '-nonexistent' >> $testroot/stdout.expected echo '\ No newline at end of file' >> $testroot/stdout.expected echo 'blob - /dev/null' >> $testroot/stdout.expected - echo 'file + zeta.link' >> $testroot/stdout.expected + echo 'file + zeta.link (mode 120000)' >> $testroot/stdout.expected echo '--- /dev/null' >> $testroot/stdout.expected echo '+++ zeta.link' >> $testroot/stdout.expected echo '@@ -0,0 +1 @@' >> $testroot/stdout.expected @@ -950,7 +950,7 @@ test_diff_binary_files() { echo "commit - $head_rev" >> $testroot/stdout.expected echo "path + $testroot/wt" >> $testroot/stdout.expected echo 'blob - /dev/null' >> $testroot/stdout.expected - echo 'file + foo' >> $testroot/stdout.expected + echo 'file + foo (mode 644)' >> $testroot/stdout.expected echo "Binary files /dev/null and foo differ" \ >> $testroot/stdout.expected @@ -967,7 +967,7 @@ test_diff_binary_files() { echo "commit - $head_rev" >> $testroot/stdout.expected echo "path + $testroot/wt" >> $testroot/stdout.expected echo 'blob - /dev/null' >> $testroot/stdout.expected - echo 'file + foo' >> $testroot/stdout.expected + echo 'file + foo (mode 644)' >> $testroot/stdout.expected echo '--- /dev/null' >> $testroot/stdout.expected echo '+++ foo' >> $testroot/stdout.expected echo '@@ -0,0 +1 @@' >> $testroot/stdout.expected @@ -1317,11 +1317,58 @@ test_diff_crlf() { @@ -1 +1 @@ -test +test 2 +EOF + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" $ret +} + +test_diff_worktree_newfile_xbit() { + local testroot=`test_init diff_worktree_newfile_xbit` + + got checkout $testroot/repo $testroot/wt > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" $ret + return 1 + fi + + echo xfile > $testroot/wt/xfile + chmod +x $testroot/wt/xfile + (cd $testroot/wt && got add xfile) > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" $ret + return 1 + fi + (cd $testroot/wt && got diff) > $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" $ret + return 1 + fi + + local commit_id=`git_show_head $testroot/repo` + cat < $testroot/stdout.expected +diff $testroot/wt +commit - $commit_id +path + $testroot/wt +blob - /dev/null +file + xfile (mode 755) +--- /dev/null ++++ xfile +@@ -0,0 +1 @@ ++xfile EOF cmp -s $testroot/stdout.expected $testroot/stdout ret=$? if [ $ret -ne 0 ]; then + echo "failed to record mode 755" diff -u $testroot/stdout.expected $testroot/stdout fi test_done "$testroot" $ret @@ -1340,3 +1387,4 @@ run_test test_diff_binary_files run_test test_diff_commits run_test test_diff_ignored_file run_test test_diff_crlf +run_test test_diff_worktree_newfile_xbit