@matheusbsbs / matheus-bagliano / commits / dbd8c09bfe
Fork 0

mergetool: allow auto-merge for meld to follow the vim-diff behavior

Make the mergetool used with "meld" backend behave similarly to "vimdiff" by telling it to auto-merge non-conflicting parts and highlight the conflicting parts when `mergetool.meld.useAutoMerge` is configured with `true`, or `auto` for detecting the `--auto-merge` option automatically. Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Helped-by: David Aguilar <davvid@gmail.com> Signed-off-by: Lin Sun <lin.sun@zoom.us> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Lin Sun committed May 7, 2020 at 07:31 UTC dbd8c09bfe9d783ae01121bafb26a2dd108c0c3f
3 files changed +96 -16
Documentation/config/mergetool.txt
+10
@@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
30 to `true` tells Git to unconditionally use the `--output` option,
31 and `false` avoids using `--output`.
32
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 +
43 mergetool.keepBackup::
44 After performing a merge, the original file with conflict markers
45 can be saved as a file with a `.orig` extension. If this variable
builtin/config.c
+17
@@ -65,6 +65,7 @@ static int show_scope;
65 #define TYPE_PATH 4
66 #define TYPE_EXPIRY_DATE 5
67 #define TYPE_COLOR 6
68 +#define TYPE_BOOL_OR_STR 7
69
70 #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
71 { 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,
95 new_type = TYPE_INT;
96 else if (!strcmp(arg, "bool-or-int"))
97 new_type = TYPE_BOOL_OR_INT;
98 + else if (!strcmp(arg, "bool-or-str"))
99 + new_type = TYPE_BOOL_OR_STR;
100 else if (!strcmp(arg, "path"))
101 new_type = TYPE_PATH;
102 else if (!strcmp(arg, "expiry-date"))
@@ -149,6 +152,7 @@ static struct option builtin_config_options[] = {
152 OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
153 OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
154 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),
156 OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
157 OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
158 OPT_GROUP(N_("Other")),
@@ -250,6 +254,12 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
254 strbuf_addstr(buf, v ? "true" : "false");
255 else
256 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");
263 } else if (type == TYPE_PATH) {
264 const char *v;
265 if (git_config_pathname(&v, key_, value_) < 0)
@@ -411,6 +421,13 @@ static char *normalize_value(const char *key, const char *value)
421 else
422 return xstrdup(v ? "true" : "false");
423 }
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 + }
431 if (type == TYPE_COLOR) {
432 char v[COLOR_MAXLEN];
433 if (git_config_color(v, key, value))
mergetools/meld
+69 -16
@@ -3,34 +3,87 @@ diff_cmd () {
3 }
4
5 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
10 then
8 - check_meld_for_output_version
11 + option_auto_merge="--auto-merge"
12 fi
13
14 if test "$meld_has_output_option" = true
15 then
13 - "$merge_tool_path" --output="$MERGED" \
16 + "$merge_tool_path" $option_auto_merge --output="$MERGED" \
17 "$LOCAL" "$BASE" "$REMOTE"
18 else
16 - "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
19 + "$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
20 fi
21 }
22
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 +}
31
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"
36 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"
60 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
88 fi
89 }