Permalink
Browse files

add git difftool

  • Loading branch information...
nikitug committed Feb 28, 2013
1 parent 993a763 commit b61f60a2224309db9d95376e117e9314c6c2df36
Showing with 86 additions and 2 deletions.
  1. +76 −0 bin/diffconflicts
  2. +2 −0 git/aliases.bash
  3. +8 −2 git/gitconfig.symlink
View
@@ -0,0 +1,76 @@
+#!/bin/bash
+#
+# Instead of editing a file with <<<< ==== >>> conflict markers, this opens
+# each "side" of the conflict markers in a two-way vimdiff window.
+#
+# Layout:
+#
+# Tab1 is a two-way diff of the conflicts.
+# +--------------------------------+
+# | LCONFL | RCONFL |
+# +--------------------------------+
+# Tab2 is a three-way diff of the original files and the merge base.
+# +--------------------------------+
+# | LOCAL | BASE | REMOTE |
+# +--------------------------------+
+# Tab3 is the MERGED or 'result' file that contains the conflict markers.
+# +--------------------------------+
+# | <<<<<<< HEAD |
+# | LCONFL |
+# | ======= |
+# | RCONFL |
+# | >>>>>>> someref |
+# +--------------------------------+
+#
+# Workflow:
+#
+# 1. Save your changes to the LCONFL temporary file (the left window on the
+# first tab; also the only file that isn't read-only).
+# 2. The LOCAL, BASE, and REMOTE versions of the file are available in the
+# second tabpage if you want to look at them.
+# 3. When vimdiff exits cleanly, the file containing the conflict markers
+# will be updated with the contents of your LCONFL file edits.
+#
+# NOTE: Use :cq to abort the merge and exit Vim with an error code.
+#
+# Add this mergetool to your ~/.gitconfig (you can substitute vim for gvim):
+#
+# git config --global merge.tool diffconflicts
+# git config --global mergetool.diffconflicts.cmd 'diffconflicts gvim $BASE $LOCAL $REMOTE $MERGED'
+# git config --global mergetool.diffconflicts.trustExitCode true
+# git config --global mergetool.diffconflicts.keepBackup false
+
+if [[ -z $@ || $# != "5" ]] ; then
+ echo -e "Usage: $0 \$BASE \$LOCAL \$REMOTE \$MERGED"
+ exit 1
+fi
+
+cmd=$1
+BASE=$2
+LOCAL=$3
+REMOTE=$4
+MERGED=$5
+LCONFL=$(dirname $5)/$$.left.tmp
+RCONFL=$(dirname $5)/$$.right.tmp
+
+# Remove the conflict markers for each 'side' and put each into a temp file
+sed -e '/^=======$/,/>>>>>>>/d' -e '/<<<<<<</d' $MERGED > $LCONFL
+sed -e '/<<<<<<</,/^=======$/d' -e '/>>>>>>>/d' $MERGED > $RCONFL
+
+# Fire up vimdiff
+$cmd -f -R -d $LCONFL $RCONFL \
+ -c ":set noro" \
+ -c ":tabe $LOCAL" -c ":vert diffs $BASE" -c ":vert diffs $REMOTE" \
+ -c ":winc t" -c ":tabe $MERGED" -c ":tabfir"
+
+EC=$?
+
+# Overwrite $MERGED only if vimdiff exits cleanly.
+if [[ $EC == "0" ]] ; then
+ cat $LCONFL > $MERGED
+fi
+
+# Always delete our temp files; Git will handle it's own temp files
+rm $LCONFL $RCONFL
+
+exit $EC
View
@@ -22,6 +22,8 @@ alias gci='git commit --interactive'
# merge
alias gm='git merge --no-ff'
alias gmff='git merge'
+alias gmt='git mergetool -t vimdiffconflicts'
+alias gmtm='git mergetool -t mvimdiffconflicts'
# branch
alias gb='git branch'
View
@@ -42,9 +42,15 @@
autosetupmerge = true
[apply]
whitespace = nowarn
-[mergetool]
- keepBackup = false
[difftool]
prompt = false
[help]
autocorrect = 1
+[mergetool]
+ keepBackup = false
+[mergetool "vimdiffconflicts"]
+ cmd = $DOTFILES/bin/diffconflicts vim $BASE $LOCAL $REMOTE $MERGED
+ trustExitCode = true
+[mergetool "mvimdiffconflicts"]
+ cmd = $DOTFILES/bin/diffconflicts mvim $BASE $LOCAL $REMOTE $MERGED
+ trustExitCode = true

0 comments on commit b61f60a

Please sign in to comment.