在.gitconfig
中,我创建了这种类型的别名:
[alias]
something = "!eval `ssh-agent -s` && ssh-add ~/.ssh/id_acub && git config --global user.email <email> && git config --global user.name <user.name>"
在这一点上,运行git something
可以正确显示信息,但是不能正常工作。
如果我在控制台中输入一行:
eval `ssh-agent -s` && ssh-add ~/.ssh/id_acub && git config --global user.email <email> && git config --global user.name <user.name>
然后一切正常。
别名有什么问题?
答案 0 :(得分:1)
让我们以比ssh-agent -s
更简单的示例开始:
$ sh -c 'FOO=bar; echo FOO is now $FOO'
FOO is now bar
$ echo FOO is now $FOO
FOO is now
为什么这个没用?设置其他外壳程序实例的FOO
变量时,为什么未设置登录外壳程序的FOO
变量?
好吧,我希望答案很明显: my shell没有设置FOO
。我设置了一些 other 外壳程序的FOO
变量。我告诉 other shell进行打印,并设置好了。然后,该 other 外壳完成(退出)并将控制权交还给我的登录外壳,当我告诉我的登录外壳打印我的登录外壳的FOO
时,它没有被设置。
ssh-agent -s
所做的是打印出一些作业。让我们尝试一下:
$ sh -c 'echo FOO=bar'
FOO=bar
$ echo FOO is now $FOO
FOO is now
这当然也不起作用,因为我只是打印了一些说明。没有人遵循这些指示。
所以让我们再尝试一件事:
$ eval `sh -c 'echo FOO=bar'`
$ echo FOO is now $FOO
FOO is now bar
这次,我:
$FOO
的shell设置并且由于我让我的shell遵循的指令更改在我的shell中,所以现在设置了 now 我的shell的FOO。
ssh-agent
的设计是相同的:它做了一些工作,然后-在包括-s
在内的各种模式下-打印出指令供后续的shell使用。您需要eval
来使该Shell遵循这些说明。
这很好,只要遵循这些说明的shell是您的 shell,它就可以满足您的要求。但是,当您创建Git别名时,Git本身会运行一个新的,不同的 shell。该外壳程序将按照说明进行操作,完成后,您的外壳程序将不受影响。
这意味着您无法使用Git别名执行所需的操作。您必须使用一个会影响您的外壳的别名或函数,而不是一个会启动新外壳,影响它,然后终止它并使这些效果消失的别名或函数。
请注意,某些更改(例如git config --global
)存储在文件中,而不是存储在shell中。当壳消失时,这些变化不会消失。关键区别在于:文件系统状态存储在各个进程之外。如果ssh-agent
所做的一切都存储在文件系统状态下,则可以使其正常运行,但是ssh-agent
的某些内容未存储在其中。