Skip to content

Commit

Permalink
add git difftool
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitug committed Feb 28, 2013
1 parent 993a763 commit b61f60a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 2 deletions.
76 changes: 76 additions & 0 deletions bin/diffconflicts
@@ -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
2 changes: 2 additions & 0 deletions git/aliases.bash
Expand Up @@ -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'
Expand Down
10 changes: 8 additions & 2 deletions git/gitconfig.symlink
Expand Up @@ -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.