首页 > 解决方案 > git 别名 ssh-add .gitconfig

问题描述

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

然后一切正常。

别名有什么问题?

标签: gitsshalias

解决方案


让我们从一个比以下更简单的例子开始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当我设置其他一些 shell 实例的FOO变量时,我的登录 shell 的变量没有设置?

好吧,我希望答案很明显:我的shell 没有FOO设置。我设置了一些其他shell的FOO变量。我告诉另一个外壳打印它,它被设置了。然后另一个shell 完成——退出——并将控制权交还给我的登录 shell,当我告诉我的登录 shell 打印我的登录 shellFOO时,它没有设置。

什么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 的 FOO 已设置。

for 的设计ssh-agent是一样的:它做了一些工作,然后——在包括 with 在内的各种模式下-s——打印出一些 shell 要遵循的指令。您需要eval使该外壳遵循这些说明。

这一切都很好,只要遵循这些说明的外壳是的外壳,就可以满足您的要求。但是当你创建一个 Git 别名时,Git 本身会运行一个新的、不同的shell。该外壳遵循说明,完成后,您的外壳不受影响。

这意味着你不能用 Git 别名做你想做的事。您必须使用会影响您的shell 的别名或函数,而不是会启动一个新的 shell、影响它、然后让它终止并使这些影响消失的别名或函数。

请注意,某些更改(例如git config --global)存储在files中,而不是您的 shell 中。当外壳消失时,这些变化不会消失。这是一个关键区别:文件系统状态存储在各个进程之外。如果所做的一切ssh-agent都存储在文件系统状态,它可以工作,但有些东西ssh-agent没有存储在那里。


推荐阅读