Skip to content

Commit abea4dc

Browse files
committed
Merge branch 'mp/diff-algo-config'
Add diff.algorithm configuration so that the user does not type "diff --histogram". * mp/diff-algo-config: diff: Introduce --diff-algorithm command line option config: Introduce diff.algorithm variable git-completion.bash: Autocomplete --minimal and --histogram for git-diff
2 parents adbbc6f + 07924d4 commit abea4dc

File tree

6 files changed

+95
-1
lines changed

6 files changed

+95
-1
lines changed

Documentation/diff-config.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,20 @@ diff.tool::
156156
that a corresponding difftool.<tool>.cmd variable is defined.
157157

158158
include::mergetools-diff.txt[]
159+
160+
diff.algorithm::
161+
Choose a diff algorithm. The variants are as follows:
162+
+
163+
--
164+
`default`, `myers`;;
165+
The basic greedy diff algorithm. Currently, this is the default.
166+
`minimal`;;
167+
Spend extra time to make sure the smallest possible diff is
168+
produced.
169+
`patience`;;
170+
Use "patience diff" algorithm when generating patches.
171+
`histogram`;;
172+
This algorithm extends the patience algorithm to "support
173+
low-occurrence common elements".
174+
--
175+
+

Documentation/diff-options.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,26 @@ endif::git-format-patch[]
5555
--histogram::
5656
Generate a diff using the "histogram diff" algorithm.
5757

58+
--diff-algorithm={patience|minimal|histogram|myers}::
59+
Choose a diff algorithm. The variants are as follows:
60+
+
61+
--
62+
`default`, `myers`;;
63+
The basic greedy diff algorithm. Currently, this is the default.
64+
`minimal`;;
65+
Spend extra time to make sure the smallest possible diff is
66+
produced.
67+
`patience`;;
68+
Use "patience diff" algorithm when generating patches.
69+
`histogram`;;
70+
This algorithm extends the patience algorithm to "support
71+
low-occurrence common elements".
72+
--
73+
+
74+
For instance, if you configured diff.algorithm variable to a
75+
non-default value and want to use the default one, then you
76+
have to use `--diff-algorithm=default` option.
77+
5878
--stat[=<width>[,<name-width>[,<count>]]]::
5979
Generate a diffstat. By default, as much space as necessary
6080
will be used for the filename part, and the rest for the graph

contrib/completion/git-completion.bash

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,8 @@ _git_describe ()
12321232
__gitcomp_nl "$(__git_refs)"
12331233
}
12341234

1235+
__git_diff_algorithms="myers minimal patience histogram"
1236+
12351237
__git_diff_common_options="--stat --numstat --shortstat --summary
12361238
--patch-with-stat --name-only --name-status --color
12371239
--no-color --color-words --no-renames --check
@@ -1242,17 +1244,22 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
12421244
--no-ext-diff
12431245
--no-prefix --src-prefix= --dst-prefix=
12441246
--inter-hunk-context=
1245-
--patience
1247+
--patience --histogram --minimal
12461248
--raw
12471249
--dirstat --dirstat= --dirstat-by-file
12481250
--dirstat-by-file= --cumulative
1251+
--diff-algorithm=
12491252
"
12501253

12511254
_git_diff ()
12521255
{
12531256
__git_has_doubledash && return
12541257

12551258
case "$cur" in
1259+
--diff-algorithm=*)
1260+
__gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
1261+
return
1262+
;;
12561263
--*)
12571264
__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
12581265
--base --ours --theirs --no-index
@@ -2058,6 +2065,7 @@ _git_config ()
20582065
diff.suppressBlankEmpty
20592066
diff.tool
20602067
diff.wordRegex
2068+
diff.algorithm
20612069
difftool.
20622070
difftool.prompt
20632071
fetch.recurseSubmodules
@@ -2331,6 +2339,10 @@ _git_show ()
23312339
" "" "${cur#*=}"
23322340
return
23332341
;;
2342+
--diff-algorithm=*)
2343+
__gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
2344+
return
2345+
;;
23342346
--*)
23352347
__gitcomp "--pretty= --format= --abbrev-commit --oneline
23362348
$__git_diff_common_options

