Merge branch 'jk/push-simple'
[gitweb.git] / git-mergetool.sh
index 9a046b75d1dd810202d784d3fffe8afe6dd1963c..d20581c15c5086b02411cab618cde0a9ff14e7ed 100755 (executable)
 
 USAGE='[--tool=tool] [--tool-help] [-y|--no-prompt|--prompt] [file to merge] ...'
 SUBDIRECTORY_OK=Yes
+NONGIT_OK=Yes
 OPTIONS_SPEC=
 TOOL_MODE=merge
 . git-sh-setup
 . git-mergetool--lib
-require_work_tree
 
 # Returns true if the mode reflects a symlink
 is_symlink () {
@@ -37,6 +37,19 @@ base_present () {
        test -n "$base_mode"
 }
 
+mergetool_tmpdir_init () {
+       if test "$(git config --bool mergetool.writeToTemp)" != true
+       then
+               MERGETOOL_TMPDIR=.
+               return 0
+       fi
+       if MERGETOOL_TMPDIR=$(mktemp -d -t "git-mergetool-XXXXXX" 2>/dev/null)
+       then
+               return 0
+       fi
+       die "error: mktemp is needed when 'mergetool.writeToTemp' is true"
+}
+
 cleanup_temp_files () {
        if test "$1" = --save-backup
        then
@@ -46,6 +59,10 @@ cleanup_temp_files () {
        else
                rm -f -- "$LOCAL" "$REMOTE" "$BASE" "$BACKUP"
        fi
+       if test "$MERGETOOL_TMPDIR" != "."
+       then
+               rmdir "$MERGETOOL_TMPDIR"
+       fi
 }
 
 describe_file () {
@@ -228,11 +245,27 @@ merge_file () {
                return 1
        fi
 
-       ext="$$$(expr "$MERGED" : '.*\(\.[^/]*\)$')"
-       BACKUP="./$MERGED.BACKUP.$ext"
-       LOCAL="./$MERGED.LOCAL.$ext"
-       REMOTE="./$MERGED.REMOTE.$ext"
-       BASE="./$MERGED.BASE.$ext"
+       if BASE=$(expr "$MERGED" : '\(.*\)\.[^/]*$')
+       then
+               ext=$(expr "$MERGED" : '.*\(\.[^/]*\)$')
+       else
+               BASE=$MERGED
+               ext=
+       fi
+
+       mergetool_tmpdir_init
+
+       if test "$MERGETOOL_TMPDIR" != "."
+       then
+               # If we're using a temporary directory then write to the
+               # top-level of that directory.
+               BASE=${BASE##*/}
+       fi
+
+       BACKUP="$MERGETOOL_TMPDIR/${BASE}_BACKUP_$$$ext"
+       LOCAL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_$$$ext"
+       REMOTE="$MERGETOOL_TMPDIR/${BASE}_REMOTE_$$$ext"
+       BASE="$MERGETOOL_TMPDIR/${BASE}_BASE_$$$ext"
 
        base_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}')
        local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}')
@@ -321,6 +354,10 @@ 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
                ;;
@@ -372,6 +409,9 @@ prompt_after_failed_merge () {
        done
 }
 
+git_dir_init
+require_work_tree
+
 if test -z "$merge_tool"
 then
        # Check if a merge tool has been configured
@@ -386,8 +426,6 @@ fi
 merge_keep_backup="$(git config --bool mergetool.keepBackup || echo true)"
 merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
 
-last_status=0
-rollup_status=0
 files=
 
 if test $# -eq 0
@@ -415,19 +453,15 @@ printf "%s\n" "$files"
 
 IFS='
 '
+rc=0
 for i in $files
 do
-       if test $last_status -ne 0
-       then
-               prompt_after_failed_merge || exit 1
-       fi
        printf "\n"
-       merge_file "$i"
-       last_status=$?
-       if test $last_status -ne 0
+       if ! merge_file "$i"
        then
-               rollup_status=1
+               rc=1
+               prompt_after_failed_merge || exit 1
        fi
 done
 
-exit $rollup_status
+exit $rc