2 # git-difftool--helper is a GIT_EXTERNAL_DIFF-compatible diff tool launcher.
3 # This script is typically launched by using the 'git difftool'
6 # Copyright (c) 2009 David Aguilar
8 # Set GIT_DIFFTOOL_NO_PROMPT to bypass the per-file prompt.
10 test -z "$GIT_DIFFTOOL_NO_PROMPT"
13 # This function prepares temporary files and launches the appropriate
15 launch_merge_tool
() {
16 # Merged is the filename as it appears in the work tree
17 # Local is the contents of a/filename
18 # Remote is the contents of b/filename
19 # Custom merge tool commands might use $BASE so we provide it
25 # $LOCAL and $REMOTE are temporary files so prompt
26 # the user with the real $MERGED name before launching $merge_tool.
27 if should_prompt
; then
28 printf "\nViewing: '$MERGED'\n"
29 printf "Hit return to launch '%s': " "$merge_tool"
33 # Run the appropriate merge tool command
36 basename=$
(basename "$MERGED")
37 "$merge_tool_path" --auto \
38 --L1 "$basename (A)" \
39 --L2 "$basename (B)" \
45 "$merge_tool_path" "$LOCAL" "$REMOTE"
49 "$merge_tool_path" "$LOCAL" "$REMOTE"
53 "$merge_tool_path" "$LOCAL" "$REMOTE"
57 "$merge_tool_path" "$LOCAL" "$REMOTE" |
cat
61 "$merge_tool_path" -d -c "wincmd l" "$LOCAL" "$REMOTE"
65 "$merge_tool_path" -d -c "wincmd l" -f "$LOCAL" "$REMOTE"
70 -R 'Accel.Search: "Ctrl+F"' \
71 -R 'Accel.SearchForward: "Ctrl-G"' \
76 "$merge_tool_path" "$LOCAL" "$REMOTE" |
cat
80 "$merge_tool_path" "$LOCAL" "$REMOTE" \
81 --default --mode=merge2
--to="$MERGED"
85 "$merge_tool_path" -f emerge-files-command \
86 "$LOCAL" "$REMOTE" "$(basename "$MERGED")"
90 if test -n "$merge_tool_cmd"; then
91 ( eval $merge_tool_cmd )
97 # Verifies that (difftool|mergetool).<tool>.cmd exists
99 merge_tool_cmd
="$(git config difftool.$1.cmd)"
100 test -z "$merge_tool_cmd" &&
101 merge_tool_cmd
="$(git config mergetool.$1.cmd)"
102 test -n "$merge_tool_cmd"
105 # Verifies that the chosen merge tool is properly setup.
106 # Built-in merge tools are always valid.
109 kdiff3 | kompare | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge
)
112 if ! valid_custom_tool
"$1"
120 # Sets up the merge_tool_path variable.
121 # This handles the difftool.<tool>.path configuration.
122 # This also falls back to mergetool defaults.
123 init_merge_tool_path
() {
124 merge_tool_path
=$
(git config difftool.
"$1".path
)
125 test -z "$merge_tool_path" &&
126 merge_tool_path
=$
(git config mergetool.
"$1".path
)
127 if test -z "$merge_tool_path"; then
136 merge_tool_path
=emacs
145 # Allow GIT_DIFF_TOOL and GIT_MERGE_TOOL to provide default values
146 test -n "$GIT_MERGE_TOOL" && merge_tool
="$GIT_MERGE_TOOL"
147 test -n "$GIT_DIFF_TOOL" && merge_tool
="$GIT_DIFF_TOOL"
149 # If merge tool was not specified then use the diff.tool
150 # configuration variable. If that's invalid then reset merge_tool.
151 # Fallback to merge.tool.
152 if test -z "$merge_tool"; then
153 merge_tool
=$
(git config
diff.tool
)
154 test -z "$merge_tool" &&
155 merge_tool
=$
(git config merge.tool
)
156 if test -n "$merge_tool" && ! valid_tool
"$merge_tool"; then
157 echo >&2 "git config option diff.tool set to unknown tool: $merge_tool"
158 echo >&2 "Resetting to default..."
163 # Try to guess an appropriate merge tool if no tool has been set.
164 if test -z "$merge_tool"; then
165 # We have a $DISPLAY so try some common UNIX merge tools
166 if test -n "$DISPLAY"; then
167 # If gnome then prefer meld, otherwise, prefer kdiff3 or kompare
168 if test -n "$GNOME_DESKTOP_SESSION_ID" ; then
169 merge_tool_candidates
="meld kdiff3 kompare tkdiff xxdiff gvimdiff diffuse"
171 merge_tool_candidates
="kdiff3 kompare tkdiff xxdiff meld gvimdiff diffuse"
174 if echo "${VISUAL:-$EDITOR}" |
grep 'emacs' > /dev
/null
2>&1; then
175 # $EDITOR is emacs so add emerge as a candidate
176 merge_tool_candidates
="$merge_tool_candidates emerge opendiff vimdiff"
177 elif echo "${VISUAL:-$EDITOR}" |
grep 'vim' > /dev
/null
2>&1; then
178 # $EDITOR is vim so add vimdiff as a candidate
179 merge_tool_candidates
="$merge_tool_candidates vimdiff opendiff emerge"
181 merge_tool_candidates
="$merge_tool_candidates opendiff emerge vimdiff"
183 echo "merge tool candidates: $merge_tool_candidates"
185 # Loop over each candidate and stop when a valid merge tool is found.
186 for i
in $merge_tool_candidates
188 init_merge_tool_path
$i
189 if type "$merge_tool_path" > /dev
/null
2>&1; then
195 if test -z "$merge_tool" ; then
196 echo "No known merge resolution program available."
201 # A merge tool has been set, so verify that it's valid.
202 if ! valid_tool
"$merge_tool"; then
203 echo >&2 "Unknown merge tool $merge_tool"
207 init_merge_tool_path
"$merge_tool"
209 if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev
/null
2>&1; then
210 echo "The merge tool $merge_tool is not available as '$merge_tool_path'"
216 # Launch the merge tool on each path provided by 'git diff'
219 launch_merge_tool
"$1" "$2" "$5"