mergetool: use $( ... ) instead of `backticks`
[git.git] / git-mergetool.sh
index 09f3a1068f69718fa544e3e614b1040ed33ab292..cceebb72103033927a520415203a23f89fa0c5d0 100755 (executable)
@@ -13,7 +13,6 @@ SUBDIRECTORY_OK=Yes
 OPTIONS_SPEC=
 . git-sh-setup
 require_work_tree
-prefix=$(git rev-parse --show-prefix)
 
 # Returns true if the mode reflects a symlink
 is_symlink () {
@@ -127,10 +126,18 @@ check_unchanged () {
     fi
 }
 
+checkout_staged_file () {
+    tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^    ]*\)    ')
+
+    if test $? -eq 0 -a -n "$tmpfile" ; then
+       mv -- "$(git rev-parse --show-cdup)$tmpfile" "$3"
+    fi
+}
+
 merge_file () {
     MERGED="$1"
 
-    f=`git ls-files -u -- "$MERGED"`
+    f=$(git ls-files -u -- "$MERGED")
     if test -z "$f" ; then
        if test ! -f "$MERGED" ; then
            echo "$MERGED: file not found"
@@ -149,13 +156,13 @@ merge_file () {
     mv -- "$MERGED" "$BACKUP"
     cp -- "$BACKUP" "$MERGED"
 
-    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;}'`
-    remote_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}'`
+    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;}')
+    remote_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}')
 
-    base_present   && git cat-file blob ":1:$prefix$MERGED" >"$BASE" 2>/dev/null
-    local_present  && git cat-file blob ":2:$prefix$MERGED" >"$LOCAL" 2>/dev/null
-    remote_present && git cat-file blob ":3:$prefix$MERGED" >"$REMOTE" 2>/dev/null
+    base_present   && checkout_staged_file 1 "$MERGED" "$BASE"
+    local_present  && checkout_staged_file 2 "$MERGED" "$LOCAL"
+    remote_present && checkout_staged_file 3 "$MERGED" "$REMOTE"
 
     if test -z "$local_mode" -o -z "$remote_mode"; then
        echo "Deleted merge conflict for '$MERGED':"
@@ -207,12 +214,12 @@ merge_file () {
            ;;
        vimdiff)
            touch "$BACKUP"
-           "$merge_tool_path" -c "wincmd l" "$LOCAL" "$MERGED" "$REMOTE"
+           "$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$MERGED" "$REMOTE"
            check_unchanged
            ;;
        gvimdiff)
            touch "$BACKUP"
-           "$merge_tool_path" -c "wincmd l" -f "$LOCAL" "$MERGED" "$REMOTE"
+           "$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$MERGED" "$REMOTE"
            check_unchanged
            ;;
        xxdiff)
@@ -258,6 +265,16 @@ merge_file () {
            fi
            status=$?
            ;;
+       tortoisemerge)
+           if base_present ; then
+               touch "$BACKUP"
+               "$merge_tool_path" -base:"$BASE" -mine:"$LOCAL" -theirs:"$REMOTE" -merged:"$MERGED"
+               check_unchanged
+           else
+               echo "TortoiseMerge cannot be used without a base" 1>&2
+               status=1
+           fi
+           ;;
        *)
            if test -n "$merge_tool_cmd"; then
                if test "$merge_tool_trust_exit_code" = "false"; then
@@ -301,7 +318,7 @@ do
        -t|--tool*)
            case "$#,$1" in
                *,*=*)
-                   merge_tool=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+                   merge_tool=$(expr "z$1" : 'z-[^=]*=\(.*\)')
                    ;;
                1,*)
                    usage ;;
@@ -338,7 +355,7 @@ valid_custom_tool()
 
 valid_tool() {
        case "$1" in
-               kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge)
+               kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge | tortoisemerge)
                        ;; # happy
                *)
                        if ! valid_custom_tool "$1"; then
@@ -349,9 +366,15 @@ valid_tool() {
 }
 
 init_merge_tool_path() {
-       merge_tool_path=`git config mergetool.$1.path`
+       merge_tool_path=$(git config mergetool.$1.path)
        if test -z "$merge_tool_path" ; then
                case "$1" in
+                       vimdiff)
+                               merge_tool_path=vim
+                               ;;
+                       gvimdiff)
+                               merge_tool_path=gvim
+                               ;;
                        emerge)
                                merge_tool_path=emacs
                                ;;
@@ -380,7 +403,7 @@ prompt_after_failed_merge() {
 }
 
 if test -z "$merge_tool"; then
-    merge_tool=`git config merge.tool`
+    merge_tool=$(git config merge.tool)
     if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
            echo >&2 "git config option merge.tool set to unknown tool: $merge_tool"
            echo >&2 "Resetting to default..."
@@ -391,9 +414,9 @@ fi
 if test -z "$merge_tool" ; then
     if test -n "$DISPLAY"; then
         if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
-            merge_tool_candidates="meld kdiff3 tkdiff xxdiff gvimdiff"
+            merge_tool_candidates="meld kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse"
         else
-            merge_tool_candidates="kdiff3 tkdiff xxdiff meld gvimdiff"
+            merge_tool_candidates="kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse"
         fi
     fi
     if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
@@ -440,7 +463,7 @@ last_status=0
 rollup_status=0
 
 if test $# -eq 0 ; then
-    files=`git ls-files -u | sed -e 's/^[^     ]*      //' | sort -u`
+    files=$(git ls-files -u | sed -e 's/^[^    ]*      //' | sort -u)
     if test -z "$files" ; then
        echo "No files need merging"
        exit 0