shell命令的git别名,以cd进入git root,不按预期工作

时间:2013-09-26 15:27:06

标签: git shell alias

我正在尝试使用cdgit rev-parse --show-toplevel我的别名定义到git根目录中。

目前我将其作为.bashrc中的别名,可以正常使用:

alias gitroot='cd "$(git rev-parse --show-toplevel)"'

但我知道你可以使用git别名运行shell命令,所以我想我会将命令移到我的.gitconfig中以使我的文件更清晰一些。

问题是,我无法弄清楚为什么我的别名不起作用。目前,我在[alias]

中的.gitconfig下有此内容
root = "!sh -c 'cd \"$(git rev-parse --show-toplevel)\"'"

但是当我运行git root时,我只是留在当前目录中。

我已尝试过其他shell别名并且他们已经工作,例如别名say = "!sh -c 'echo \"$0\"'"工作得很好:

$ git say hello
hello

虽然我注意到类似的cd命令(cd = "!sh -c 'cd \"$0\"'")失败了:

~/repos/myproject$ git cd /home/
~/repos/myproject$

我无法弄清楚它是否与我的语法有关,或者它是一个git别名的怪癖,它不支持cd命令,或完全不支持其他内容。

如果有帮助,我正在使用Git 1.7.9.5。

1 个答案:

答案 0 :(得分:18)

你的shell正在调用Git,而Git正在调用另一个shell来运行你的cd命令。此命令成功,这将更改子shell的工作目录,但它不会更改Git的工作目录,也不会更改父shell的工作目录。

要执行此操作,您需要在当前 shell中运行该命令,这意味着调用Git将无法完成此操作。您将不得不继续使用shell别名。


为了说明,假设您有以下名为up.sh的shell脚本:

#!/bin/sh
cd ..

如果您将此脚本作为./up.sh执行,那么从当前shell的角度来看,任何内容都不会发生变化,因为cd是在新的shell实例中执行的。但是,如果您将其作为. up.sh执行,则会指示您当前的shell自行执行文件的内容,而不会生成子shell。在这种情况下,当前shell的工作目录将会改变。

这是关键的区别。使用Git别名类似于./up.sh方法,而shell别名类似于. up.sh方法。