Merge branch 'jk/mergetool'
authorJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2013 22:41:57 +0000 (14:41 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2013 22:41:57 +0000 (14:41 -0800)
Cleans up mergetool/difftool combo.

* jk/mergetool:
  mergetools: simplify how we handle "vim" and "defaults"
  mergetool--lib: don't call "exit" in setup_tool
  mergetool--lib: improve show_tool_help() output
  mergetools/vim: remove redundant diff command
  git-difftool: use git-mergetool--lib for "--tool-help"
  git-mergetool: don't hardcode 'mergetool' in show_tool_help
  git-mergetool: remove redundant assignment
  git-mergetool: move show_tool_help to mergetool--lib

git-difftool.perl
git-mergetool--lib.sh
git-mergetool.sh
mergetools/defaults [deleted file]
mergetools/gvimdiff [new file with mode: 0644]
mergetools/gvimdiff2 [new file with mode: 0644]
mergetools/vimdiff [moved from mergetools/vim with 68% similarity]
mergetools/vimdiff2 [new file with mode: 0644]

index edd0493a08b501d60c04044e79a9e0b096d77953..0a90de414646b901e13abbf89aa78ae71e8b12f0 100755 (executable)
@@ -59,57 +59,16 @@ sub find_worktree
        return $worktree;
 }
 
-sub filter_tool_scripts
-{
-       my ($tools) = @_;
-       if (-d $_) {
-               if ($_ ne ".") {
-                       # Ignore files in subdirectories
-                       $File::Find::prune = 1;
-               }
-       } else {
-               if ((-f $_) && ($_ ne "defaults")) {
-                       push(@$tools, $_);
-               }
-       }
-}
-
 sub print_tool_help
 {
-       my ($cmd, @found, @notfound, @tools);
-       my $gitpath = Git::exec_path();
-
-       find(sub { filter_tool_scripts(\@tools) }, "$gitpath/mergetools");
-
-       foreach my $tool (@tools) {
-               $cmd  = "TOOL_MODE=diff";
-               $cmd .= ' && . "$(git --exec-path)/git-mergetool--lib"';
-               $cmd .= " && get_merge_tool_path $tool >/dev/null 2>&1";
-               $cmd .= " && can_diff >/dev/null 2>&1";
-               if (system('sh', '-c', $cmd) == 0) {
-                       push(@found, $tool);
-               } else {
-                       push(@notfound, $tool);
-               }
-       }
-
-       print << 'EOF';
-'git difftool --tool=<tool>' may be set to one of the following:
-EOF
-       print "\t$_\n" for (sort(@found));
+       my $cmd = 'TOOL_MODE=diff';
+       $cmd .= ' && . "$(git --exec-path)/git-mergetool--lib"';
+       $cmd .= ' && show_tool_help';
 
-       print << 'EOF';
-
-The following tools are valid, but not currently available:
-EOF
-       print "\t$_\n" for (sort(@notfound));
-
-       print << 'EOF';
-
-NOTE: Some of the tools listed above only work in a windowed
-environment. If run in a terminal-only session, they will fail.
-EOF
-       exit(0);
+       # See the comment at the bottom of file_diff() for the reason behind
+       # using system() followed by exit() instead of exec().
+       my $rc = system('sh', '-c', $cmd);
+       exit($rc | ($rc >> 8));
 }
 
 sub exit_cleanup
index f013a0350665e8c11b52853b5794631dcf7694d0..211ffe5d322ec2e1f48739c6c5b33ddddf0de65d 100644 (file)
@@ -1,5 +1,7 @@
 #!/bin/sh
 # git-mergetool--lib is a library for common merge tool functions
+MERGE_TOOLS_DIR=$(git --exec-path)/mergetools
+
 diff_mode() {
        test "$TOOL_MODE" = diff
 }
@@ -44,34 +46,51 @@ valid_tool () {
 }
 
 setup_tool () {
-       case "$1" in
-       vim*|gvim*)
-               tool=vim
-               ;;
-       *)
-               tool="$1"
-               ;;
-       esac
-       mergetools="$(git --exec-path)/mergetools"
+       tool="$1"
+
+       # Fallback definitions, to be overriden by tools.
+       can_merge () {
+               return 0
+       }
+
+       can_diff () {
+               return 0
+       }
+
+       diff_cmd () {
+               status=1
+               return $status
+       }
 
-       # Load the default definitions
-       . "$mergetools/defaults"
-       if ! test -f "$mergetools/$tool"
+       merge_cmd () {
+               status=1
+               return $status
+       }
+
+       translate_merge_tool_path () {
+               echo "$1"
+       }
+
+       if ! test -f "$MERGE_TOOLS_DIR/$tool"
        then
-               return 1
+               # Use a special return code for this case since we want to
+               # source "defaults" even when an explicit tool path is
+               # configured since the user can use that to override the
+               # default path in the scriptlet.
+               return 2
        fi
 
        # Load the redefined functions
-       . "$mergetools/$tool"
+       . "$MERGE_TOOLS_DIR/$tool"
 
        if merge_mode && ! can_merge
        then
                echo "error: '$tool' can not be used to resolve merges" >&2
-               exit 1
+               return 1
        elif diff_mode && ! can_diff
        then
                echo "error: '$tool' can only be used to resolve merges" >&2
-               exit 1
+               return 1
        fi
        return 0
 }
