{"thread":{"id":"16898","subject":"[PATCH v2] diff: add option to show context between close hunks","startedAt":"2008-12-28T18:45:32Z","lastAt":"2008-12-29T09:05:28Z","messageCount":2,"participants":["René Scharfe","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"98846","messageId":"1230489932.8791.25.camel@ubuntu.ubuntu-domain","threadId":"16898","inReplyTo":null,"subject":"[PATCH v2] diff: add option to show context between close hunks","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-12-28T18:45:32Z","receivedAt":"2008-12-28T18:45:32Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Merge two hunks if there is only the specified number of otherwise unshown\ncontext between them.  For --inter-hunk-context=1, the resulting patch has\nthe same number of lines but shows uninterrupted context instead of a\ncontext header line in between.\n\nPatches generated with this option are easier to read but are also more\nlikely to conflict if the file to be patched contains other changes.\n\nThis patch keeps the default for this option at 0.  It is intended to just\nmake the feature available in order to see its advantages and downsides.\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\nChanges: s/chunk/hunk/g, bash completion, redone test script.\n\n Documentation/diff-options.txt         |    4 ++\n contrib/completion/git-completion.bash |    2 +\n diff.c                                 |    4 ++\n diff.h                                 |    1 +\n t/t4032-diff-inter-hunk-context.sh     |   92 ++++++++++++++++++++++++++++++++\n xdiff/xdiff.h                          |    1 +\n xdiff/xemit.c                          |    3 +-\n 7 files changed, 106 insertions(+), 1 deletions(-)\n create mode 100755 t/t4032-diff-inter-hunk-context.sh\n\ndiff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt\nindex c62b45c..c7fcc80 100644\n--- a/Documentation/diff-options.txt\n+++ b/Documentation/diff-options.txt\n@@ -215,6 +215,10 @@ endif::git-format-patch[]\n -w::\n \tShorthand for \"--ignore-all-space\".\n \n+--inter-hunk-context=<lines>::\n+\tShow the context between diff hunks, up to the specified number\n+\tof lines, thereby fusing hunks that are close to each other.\n+\n --exit-code::\n \tMake the program exit with codes similar to diff(1).\n \tThat is, it exits with 1 if there were differences and\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex e004549..a046441 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -776,6 +776,7 @@ _git_diff ()\n \t\t\t--no-ext-diff\n \t\t\t--no-prefix --src-prefix= --dst-prefix=\n \t\t\t--base --ours --theirs\n+\t\t\t--inter-hunk-context=\n \t\t\t\"\n \t\treturn\n \t\t;;\n@@ -967,6 +968,7 @@ _git_log ()\n \t\t\t--color-words --walk-reflogs\n \t\t\t--parents --children --full-history\n \t\t\t--merge\n+\t\t\t--inter-hunk-context=\n \t\t\t\"\n \t\treturn\n \t\t;;\ndiff --git a/diff.c b/diff.c\nindex 0484601..56b80f9 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -1469,6 +1469,7 @@ static void builtin_diff(const char *name_a,\n \t\tecbdata.file = o->file;\n \t\txpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;\n \t\txecfg.ctxlen = o->context;\n+\t\txecfg.interhunkctxlen = o->interhunkcontext;\n \t\txecfg.flags = XDL_EMIT_FUNCNAMES;\n \t\tif (pe)\n \t\t\txdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);\n@@ -2538,6 +2539,9 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)\n \t\toptions->b_prefix = arg + 13;\n \telse if (!strcmp(arg, \"--no-prefix\"))\n \t\toptions->a_prefix = options->b_prefix = \"\";\n+\telse if (opt_arg(arg, '\\0', \"inter-hunk-context\",\n+\t\t\t &options->interhunkcontext))\n+\t\t;\n \telse if (!prefixcmp(arg, \"--output=\")) {\n \t\toptions->file = fopen(arg + strlen(\"--output=\"), \"w\");\n \t\toptions->close_file = 1;\ndiff --git a/diff.h b/diff.h\nindex 42582ed..4d5a327 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -78,6 +78,7 @@ struct diff_options {\n \tconst char *a_prefix, *b_prefix;\n \tunsigned flags;\n \tint context;\n+\tint interhunkcontext;\n \tint break_opt;\n \tint detect_rename;\n \tint skip_stat_unmatch;\ndiff --git a/t/t4032-diff-inter-hunk-context.sh b/t/t4032-diff-inter-hunk-context.sh\nnew file mode 100755\nindex 0000000..e4e3e28\n--- /dev/null\n+++ b/t/t4032-diff-inter-hunk-context.sh\n@@ -0,0 +1,92 @@\n+#!/bin/sh\n+\n+test_description='diff hunk fusing'\n+\n+. ./test-lib.sh\n+\n+f() {\n+\techo $1\n+\ti=1\n+\twhile test $i -le $2\n+\tdo\n+\t\techo $i\n+\t\ti=$(expr $i + 1)\n+\tdone\n+\techo $3\n+}\n+\n+t() {\n+\tcase $# in\n+\t4) hunks=$4; cmd=\"diff -U$3\";;\n+\t5) hunks=$5; cmd=\"diff -U$3 --inter-hunk-context=$4\";;\n+\tesac\n+\tlabel=\"$cmd, $1 common $2\"\n+\tfile=f$1\n+\texpected=expected.$file.$3.$hunks\n+\n+\tif ! test -f $file\n+\tthen\n+\t\tf A $1 B >$file\n+\t\tgit add $file\n+\t\tgit commit -q -m. $file\n+\t\tf X $1 Y >$file\n+\tfi\n+\n+\ttest_expect_success \"$label: count hunks ($hunks)\" \"\n+\t\ttest $(git $cmd $file | grep '^@@ ' | wc -l) = $hunks\n+\t\"\n+\n+\ttest -f $expected &&\n+\ttest_expect_success \"$label: check output\" \"\n+\t\tgit $cmd $file | grep -v '^index ' >actual &&\n+\t\ttest_cmp $expected actual\n+\t\"\n+}\n+\n+cat <<EOF >expected.f1.0.1 || exit 1\n+diff --git a/f1 b/f1\n+--- a/f1\n++++ b/f1\n+@@ -1,3 +1,3 @@\n+-A\n++X\n+ 1\n+-B\n++Y\n+EOF\n+\n+cat <<EOF >expected.f1.0.2 || exit 1\n+diff --git a/f1 b/f1\n+--- a/f1\n++++ b/f1\n+@@ -1 +1 @@\n+-A\n++X\n+@@ -3 +3 @@ A\n+-B\n++Y\n+EOF\n+\n+# common lines\tctx\tintrctx\thunks\n+t 1 line\t0\t\t2\n+t 1 line\t0\t0\t2\n+t 1 line\t0\t1\t1\n+t 1 line\t0\t2\t1\n+t 1 line\t1\t\t1\n+\n+t 2 lines\t0\t\t2\n+t 2 lines\t0\t0\t2\n+t 2 lines\t0\t1\t2\n+t 2 lines\t0\t2\t1\n+t 2 lines\t1\t\t1\n+\n+t 3 lines\t1\t\t2\n+t 3 lines\t1\t0\t2\n+t 3 lines\t1\t1\t1\n+t 3 lines\t1\t2\t1\n+\n+t 9 lines\t3\t\t2\n+t 9 lines\t3\t2\t2\n+t 9 lines\t3\t3\t1\n+\n+test_done\ndiff --git a/xdiff/xdiff.h b/xdiff/xdiff.h\nindex 84fff58..361f802 100644\n--- a/xdiff/xdiff.h\n+++ b/xdiff/xdiff.h\n@@ -84,6 +84,7 @@ typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long\n \n typedef struct s_xdemitconf {\n \tlong ctxlen;\n+\tlong interhunkctxlen;\n \tunsigned long flags;\n \tfind_func_t find_func;\n \tvoid *find_func_priv;\ndiff --git a/xdiff/xemit.c b/xdiff/xemit.c\nindex 4625c1b..05bfa41 100644\n--- a/xdiff/xemit.c\n+++ b/xdiff/xemit.c\n@@ -59,9 +59,10 @@ static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *\n  */\n xdchange_t *xdl_get_hunk(xdchange_t *xscr, xdemitconf_t const *xecfg) {\n \txdchange_t *xch, *xchp;\n+\tlong max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen;\n \n \tfor (xchp = xscr, xch = xscr->next; xch; xchp = xch, xch = xch->next)\n-\t\tif (xch->i1 - (xchp->i1 + xchp->chg1) > 2 * xecfg->ctxlen)\n+\t\tif (xch->i1 - (xchp->i1 + xchp->chg1) > max_common)\n \t\t\tbreak;\n \n \treturn xchp;\n-- \n1.6.1\n"},{"id":"98875","messageId":"7v1vvre4h3.fsf@gitster.siamese.dyndns.org","threadId":"16898","inReplyTo":"1230489932.8791.25.camel@ubuntu.ubuntu-domain","subject":"Re: [PATCH v2] diff: add option to show context between close hunks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-12-29T09:05:28Z","receivedAt":"2008-12-29T09:05:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks; will queue.\n"}]}