summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/config/mergetool.txt15
-rw-r--r--Documentation/git-mergetool--lib.txt4
-rwxr-xr-xgit-difftool--helper.sh6
-rw-r--r--git-mergetool--lib.sh11
-rwxr-xr-xgit-mergetool.sh50
-rwxr-xr-xt/t7610-mergetool.sh18
6 files changed, 101 insertions, 3 deletions
diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 16a27443a3..90f76f5b9b 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -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
diff --git a/Documentation/git-mergetool--lib.txt b/Documentation/git-mergetool--lib.txt
index 4da9d24096..3e8f59ac0e 100644
--- a/Documentation/git-mergetool--lib.txt
+++ b/Documentation/git-mergetool--lib.txt
@@ -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.
diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index 46af3e60b7..992124cc67 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -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'
diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh
index 78f3647ed9..542a6a75eb 100644
--- a/git-mergetool--lib.sh
+++ b/git-mergetool--lib.sh
@@ -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"
diff --git a/git-mergetool.sh b/git-mergetool.sh
index e3f6d543fb..911470a5b2 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -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':"
diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh
index 04b0095072..8cc64729ad 100755
--- a/t/t7610-mergetool.sh
+++ b/t/t7610-mergetool.sh
@@ -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