2

当使用“git difftool”时,当其中一个文件是最新版本时,它会将相对路径传递给外部 diff 应用程序。

~/.gitconfig

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

示例命令

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

在这个例子app/views/shared/_graph.html.slim中是相对路径,它将被传递给外部 diff 应用程序,因为它是相对的,所以 diff 应用程序不知道如何打开它。

如何使“git difftool”始终导出绝对路径?

4

4 回答 4

3

将 echo 命令放在包装脚本中

$ 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"
$

然后它将输出文件的绝对路径:

$ 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
$
于 2014-03-14T07:18:28.423 回答
2

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'); 
} 
于 2014-03-14T07:13:07.177 回答
2

这是基于我最终使用的 hlovdal 和 VonC 答案的解决方案。

~/.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

这里的不同之处在于我们为每个路径重用了单个脚本。

于 2014-03-15T08:43:31.530 回答
1

尽管没有记录,但似乎$PWD即使从 Windows 命令提示符调用 git 也会解释为打印工作目录 Linux 命令,这是 git 存储库的工作目录。

因此,您可以$PWD$BASE$LOCAL$REMOTE一起使用$MERGED

于 2020-02-04T14:07:43.157 回答