Merge branch 'sh/mergetool-hideresolved'
"git mergetool" feeds three versions (base, local and remote) of a conflicted path unmodified. The command learned to optionally prepare these files with unconflicted parts already resolved. * sh/mergetool-hideresolved: mergetool: add per-tool support and overrides for the hideResolved flag mergetool: break setup_tool out into separate initialization function mergetool: add hideResolved configuration
This commit is contained in:
commit
78a26cb720
@ -13,6 +13,11 @@ mergetool.<tool>.cmd::
|
||||
merged; 'MERGED' contains the name of the file to which the merge
|
||||
tool should write the results of a successful merge.
|
||||
|
||||
mergetool.<tool>.hideResolved::
|
||||
Allows the user to override the global `mergetool.hideResolved` value
|
||||
for a specific tool. See `mergetool.hideResolved` for the full
|
||||
description.
|
||||
|
||||
mergetool.<tool>.trustExitCode::
|
||||
For a custom merge command, specify whether the exit code of
|
||||
the merge command can be used to determine whether the merge was
|
||||
@ -40,6 +45,16 @@ mergetool.meld.useAutoMerge::
|
||||
value of `false` avoids using `--auto-merge` altogether, and is the
|
||||
default value.
|
||||
|
||||
mergetool.hideResolved::
|
||||
During a merge Git will automatically resolve as many conflicts as
|
||||
possible and write the 'MERGED' file containing conflict markers around
|
||||
any conflicts that it cannot resolve; 'LOCAL' and 'REMOTE' normally
|
||||
represent the versions of the file from before Git's conflict
|
||||
resolution. This flag causes 'LOCAL' and 'REMOTE' to be overwriten so
|
||||
that only the unresolved conflicts are presented to the merge tool. Can
|
||||
be configured per-tool via the `mergetool.<tool>.hideResolved`
|
||||
configuration variable. Defaults to `true`.
|
||||
|
||||
mergetool.keepBackup::
|
||||
After performing a merge, the original file with conflict markers
|
||||
can be saved as a file with a `.orig` extension. If this variable
|
||||
|
@ -38,6 +38,10 @@ get_merge_tool_cmd::
|
||||
get_merge_tool_path::
|
||||
returns the custom path for a merge tool.
|
||||
|
||||
initialize_merge_tool::
|
||||
bring merge tool specific functions into scope so they can be used or
|
||||
overridden.
|
||||
|
||||
run_merge_tool::
|
||||
launches a merge tool given the tool name and a true/false
|
||||
flag to indicate whether a merge base is present.
|
||||
|
@ -61,6 +61,9 @@ launch_merge_tool () {
|
||||
export BASE
|
||||
eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"'
|
||||
else
|
||||
initialize_merge_tool "$merge_tool"
|
||||
# ignore the error from the above --- run_merge_tool
|
||||
# will diagnose unusable tool by itself
|
||||
run_merge_tool "$merge_tool"
|
||||
fi
|
||||
}
|
||||
@ -79,6 +82,9 @@ if test -n "$GIT_DIFFTOOL_DIRDIFF"
|
||||
then
|
||||
LOCAL="$1"
|
||||
REMOTE="$2"
|
||||
initialize_merge_tool "$merge_tool"
|
||||
# ignore the error from the above --- run_merge_tool
|
||||
# will diagnose unusable tool by itself
|
||||
run_merge_tool "$merge_tool" false
|
||||
else
|
||||
# Launch the merge tool on each path provided by 'git diff'
|
||||
|
@ -166,6 +166,10 @@ setup_tool () {
|
||||
return 1
|
||||
}
|
||||
|
||||
hide_resolved_enabled () {
|
||||
return 0
|
||||
}
|
||||
|
||||
translate_merge_tool_path () {
|
||||
echo "$1"
|
||||
}
|
||||
@ -250,6 +254,10 @@ trust_exit_code () {
|
||||
fi
|
||||
}
|
||||
|
||||
initialize_merge_tool () {
|
||||
# Bring tool-specific functions into scope
|
||||
setup_tool "$1" || return 1
|
||||
}
|
||||
|
||||
# Entry point for running tools
|
||||
run_merge_tool () {
|
||||
@ -261,9 +269,6 @@ run_merge_tool () {
|
||||
merge_tool_path=$(get_merge_tool_path "$1") || exit
|
||||
base_present="$2"
|
||||
|
||||
# Bring tool-specific functions into scope
|
||||
setup_tool "$1" || return 1
|
||||
|
||||
if merge_mode
|
||||
then
|
||||
run_merge_cmd "$1"
|
||||
|
@ -239,6 +239,13 @@ checkout_staged_file () {
|
||||
fi
|
||||
}
|
||||
|
||||
hide_resolved () {
|
||||
git merge-file --ours -q -p "$LOCAL" "$BASE" "$REMOTE" >"$LCONFL"
|
||||
git merge-file --theirs -q -p "$LOCAL" "$BASE" "$REMOTE" >"$RCONFL"
|
||||
mv -- "$LCONFL" "$LOCAL"
|
||||
mv -- "$RCONFL" "$REMOTE"
|
||||
}
|
||||
|
||||
merge_file () {
|
||||
MERGED="$1"
|
||||
|
||||
@ -265,6 +272,8 @@ merge_file () {
|
||||
ext=
|
||||
esac
|
||||
|
||||
initialize_merge_tool "$merge_tool" || return
|
||||
|
||||
mergetool_tmpdir_init
|
||||
|
||||
if test "$MERGETOOL_TMPDIR" != "."
|
||||
@ -276,7 +285,9 @@ merge_file () {
|
||||
|
||||
BACKUP="$MERGETOOL_TMPDIR/${BASE}_BACKUP_$$$ext"
|
||||
LOCAL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_$$$ext"
|
||||
LCONFL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_LCONFL_$$$ext"
|
||||
REMOTE="$MERGETOOL_TMPDIR/${BASE}_REMOTE_$$$ext"
|
||||
RCONFL="$MERGETOOL_TMPDIR/${BASE}_REMOTE_RCONFL_$$$ext"
|
||||
BASE="$MERGETOOL_TMPDIR/${BASE}_BASE_$$$ext"
|
||||
|
||||
base_mode= local_mode= remote_mode=
|
||||
@ -322,6 +333,45 @@ merge_file () {
|
||||
checkout_staged_file 2 "$MERGED" "$LOCAL"
|
||||
checkout_staged_file 3 "$MERGED" "$REMOTE"
|
||||
|
||||
# hideResolved preferences hierarchy.
|
||||
global_config="mergetool.hideResolved"
|
||||
tool_config="mergetool.${merge_tool}.hideResolved"
|
||||
|
||||
if enabled=$(git config --type=bool "$tool_config")
|
||||
then
|
||||
# The user has a specific preference for a specific tool and no
|
||||
# other preferences should override that.
|
||||
: ;
|
||||
elif enabled=$(git config --type=bool "$global_config")
|
||||
then
|
||||
# The user has a general preference for all tools.
|
||||
#
|
||||
# 'true' means the user likes the feature so we should use it
|
||||
# where possible but tool authors can still override.
|
||||
#
|
||||
# 'false' means the user doesn't like the feature so we should
|
||||
# not use it anywhere.
|
||||
if test "$enabled" = true && hide_resolved_enabled
|
||||
then
|
||||
enabled=true
|
||||
else
|
||||
enabled=false
|
||||
fi
|
||||
else
|
||||
# The user does not have a preference. Ask the tool.
|
||||
if hide_resolved_enabled
|
||||
then
|
||||
enabled=true
|
||||
else
|
||||
enabled=false
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$enabled" = true
|
||||
then
|
||||
hide_resolved
|
||||
fi
|
||||
|
||||
if test -z "$local_mode" || test -z "$remote_mode"
|
||||
then
|
||||
echo "Deleted merge conflict for '$MERGED':"
|
||||
|
@ -842,4 +842,22 @@ test_expect_success 'mergetool --tool-help shows recognized tools' '
|
||||
grep meld mergetools
|
||||
'
|
||||
|
||||
test_expect_success 'mergetool hideResolved' '
|
||||
test_config mergetool.hideResolved true &&
|
||||
test_when_finished "git reset --hard" &&
|
||||
git checkout -b test${test_count}_b main &&
|
||||
test_write_lines >file1 base "" a &&
|
||||
git commit -a -m "base" &&
|
||||
test_write_lines >file1 base "" c &&
|
||||
git commit -a -m "remote update" &&
|
||||
git checkout -b test${test_count}_a HEAD~ &&
|
||||
test_write_lines >file1 local "" b &&
|
||||
git commit -a -m "local update" &&
|
||||
test_must_fail git merge test${test_count}_b &&
|
||||
yes "" | git mergetool file1 &&
|
||||
test_write_lines >expect local "" c &&
|
||||
test_cmp expect file1 &&
|
||||
git commit -m "test resolved with mergetool"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user