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>
This commit is contained in:
parent
a08a83db2b
commit
dbd8c09bfe
@ -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
|
||||||
|
@ -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))
|
||||||
|
@ -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}"
|
|
||||||
|
|
||||||
if meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
|
|
||||||
then
|
then
|
||||||
: use configured value
|
meld_path="$(git config mergetool.meld.path || echo meld)"
|
||||||
elif "$meld_path" --help 2>&1 |
|
meld_help_msg=$("$meld_path" --help 2>&1)
|
||||||
grep -e '--output=' -e '\[OPTION\.\.\.\]' >/dev/null
|
fi
|
||||||
then
|
}
|
||||||
: old ones mention --output and new ones just say OPTION...
|
|
||||||
meld_has_output_option=true
|
# Check the features and set flags
|
||||||
else
|
check_meld_for_features () {
|
||||||
meld_has_output_option=false
|
# Check whether we should use 'meld --output <file>'
|
||||||
|
if test -z "$meld_has_output_option"
|
||||||
|
then
|
||||||
|
meld_has_output_option=$(git config --bool mergetool.meld.hasOutput)
|
||||||
|
case "$meld_has_output_option" in
|
||||||
|
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
|
||||||
|
meld_use_auto_merge_option=$(
|
||||||
|
git config --bool-or-str mergetool.meld.useAutoMerge
|
||||||
|
)
|
||||||
|
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…
Reference in New Issue
Block a user