Merge branch 'da/mergetool-diff-order'

"git mergetool" learned to honor "-O<orderfile>" to control the
order of paths to present to the end user.

* da/mergetool-diff-order:
  mergetool: honor -O<orderfile>
  mergetool: honor diff.orderFile
  mergetool: move main program flow into a main() function
  mergetool: add copyright
This commit is contained in:
Junio C Hamano 2016-10-17 13:25:21 -07:00
commit 5b4c45af0c
3 changed files with 172 additions and 93 deletions

View file

@ -79,6 +79,13 @@ success of the resolution after the custom tool has exited.
Prompt before each invocation of the merge resolution program Prompt before each invocation of the merge resolution program
to give the user a chance to skip the path. to give the user a chance to skip the path.
-O<orderfile>::
Process files in the order specified in the
<orderfile>, which has one shell glob pattern per line.
This overrides the `diff.orderFile` configuration variable
(see linkgit:git-config[1]). To cancel `diff.orderFile`,
use `-O/dev/null`.
TEMPORARY FILES TEMPORARY FILES
--------------- ---------------
`git mergetool` creates `*.orig` backup files while resolving merges. `git mergetool` creates `*.orig` backup files while resolving merges.

View file

@ -3,12 +3,13 @@
# This program resolves merge conflicts in git # This program resolves merge conflicts in git
# #
# Copyright (c) 2006 Theodore Y. Ts'o # Copyright (c) 2006 Theodore Y. Ts'o
# Copyright (c) 2009-2016 David Aguilar
# #
# This file is licensed under the GPL v2, or a later version # This file is licensed under the GPL v2, or a later version
# at the discretion of Junio C Hamano. # at the discretion of Junio C Hamano.
# #
USAGE='[--tool=tool] [--tool-help] [-y|--no-prompt|--prompt] [file to merge] ...' USAGE='[--tool=tool] [--tool-help] [-y|--no-prompt|--prompt] [-O<orderfile>] [file to merge] ...'
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
NONGIT_OK=Yes NONGIT_OK=Yes
OPTIONS_SPEC= OPTIONS_SPEC=
@ -365,51 +366,6 @@ merge_file () {
return 0 return 0
} }
prompt=$(git config --bool mergetool.prompt)
guessed_merge_tool=false
while test $# != 0
do
case "$1" in
--tool-help=*)
TOOL_MODE=${1#--tool-help=}
show_tool_help
;;
--tool-help)
show_tool_help
;;
-t|--tool*)
case "$#,$1" in
*,*=*)
merge_tool=$(expr "z$1" : 'z-[^=]*=\(.*\)')
;;
1,*)
usage ;;
*)
merge_tool="$2"
shift ;;
esac
;;
-y|--no-prompt)
prompt=false
;;
--prompt)
prompt=true
;;
--)
shift
break
;;
-*)
usage
;;
*)
break
;;
esac
shift
done
prompt_after_failed_merge () { prompt_after_failed_merge () {
while true while true
do do
@ -426,57 +382,113 @@ prompt_after_failed_merge () {
done done
} }
git_dir_init print_noop_and_exit () {
require_work_tree
if test -z "$merge_tool"
then
# Check if a merge tool has been configured
merge_tool=$(get_configured_merge_tool)
# Try to guess an appropriate merge tool if no tool has been set.
if test -z "$merge_tool"
then
merge_tool=$(guess_merge_tool) || exit
guessed_merge_tool=true
fi
fi
merge_keep_backup="$(git config --bool mergetool.keepBackup || echo true)"
merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
files=
if test $# -eq 0
then
cd_to_toplevel
if test -e "$GIT_DIR/MERGE_RR"
then
files=$(git rerere remaining)
else
files=$(git ls-files -u | sed -e 's/^[^ ]* //' | sort -u)
fi
else
files=$(git ls-files -u -- "$@" | sed -e 's/^[^ ]* //' | sort -u)
fi
if test -z "$files"
then
echo "No files need merging" echo "No files need merging"
exit 0 exit 0
fi }
printf "Merging:\n" main () {
printf "%s\n" "$files" prompt=$(git config --bool mergetool.prompt)
guessed_merge_tool=false
orderfile=
rc=0 while test $# != 0
for i in $files do
do case "$1" in
printf "\n" --tool-help=*)
if ! merge_file "$i" TOOL_MODE=${1#--tool-help=}
show_tool_help
;;
--tool-help)
show_tool_help
;;
-t|--tool*)
case "$#,$1" in
*,*=*)
merge_tool=$(expr "z$1" : 'z-[^=]*=\(.*\)')
;;
1,*)
usage ;;
*)
merge_tool="$2"
shift ;;
esac
;;
-y|--no-prompt)
prompt=false
;;
--prompt)
prompt=true
;;
-O*)
orderfile="$1"
;;
--)
shift
break
;;
-*)
usage
;;
*)
break
;;
esac
shift
done
git_dir_init
require_work_tree
if test -z "$merge_tool"
then then
rc=1 # Check if a merge tool has been configured
prompt_after_failed_merge || exit 1 merge_tool=$(get_configured_merge_tool)
# Try to guess an appropriate merge tool if no tool has been set.
if test -z "$merge_tool"
then
merge_tool=$(guess_merge_tool) || exit
guessed_merge_tool=true
fi
fi fi
done merge_keep_backup="$(git config --bool mergetool.keepBackup || echo true)"
merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
exit $rc if test $# -eq 0 && test -e "$GIT_DIR/MERGE_RR"
then
set -- $(git rerere remaining)
if test $# -eq 0
then
print_noop_and_exit
fi
fi
files=$(git -c core.quotePath=false \
diff --name-only --diff-filter=U \
${orderfile:+"$orderfile"} -- "$@")
cd_to_toplevel
if test -z "$files"
then
print_noop_and_exit
fi
printf "Merging:\n"
printf "%s\n" "$files"
rc=0
for i in $files
do
printf "\n"
if ! merge_file "$i"
then
rc=1
prompt_after_failed_merge || exit 1
fi
done
exit $rc
}
main "$@"

