diff: --ignore-cr-at-eol
A new option --ignore-cr-at-eol tells the diff machinery to treat a carriage-return at the end of a (complete) line as if it does not exist. Just like other "--ignore-*" options to ignore various kinds of whitespace differences, this will help reviewing the real changes you made without getting distracted by spurious CRLF<->LF conversion made by your editor program. Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> [jch: squashed in command line completion by Dscho] Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
446d12cb3f
commit
e9282f02b2
@ -519,6 +519,9 @@ endif::git-format-patch[]
|
|||||||
--text::
|
--text::
|
||||||
Treat all files as text.
|
Treat all files as text.
|
||||||
|
|
||||||
|
--ignore-cr-at-eol::
|
||||||
|
Ignore carrige-return at the end of line when doing a comparison.
|
||||||
|
|
||||||
--ignore-space-at-eol::
|
--ignore-space-at-eol::
|
||||||
Ignore changes in whitespace at EOL.
|
Ignore changes in whitespace at EOL.
|
||||||
|
|
||||||
|
@ -57,11 +57,12 @@ diff-algorithm=[patience|minimal|histogram|myers];;
|
|||||||
ignore-space-change;;
|
ignore-space-change;;
|
||||||
ignore-all-space;;
|
ignore-all-space;;
|
||||||
ignore-space-at-eol;;
|
ignore-space-at-eol;;
|
||||||
|
ignore-cr-at-eol;;
|
||||||
Treats lines with the indicated type of whitespace change as
|
Treats lines with the indicated type of whitespace change as
|
||||||
unchanged for the sake of a three-way merge. Whitespace
|
unchanged for the sake of a three-way merge. Whitespace
|
||||||
changes mixed with other changes to a line are not ignored.
|
changes mixed with other changes to a line are not ignored.
|
||||||
See also linkgit:git-diff[1] `-b`, `-w`, and
|
See also linkgit:git-diff[1] `-b`, `-w`,
|
||||||
`--ignore-space-at-eol`.
|
`--ignore-space-at-eol`, and `--ignore-cr-at-eol`.
|
||||||
+
|
+
|
||||||
* If 'their' version only introduces whitespace changes to a line,
|
* If 'their' version only introduces whitespace changes to a line,
|
||||||
'our' version is used;
|
'our' version is used;
|
||||||
|
@ -1399,7 +1399,7 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
|
|||||||
--patch-with-stat --name-only --name-status --color
|
--patch-with-stat --name-only --name-status --color
|
||||||
--no-color --color-words --no-renames --check
|
--no-color --color-words --no-renames --check
|
||||||
--full-index --binary --abbrev --diff-filter=
|
--full-index --binary --abbrev --diff-filter=
|
||||||
--find-copies-harder
|
--find-copies-harder --ignore-cr-at-eol
|
||||||
--text --ignore-space-at-eol --ignore-space-change
|
--text --ignore-space-at-eol --ignore-space-change
|
||||||
--ignore-all-space --ignore-blank-lines --exit-code
|
--ignore-all-space --ignore-blank-lines --exit-code
|
||||||
--quiet --ext-diff --no-ext-diff
|
--quiet --ext-diff --no-ext-diff
|
||||||
|
2
diff.c
2
diff.c
@ -3888,6 +3888,8 @@ int diff_opt_parse(struct diff_options *options,
|
|||||||
DIFF_XDL_SET(options, IGNORE_WHITESPACE_CHANGE);
|
DIFF_XDL_SET(options, IGNORE_WHITESPACE_CHANGE);
|
||||||
else if (!strcmp(arg, "--ignore-space-at-eol"))
|
else if (!strcmp(arg, "--ignore-space-at-eol"))
|
||||||
DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
|
DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
|
||||||
|
else if (!strcmp(arg, "--ignore-cr-at-eol"))
|
||||||
|
DIFF_XDL_SET(options, IGNORE_CR_AT_EOL);
|
||||||
else if (!strcmp(arg, "--ignore-blank-lines"))
|
else if (!strcmp(arg, "--ignore-blank-lines"))
|
||||||
DIFF_XDL_SET(options, IGNORE_BLANK_LINES);
|
DIFF_XDL_SET(options, IGNORE_BLANK_LINES);
|
||||||
else if (!strcmp(arg, "--indent-heuristic"))
|
else if (!strcmp(arg, "--indent-heuristic"))
|
||||||
|
@ -2214,6 +2214,8 @@ int parse_merge_opt(struct merge_options *o, const char *s)
|
|||||||
DIFF_XDL_SET(o, IGNORE_WHITESPACE);
|
DIFF_XDL_SET(o, IGNORE_WHITESPACE);
|
||||||
else if (!strcmp(s, "ignore-space-at-eol"))
|
else if (!strcmp(s, "ignore-space-at-eol"))
|
||||||
DIFF_XDL_SET(o, IGNORE_WHITESPACE_AT_EOL);
|
DIFF_XDL_SET(o, IGNORE_WHITESPACE_AT_EOL);
|
||||||
|
else if (!strcmp(s, "ignore-cr-at-eol"))
|
||||||
|
DIFF_XDL_SET(o, IGNORE_CR_AT_EOL);
|
||||||
else if (!strcmp(s, "renormalize"))
|
else if (!strcmp(s, "renormalize"))
|
||||||
o->renormalize = 1;
|
o->renormalize = 1;
|
||||||
else if (!strcmp(s, "no-renormalize"))
|
else if (!strcmp(s, "no-renormalize"))
|
||||||
|
@ -106,6 +106,8 @@ test_expect_success 'another test, without options' '
|
|||||||
git diff -w -b --ignore-space-at-eol >out &&
|
git diff -w -b --ignore-space-at-eol >out &&
|
||||||
test_cmp expect out &&
|
test_cmp expect out &&
|
||||||
|
|
||||||
|
git diff -w --ignore-cr-at-eol >out &&
|
||||||
|
test_cmp expect out &&
|
||||||
|
|
||||||
tr "Q_" "\015 " <<-\EOF >expect &&
|
tr "Q_" "\015 " <<-\EOF >expect &&
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
@ -128,6 +130,9 @@ test_expect_success 'another test, without options' '
|
|||||||
git diff -b --ignore-space-at-eol >out &&
|
git diff -b --ignore-space-at-eol >out &&
|
||||||
test_cmp expect out &&
|
test_cmp expect out &&
|
||||||
|
|
||||||
|
git diff -b --ignore-cr-at-eol >out &&
|
||||||
|
test_cmp expect out &&
|
||||||
|
|
||||||
tr "Q_" "\015 " <<-\EOF >expect &&
|
tr "Q_" "\015 " <<-\EOF >expect &&
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
index d99af23..22d9f73 100644
|
index d99af23..22d9f73 100644
|
||||||
@ -145,6 +150,29 @@ test_expect_success 'another test, without options' '
|
|||||||
CR at end
|
CR at end
|
||||||
EOF
|
EOF
|
||||||
git diff --ignore-space-at-eol >out &&
|
git diff --ignore-space-at-eol >out &&
|
||||||
|
test_cmp expect out &&
|
||||||
|
|
||||||
|
git diff --ignore-space-at-eol --ignore-cr-at-eol >out &&
|
||||||
|
test_cmp expect out &&
|
||||||
|
|
||||||
|
tr "Q_" "\015 " <<-\EOF >expect &&
|
||||||
|
diff --git a/x b/x
|
||||||
|
index_d99af23..22d9f73 100644
|
||||||
|
--- a/x
|
||||||
|
+++ b/x
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
-whitespace at beginning
|
||||||
|
-whitespace change
|
||||||
|
-whitespace in the middle
|
||||||
|
-whitespace at end
|
||||||
|
+_ whitespace at beginning
|
||||||
|
+whitespace_ _change
|
||||||
|
+white space in the middle
|
||||||
|
+whitespace at end__
|
||||||
|
unchanged line
|
||||||
|
CR at end
|
||||||
|
EOF
|
||||||
|
git diff --ignore-cr-at-eol >out &&
|
||||||
test_cmp expect out
|
test_cmp expect out
|
||||||
'
|
'
|
||||||
|
|
||||||
|
@ -33,9 +33,11 @@ extern "C" {
|
|||||||
#define XDF_IGNORE_WHITESPACE (1 << 1)
|
#define XDF_IGNORE_WHITESPACE (1 << 1)
|
||||||
#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 2)
|
#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 2)
|
||||||
#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 3)
|
#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 3)
|
||||||
|
#define XDF_IGNORE_CR_AT_EOL (1 << 4)
|
||||||
#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | \
|
#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | \
|
||||||
XDF_IGNORE_WHITESPACE_CHANGE | \
|
XDF_IGNORE_WHITESPACE_CHANGE | \
|
||||||
XDF_IGNORE_WHITESPACE_AT_EOL)
|
XDF_IGNORE_WHITESPACE_AT_EOL | \
|
||||||
|
XDF_IGNORE_CR_AT_EOL)
|
||||||
|
|
||||||
#define XDF_IGNORE_BLANK_LINES (1 << 7)
|
#define XDF_IGNORE_BLANK_LINES (1 << 7)
|
||||||
|
|
||||||
|
@ -156,6 +156,24 @@ int xdl_blankline(const char *line, long size, long flags)
|
|||||||
return (i == size);
|
return (i == size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Have we eaten everything on the line, except for an optional
|
||||||
|
* CR at the very end?
|
||||||
|
*/
|
||||||
|
static int ends_with_optional_cr(const char *l, long s, long i)
|
||||||
|
{
|
||||||
|
int complete = s && l[s-1] == '\n';
|
||||||
|
|
||||||
|
if (complete)
|
||||||
|
s--;
|
||||||
|
if (s == i)
|
||||||
|
return 1;
|
||||||
|
/* do not ignore CR at the end of an incomplete line */
|
||||||
|
if (complete && s == i + 1 && l[i] == '\r')
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
|
int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
|
||||||
{
|
{
|
||||||
int i1, i2;
|
int i1, i2;
|
||||||
@ -170,7 +188,8 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* -w matches everything that matches with -b, and -b in turn
|
* -w matches everything that matches with -b, and -b in turn
|
||||||
* matches everything that matches with --ignore-space-at-eol.
|
* matches everything that matches with --ignore-space-at-eol,
|
||||||
|
* which in turn matches everything that matches with --ignore-cr-at-eol.
|
||||||
*
|
*
|
||||||
* Each flavor of ignoring needs different logic to skip whitespaces
|
* Each flavor of ignoring needs different logic to skip whitespaces
|
||||||
* while we have both sides to compare.
|
* while we have both sides to compare.
|
||||||
@ -204,6 +223,14 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
|
|||||||
i1++;
|
i1++;
|
||||||
i2++;
|
i2++;
|
||||||
}
|
}
|
||||||
|
} else if (flags & XDF_IGNORE_CR_AT_EOL) {
|
||||||
|
/* Find the first difference and see how the line ends */
|
||||||
|
while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) {
|
||||||
|
i1++;
|
||||||
|
i2++;
|
||||||
|
}
|
||||||
|
return (ends_with_optional_cr(l1, s1, i1) &&
|
||||||
|
ends_with_optional_cr(l2, s2, i2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -230,9 +257,16 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data,
|
|||||||
char const *top, long flags) {
|
char const *top, long flags) {
|
||||||
unsigned long ha = 5381;
|
unsigned long ha = 5381;
|
||||||
char const *ptr = *data;
|
char const *ptr = *data;
|
||||||
|
int cr_at_eol_only = (flags & XDF_WHITESPACE_FLAGS) == XDF_IGNORE_CR_AT_EOL;
|
||||||
|
|
||||||
for (; ptr < top && *ptr != '\n'; ptr++) {
|
for (; ptr < top && *ptr != '\n'; ptr++) {
|
||||||
if (XDL_ISSPACE(*ptr)) {
|
if (cr_at_eol_only) {
|
||||||
|
/* do not ignore CR at the end of an incomplete line */
|
||||||
|
if (*ptr == '\r' &&
|
||||||
|
(ptr + 1 < top && ptr[1] == '\n'))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (XDL_ISSPACE(*ptr)) {
|
||||||
const char *ptr2 = ptr;
|
const char *ptr2 = ptr;
|
||||||
int at_eol;
|
int at_eol;
|
||||||
while (ptr + 1 < top && XDL_ISSPACE(ptr[1])
|
while (ptr + 1 < top && XDL_ISSPACE(ptr[1])
|
||||||
|
Loading…
Reference in New Issue
Block a user