Skip to content

Commit

Permalink
difftool/mergetool: refactor commands to use git-mergetool--lib
Browse files Browse the repository at this point in the history
This consolidates the common functionality from git-mergetool and
git-difftool--helper into a single git-mergetool--lib scriptlet.

Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
David Aguilar authored and Junio C Hamano committed Apr 8, 2009
1 parent 9a62d72 commit 21d0ba7
Show file tree
Hide file tree
Showing 6 changed files with 458 additions and 388 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ git-merge-recursive
git-merge-resolve
git-merge-subtree
git-mergetool
git-mergetool--lib
git-mktag
git-mktree
git-name-rev
Expand Down
56 changes: 56 additions & 0 deletions Documentation/git-mergetool--lib.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
git-mergetool--lib(1)
=====================

NAME
----
git-mergetool--lib - Common git merge tool shell scriptlets

SYNOPSIS
--------
'. "$(git --exec-path)/git-mergetool--lib"'

DESCRIPTION
-----------

This is not a command the end user would want to run. Ever.
This documentation is meant for people who are studying the
Porcelain-ish scripts and/or are writing new ones.

The 'git-mergetool--lib' scriptlet is designed to be sourced (using
`.`) by other shell scripts to set up functions for working
with git merge tools.

Before sourcing it, your script should set up a few variables;
`TOOL_MODE` is used to define the operation mode for various
functions. 'diff' and 'merge' are valid values.

FUNCTIONS
---------
get_merge_tool::
returns a merge tool

get_merge_tool_cmd::
returns the custom command for a merge tool.

get_merge_tool_path::
returns the custom path for a merge tool.

run_merge_tool::
launches a merge tool given the tool name and a true/false
flag to indicate whether a merge base is present.
'$merge_tool', '$merge_tool_path', and for custom commands,
'$merge_tool_cmd', must be defined prior to calling
run_merge_tool. Additionally, '$MERGED', '$LOCAL', '$REMOTE',
and '$BASE' must be defined for use by the merge tool.

Author
------
Written by David Aguilar <davvid@gmail.com>

Documentation
--------------
Documentation by David Aguilar and the git-list <git@vger.kernel.org>.

GIT
---
Part of the linkgit:git[1] suite
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ SCRIPT_SH += git-merge-octopus.sh
SCRIPT_SH += git-merge-one-file.sh
SCRIPT_SH += git-merge-resolve.sh
SCRIPT_SH += git-mergetool.sh
SCRIPT_SH += git-mergetool--lib.sh
SCRIPT_SH += git-parse-remote.sh
SCRIPT_SH += git-pull.sh
SCRIPT_SH += git-quiltimport.sh
Expand Down
186 changes: 9 additions & 177 deletions git-difftool--helper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#
# Copyright (c) 2009 David Aguilar

# Load common functions from git-mergetool--lib
TOOL_MODE=diff
. git-mergetool--lib

# difftool.prompt controls the default prompt/no-prompt behavior
# and is overridden with $GIT_DIFFTOOL*_PROMPT.
should_prompt () {
Expand All @@ -16,8 +20,7 @@ should_prompt () {
fi
}

# This function prepares temporary files and launches the appropriate
# merge tool.
# Sets up shell variables and runs a merge tool
launch_merge_tool () {
# Merged is the filename as it appears in the work tree
# Local is the contents of a/filename
Expand All @@ -37,187 +40,16 @@ launch_merge_tool () {
fi

# Run the appropriate merge tool command
case "$merge_tool" in
kdiff3)
basename=$(basename "$MERGED")
"$merge_tool_path" --auto \
--L1 "$basename (A)" \
--L2 "$basename (B)" \
"$LOCAL" "$REMOTE" \
> /dev/null 2>&1
;;

kompare)
"$merge_tool_path" "$LOCAL" "$REMOTE"
;;

tkdiff)
"$merge_tool_path" "$LOCAL" "$REMOTE"
;;

meld)
"$merge_tool_path" "$LOCAL" "$REMOTE"
;;

diffuse)
"$merge_tool_path" "$LOCAL" "$REMOTE" | cat
;;

vimdiff)
"$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$REMOTE"
;;

gvimdiff)
"$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$REMOTE"
;;

xxdiff)
"$merge_tool_path" \
-R 'Accel.Search: "Ctrl+F"' \
-R 'Accel.SearchForward: "Ctrl-G"' \
"$LOCAL" "$REMOTE"
;;

