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
|
merged; 'MERGED' contains the name of the file to which the merge
|
||||||
tool should write the results of a successful 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::
|
mergetool.<tool>.trustExitCode::
|
||||||
For a custom merge command, specify whether the exit code of
|
For a custom merge command, specify whether the exit code of
|
||||||
the merge command can be used to determine whether the merge was
|
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
|
value of `false` avoids using `--auto-merge` altogether, and is the
|
||||||
default value.
|
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::
|
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
|
||||||
|
@ -38,6 +38,10 @@ get_merge_tool_cmd::
|
|||||||
get_merge_tool_path::
|
get_merge_tool_path::
|
||||||
returns the custom path for a merge tool.
|
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::
|
run_merge_tool::
|
||||||
launches a merge tool given the tool name and a true/false
|
launches a merge tool given the tool name and a true/false
|
||||||
flag to indicate whether a merge base is present.
|
flag to indicate whether a merge base is present.
|
||||||
|
@ -61,6 +61,9 @@ launch_merge_tool () {
|
|||||||
export BASE
|
export BASE
|
||||||
eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"'
|
eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"'
|
||||||
else
|
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"
|
run_merge_tool "$merge_tool"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -79,6 +82,9 @@ if test -n "$GIT_DIFFTOOL_DIRDIFF"
|
|||||||
then
|
then
|
||||||
LOCAL="$1"
|
LOCAL="$1"
|
||||||
REMOTE="$2"
|
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
|
run_merge_tool "$merge_tool" false
|
||||||
else
|
else
|
||||||
# Launch the merge tool on each path provided by 'git diff'
|
# Launch the merge tool on each path provided by 'git diff'
|
||||||
|
@ -166,6 +166,10 @@ setup_tool () {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hide_resolved_enabled () {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
translate_merge_tool_path () {
|
translate_merge_tool_path () {
|
||||||
echo "$1"
|
echo "$1"
|
||||||
}
|
}
|
||||||
@ -250,6 +254,10 @@ trust_exit_code () {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialize_merge_tool () {
|
||||||
|
# Bring tool-specific functions into scope
|
||||||
|
setup_tool "$1" || return 1
|
||||||
|
}
|
||||||
|
|
||||||
# Entry point for running tools
|
# Entry point for running tools
|
||||||
run_merge_tool () {
|
run_merge_tool () {
|
||||||
@ -261,9 +269,6 @@ run_merge_tool () {
|
|||||||
merge_tool_path=$(get_merge_tool_path "$1") || exit
|
merge_tool_path=$(get_merge_tool_path "$1") || exit
|
||||||
base_present="$2"
|
base_present="$2"
|
||||||
|
|
||||||
# Bring tool-specific functions into scope
|
|
||||||
setup_tool "$1" || return 1
|
|
||||||
|
|
||||||
if merge_mode
|
if merge_mode
|
||||||
then
|
then
|
||||||
run_merge_cmd "$1"
|
run_merge_cmd "$1"
|
||||||
|
@ -239,6 +239,13 @@ checkout_staged_file () {
|
|||||||
fi
|
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 () {
|
merge_file () {
|
||||||
MERGED="$1"
|
MERGED="$1"
|
||||||
|
|
||||||
@ -265,6 +272,8 @@ merge_file () {
|
|||||||
ext=
|
ext=
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
initialize_merge_tool "$merge_tool" || return
|
||||||
|
|
||||||
mergetool_tmpdir_init
|
mergetool_tmpdir_init
|
||||||
|
|
||||||
if test "$MERGETOOL_TMPDIR" != "."
|
if test "$MERGETOOL_TMPDIR" != "."
|
||||||
@ -276,7 +285,9 @@ merge_file () {
|
|||||||
|
|
||||||
BACKUP="$MERGETOOL_TMPDIR/${BASE}_BACKUP_$$$ext"
|
BACKUP="$MERGETOOL_TMPDIR/${BASE}_BACKUP_$$$ext"
|
||||||
LOCAL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_$$$ext"
|
LOCAL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_$$$ext"
|
||||||
|
LCONFL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_LCONFL_$$$ext"
|
||||||
REMOTE="$MERGETOOL_TMPDIR/${BASE}_REMOTE_$$$ext"
|
REMOTE="$MERGETOOL_TMPDIR/${BASE}_REMOTE_$$$ext"
|
||||||
|
RCONFL="$MERGETOOL_TMPDIR/${BASE}_REMOTE_RCONFL_$$$ext"
|
||||||
BASE="$MERGETOOL_TMPDIR/${BASE}_BASE_$$$ext"
|
BASE="$MERGETOOL_TMPDIR/${BASE}_BASE_$$$ext"
|
||||||
|
|
||||||
base_mode= local_mode= remote_mode=
|
base_mode= local_mode= remote_mode=
|
||||||
@ -322,6 +333,45 @@ merge_file () {
|
|||||||
checkout_staged_file 2 "$MERGED" "$LOCAL"
|
checkout_staged_file 2 "$MERGED" "$LOCAL"
|
||||||
checkout_staged_file 3 "$MERGED" "$REMOTE"
|
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"
|
if test -z "$local_mode" || test -z "$remote_mode"
|
||||||
then
|
then
|
||||||
echo "Deleted merge conflict for '$MERGED':"
|
echo "Deleted merge conflict for '$MERGED':"
|
||||||
|
@ -842,4 +842,22 @@ test_expect_success 'mergetool --tool-help shows recognized tools' '
|
|||||||
grep meld mergetools
|
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
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user