Browse Source

Merge branch 'ls/mergetool-meld-auto-merge'

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:
  mergetool: allow auto-merge for meld to follow the vim-diff behavior
maint
Junio C Hamano 4 years ago
parent
commit
4aff18a3f0
  1. 10
      Documentation/config/mergetool.txt
  2. 17
      builtin/config.c
  3. 85
      mergetools/meld

10
Documentation/config/mergetool.txt

@ -30,6 +30,16 @@ mergetool.meld.hasOutput::
to `true` tells Git to unconditionally use the `--output` option, to `true` tells Git to unconditionally use the `--output` option,
and `false` avoids using `--output`. and `false` avoids using `--output`.


mergetool.meld.useAutoMerge::
When the `--auto-merge` is given, meld will merge all non-conflicting
parts automatically, highlight the conflicting parts and wait for
user decision. Setting `mergetool.meld.useAutoMerge` to `true` tells
Git to unconditionally use the `--auto-merge` option with `meld`.
Setting this value to `auto` makes git detect whether `--auto-merge`
is supported and will only use `--auto-merge` when available. A
value of `false` avoids using `--auto-merge` altogether, and is the
default value.

mergetool.keepBackup:: mergetool.keepBackup::
After performing a merge, the original file with conflict markers After performing a merge, the original file with conflict markers
can be saved as a file with a `.orig` extension. If this variable can be saved as a file with a `.orig` extension. If this variable

17
builtin/config.c

@ -65,6 +65,7 @@ static int show_scope;
#define TYPE_PATH 4 #define TYPE_PATH 4
#define TYPE_EXPIRY_DATE 5 #define TYPE_EXPIRY_DATE 5
#define TYPE_COLOR 6 #define TYPE_COLOR 6
#define TYPE_BOOL_OR_STR 7


#define OPT_CALLBACK_VALUE(s, l, v, h, i) \ #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \ { 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,
new_type = TYPE_INT; new_type = TYPE_INT;
else if (!strcmp(arg, "bool-or-int")) else if (!strcmp(arg, "bool-or-int"))
new_type = TYPE_BOOL_OR_INT; new_type = TYPE_BOOL_OR_INT;
else if (!strcmp(arg, "bool-or-str"))
new_type = TYPE_BOOL_OR_STR;
else if (!strcmp(arg, "path")) else if (!strcmp(arg, "path"))
new_type = TYPE_PATH; new_type = TYPE_PATH;
else if (!strcmp(arg, "expiry-date")) else if (!strcmp(arg, "expiry-date"))
@ -149,6 +152,7 @@ static struct option builtin_config_options[] = {
OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL), OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT), OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT), OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH), OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE), OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
OPT_GROUP(N_("Other")), OPT_GROUP(N_("Other")),
@ -250,6 +254,12 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
strbuf_addstr(buf, v ? "true" : "false"); strbuf_addstr(buf, v ? "true" : "false");
else else
strbuf_addf(buf, "%d", v); strbuf_addf(buf, "%d", v);
} else if (type == TYPE_BOOL_OR_STR) {
int v = git_parse_maybe_bool(value_);
if (v < 0)
strbuf_addstr(buf, value_);
else
strbuf_addstr(buf, v ? "true" : "false");
} else if (type == TYPE_PATH) { } else if (type == TYPE_PATH) {
const char *v; const char *v;
if (git_config_pathname(&v, key_, value_) < 0) if (git_config_pathname(&v, key_, value_) < 0)
@ -411,6 +421,13 @@ static char *normalize_value(const char *key, const char *value)
else else
return xstrdup(v ? "true" : "false"); return xstrdup(v ? "true" : "false");
} }
if (type == TYPE_BOOL_OR_STR) {
int v = git_parse_maybe_bool(value);
if (v < 0)
return xstrdup(value);
else
return xstrdup(v ? "true" : "false");
}
if (type == TYPE_COLOR) { if (type == TYPE_COLOR) {
char v[COLOR_MAXLEN]; char v[COLOR_MAXLEN];
if (git_config_color(v, key, value)) if (git_config_color(v, key, value))

85
mergetools/meld

@ -3,34 +3,87 @@ diff_cmd () {
} }


merge_cmd () { merge_cmd () {
if test -z "${meld_has_output_option:+set}" check_meld_for_features

option_auto_merge=
if test "$meld_use_auto_merge_option" = true
then then
check_meld_for_output_version option_auto_merge="--auto-merge"
fi fi


if test "$meld_has_output_option" = true if test "$meld_has_output_option" = true
then then
"$merge_tool_path" --output="$MERGED" \ "$merge_tool_path" $option_auto_merge --output="$MERGED" \
"$LOCAL" "$BASE" "$REMOTE" "$LOCAL" "$BASE" "$REMOTE"
else else
"$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE" "$merge_tool_path" $option_auto_merge "$LOCAL" "$MERGED" "$REMOTE"
fi fi
} }


# Check whether we should use 'meld --output <file>' # Get meld help message
check_meld_for_output_version () { init_meld_help_msg () {
meld_path="$(git config mergetool.meld.path)" if test -z "$meld_help_msg"
meld_path="${meld_path:-meld}" then
meld_path="$(git config mergetool.meld.path || echo meld)"
meld_help_msg=$("$meld_path" --help 2>&1)
fi
}


if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput) # Check the features and set flags
check_meld_for_features () {
# Check whether we should use 'meld --output <file>'
if test -z "$meld_has_output_option"
then then
: use configured value meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
elif "$meld_path" --help 2>&1 | case "$meld_has_output_option" in
grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null true | false)
: use configured value
;;
*)
: empty or invalid configured value, detecting "--output" automatically
init_meld_help_msg

case "$meld_help_msg" in
*"--output="* | *'[OPTION...]'*)
# All version that has [OPTION...] supports --output
meld_has_output_option=true
;;
*)
meld_has_output_option=false
;;
esac
;;
esac
fi
# Check whether we should use 'meld --auto-merge ...'
if test -z "$meld_use_auto_merge_option"
then then
: old ones mention --output and new ones just say OPTION... meld_use_auto_merge_option=$(
meld_has_output_option=true git config --bool-or-str mergetool.meld.useAutoMerge
else )
meld_has_output_option=false case "$meld_use_auto_merge_option" in
true | false)
: use well formatted boolean value
;;
auto)
# testing the "--auto-merge" option only if config is "auto"
init_meld_help_msg

case "$meld_help_msg" in
*"--auto-merge"* | *'[OPTION...]'*)
meld_use_auto_merge_option=true
;;
*)
meld_use_auto_merge_option=false
;;
esac
;;
"")
meld_use_auto_merge_option=false
;;
*)
die "unknown mergetool.meld.useAutoMerge: $meld_use_auto_merge_option"
;;
esac
fi fi
} }

Loading…
Cancel
Save