Skip to content

Commit a51c706

Browse files
committed
Merge branch 'ls/mergetool-meld-auto-merge' into seen
The 'meld' backend of the "git mergetool" learned to give the underlying 'meld' the '--auto-merge' option, which would help reduce the amount of text that requires manual merging. * ls/mergetool-meld-auto-merge: SQUASH??? Support auto-merge for meld to follow the vim-diff behavior
2 parents 34ad434 + 5b26a7e commit a51c706

File tree

3 files changed

+96
-16
lines changed

3 files changed

+96
-16
lines changed

Documentation/config/mergetool.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
3030
to `true` tells Git to unconditionally use the `--output` option,
3131
and `false` avoids using `--output`.
3232

33+
mergetool.meld.useAutoMerge::
34+
When the `--auto-merge` is given, meld will merge all non-conflicting
35+
parts automatically, highlight the conflicting parts and wait for
36+
user decision. Setting `mergetool.meld.useAutoMerge` to `true` tells
37+
Git to unconditionally use the `--auto-merge` option with `meld`.
38+
Setting this value to `auto` makes git detect whether `--auto-merge`
39+
is supported and will only use `--auto-merge` when available. A
40+
value of `false` avoids using `--auto-merge` altogether, and is the
41+
default value.
42+
3343
mergetool.keepBackup::
3444
After performing a merge, the original file with conflict markers
3545
can be saved as a file with a `.orig` extension. If this variable

builtin/config.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ static int show_scope;
6565
#define TYPE_PATH 4
6666
#define TYPE_EXPIRY_DATE 5
6767
#define TYPE_COLOR 6
68+
#define TYPE_BOOL_OR_STR 7
6869

6970
#define OPT_CALLBACK_VALUE(s, l, v, h, i) \
7071
{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
@@ -94,6 +95,8 @@ static int option_parse_type(const struct option *opt, const char *arg,
9495
new_type = TYPE_INT;
9596
else if (!strcmp(arg, "bool-or-int"))
9697
new_type = TYPE_BOOL_OR_INT;
98+
else if (!strcmp(arg, "bool-or-str"))
99+
new_type = TYPE_BOOL_OR_STR;
97100
else if (!strcmp(arg, "path"))
98101
new_type = TYPE_PATH;
99102
else if (!strcmp(arg, "expiry-date"))
@@ -149,6 +152,7 @@ static struct option builtin_config_options[] = {
149152
OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
150153
OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
151154
OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
155+
OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
152156
OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
153157
OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
154158
OPT_GROUP(N_("Other")),
@@ -250,6 +254,12 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
250254
strbuf_addstr(buf, v ? "true" : "false");
251255
else
252256
strbuf_addf(buf, "%d", v);
257+
} else if (type == TYPE_BOOL_OR_STR) {
258+
int v = git_parse_maybe_bool(value_);
259+
if (v < 0)
260+
strbuf_addstr(buf, value_);
261+
else
262+
strbuf_addstr(buf, v ? "true" : "false");
253263
} else if (type == TYPE_PATH) {
254264
const char *v;
255265
if (git_config_pathname(&v, key_, value_) < 0)
@@ -411,6 +421,13 @@ static char *normalize_value(const char *key, const char *value)
411421
else
412422
return xstrdup(v ? "true" : "false");
413423
}
424+
if (type == TYPE_BOOL_OR_STR) {
425+
int v = git_parse_maybe_bool(value);
426+
if (v < 0)
427+
return xstrdup(value);
428+
else
429+
return xstrdup(v ? "true" : "false");
430+
}
414431
if (type == TYPE_COLOR) {
415432
char v[COLOR_MAXLEN];
416433
if (git_config_color(v, key, value))

mergetools/meld

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,87 @@ diff_cmd () {
33
}
44

55
merge_cmd () {
6-
if test -z "${meld_has_output_option:+set}"
6+
check_meld_for_features
7+
8+
option_auto_merge=
9+
if test "$meld_use_auto_merge_option" = true
710
then
8-
check_meld_for_output_version
11+
option_auto_merge="--auto-merge"
912
fi
1013

1114
if test "$meld_has_output_option" = true
1215
then
13-
"$merge_tool_path" --output="$MERGED" \
16+
"$merge_tool_path" $option_auto_merge --output="$MERGED" \
1417
"$LOCAL" "$BASE" "$REMOTE"
1518
else
16-
"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
19+
"$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
1720
fi
1821
}
1922

20-
# Check whether we should use 'meld --output <file>'
21-
check_meld_for_output_version () {
22-
meld_path="$(git config mergetool.meld.path)"
23-
meld_path="${meld_path:-meld}"
23+
# Get meld help message
24+
init_meld_help_msg () {
25+
if test -z "$meld_help_msg"
26+
then
27+
meld_path="$(git config mergetool.meld.path || echo meld)"
28+
meld_help_msg=$("$meld_path" --help 2>&1)
29+
fi
30+
}
2431

25-
if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
32+
# Check the features and set flags
33+
check_meld_for_features () {
34+
# Check whether we should use 'meld --output <file>'
35+
if test -z "$meld_has_output_option"
2636
then
27-
: use configured value
28-
elif "$meld_path" --help 2>&1 |
29-
grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
37+
meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
38+
case "$meld_has_output_option" in
39+
true | false)
40+
: use configured value
41+
;;
42+
*)
43+
: empty or invalid configured value, detecting "--output" automatically
44+
init_meld_help_msg
45+
46+
case "$meld_help_msg" in
47+
*"--output="* | *'[OPTION...]'*)
48+
# All version that has [OPTION...] supports --output
49+
meld_has_output_option=true
50+
;;
51+
*)
52+
meld_has_output_option=false
53+
;;
54+
esac
55+
;;
56+
esac
57+
fi
58+
# Check whether we should use 'meld --auto-merge ...'
59+
if test -z "$meld_use_auto_merge_option"
3060
then
31-
: old ones mention --output and new ones just say OPTION...
32-
meld_has_output_option=true
33-
else
34-
meld_has_output_option=false
61+
meld_use_auto_merge_option=$(
62+
git config --bool-or-str mergetool.meld.useAutoMerge
63+
)
64+
case "$meld_use_auto_merge_option" in
65+
true | false)
66+
: use well formatted boolean value
67+
;;
68+
auto)
69+
# testing the "--auto-merge" option only if config is "auto"
70+
init_meld_help_msg
71+
72+
case "$meld_help_msg" in
73+
*"--auto-merge"* | *'[OPTION...]'*)
74+
meld_use_auto_merge_option=true
75+
;;
76+
*)
77+
meld_use_auto_merge_option=false
78+
;;
79+
esac
80+
;;
81+
"")
82+
meld_use_auto_merge_option=false
83+
;;
84+
*)
85+
die "unknown mergetool.meld.useAutoMerge: $meld_use_auto_merge_option"
86+
;;
87+
esac
3588
fi
3689
}

0 commit comments

Comments
 (0)