Merge branch 'ap/combine-diff-ignore-whitespace'
Teach "diff --cc" output to honor options to ignore various forms of whitespace changes. * ap/combine-diff-ignore-whitespace: Allow combined diff to ignore white-spaces
This commit is contained in:
@ -5,6 +5,7 @@
|
|||||||
#include "diffcore.h"
|
#include "diffcore.h"
|
||||||
#include "quote.h"
|
#include "quote.h"
|
||||||
#include "xdiff-interface.h"
|
#include "xdiff-interface.h"
|
||||||
|
#include "xdiff/xmacros.h"
|
||||||
#include "log-tree.h"
|
#include "log-tree.h"
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
#include "userdiff.h"
|
#include "userdiff.h"
|
||||||
@ -122,7 +123,47 @@ static char *grab_blob(const unsigned char *sha1, unsigned int mode,
|
|||||||
return blob;
|
return blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append_lost(struct sline *sline, int n, const char *line, int len)
|
static int match_string_spaces(const char *line1, int len1,
|
||||||
|
const char *line2, int len2,
|
||||||
|
long flags)
|
||||||
|
{
|
||||||
|
if (flags & XDF_WHITESPACE_FLAGS) {
|
||||||
|
for (; len1 > 0 && XDL_ISSPACE(line1[len1 - 1]); len1--);
|
||||||
|
for (; len2 > 0 && XDL_ISSPACE(line2[len2 - 1]); len2--);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(flags & (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE)))
|
||||||
|
return (len1 == len2 && !memcmp(line1, line2, len1));
|
||||||
|
|
||||||
|
while (len1 > 0 && len2 > 0) {
|
||||||
|
len1--;
|
||||||
|
len2--;
|
||||||
|
if (XDL_ISSPACE(line1[len1]) || XDL_ISSPACE(line2[len2])) {
|
||||||
|
if ((flags & XDF_IGNORE_WHITESPACE_CHANGE) &&
|
||||||
|
(!XDL_ISSPACE(line1[len1]) || !XDL_ISSPACE(line2[len2])))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (; len1 > 0 && XDL_ISSPACE(line1[len1]); len1--);
|
||||||
|
for (; len2 > 0 && XDL_ISSPACE(line2[len2]); len2--);
|
||||||
|
}
|
||||||
|
if (line1[len1] != line2[len2])
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & XDF_IGNORE_WHITESPACE) {
|
||||||
|
/* Consume remaining spaces */
|
||||||
|
for (; len1 > 0 && XDL_ISSPACE(line1[len1 - 1]); len1--);
|
||||||
|
for (; len2 > 0 && XDL_ISSPACE(line2[len2 - 1]); len2--);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We matched full line1 and line2 */
|
||||||
|
if (!len1 && !len2)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void append_lost(struct sline *sline, int n, const char *line, int len, long flags)
|
||||||
{
|
{
|
||||||
struct lline *lline;
|
struct lline *lline;
|
||||||
unsigned long this_mask = (1UL<<n);
|
unsigned long this_mask = (1UL<<n);
|
||||||
@ -133,8 +174,8 @@ static void append_lost(struct sline *sline, int n, const char *line, int len)
|
|||||||
if (sline->lost_head) {
|
if (sline->lost_head) {
|
||||||
lline = sline->next_lost;
|
lline = sline->next_lost;
|
||||||
while (lline) {
|
while (lline) {
|
||||||
if (lline->len == len &&
|
if (match_string_spaces(lline->line, lline->len,
|
||||||
!memcmp(lline->line, line, len)) {
|
line, len, flags)) {
|
||||||
lline->parent_map |= this_mask;
|
lline->parent_map |= this_mask;
|
||||||
sline->next_lost = lline->next;
|
sline->next_lost = lline->next;
|
||||||
return;
|
return;
|
||||||
@ -162,6 +203,7 @@ struct combine_diff_state {
|
|||||||
int n;
|
int n;
|
||||||
struct sline *sline;
|
struct sline *sline;
|
||||||
struct sline *lost_bucket;
|
struct sline *lost_bucket;
|
||||||
|
long flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void consume_line(void *state_, char *line, unsigned long len)
|
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)
|
|||||||
return; /* not in any hunk yet */
|
return; /* not in any hunk yet */
|
||||||
switch (line[0]) {
|
switch (line[0]) {
|
||||||
case '-':
|
case '-':
|
||||||
append_lost(state->lost_bucket, state->n, line+1, len-1);
|
append_lost(state->lost_bucket, state->n, line+1, len-1, state->flags);
|
||||||
break;
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
state->sline[state->lno-1].flag |= state->nmask;
|
state->sline[state->lno-1].flag |= state->nmask;
|
||||||
@ -215,7 +257,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
|
|||||||
struct sline *sline, unsigned int cnt, int n,
|
struct sline *sline, unsigned int cnt, int n,
|
||||||
int num_parent, int result_deleted,
|
int num_parent, int result_deleted,
|
||||||
struct userdiff_driver *textconv,
|
struct userdiff_driver *textconv,
|
||||||
const char *path)
|
const char *path, long flags)
|
||||||
{
|
{
|
||||||
unsigned int p_lno, lno;
|
unsigned int p_lno, lno;
|
||||||
unsigned long nmask = (1UL << n);
|
unsigned long nmask = (1UL << n);
|
||||||
@ -231,9 +273,10 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
|
|||||||
parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path);
|
parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path);
|
||||||
parent_file.size = sz;
|
parent_file.size = sz;
|
||||||
memset(&xpp, 0, sizeof(xpp));
|
memset(&xpp, 0, sizeof(xpp));
|
||||||
xpp.flags = 0;
|
xpp.flags = flags;
|
||||||
memset(&xecfg, 0, sizeof(xecfg));
|
memset(&xecfg, 0, sizeof(xecfg));
|
||||||
memset(&state, 0, sizeof(state));
|
memset(&state, 0, sizeof(state));
|
||||||
|
state.flags = flags;
|
||||||
state.nmask = nmask;
|
state.nmask = nmask;
|
||||||
state.sline = sline;
|
state.sline = sline;
|
||||||
state.lno = 1;
|
state.lno = 1;
|
||||||
@ -962,7 +1005,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
|
|||||||
elem->parent[i].mode,
|
elem->parent[i].mode,
|
||||||
&result_file, sline,
|
&result_file, sline,
|
||||||
cnt, i, num_parent, result_deleted,
|
cnt, i, num_parent, result_deleted,
|
||||||
textconv, elem->path);
|
textconv, elem->path, opt->xdl_opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
show_hunks = make_hunks(sline, cnt, num_parent, dense);
|
show_hunks = make_hunks(sline, cnt, num_parent, dense);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
test_description='combined diff'
|
test_description='combined diff'
|
||||||
|
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
. "$TEST_DIRECTORY"/diff-lib.sh
|
||||||
|
|
||||||
setup_helper () {
|
setup_helper () {
|
||||||
one=$1 branch=$2 side=$3 &&
|
one=$1 branch=$2 side=$3 &&
|
||||||
@ -113,4 +114,114 @@ test_expect_success 'check --cc --raw with forty trees' '
|
|||||||
grep "^::::::::::::::::::::::::::::::::::::::::[^:]" out
|
grep "^::::::::::::::::::::::::::::::::::::::::[^:]" out
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'setup combined ignore spaces' '
|
||||||
|
git checkout master &&
|
||||||
|
>test &&
|
||||||
|
git add test &&
|
||||||
|
git commit -m initial &&
|
||||||
|
|
||||||
|
tr -d Q <<-\EOF >test &&
|
||||||
|
always coalesce
|
||||||
|
eol space coalesce Q
|
||||||
|
space change coalesce
|
||||||
|
all spa ces coalesce
|
||||||
|
eol spaces Q
|
||||||
|
space change
|
||||||
|
all spa ces
|
||||||
|
EOF
|
||||||
|
git commit -m "test space change" -a &&
|
||||||
|
|
||||||
|
git checkout -b side HEAD^ &&
|
||||||
|
tr -d Q <<-\EOF >test &&
|
||||||
|
always coalesce
|
||||||
|
eol space coalesce
|
||||||
|
space change coalesce
|
||||||
|
all spaces coalesce
|
||||||
|
eol spaces
|
||||||
|
space change
|
||||||
|
all spaces
|
||||||
|
EOF
|
||||||
|
git commit -m "test other space changes" -a &&
|
||||||
|
|
||||||
|
test_must_fail git merge master &&
|
||||||
|
tr -d Q <<-\EOF >test &&
|
||||||
|
eol spaces Q
|
||||||
|
space change
|
||||||
|
all spa ces
|
||||||
|
EOF
|
||||||
|
git commit -m merged -a
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'check combined output (no ignore space)' '
|
||||||
|
git show >actual.tmp &&
|
||||||
|
sed -e "1,/^@@@/d" < actual.tmp >actual &&
|
||||||
|
tr -d Q <<-\EOF >expected &&
|
||||||
|
--always coalesce
|
||||||
|
- eol space coalesce
|
||||||
|
- space change coalesce
|
||||||
|
- all spaces coalesce
|
||||||
|
- eol spaces
|
||||||
|
- space change
|
||||||
|
- all spaces
|
||||||
|
-eol space coalesce Q
|
||||||
|
-space change coalesce
|
||||||
|
-all spa ces coalesce
|
||||||
|
+ eol spaces Q
|
||||||
|
+ space change
|
||||||
|
+ all spa ces
|
||||||
|
EOF
|
||||||
|
compare_diff_patch expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'check combined output (ignore space at eol)' '
|
||||||
|
git show --ignore-space-at-eol >actual.tmp &&
|
||||||
|
sed -e "1,/^@@@/d" < actual.tmp >actual &&
|
||||||
|
tr -d Q <<-\EOF >expected &&
|
||||||
|
--always coalesce
|
||||||
|
--eol space coalesce
|
||||||
|
- space change coalesce
|
||||||
|
- all spaces coalesce
|
||||||
|
-space change coalesce
|
||||||
|
-all spa ces coalesce
|
||||||
|
eol spaces Q
|
||||||
|
- space change
|
||||||
|
- all spaces
|
||||||
|
+ space change
|
||||||
|
+ all spa ces
|
||||||
|
EOF
|
||||||
|
compare_diff_patch expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'check combined output (ignore space change)' '
|
||||||
|
git show -b >actual.tmp &&
|
||||||
|
sed -e "1,/^@@@/d" < actual.tmp >actual &&
|
||||||
|
tr -d Q <<-\EOF >expected &&
|
||||||
|
--always coalesce
|
||||||
|
--eol space coalesce
|
||||||
|
--space change coalesce
|
||||||
|
- all spaces coalesce
|
||||||
|
-all spa ces coalesce
|
||||||
|
eol spaces Q
|
||||||
|
space change
|
||||||
|
- all spaces
|
||||||
|
+ all spa ces
|
||||||
|
EOF
|
||||||
|
compare_diff_patch expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'check combined output (ignore all spaces)' '
|
||||||
|
git show -w >actual.tmp &&
|
||||||
|
sed -e "1,/^@@@/d" < actual.tmp >actual &&
|
||||||
|
tr -d Q <<-\EOF >expected &&
|
||||||
|
--always coalesce
|
||||||
|
--eol space coalesce
|
||||||
|
--space change coalesce
|
||||||
|
--all spaces coalesce
|
||||||
|
eol spaces Q
|
||||||
|
space change
|
||||||
|
all spa ces
|
||||||
|
EOF
|
||||||
|
compare_diff_patch expected actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Reference in New Issue
Block a user