git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFC/PATCH] git-mergetool: allow using merge tools for staging changes

From
David Aguilar <davvid@gmail.com>
Date
Sep 2, 2008, 07:25 UTC
Message-ID
<ca72cec5020d847ac7d1577c586772ae22810bef.1220339887.git.davvid@gmail.com>

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@gmail.com>
---
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
Message 1 of 1 in “git-mergetool: allow using merge tools for staging changes”
  1. git-mergetool: allow using merge tools for staging changesDavid Aguilar, Sep 2, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.