opendiff)
"$merge_tool_path" "$LOCAL" "$REMOTE" | cat
;;

ecmerge)
"$merge_tool_path" "$LOCAL" "$REMOTE" \
--default --mode=merge2 --to="$MERGED"
;;

emerge)
"$merge_tool_path" -f emerge-files-command \
"$LOCAL" "$REMOTE" "$(basename "$MERGED")"
;;

*)
if test -n "$merge_tool_cmd"; then
( eval $merge_tool_cmd )
fi
;;
esac
}

# Verifies that (difftool|mergetool).<tool>.cmd exists
valid_custom_tool() {
merge_tool_cmd="$(git config difftool.$1.cmd)"
test -z "$merge_tool_cmd" &&
merge_tool_cmd="$(git config mergetool.$1.cmd)"
test -n "$merge_tool_cmd"
}

# Verifies that the chosen merge tool is properly setup.
# Built-in merge tools are always valid.
valid_tool() {
case "$1" in
kdiff3 | kompare | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge)
;; # happy
*)
if ! valid_custom_tool "$1"
then
return 1
fi
;;
esac
}

# Sets up the merge_tool_path variable.
# This handles the difftool.<tool>.path configuration.
# This also falls back to mergetool defaults.
init_merge_tool_path() {
merge_tool_path=$(git config difftool."$1".path)
test -z "$merge_tool_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
;;
*)
merge_tool_path="$1"
;;
esac
fi
run_merge_tool "$merge_tool"
}

# Allow GIT_DIFF_TOOL and GIT_MERGE_TOOL to provide default values
test -n "$GIT_MERGE_TOOL" && merge_tool="$GIT_MERGE_TOOL"
test -n "$GIT_DIFF_TOOL" && merge_tool="$GIT_DIFF_TOOL"

# If merge tool was not specified then use the diff.tool
# configuration variable. If that's invalid then reset merge_tool.
# Fallback to merge.tool.
if test -z "$merge_tool"; then
merge_tool=$(git config diff.tool)
test -z "$merge_tool" &&
merge_tool=$(git config merge.tool)
if test -n "$merge_tool" && ! valid_tool "$merge_tool"; then
echo >&2 "git config option diff.tool set to unknown tool: $merge_tool"
echo >&2 "Resetting to default..."
unset merge_tool
fi
fi

# Try to guess an appropriate merge tool if no tool has been set.
if test -z "$merge_tool"; then
# We have a $DISPLAY so try some common UNIX merge tools
if test -n "$DISPLAY"; then
# If gnome then prefer meld, otherwise, prefer kdiff3 or kompare
if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
merge_tool_candidates="meld kdiff3 kompare tkdiff xxdiff gvimdiff diffuse"
else
merge_tool_candidates="kdiff3 kompare tkdiff xxdiff meld gvimdiff diffuse"
fi
fi
if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
# $EDITOR is emacs so add emerge as a candidate
merge_tool_candidates="$merge_tool_candidates emerge opendiff vimdiff"
elif echo "${VISUAL:-$EDITOR}" | grep 'vim' > /dev/null 2>&1; then
# $EDITOR is vim so add vimdiff as a candidate
merge_tool_candidates="$merge_tool_candidates vimdiff opendiff emerge"
else
merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff"
fi
echo "merge tool candidates: $merge_tool_candidates"

# Loop over each candidate and stop when a valid merge tool is found.
for i in $merge_tool_candidates
do
init_merge_tool_path $i
if type "$merge_tool_path" > /dev/null 2>&1; then
merge_tool=$i
break
fi
done

if test -z "$merge_tool" ; then
echo "No known merge resolution program available."
exit 1
fi

else
# A merge tool has been set, so verify that it's valid.
if ! valid_tool "$merge_tool"; then
echo >&2 "Unknown merge tool $merge_tool"
exit 1
fi

init_merge_tool_path "$merge_tool"

if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then
echo "The merge tool $merge_tool is not available as '$merge_tool_path'"
exit 1
fi
fi

merge_tool=$(get_merge_tool "$merge_tool") || exit
merge_tool_cmd="$(get_merge_tool_cmd "$merge_tool")"
merge_tool_path="$(get_merge_tool_path "$merge_tool")" || exit

# Launch the merge tool on each path provided by 'git diff'
while test $# -gt 6
Expand Down
Loading

0 comments on commit 21d0ba7

Please sign in to comment.