git-mergetool contains a lot of useful code for interfacing with arbitrary diff/merge tools. This code is only ever used when merge conflicts occur, though. This change allows git-mergetool to be used for the common task of comparing unstaged changes against the latest commit. Being able to see side-by-side diffs in your favorite $mergetool is the benefit of these changes. When additional changes are staged in the index, those changes are provided as the $BASE merge file. Signed-off-by: David Aguilar <davvid@xxxxxxxxx> --- Notes: I am aware that git-citool is a viable alternative in such a scenario, but being able to see a side-by-side diff is one of the first things that CVS-using co-workers asked me about when using git. This only affects the "git mergetool -t <tool> <file(s)>" scenario. The behavior of the no-argument "git mergetool" invocation is unchanged. Style note: This patch mixes tabs and spaces (indent: 4) to be consistent with the rest of git-mergetool.sh. git-mergetool.sh | 32 ++++++++++++++++++++++++++------ 1 files changed, 26 insertions(+), 6 deletions(-) diff --git a/git-mergetool.sh b/git-mergetool.sh index 94187c3..9e5cc68 100755 --- a/git-mergetool.sh +++ b/git-mergetool.sh @@ -131,6 +131,13 @@ merge_file () { MERGED="$1" f=`git ls-files -u -- "$MERGED"` + + if test -z "$f" ; then + f=$(git ls-files --modified -- "$MERGED") + test -z "$f" && f=$(git diff --name-only --cached -- "$MERGED") + test -f "$f" && worktree_mode=1 + fi + if test -z "$f" ; then if test ! -f "$MERGED" ; then echo "$MERGED: file not found" @@ -149,13 +156,26 @@ merge_file () { mv -- "$MERGED" "$BACKUP" cp -- "$BACKUP" "$MERGED" - base_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}'` - local_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}'` - remote_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}'` + if test -n "$worktree_mode" ; then + base_mode=$(git diff --name-only --cached -- "$MERGED") + local_mode=1 + remote_mode=1 + cp "$MERGED" "$LOCAL" + git show HEAD:"$MERGED" > "$REMOTE" + if base_present ; then + # If changes are present in the index use them as $BASE + git checkout-index --prefix=.remote- "$MERGED" + mv .remote-"$MERGED" "$BASE" + fi + else + base_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}'` + local_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}'` + remote_mode=`git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}'` - base_present && git cat-file blob ":1:$prefix$MERGED" >"$BASE" 2>/dev/null - local_present && git cat-file blob ":2:$prefix$MERGED" >"$LOCAL" 2>/dev/null - remote_present && git cat-file blob ":3:$prefix$MERGED" >"$REMOTE" 2>/dev/null + base_present && git cat-file blob ":1:$prefix$MERGED" >"$BASE" 2>/dev/null + local_present && git cat-file blob ":2:$prefix$MERGED" >"$LOCAL" 2>/dev/null + remote_present && git cat-file blob ":3:$prefix$MERGED" >"$REMOTE" 2>/dev/null + fi if test -z "$local_mode" -o -z "$remote_mode"; then echo "Deleted merge conflict for '$MERGED':" -- 1.6.0.1.161.g7f314 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html