View file

@ -606,4 +606,64 @@ test_expect_success MKTEMP 'temporary filenames are used with mergetool.writeToT
git reset --hard master >/dev/null 2>&1 git reset --hard master >/dev/null 2>&1
' '
test_expect_success 'diff.orderFile configuration is honored' '
test_config diff.orderFile order-file &&
test_config mergetool.myecho.cmd "echo \"\$LOCAL\"" &&
test_config mergetool.myecho.trustExitCode true &&
echo b >order-file &&
echo a >>order-file &&
git checkout -b order-file-start master &&
echo start >a &&
echo start >b &&
git add a b &&
git commit -m start &&
git checkout -b order-file-side1 order-file-start &&
echo side1 >a &&
echo side1 >b &&
git add a b &&
git commit -m side1 &&
git checkout -b order-file-side2 order-file-start &&
echo side2 >a &&
echo side2 >b &&
git add a b &&
git commit -m side2 &&
test_must_fail git merge order-file-side1 &&
cat >expect <<-\EOF &&
Merging:
b
a
EOF
git mergetool --no-prompt --tool myecho >output &&
git grep --no-index -h -A2 Merging: output >actual &&
test_cmp expect actual &&
git reset --hard >/dev/null
'
test_expect_success 'mergetool -Oorder-file is honored' '
test_config diff.orderFile order-file &&
test_config mergetool.myecho.cmd "echo \"\$LOCAL\"" &&
test_config mergetool.myecho.trustExitCode true &&
test_must_fail git merge order-file-side1 &&
cat >expect <<-\EOF &&
Merging:
a
b
EOF
git mergetool -O/dev/null --no-prompt --tool myecho >output &&
git grep --no-index -h -A2 Merging: output >actual &&
test_cmp expect actual &&
git reset --hard >/dev/null 2>&1 &&
git config --unset diff.orderFile &&
test_must_fail git merge order-file-side1 &&
cat >expect <<-\EOF &&
Merging:
b
a
EOF
git mergetool -Oorder-file --no-prompt --tool myecho >output &&
git grep --no-index -h -A2 Merging: output >actual &&
test_cmp expect actual &&
git reset --hard >/dev/null 2>&1
'
test_done test_done