Skip to content

Commit

Permalink
diff: add --ignore-blank-lines option
Browse files Browse the repository at this point in the history
The goal of the patch is to introduce the GNU diff
-B/--ignore-blank-lines as closely as possible. The short option is not
available because it's already used for "break-rewrites".

When this option is used, git-diff will not create hunks that simply
add or remove empty lines, but will still show empty lines
addition/suppression if they are close enough to "valuable" changes.

There are two differences between this option and GNU diff -B option:
- GNU diff doesn't have "--inter-hunk-context", so this must be handled
- The following sequence looks like a bug (context is displayed twice):

    $ seq 5 >file1
    $ cat <<EOF >file2
    change
    1
    2

    3
    4
    5
    change
    EOF
    $ diff -u -B file1 file2
    --- file1	2013-06-08 22:13:04.471517834 +0200
    +++ file2	2013-06-08 22:13:23.275517855 +0200
    @@ -1,5 +1,7 @@
    +change
     1
     2
    +
     3
     4
     5
    @@ -3,3 +5,4 @@
     3
     4
     5
    +change

So here is a more thorough description of the option:
- real changes are interesting
- blank lines that are close enough (less than context size) to
interesting changes are considered interesting (recursive definition)
- "context" lines are used around each hunk of interesting changes
- If two hunks are separated by less than "inter-hunk-context", they
will be merged into one.

The implementation does the "interesting changes selection" in a single
pass.

Signed-off-by: Antoine Pelisse <apelisse@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
apelisse authored and gitster committed Jun 19, 2013
1 parent edca415 commit 36617af
Show file tree
Hide file tree
Showing 10 changed files with 439 additions and 8 deletions.
3 changes: 3 additions & 0 deletions Documentation/diff-options.txt
Expand Up @@ -439,6 +439,9 @@ endif::git-format-patch[]
differences even if one line has whitespace where the other
line has none.

--ignore-blank-lines::
Ignore changes whose lines are all blank.

--inter-hunk-context=<lines>::
Show the context between diff hunks, up to the specified number
of lines, thereby fusing hunks that are close to each other.
Expand Down
2 changes: 2 additions & 0 deletions diff.c
Expand Up @@ -3593,6 +3593,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
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-blank-lines"))
DIFF_XDL_SET(options, IGNORE_BLANK_LINES);
else if (!strcmp(arg, "--patience"))
options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
else if (!strcmp(arg, "--histogram"))
Expand Down
345 changes: 345 additions & 0 deletions t/t4015-diff-whitespace.sh
Expand Up @@ -142,6 +142,351 @@ EOF
git diff --ignore-space-at-eol > out
test_expect_success 'another test, with --ignore-space-at-eol' 'test_cmp expect out'

test_expect_success 'ignore-blank-lines: only new lines' '
test_seq 5 >x &&
git update-index x &&
test_seq 5 | sed "/3/i \\
" >x &&
git diff --ignore-blank-lines >out &&
>expect &&
test_cmp out expect
'

test_expect_success 'ignore-blank-lines: only new lines with space' '
test_seq 5 >x &&
git update-index x &&
test_seq 5 | sed "/3/i \ " >x &&
git diff -w --ignore-blank-lines >out &&
>expect &&
test_cmp out expect
'

test_expect_success 'ignore-blank-lines: after change' '
cat <<-\EOF >x &&
1
2
3
4
5
6
7
EOF
git update-index x &&
cat <<-\EOF >x &&
change
1
2
3
4
5
6
7
EOF
git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
cat <<-\EOF >expected &&
diff --git a/x b/x
--- a/x
+++ b/x
@@ -1,6 +1,7 @@
+change
+
1
2
-
3
4
5
EOF
compare_diff_patch expected out.tmp
'