@@ -101,6 +120,19 @@ run_merge_tool () {
 
        # Bring tool-specific functions into scope
        setup_tool "$1"
+       exitcode=$?
+       case $exitcode in
+       0)
+               :
+               ;;
+       2)
+               # The configured tool is not a built-in tool.
+               test -n "$merge_tool_path" || return 1
+               ;;
+       *)
+               return $exitcode
+               ;;
+       esac
 
        if merge_mode
        then
@@ -174,6 +206,46 @@ list_merge_tool_candidates () {
        esac
 }
 
+show_tool_help () {
+       unavailable= available= LF='
+'
+       for i in "$MERGE_TOOLS_DIR"/*
+       do
+               tool=$(basename "$i")
+               setup_tool "$tool" 2>/dev/null || continue
+
+               merge_tool_path=$(translate_merge_tool_path "$tool")
+               if type "$merge_tool_path" >/dev/null 2>&1
+               then
+                       available="$available$tool$LF"
+               else
+                       unavailable="$unavailable$tool$LF"
+               fi
+       done
+
+       cmd_name=${TOOL_MODE}tool
+       if test -n "$available"
+       then
+               echo "'git $cmd_name --tool=<tool>' may be set to one of the following:"
+               echo "$available" | sort | sed -e 's/^/ /'
+       else
+               echo "No suitable tool for 'git $cmd_name --tool=<tool>' found."
+       fi
+       if test -n "$unavailable"
+       then
+               echo
+               echo 'The following tools are valid, but not currently available:'
+               echo "$unavailable" | sort | sed -e 's/^/       /'
+       fi
+       if test -n "$unavailable$available"
+       then
+               echo
+               echo "Some of the tools listed above only work in a windowed"
+               echo "environment. If run in a terminal-only session, they will fail."
+       fi
+       exit 0
+}
+
 guess_merge_tool () {
        list_merge_tool_candidates
        echo >&2 "merge tool candidates: $tools"
index c50e18a8998c1f4ca1449e1733f76cb769f501b9..c0ee9aaf8136a6b5e3e7401504204caa9fcc4fe8 100755 (executable)
@@ -315,43 +315,6 @@ merge_file () {
        return 0
 }
 
-show_tool_help () {
-       TOOL_MODE=merge
-       list_merge_tool_candidates
-       unavailable= available= LF='
-'
-       for i in $tools
-       do
-               merge_tool_path=$(translate_merge_tool_path "$i")
-               if type "$merge_tool_path" >/dev/null 2>&1
-               then
-                       available="$available$i$LF"
-               else
-                       unavailable="$unavailable$i$LF"
-               fi
-       done
-       if test -n "$available"
-       then
-               echo "'git mergetool --tool=<tool>' may be set to one of the following:"
-               echo "$available" | sort | sed -e 's/^/ /'
-       else
-               echo "No suitable tool for 'git mergetool --tool=<tool>' found."
-       fi
-       if test -n "$unavailable"
-       then
-               echo
-               echo 'The following tools are valid, but not currently available:'
-               echo "$unavailable" | sort | sed -e 's/^/       /'
-       fi
-       if test -n "$unavailable$available"
-       then
-               echo
-               echo "Some of the tools listed above only work in a windowed"
-               echo "environment. If run in a terminal-only session, they will fail."
-       fi
-       exit 0
-}
-
 prompt=$(git config --bool mergetool.prompt || echo true)
 
 while test $# != 0
diff --git a/mergetools/defaults b/mergetools/defaults
deleted file mode 100644 (file)
index 21e63ec..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# Redefined by builtin tools
-can_merge () {
-       return 0
-}
-
-can_diff () {
-       return 0
-}
-
-diff_cmd () {
-       status=1
-       return $status
-}
-
-merge_cmd () {
-       status=1
-       return $status
-}
-
-translate_merge_tool_path () {
-       echo "$1"
-}
diff --git a/mergetools/gvimdiff b/mergetools/gvimdiff
new file mode 100644 (file)
index 0000000..04a5bb0
--- /dev/null
@@ -0,0 +1 @@
+. "$MERGE_TOOLS_DIR/vimdiff"
diff --git a/mergetools/gvimdiff2 b/mergetools/gvimdiff2
new file mode 100644 (file)
index 0000000..04a5bb0
--- /dev/null
@@ -0,0 +1 @@
+. "$MERGE_TOOLS_DIR/vimdiff"
similarity index 68%
rename from mergetools/vim
rename to mergetools/vimdiff
index 619594ae4bb54bb36f72efb496a5bd6fe59a3618..39d032771b8525253d3828fd68b2c7f6d6df8478 100644 (file)
@@ -1,14 +1,6 @@
 diff_cmd () {
-       case "$1" in
-       gvimdiff|vimdiff)
-               "$merge_tool_path" -R -f -d \
-                       -c 'wincmd l' -c 'cd $GIT_PREFIX' "$LOCAL" "$REMOTE"
-               ;;
-       gvimdiff2|vimdiff2)
-               "$merge_tool_path" -R -f -d \
-                       -c 'wincmd l' -c 'cd $GIT_PREFIX' "$LOCAL" "$REMOTE"
-               ;;
-       esac
+       "$merge_tool_path" -R -f -d \
+               -c 'wincmd l' -c 'cd $GIT_PREFIX' "$LOCAL" "$REMOTE"
 }
 
 merge_cmd () {
diff --git a/mergetools/vimdiff2 b/mergetools/vimdiff2
new file mode 100644 (file)
index 0000000..04a5bb0
--- /dev/null
@@ -0,0 +1 @@
+. "$MERGE_TOOLS_DIR/vimdiff"