From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH v2 2/2] diff: --ignore-cr-at-eol
Date: Tue, 7 Nov 2017 15:40:11 +0900 [thread overview]
Message-ID: <20171107064011.18399-3-gitster@pobox.com> (raw)
In-Reply-To: <20171107064011.18399-1-gitster@pobox.com>
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.
This would make it easier to review a change whose only effect is to
turn line endings from CRLF to LF or the other way around.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/diff-options.txt | 3 +++
Documentation/merge-strategies.txt | 5 +++--
diff.c | 2 ++
merge-recursive.c | 2 ++
t/t4015-diff-whitespace.sh | 28 ++++++++++++++++++++++++++++
xdiff/xdiff.h | 4 +++-
xdiff/xutils.c | 38 ++++++++++++++++++++++++++++++++++++--
7 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 89cc0f48de..aa2c0ff74d 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -519,6 +519,9 @@ endif::git-format-patch[]
--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 changes in whitespace at EOL.
diff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.txt
index 2eb92b9327..030744910e 100644
--- a/Documentation/merge-strategies.txt
+++ b/Documentation/merge-strategies.txt
@@ -57,11 +57,12 @@ diff-algorithm=[patience|minimal|histogram|myers];;
ignore-space-change;;
ignore-all-space;;
ignore-space-at-eol;;
+ignore-cr-at-eol;;
Treats lines with the indicated type of whitespace change as
unchanged for the sake of a three-way merge. Whitespace
changes mixed with other changes to a line are not ignored.
- See also linkgit:git-diff[1] `-b`, `-w`, and
- `--ignore-space-at-eol`.
+ See also linkgit:git-diff[1] `-b`, `-w`,
+ `--ignore-space-at-eol`, and `--ignore-cr-at-eol`.
+
* If 'their' version only introduces whitespace changes to a line,
'our' version is used;
diff --git a/diff.c b/diff.c
index 790250fe86..dd14e4190c 100644
--- a/diff.c
+++ b/diff.c
@@ -3888,6 +3888,8 @@ int diff_opt_parse(struct diff_options *options,
DIFF_XDL_SET(options, IGNORE_WHITESPACE_CHANGE);
else if (!strcmp(arg, "--ignore-space-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"))
DIFF_XDL_SET(options, IGNORE_BLANK_LINES);
else if (!strcmp(arg, "--indent-heuristic"))
diff --git a/merge-recursive.c b/merge-recursive.c
index 7a7d55aabe..006b94baf2 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -2214,6 +2214,8 @@ int parse_merge_opt(struct merge_options *o, const char *s)
DIFF_XDL_SET(o, IGNORE_WHITESPACE);
else if (!strcmp(s, "ignore-space-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"))
o->renormalize = 1;
else if (!strcmp(s, "no-renormalize"))
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index 289806d0c7..32dd54c21d 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -106,6 +106,8 @@ test_expect_success 'another test, without options' '
git diff -w -b --ignore-space-at-eol >out &&
test_cmp expect out &&
+ git diff -w --ignore-cr-at-eol >out &&
+ test_cmp expect out &&
tr "Q_" "\015 " <<-\EOF >expect &&
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 &&
test_cmp expect out &&
+ git diff -b --ignore-cr-at-eol >out &&
+ test_cmp expect out &&
+
tr "Q_" "\015 " <<-\EOF >expect &&
diff --git a/x b/x
index d99af23..22d9f73 100644
@@ -145,6 +150,29 @@ test_expect_success 'another test, without options' '
CR at end
EOF
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
'
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index cbf5d8e166..51f8926215 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -33,9 +33,11 @@ extern "C" {
#define XDF_IGNORE_WHITESPACE (1 << 1)
#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 2)
#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 3)
+#define XDF_IGNORE_CR_AT_EOL (1 << 4)
#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | \
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)
diff --git a/xdiff/xutils.c b/xdiff/xutils.c
index 04d7b32e4e..b2cbcc818f 100644
--- a/xdiff/xutils.c
+++ b/xdiff/xutils.c
@@ -156,6 +156,24 @@ int xdl_blankline(const char *line, long size, long flags)
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 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
- * 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
* 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++;
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) {
unsigned long ha = 5381;
char const *ptr = *data;
+ int cr_at_eol_only = (flags & XDF_WHITESPACE_FLAGS) == XDF_IGNORE_CR_AT_EOL;
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;
int at_eol;
while (ptr + 1 < top && XDL_ISSPACE(ptr[1])
--
2.15.0-263-g47cc852023
next prev parent reply other threads:[~2017-11-07 6:40 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-24 17:48 Consequences of CRLF in index? Lars Schneider
2017-10-24 18:14 ` Jonathan Nieder
2017-10-24 19:02 ` Torsten Bögershausen
2017-10-25 12:13 ` Johannes Schindelin
2017-10-25 1:51 ` Junio C Hamano
2017-10-25 4:53 ` Junio C Hamano
2017-10-25 16:44 ` Stefan Beller
2017-10-26 5:54 ` Junio C Hamano
2017-10-27 6:13 ` Re* " Junio C Hamano
2017-10-27 17:06 ` Stefan Beller
2017-10-27 17:07 ` [PATCH 0/2] " Stefan Beller
2017-10-27 17:07 ` [PATCH 1/2] xdiff/xdiff.h: remove unused flags Stefan Beller
2017-10-27 17:07 ` [PATCH 2/2] xdiff/xdiffi.c: remove unneeded function declarations Stefan Beller
2017-10-30 17:20 ` [PATCH 0/2] Re* Consequences of CRLF in index? Stefan Beller
2017-10-31 2:44 ` Junio C Hamano
2017-10-31 16:41 ` Stefan Beller
2017-10-31 17:01 ` Jeff King
2017-11-07 6:40 ` [PATCH v2 0/2] Teach "diff" to ignore only CR at EOL Junio C Hamano
2017-11-07 6:40 ` [PATCH v2 1/2] xdiff: reassign xpparm_t.flags bits Junio C Hamano
2017-11-07 12:44 ` Johannes Schindelin
2017-11-07 15:02 ` Junio C Hamano
2017-11-07 6:40 ` Junio C Hamano [this message]
2017-11-07 13:23 ` [PATCH v2 2/2] diff: --ignore-cr-at-eol Johannes Schindelin
2017-11-08 0:43 ` Junio C Hamano
2017-11-08 0:49 ` Junio C Hamano
2017-11-15 4:28 ` Junio C Hamano
2017-11-07 12:30 ` [PATCH v2 0/2] Teach "diff" to ignore only CR at EOL Johannes Schindelin
2017-11-07 15:12 ` Junio C Hamano
2017-11-07 17:42 ` Stefan Beller
2017-10-25 17:04 ` Consequences of CRLF in index? Lars Schneider
2017-10-25 17:13 ` Jonathan Nieder
2017-10-26 11:06 ` Lars Schneider
2017-10-26 19:15 ` Torsten Bögershausen
2017-10-24 21:04 ` Johannes Sixt
2017-10-25 12:19 ` Johannes Schindelin
2017-10-26 7:09 ` Johannes Sixt
2017-10-26 11:01 ` Lars Schneider
2017-10-26 19:22 ` Torsten Bögershausen
2017-10-26 20:20 ` Johannes Sixt
2017-10-26 20:30 ` Jonathan Nieder
2017-10-26 20:51 ` Johannes Sixt
2017-10-26 22:27 ` Ross Kabus
2017-10-27 1:05 ` Junio C Hamano
2017-10-27 15:18 ` Johannes Schindelin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171107064011.18399-3-gitster@pobox.com \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.