Skip to content

Commit 2c697a6

Browse files
committed
Merge branch 'ap/combine-diff-ignore-whitespace' into maint
* ap/combine-diff-ignore-whitespace: Allow combined diff to ignore white-spaces
2 parents 4aaafdc + fa04ae0 commit 2c697a6

File tree

2 files changed

+161
-7
lines changed

2 files changed

+161
-7
lines changed

combine-diff.c

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "diffcore.h"
66
#include "quote.h"
77
#include "xdiff-interface.h"
8+
#include "xdiff/xmacros.h"
89
#include "log-tree.h"
910
#include "refs.h"
1011
#include "userdiff.h"
@@ -122,7 +123,47 @@ static char *grab_blob(const unsigned char *sha1, unsigned int mode,
122123
return blob;
123124
}
124125

125-
static void append_lost(struct sline *sline, int n, const char *line, int len)
126+
static int match_string_spaces(const char *line1, int len1,
127+
const char *line2, int len2,
128+
long flags)
129+
{
130+
if (flags & XDF_WHITESPACE_FLAGS) {
131+
for (; len1 > 0 && XDL_ISSPACE(line1[len1 - 1]); len1--);
132+
for (; len2 > 0 && XDL_ISSPACE(line2[len2 - 1]); len2--);
133+
}
134+
135+
if (!(flags & (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE)))
136+
return (len1 == len2 && !memcmp(line1, line2, len1));
137+
138+
while (len1 > 0 && len2 > 0) {
139+
len1--;
140+
len2--;
141+
if (XDL_ISSPACE(line1[len1]) || XDL_ISSPACE(line2[len2])) {
142+
if ((flags & XDF_IGNORE_WHITESPACE_CHANGE) &&
143+
(!XDL_ISSPACE(line1[len1]) || !XDL_ISSPACE(line2[len2])))
144+
return 0;
145+
146+
for (; len1 > 0 && XDL_ISSPACE(line1[len1]); len1--);
147+
for (; len2 > 0 && XDL_ISSPACE(line2[len2]); len2--);
148+
}
149+
if (line1[len1] != line2[len2])
150+
return 0;
151+
}
152+
153+
if (flags & XDF_IGNORE_WHITESPACE) {
154+
/* Consume remaining spaces */
155+
for (; len1 > 0 && XDL_ISSPACE(line1[len1 - 1]); len1--);
156+
for (; len2 > 0 && XDL_ISSPACE(line2[len2 - 1]); len2--);
157+
}
158+
159+
/* We matched full line1 and line2 */
160+
if (!len1 && !len2)
161+
return 1;
162+
163+
return 0;
164+
}
165+
166+
static void append_lost(struct sline *sline, int n, const char *line, int len, long flags)
126167
{
127168
struct lline *lline;
128169
unsigned long this_mask = (1UL<<n);
@@ -133,8 +174,8 @@ static void append_lost(struct sline *sline, int n, const char *line, int len)
133174
if (sline->lost_head) {
134175
lline = sline->next_lost;
135176
while (lline) {
136-
if (lline->len == len &&
137-
!memcmp(lline->line, line, len)) {
177+
if (match_string_spaces(lline->line, lline->len,
178+
line, len, flags)) {
138179
lline->parent_map |= this_mask;
139180
sline->next_lost = lline->next;
140181
return;
@@ -162,6 +203,7 @@ struct combine_diff_state {
162203
int n;
163204
struct sline *sline;
164205
struct sline *lost_bucket;
206+
long flags;
165207
};
166208

167209
static void consume_line(void *state_, char *line, unsigned long len)
@@ -201,7 +243,7 @@ static void consume_line(void *state_, char *line, unsigned long len)
201243
return; /* not in any hunk yet */
202244
switch (line[0]) {
203245
case '-':
204-
append_lost(state->lost_bucket, state->n, line+1, len-1);
246+
append_lost(state->lost_bucket, state->n, line+1, len-1, state->flags);
205247
break;
206248
case '+':
207249
state->sline[state->lno-1].flag |= state->nmask;
@@ -215,7 +257,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
215257
struct sline *sline, unsigned int cnt, int n,
216258
int num_parent, int result_deleted,
217259
struct userdiff_driver *textconv,
218-
const char *path)
260+
const char *path, long flags)
219261
{
220262
unsigned int p_lno, lno;
221263
unsigned long nmask = (1UL << n);
@@ -231,9 +273,10 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
231273
parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path);
232274
parent_file.size = sz;
233275
memset(&xpp, 0, sizeof(xpp));
234-
xpp.flags = 0;
276+
xpp.flags = flags;
235277
memset(&xecfg, 0, sizeof(xecfg));
236278
memset(&state, 0, sizeof(state));
279+
state.flags = flags;
237280
state.nmask = nmask;
238281
state.sline = sline;
239282
state.lno = 1;
@@ -962,7 +1005,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
9621005
elem->parent[i].mode,
9631006
&result_file, sline,
9641007
cnt, i, num_parent, result_deleted,
965-
textconv, elem->path);
1008+
textconv, elem->path, opt->xdl_opts);
9661009
}
9671010

9681011
show_hunks = make_hunks(sline, cnt, num_parent, dense);

t/t4038-diff-combined.sh

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
test_description='combined diff'
44

55
. ./test-lib.sh
6+
. "$TEST_DIRECTORY"/diff-lib.sh
67

78
setup_helper () {
89
one=$1 branch=$2 side=$3 &&
@@ -113,4 +114,114 @@ test_expect_success 'check --cc --raw with forty trees' '
113114
grep "^::::::::::::::::::::::::::::::::::::::::[^:]" out
114115
'
115116

117+
test_expect_success 'setup combined ignore spaces' '
118+
git checkout master &&
119+
>test &&
120+
git add test &&
121+
git commit -m initial &&
122+
123+
tr -d Q <<-\EOF >test &&
124+
always coalesce
125+
eol space coalesce Q
126+
space change coalesce
127+
all spa ces coalesce
128+
eol spaces Q
129+
space change
130+
all spa ces
131+
EOF
132+
git commit -m "test space change" -a &&
133+
134+
git checkout -b side HEAD^ &&
135+
tr -d Q <<-\EOF >test &&
136+
always coalesce
137+
eol space coalesce
138+
space change coalesce
139+
all spaces coalesce
140+
eol spaces
141+
space change
142+
all spaces
143+
EOF
144+
git commit -m "test other space changes" -a &&
145+
146+
test_must_fail git merge master &&
147+
tr -d Q <<-\EOF >test &&
148+
eol spaces Q
149+
space change
150+
all spa ces
151+
EOF
152+
git commit -m merged -a
153+
'
154+
155+
test_expect_success 'check combined output (no ignore space)' '
156+
git show >actual.tmp &&
157+
sed -e "1,/^@@@/d" < actual.tmp >actual &&
158+
tr -d Q <<-\EOF >expected &&
159+
--always coalesce
160+
- eol space coalesce
161+
- space change coalesce
162+
- all spaces coalesce
163+
- eol spaces
164+
- space change
165+
- all spaces
166+
-eol space coalesce Q
167+
-space change coalesce
168+
-all spa ces coalesce
169+
+ eol spaces Q
170+
+ space change
171+
+ all spa ces
172+
EOF
173+
compare_diff_patch expected actual
174+
'
175+
176+
test_expect_success 'check combined output (ignore space at eol)' '
177+
git show --ignore-space-at-eol >actual.tmp &&
178+
sed -e "1,/^@@@/d" < actual.tmp >actual &&
179+
tr -d Q <<-\EOF >expected &&
180+
--always coalesce
181+
--eol space coalesce
182+
- space change coalesce
183+
- all spaces coalesce
184+
-space change coalesce
185+
-all spa ces coalesce
186+
eol spaces Q
187+
- space change
188+
- all spaces
189+
+ space change
190+
+ all spa ces
191+
EOF
192+
compare_diff_patch expected actual
193+
'
194+
195+
test_expect_success 'check combined output (ignore space change)' '
196+
git show -b >actual.tmp &&
197+
sed -e "1,/^@@@/d" < actual.tmp >actual &&
198+
tr -d Q <<-\EOF >expected &&
199+
--always coalesce
200+
--eol space coalesce
201+
--space change coalesce
202+
- all spaces coalesce
203+
-all spa ces coalesce
204+
eol spaces Q
205+
space change
206+
- all spaces
207+
+ all spa ces
208+
EOF
209+
compare_diff_patch expected actual
210+
'
211+
212+
test_expect_success 'check combined output (ignore all spaces)' '
213+
git show -w >actual.tmp &&
214+
sed -e "1,/^@@@/d" < actual.tmp >actual &&
215+
tr -d Q <<-\EOF >expected &&
216+
--always coalesce
217+
--eol space coalesce
218+
--space change coalesce
219+
--all spaces coalesce
220+
eol spaces Q
221+
space change
222+
all spa ces
223+
EOF
224+
compare_diff_patch expected actual
225+
'
226+
116227
test_done

0 commit comments

Comments
 (0)