工作树中的Git别名在git 2.16中没有按预期工作

时间:2018-06-12 21:49:51

标签: git

转换为特定Git存储库的Git别名,然后运行提供的Git命令,即:

[alias]
    repo1 = "!f() { cd /path/to/repo1 && git \"$@\" ; } ; f"
如果在Git工作树中执行,

不适用于Git 2.16.2。它在Git 2.12.0中运行良好。

无论Git命令传递给别名,都会在原始的worktree目录中执行,而不是在目标目标目录中执行。

重现的步骤:

$ mkdir -p /tmp/git
$ cd /tmp/git
$ mkdir repo1 repo2
$ cd repo1
$ git init
Initialized empty Git repository in /private/tmp/git/repo1/.git/
$ touch foo
$ git add foo
$ git commit -m"git log should show this"
[master (root-commit) 6c366be] git log should show this
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo
$ cd ../repo2
$ git init
Initialized empty Git repository in /private/tmp/git/repo2/.git/
$ touch bar
$ git add bar
$ git commit -m"git log should NOT show this"
[master (root-commit) 27f9a83] git log should NOT show this
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bar
$ git branch new
$ mkdir ../repo2worktrees
$ git worktree add ../repo2worktrees/new new
Preparing ../repo2worktrees/new (identifier new)
HEAD is now at 27f9a83 git log should NOT show this

$ git config --global alias.cdg '!f() { cd /tmp/git/repo1 && git "$@" ; } ; f'

# From inside normal Git repo, works as expected:
$ git cdg log
commit 6c366be9188da3c8f9308ccfe1682c605ff6fed2 (HEAD -> master)
Author: msleigh 
Date:   Tue Jun 12 22:22:06 2018 +0100

    git log should show this

# From outside Git repo, works as expected:
$ cd .. ; git cdg log
commit 6c366be9188da3c8f9308ccfe1682c605ff6fed2 (HEAD -> master)
Author: msleigh 
Date:   Tue Jun 12 22:22:06 2018 +0100

    git log should show this

# From inside worktree:
$ cd repo2worktrees/new ; git cdg log
commit 27f9a83b7f62830b43277517b237e9b22cb9df9c (HEAD -> new, master)
Author: msleigh 
Date:   Tue Jun 12 22:22:42 2018 +0100

    git log should NOT show this

Git bug?如果有任何想法我怎么可以重写别名以达到正确的结果?

更新

我应该补充一点,如果我在别名中使用git -C <destination> <command>而不是cd <destination> ; git <command>,效果是相同的。

1 个答案:

答案 0 :(得分:2)

可能不是一个错误,取决于你对其他事物的看法:它可能与Git 2.12.0和2.16.0之间的许多其他git worktree和别名相关的修复有关。特别是,某些操作需要知道Git目录和工作树“确实在哪里”,因此它们将设置携带该信息的特殊环境变量。没有设置这些内容,其他命令行为不端。

如果在环境中设置了$GIT_DIR和/或$GIT_WORK_TREE,则确定存储库和工作树所在的位置。执行任何cd不会取消 - 设置环境变量;它会持久存在别名的子shell中。

您可以自己覆盖这些内容,设置或取消设置环境变量或使用--work-tree--git-dir选项。也就是说,而不是:

repo1 = "!f() { cd /path/to/repo1 && git \"$@\" ; } ; f"

您可以将其定义为:

repo1 = "!f(){ git --git-dir=/path/to/repo1.git --work-tree=/path/to/repo1 \"$@\";}; f"

(我在这里压缩了一些空格以使其更适合StackOverflow)或:

repo1 = "!f() { unset GIT_DIR GIT_WORK_TREE; cd /path/to/repo1 && git \"$@\"; } ; f"