diff.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static int diff_no_prefix;
3636
static int diff_stat_graph_width;
3737
static int diff_dirstat_permille_default = 30;
3838
static struct diff_options default_diff_options;
39+
static long diff_algorithm;
3940

4041
static char diff_colors[][COLOR_MAXLEN] = {
4142
GIT_COLOR_RESET,
@@ -143,6 +144,21 @@ static int git_config_rename(const char *var, const char *value)
143144
return git_config_bool(var,value) ? DIFF_DETECT_RENAME : 0;
144145
}
145146

147+
long parse_algorithm_value(const char *value)
148+
{
149+
if (!value)
150+
return -1;
151+
else if (!strcasecmp(value, "myers") || !strcasecmp(value, "default"))
152+
return 0;
153+
else if (!strcasecmp(value, "minimal"))
154+
return XDF_NEED_MINIMAL;
155+
else if (!strcasecmp(value, "patience"))
156+
return XDF_PATIENCE_DIFF;
157+
else if (!strcasecmp(value, "histogram"))
158+
return XDF_HISTOGRAM_DIFF;
159+
return -1;
160+
}
161+
146162
/*
147163
* These are to give UI layer defaults.
148164
* The core-level commands such as git-diff-files should
@@ -196,6 +212,13 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
196212
return 0;
197213
}
198214

215+
if (!strcmp(var, "diff.algorithm")) {
216+
diff_algorithm = parse_algorithm_value(value);
217+
if (diff_algorithm < 0)
218+
return -1;
219+
return 0;
220+
}
221+
199222
if (git_color_config(var, value, cb) < 0)
200223
return -1;
201224

@@ -3163,6 +3186,7 @@ void diff_setup(struct diff_options *options)
31633186
options->add_remove = diff_addremove;
31643187
options->use_color = diff_use_color_default;
31653188
options->detect_rename = diff_detect_rename_default;
3189+
options->xdl_opts |= diff_algorithm;
31663190

31673191
if (diff_no_prefix) {
31683192
options->a_prefix = options->b_prefix = "";
@@ -3560,6 +3584,16 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
35603584
options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
35613585
else if (!strcmp(arg, "--histogram"))
35623586
options->xdl_opts = DIFF_WITH_ALG(options, HISTOGRAM_DIFF);
3587+
else if (!prefixcmp(arg, "--diff-algorithm=")) {
3588+
long value = parse_algorithm_value(arg+17);
3589+
if (value < 0)
3590+
return error("option diff-algorithm accepts \"myers\", "
3591+
"\"minimal\", \"patience\" and \"histogram\"");
3592+
/* clear out previous settings */
3593+
DIFF_XDL_CLR(options, NEED_MINIMAL);
3594+
options->xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK;
3595+
options->xdl_opts |= value;
3596+
}
35633597

35643598
/* flags options */
35653599
else if (!strcmp(arg, "--binary")) {

diff.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ extern struct userdiff_driver *get_textconv(struct diff_filespec *one);
336336

337337
extern int parse_rename_score(const char **cp_p);
338338

339+
extern long parse_algorithm_value(const char *value);
340+
339341
extern int print_stat_summary(FILE *fp, int files,
340342
int insertions, int deletions);
341343
extern void setup_diff_pager(struct diff_options *);

merge-recursive.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,15 @@ int parse_merge_opt(struct merge_options *o, const char *s)
20682068
o->xdl_opts = DIFF_WITH_ALG(o, PATIENCE_DIFF);
20692069
else if (!strcmp(s, "histogram"))
20702070
o->xdl_opts = DIFF_WITH_ALG(o, HISTOGRAM_DIFF);
2071+
else if (!strcmp(s, "diff-algorithm=")) {
2072+
long value = parse_algorithm_value(s+15);
2073+
if (value < 0)
2074+
return -1;
2075+
/* clear out previous settings */
2076+
DIFF_XDL_CLR(o, NEED_MINIMAL);
2077+
o->xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK;
2078+
o->xdl_opts |= value;
2079+
}
20712080
else if (!strcmp(s, "ignore-space-change"))
20722081
o->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
20732082
else if (!strcmp(s, "ignore-all-space"))

0 commit comments

Comments
 (0)