commit - 790ca73c1011a3aedd266ed382a84bd9a5094816
commit + 6d054bb9e38d22dc37c9141e75db6b8b9cd7ca9b
blob - 0ef1bde429a115ad0f96ae4adcaedfd38f7704f0
blob + aa4a411ffcd6b1548c7dd705448a655602514913
--- got/got.c
+++ got/got.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 &&
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");
goto done;
}
fd = -1;
- } else {
- sb.st_size = 0;
- f2_exists = 0;
+ f2_exists = 1;
}
if (blob1) {
}
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
* 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 - 1174cfde7a73bb0a1bb62e32a59759f03e7c66eb
blob + 4e77651dc35e2405f41d383a4af005829a48743e
--- lib/diff.c
+++ lib/diff.c
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)
{
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,
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 - 2f96f78243ecc7610927ef5df3b037cb40f8b7d2
blob + 2629b8eb5ac5bf6ef386a08e8ee437b27ef5fd41
--- libexec/got-read-patch/got-read-patch.c
+++ libexec/got-read-patch/got-read-patch.c
} 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 - b9d15eb9d66bfe79b16eb3334fd9628431af7f0d
blob + 84e63ab3e0ed94eb29e2fcdd5b9e529332c4f093
--- regress/cmdline/diff.sh
+++ regress/cmdline/diff.sh
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
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
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
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
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
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
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
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
@@ -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 <<EOF > $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
run_test test_diff_commits
run_test test_diff_ignored_file
run_test test_diff_crlf
+run_test test_diff_worktree_newfile_xbit