test_expect_success 'ignore-blank-lines: before change' '
cat <<-\EOF >x &&
1
2
3
4
5
6
7
EOF
git update-index x &&
cat <<-\EOF >x &&
1
2
3
4
5
6
7
change
EOF
git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
cat <<-\EOF >expected &&
diff --git a/x b/x
--- a/x
+++ b/x
@@ -4,5 +4,7 @@
3
4
5
+
6
7
+change
EOF
compare_diff_patch expected out.tmp
'

test_expect_success 'ignore-blank-lines: between changes' '
cat <<-\EOF >x &&
1
2
3
4
5
6
7
8
9
10
EOF
git update-index x &&
cat <<-\EOF >x &&
change
1
2
3
4
5
6
7
8
9
10
change
EOF
git diff --ignore-blank-lines >out.tmp &&
cat <<-\EOF >expected &&
diff --git a/x b/x
--- a/x
+++ b/x
@@ -1,5 +1,7 @@
+change
1
2
+
3
4
5
@@ -8,5 +8,7 @@
6
7
8
+
9
10
+change
EOF
compare_diff_patch expected out.tmp
'

test_expect_success 'ignore-blank-lines: between changes (with interhunkctx)' '
test_seq 10 >x &&
git update-index x &&
cat <<-\EOF >x &&
change
1
2
3
4
5
6
7
8
9
10
change
EOF
git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
cat <<-\EOF >expected &&
diff --git a/x b/x
--- a/x
+++ b/x
@@ -1,10 +1,15 @@
+change
1
2
+
3
4
5
+
6
7
8
9
+
10
+change
EOF
compare_diff_patch expected out.tmp
'

test_expect_success 'ignore-blank-lines: scattered spaces' '
test_seq 10 >x &&
git update-index x &&
cat <<-\EOF >x &&
change
1
2
3
4
5
6
7
8
9
10
change
EOF
git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
cat <<-\EOF >expected &&
diff --git a/x b/x
--- a/x
+++ b/x
@@ -1,3 +1,4 @@
+change
1
2
3
@@ -8,3 +15,4 @@
8
9
10
+change
EOF
compare_diff_patch expected out.tmp
'

test_expect_success 'ignore-blank-lines: spaces coalesce' '
test_seq 6 >x &&
git update-index x &&
cat <<-\EOF >x &&
change
1
2
3
4
5
6
change
EOF
git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
cat <<-\EOF >expected &&
diff --git a/x b/x
--- a/x
+++ b/x
@@ -1,6 +1,11 @@
+change
1
2
3
+
4
+
5
+
6
+change
EOF
compare_diff_patch expected out.tmp
'

test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
test_seq 16 >x &&
git update-index x &&
cat <<-\EOF >x &&
change
1
2
3
4
5
change
6
7
8
9
10
11
change
12
13
14
15
16
change
EOF
git diff --ignore-blank-lines >out.tmp &&
cat <<-\EOF >expected &&
diff --git a/x b/x
--- a/x
+++ b/x
@@ -1,8 +1,11 @@
+change
1
2
+
3
4
5
+change
6
7
8
@@ -9,8 +13,11 @@
9
10
11
+change
12
13
14
+
15
16
+change
EOF
compare_diff_patch expected out.tmp
'

test_expect_success 'check mixed spaces and tabs in indent' '
# This is indented with SP HT SP.
Expand Down
2 changes: 2 additions & 0 deletions xdiff/xdiff.h
Expand Up @@ -39,6 +39,8 @@ extern "C" {
#define XDF_DIFF_ALGORITHM_MASK (XDF_PATIENCE_DIFF | XDF_HISTOGRAM_DIFF)
#define XDF_DIFF_ALG(x) ((x) & XDF_DIFF_ALGORITHM_MASK)

#define XDF_IGNORE_BLANK_LINES (1 << 7)

#define XDL_EMIT_FUNCNAMES (1 << 0)
#define XDL_EMIT_COMMON (1 << 1)
#define XDL_EMIT_FUNCCONTEXT (1 << 2)
Expand Down

0 comments on commit 36617af

Please sign in to comment.