mirror of
https://github.com/git/git.git
synced 2026-02-26 18:06:53 +00:00
Merge branch 'jc/whitespace-incomplete-line' into jch
It does not make much sense to apply the "incomplete-line" whitespace rule to symbolic links, whose contents almost always lack the final newline. "git apply" and "git diff" are now taught to exclude them for a change to symbolic links. * jc/whitespace-incomplete-line: whitespace: symbolic links usually lack LF at the end
This commit is contained in:
20
apply.c
20
apply.c
@@ -1725,6 +1725,26 @@ static int parse_fragment(struct apply_state *state,
|
||||
unsigned long oldlines, newlines;
|
||||
unsigned long leading, trailing;
|
||||
|
||||
/* do not complain a symbolic link being an incomplete line */
|
||||
if (patch->ws_rule & WS_INCOMPLETE_LINE) {
|
||||
/*
|
||||
* We want to figure out if the postimage is a
|
||||
* symbolic link when applying the patch normally, or
|
||||
* if the preimage is a symbolic link when applying
|
||||
* the patch in reverse. A normal patch only has
|
||||
* old_mode without new_mode. If it changes the
|
||||
* filemode, new_mode has value, which is different
|
||||
* from old_mode.
|
||||
*/
|
||||
unsigned mode = (state->apply_in_reverse
|
||||
? patch->old_mode
|
||||
: patch->new_mode
|
||||
? patch->new_mode
|
||||
: patch->old_mode);
|
||||
if (mode && S_ISLNK(mode))
|
||||
patch->ws_rule &= ~WS_INCOMPLETE_LINE;
|
||||
}
|
||||
|
||||
offset = parse_fragment_header(line, len, fragment);
|
||||
if (offset < 0)
|
||||
return -1;
|
||||
|
||||
22
diff.c
22
diff.c
@@ -1837,6 +1837,7 @@ static void emit_rewrite_diff(const char *name_a,
|
||||
const char *a_prefix, *b_prefix;
|
||||
char *data_one, *data_two;
|
||||
size_t size_one, size_two;
|
||||
unsigned ws_rule;
|
||||
struct emit_callback ecbdata;
|
||||
struct strbuf out = STRBUF_INIT;
|
||||
|
||||
@@ -1859,9 +1860,15 @@ static void emit_rewrite_diff(const char *name_a,
|
||||
size_one = fill_textconv(o->repo, textconv_one, one, &data_one);
|
||||
size_two = fill_textconv(o->repo, textconv_two, two, &data_two);
|
||||
|
||||
ws_rule = whitespace_rule(o->repo->index, name_b);
|
||||
|
||||
/* symlink being an incomplete line is not a news */
|
||||
if (DIFF_FILE_VALID(two) && S_ISLNK(two->mode))
|
||||
ws_rule &= ~WS_INCOMPLETE_LINE;
|
||||
|
||||
memset(&ecbdata, 0, sizeof(ecbdata));
|
||||
ecbdata.color_diff = o->use_color;
|
||||
ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b);
|
||||
ecbdata.ws_rule = ws_rule;
|
||||
ecbdata.opt = o;
|
||||
if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
|
||||
mmfile_t mf1, mf2;
|
||||
@@ -3759,6 +3766,7 @@ static void builtin_diff(const char *name_a,
|
||||
xpparam_t xpp;
|
||||
xdemitconf_t xecfg;
|
||||
struct emit_callback ecbdata;
|
||||
unsigned ws_rule;
|
||||
const struct userdiff_funcname *pe;
|
||||
|
||||
if (must_show_header) {
|
||||
@@ -3770,6 +3778,12 @@ static void builtin_diff(const char *name_a,
|
||||
mf1.size = fill_textconv(o->repo, textconv_one, one, &mf1.ptr);
|
||||
mf2.size = fill_textconv(o->repo, textconv_two, two, &mf2.ptr);
|
||||
|
||||
ws_rule = whitespace_rule(o->repo->index, name_b);
|
||||
|
||||
/* symlink being an incomplete line is not a news */
|
||||
if (DIFF_FILE_VALID(two) && S_ISLNK(two->mode))
|
||||
ws_rule &= ~WS_INCOMPLETE_LINE;
|
||||
|
||||
pe = diff_funcname_pattern(o, one);
|
||||
if (!pe)
|
||||
pe = diff_funcname_pattern(o, two);
|
||||
@@ -3781,7 +3795,7 @@ static void builtin_diff(const char *name_a,
|
||||
lbl[0] = NULL;
|
||||
ecbdata.label_path = lbl;
|
||||
ecbdata.color_diff = o->use_color;
|
||||
ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b);
|
||||
ecbdata.ws_rule = ws_rule;
|
||||
if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
|
||||
check_blank_at_eof(&mf1, &mf2, &ecbdata);
|
||||
ecbdata.opt = o;
|
||||
@@ -3988,6 +4002,10 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
|
||||
data.ws_rule = whitespace_rule(o->repo->index, attr_path);
|
||||
data.conflict_marker_size = ll_merge_marker_size(o->repo->index, attr_path);
|
||||
|
||||
/* symlink being an incomplete line is not a news */
|
||||
if (DIFF_FILE_VALID(two) && S_ISLNK(two->mode))
|
||||
data.ws_rule &= ~WS_INCOMPLETE_LINE;
|
||||
|
||||
if (fill_mmfile(o->repo, &mf1, one) < 0 ||
|
||||
fill_mmfile(o->repo, &mf2, two) < 0)
|
||||
die("unable to read files to diff");
|
||||
|
||||
@@ -90,6 +90,32 @@ test_expect_success "new incomplete line in post-image" '
|
||||
git -c core.whitespace=incomplete diff -R --check x
|
||||
'
|
||||
|
||||
test_expect_success SYMLINKS "incomplete-line error is disabled for symlinks" '
|
||||
test_when_finished "git reset --hard" &&
|
||||
test_when_finished "rm -f mylink" &&
|
||||
|
||||
# a regular file with an incomplete line
|
||||
printf "%s" one >mylink &&
|
||||
git add mylink &&
|
||||
|
||||
# a symbolic link
|
||||
rm mylink &&
|
||||
ln -s two mylink &&
|
||||
|
||||
git -c diff.color=always -c core.whitespace=incomplete \
|
||||
diff mylink >forward.raw &&
|
||||
test_decode_color >forward <forward.raw &&
|
||||
test_grep ! "<BRED>\\\\ No newline at end of file<RESET>" forward &&
|
||||
|
||||
git -c diff.color=always -c core.whitespace=incomplete \
|
||||
diff -R mylink >reverse.raw &&
|
||||
test_decode_color >reverse <reverse.raw &&
|
||||
test_grep "<BRED>\\\\ No newline at end of file<RESET>" reverse &&
|
||||
|
||||
git -c core.whitespace=incomplete diff --check mylink &&
|
||||
test_must_fail git -c core.whitespace=incomplete diff --check -R mylink
|
||||
'
|
||||
|
||||
test_expect_success "Ray Lehtiniemi's example" '
|
||||
cat <<-\EOF >x &&
|
||||
do {
|
||||
|
||||
@@ -743,4 +743,90 @@ test_expect_success 'incomplete line modified at the end (error)' '
|
||||
test_cmp sample target
|
||||
'
|
||||
|
||||
test_expect_success "incomplete-line error is disabled for symlinks" '
|
||||
test_when_finished "git reset" &&
|
||||
test_when_finished "rm -f patch.txt" &&
|
||||
oneblob=$(printf "one" | git hash-object --stdin -w -t blob) &&
|
||||
twoblob=$(printf "two" | git hash-object --stdin -w -t blob) &&
|
||||
|
||||
oneshort=$(git rev-parse --short $oneblob) &&
|
||||
twoshort=$(git rev-parse --short $twoblob) &&
|
||||
|
||||
cat >patch0.txt <<-EOF &&
|
||||
diff --git a/mylink b/mylink
|
||||
index $oneshort..$twoshort 120000
|
||||
--- a/mylink
|
||||
+++ b/mylink
|
||||
@@ -1 +1 @@
|
||||
-one
|
||||
\ No newline at end of file
|
||||
+two
|
||||
\ No newline at end of file
|
||||
EOF
|
||||
|
||||
# the index has the preimage symlink
|
||||
git update-index --add --cacheinfo "120000,$oneblob,mylink" &&
|
||||
|
||||
# check the patch going forward and reverse
|
||||
git -c core.whitespace=incomplete apply --cached --check \
|
||||
--whitespace=error patch0.txt &&
|
||||
|
||||
git update-index --add --cacheinfo "120000,$twoblob,mylink" &&
|
||||
git -c core.whitespace=incomplete apply --cached --check \
|
||||
--whitespace=error -R patch0.txt &&
|
||||
|
||||
# the patch turns it into the postimage symlink
|
||||
git update-index --add --cacheinfo "120000,$oneblob,mylink" &&
|
||||
git -c core.whitespace=incomplete apply --cached --whitespace=error \
|
||||
patch0.txt &&
|
||||
|
||||
# and then back.
|
||||
git -c core.whitespace=incomplete apply --cached -R --whitespace=error \
|
||||
patch0.txt &&
|
||||
|
||||
# a text file turns into a symlink
|
||||
cat >patch1.txt <<-EOF &&
|
||||
diff --git a/mylink b/mylink
|
||||
deleted file mode 100644
|
||||
index $oneshort..0000000
|
||||
--- a/mylink
|
||||
+++ /dev/null
|
||||
@@ -1 +0,0 @@
|
||||
-one
|
||||
\ No newline at end of file
|
||||
diff --git a/mylink b/mylink
|
||||
new file mode 120000
|
||||
index 0000000..$twoshort
|
||||
--- /dev/null
|
||||
+++ b/mylink
|
||||
@@ -0,0 +1 @@
|
||||
+two
|
||||
\ No newline at end of file
|
||||
EOF
|
||||
|
||||
# the index has the preimage text
|
||||
git update-index --cacheinfo "100644,$oneblob,mylink" &&
|
||||
|
||||
# check
|
||||
git -c core.whitespace=incomplete apply --cached \
|
||||
--check --whitespace=error patch1.txt &&
|
||||
|
||||
# reverse, leaving an incomplete text file, should error
|
||||
git update-index --cacheinfo "120000,$twoblob,mylink" &&
|
||||
test_must_fail git -c core.whitespace=incomplete \
|
||||
apply --cached --check --whitespace=error -R patch1.txt &&
|
||||
|
||||
# apply to create a symbolic link
|
||||
git update-index --cacheinfo "100644,$oneblob,mylink" &&
|
||||
git -c core.whitespace=incomplete apply --cached --whitespace=error \
|
||||
patch1.txt &&
|
||||
|
||||
# turning it back into an incomplete text file is an error
|
||||
test_must_fail git -c core.whitespace=incomplete \
|
||||
apply --cached --whitespace=error -R patch1.txt
|
||||
|
||||
|
||||
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
Reference in New Issue
Block a user