Anton K
Anton K

Reputation: 576

how to make git difftool to always export absolute paths

When using 'git difftool' it passes relative path to external diff application when one of the files is the latest version.

~/.gitconfig

[difftool "echo"]
    cmd = echo $LOCAL $REMOTE
    path =
[diff]
    tool = echo

example command

git difftool e3d654bc65404b9229abc0251a6793ffbfccdee3 6c6b5fd34196402e4fa0e8cf42f681d9fbd5359f

Viewing: 'app/views/shared/_graph.html.slim'
Launch 'echo' [Y/n]: y
app/views/shared/_graph.html.slim /var/folders/fs/3pgvhwkj2vq4qt3q6n74s5880000gn/T//XGFoyj__graph.html.slim

In this example app/views/shared/_graph.html.slim is relative path which would be passed to external diff application and since it is relative the diff application doesn't know how to open it.

How can I make 'git difftool' to ALWAYS export absolute paths?

Upvotes: 3

Views: 1440

Answers (4)

Jonathan
Jonathan

Reputation: 95

Although it is not documented, it appears that git interprets $PWD as the Print Working Directory Linux command even when invoked from the Windows command prompt and this is the working directory of the git repository.

Therefore, you can use $PWD alongside $BASE, $LOCAL, $REMOTE and $MERGED.

Upvotes: 1

Anton K
Anton K

Reputation: 576

This is solution based on hlovdal and VonC answers which I've ended up using.

~/.git_absolute_path.sh

#!/bin/sh

FILE_PATH="$1"

case "$FILE_PATH"
in
        /*)
                NEW_PATH="$FILE_PATH"
                ;;
        *)
                NEW_PATH=`git rev-parse --show-toplevel`/"$FILE_PATH"
                ;;
esac

echo "$NEW_PATH"

~/.gitconfig

[difftool "echo"]
    cmd = echo `~/.git_absolute_path.sh $LOCAL` `~/.git_absolute_path.sh $REMOTE`
    path =
[mergetool "echo"]
    cmd = echo `~/.git_absolute_path.sh $LOCAL` `~/.git_absolute_path.sh $REMOTE` `~/.git_absolute_path.sh $BASE` `~/.git_absolute_path.sh $MERGED`
    trustExitCode = true
[diff]
    tool = echo

the difference here is that we are reusing the single script for each path.

Upvotes: 3

VonC
VonC

Reputation: 1324238

You could use git rev-parse --show-toplevel to add before your $LOCAL variable in order to get the full path.

Interestingly enough, there is a patch in progress (February 2014) which would add that very command in order to make difftool work from within a submodule:

"[PATCH] difftool: support repositories with .git-files"

The git-difftool.perl#find_worktree becomes

sub find_worktree 
{ 
    # Git->repository->wc_path() does not honor changes to the working 
    # tree location made by $ENV{GIT_WORK_TREE} or the 'core.worktree' 
    # config variable. 
    return Git::command_oneline('rev-parse', '--show-toplevel'); 
} 

Upvotes: 2

hlovdal
hlovdal

Reputation: 28180

Put the echo command inside a wrapper script

$ tail -5 ~/.gitconfig
[difftool "echo"]
        cmd = /tmp/test/echo.sh $LOCAL $REMOTE
        path =
[diff]
        tool = echo
$ cat /tmp/test/echo.sh
#!/bin/sh

LOCAL="$1"
REMOTE="$2"

case "$LOCAL"
in
        /*)
                L="$LOCAL"
                ;;
        *)
                L=`git rev-parse --show-toplevel`/"$LOCAL"
                ;;
esac

case "$REMOTE"
in
        /*)
                R="$REMOTE"
                ;;
        *)
                R=`git rev-parse --show-toplevel`/"$REMOTE"
                ;;
esac

echo "$L" "$R"
$

Then it will output the absolute path for files:

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   dummy
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git difftool

Viewing: 'a/b/c/dummy'
Hit return to launch 'echo': 
/tmp/vsDkDe_dummy /tmp/test/a/b/c/dummy
$

Upvotes: 4

Related Questions