【问题标题】:git bitbucket private submodule ssh alias issuesgit bitbucket 私有子模块 ssh 别名问题
【发布时间】:2016-05-25 04:27:23
【问题描述】:

git 版本 1.7.1(我对此服务器无权)

我有一个包含多个子模块的私有仓库,其中一些也是私有的。 非私有的子模块毫无问题地进入。然而,遇到的第一个私人回购返回这个 ssh: Could not resolve hostname bitbucket.org:username: Name or service not known,进程到此停止。

As per the docs,我已经为登台服务器设置了一个部署密钥,并创建了一个 ~/.ssh/config 别名来将 bitbucket.org 指向该密钥。这是有效的,因为私人父回购很好。 登台服务器在环境中有一些我必须解决的锁定文件,所以我初始化如下:

git init
git remote add origin ssh://git@bitbucket.org/user/parent-repo.git 
git fetch
git checkout -t origin/master

到目前为止一切顺利,但子模块为空:

# Update submodules 
git submodule update --init --recursive
# git submodule update --remote # Not available in 1.7.1
git submodule foreach git pull origin master 
## git fetch --recurse-submodules=yes # introduced 1.7.3 

这是出现问题的地方,ssh 无法连接,并且进程在第一个私有 repo 时停止。访问私有存储库并不完全令人惊讶,我们需要关联另一个密钥 which cannot be the same as the one associated with the account。 (向下滚动到 Luke Woodward 这篇文章中一些有趣的 cmets 的“私人回购”标题)

因此,在创建了单个(我可以只创建一个)密钥并为每个密钥创建 ssh 别名(在登台服务器上)之后,我不知道如何正确引用这些密钥。

为了确保别名正常工作,我们 can test 他们使用:

ssh -Tv git@<alias>

成功时会返回大量以以下结尾的输出:

....
authenticated via a deploy key.
You can use git or hg to connect to Bitbucket. Shell access is disabled.
This deploy key has read access to the following repositories: XXXXX

这是我迄今为止尝试过的。每次更改后,我都在运行:

git submodule update --init --recursive
git submodule foreach git pull origin master

编辑:正如 cmets 重新更新链接中所建议的那样,此时 git submodule sync 将同步所有已经完成拉取的子模块。此操作中不会列出任何私人回购。很遗憾,这个操作似乎并没有解决缺少私人回购的问题。

  1. 将路径更改为 ssh 密钥别名 .gitmodules

结果:ssh: Could not resolve hostname bitbucket.org:username

看起来别名正在解析,但有什么东西阻塞了密钥?

  1. .git/config 中更改ssh 密钥别名的路径。

结果:ssh: Could not resolve hostname &lt;alias&gt;:username

显然别名根本没有解析。


由于选项 1 似乎至少发出了 ssh 请求,我操纵了 ssh 别名,我认为该别名将请求路由到正确的密钥。必须有一些有效的缓存,因为将别名上的主机更改为不可能的东西,例如bitbucketXXX.org。结果是同样的错误:ssh: Could not resolve hostname bitbucket.org:username。我原以为错误会读到ssh: Could not resolve hostname *bitbucketXXX.org:username* --HUMMMM


更新:经过一番思考

到目前为止,我的方法是创建一个 ssh 密钥别名,将 bitbucket.org 链接到我在个人 bitbucket 设置中为此服务器建立的父密钥。

当这对 subs 不起作用时,我为他们每个人设置了密钥,然后在服务器上为每个人设置了别名,但保持父 repo 密钥与以前相同。到目前为止,我一直在寻找在.gitmodules.git/config 中引用这些别名键的方法。但这根本不起作用,父键被识别,但子模块键的别名不是。

我的最后一种方法是制作一个通用密钥(与我的帐户密钥不同,他们不会让你这样做)并将其分配给父仓库,每个子模块。在服务器上,bitbucket.org 的别名指向这个公共密钥。

现在当我在大量输出后使用ssh -Tv git@bitbucket.org 对其进行测试时,我们得到:

authenticated via a deploy key.
You can use git or hg to connect to Bitbucket. Shell access is disabled.
This deploy key has read access to the following repositories:
*A list of all the repos associated with that key*

虽然这看起来很有希望,但结果是一样的ssh: Could not resolve hostname . . .

我什至尝试过像这样将用户名吸收到别名中

Host bitbucket.org:<user_name>
    HostName bitbucket.org          
    IdentityFile ~/.ssh/shared_bb_key

但这会导致conq: invalid repository syntax.


此时我看不到森林,更别提树木了。有什么想法吗?

【问题讨论】:

  • 在使用别名更改子模块 url 后再次尝试之前,您是否像 stackoverflow.com/a/914090/6309 那样进行了 git 子模块同步?
  • 这列出了已经成功的子程序,没有出错的子程序。以下git submodule foreach git pull origin master 仍然显示之前的错误。我怀疑.git/config 中引用了该链接。所以那里没有快乐。
  • @vonC,我已将您的评论纳入测试。然而,它似乎并没有解决这个问题。不过,感谢您抽出宝贵时间查看此内容。

标签: git git-submodules ssh-keys


【解决方案1】:

如何在 repo 中使用公共和私有子模块

我需要为使用私有子模块存储库的 wordpress 创建部署策略。互联网上已经有一些good source,但它们并不直接针对私有子模块。因此,我正在记录使用 Bitbucket 完成这项工作所采取的步骤。其中一些可能也适用于其他服务,尽管我只使用 Bitbucket 对其进行了测试。如果你使用 Github,你可能对 in this answer too 感兴趣。

作为序言,我是 stuck 在我的临时服务器上使用 git 1.7.1,据我所知,它是在 2011 年初发布的,所以现在只有 年了。也许这使我的情况复杂化,但如果你看到我使用command x,而不是command Y,这可能就是原因。我试图记录我所理解的更现代的方法,当然会根据任何反馈进行更新。我还尝试在此过程中标出危险,但我不认为问题或解决方案是我的特定主机所独有的。

我假设您已经熟悉或在您的项目中设置了子模块。如果不是这些文章是一个开始的地方: https://www.atlassian.com/git/tutorials/
http://blogs.atlassian.com/2013/03/git-submodules-workflows-tips/

对于那些已经知道的人

如果您已经建立了密钥和别名,并且想知道为什么这不起作用,请跳过。答案在于在您的 ssh 密钥别名中将 git 标识为用户。

基础工作:设置 SSH 密钥

首先,您需要能够使用终端 ssh 进入您的服务器,然后您需要为要拉取的模块建立一个(或多个)密钥。 Bitbucket 允许您在存储库之间共享 ssh 密钥,因此您的用例可能需要不止一个。然而,为简单起见,我将说明一种“一键统治一切”的方法。

注意:此密钥不是在您的用户帐户中建立的允许您推送到您的存储库的密钥。出于安全原因,Bitbucket 不允许您将此密钥用作存储库上的部署密钥。

此外,由于此过程将仅使用部署密钥,因此我们只能拉取。如果您拥有父存储库,则可以将其推回上游,但需要该存储库的单独别名。但是,我的用例是用于测试网站的登台服务器,因此仅拉取对我来说已经足够了。

Atlassian 在此处提供了生成密钥的完整说明:https://confluence.atlassian.com/x/YwV9E

简而言之,密钥通常保存在 ~/.ssh/ 中,运行 ssh-keygen 将提示您完成创建密钥的步骤 –请记住:不要指定密码

注意:我发现从我的~/.ssh 目录 运行keygen 会导致后来出现权限问题。这可能是我的服务器独有的,但为了安全起见,只需从您的主目录之类的地方启动该进程即可。

创建密钥后,如果您li -a ~/.ssh/,您应该能够看到它。 假设这是您保存密钥的位置,cat ~/.ssh/your_bitbucket_submod.pub 将返回密钥的公共部分,因此请复制此部分(注意不要添加任何额外字符),并将其粘贴到每个私有存储库的部署密钥部分。

此处的说明:https://confluence.atlassian.com/display/BITBUCKET/Use+deployment+keys

创建 SSH 别名

将密钥分配给 Bitbucket 上的存储库后,您需要在服务器上创建 ssh 别名。每当调用 ssh 连接到这些私有存储库时,这些别名都会将公钥传递给 bitbucket.org。

您可能已经猜到了,我们将使用 ssh,而不是 https 来进行我们所有的私有 repo 连接。

正常的 git ssh 路径应该是这样的:ssh://git@bitbucket.org:&lt;USER-NAME&gt;/repo-name,虽然 Bitbucket will accept the path with or without ssh://

SSH 别名相对简单,在~/.ssh/config/ 中指定。

如果此配置文件存在,我们将对其进行修改,否则我们将创建它。使用您喜欢的文本编辑器,添加以下行:

Host your_bitbucket_submod.pub
    HostName bitbucket.org
    IdentityFile ~/.ssh/your_bitbucket_submod
    User git

这是我们需要的肉,或者至少是其中的一个主要部分。

只是一个失败:

  • Host 是 ssh 将在发送给它的路径中查找的别名关键字。这可以是任何东西,但我经常将其命名为与生成的密钥相同的名称。

  • HostName 是别名指向的域,在本例中为 bitbucket.org。

  • IdentityFile 指向密钥的 private 部分(注意不是.pub),通过这两个部分,ssh 可以验证会话。

  • User 指定 ssh 用户 http://unixhelp.ed.ac.uk/CGI/man-cgi?ssh+1 查看环境

User?现在,这与您将找到的其他一些指令有所不同。事实证明,使用 ssh,Git 将自己指定为 user,并将托管 repo 的 git 帐户(即您的 Bitbucket 用户名)放在分号之后。这一行花了我几天的head scratching,直到我重新阅读了Jochen Kupperschmidt 的这篇文章,终于明白了他的意思。这是我发现的唯一一篇在此上下文中专门引用 User 参数的文章,因此向 Jochen 致敬。

测试你的别名

值得检查您的别名是否正在连接,以及密钥是否已分配给您期望的所有存储库。为了检查,运行以下命令:

ssh -Tv your_bitbucket_submod

如果运气好的话,你应该会看到很多类似这样结尾的废话:

authenticated via a deploy key.
You can use git or hg to connect to Bitbucket. Shell access is disabled.
This deploy key has read access to the following repositories:
* A list of all the repos associated with this key . . . *

没有快乐?这里有一些帮助: https://confluence.atlassian.com/display/BITBUCKET/Troubleshoot+SSH+Issues

设置回购:

现在我不是 git 的专家,所以对于如何最好地完成下一部分可能会有不同的意见。我的用例是将一个 repo 放入一个目录中,该目录包含不会被跟踪的预先存在的内容,but must remain。我怀疑这是一个会随着我的更好的人提供反馈而有所改进的领域。

首先,我们将cd 放入存储库所在的目录。到达那里后,我们将执行以下操作:

git init
git remote add origin your_bitbucket_submod:<USER-NAME>/your-fav-repo.git
git fetch
git checkout -t origin/master

请注意,我们在此处使用 别名,因为我的父 repo 也是私有的,并且我也有与之关联的部署密钥。

您可以在此处设置第二个别名,以指向您的主帐户密钥。虽然我没有对此进行测试,但这应该能够将所有子模块向上推送,即使它们与您的配置文件的 ssh 主密钥位于同一帐户下。

所以,如果我们走到这一步,我们的别名和密钥正在工作,并且父 repo 现已建立。此时您可能会想通过以下方式引入子模块:

# Update submodules without risk of recursion
git submodule update --init --recursive
## git submodule update --remote # Not available in 1.7.1
git submodule foreach git pull origin master 
# git fetch --recurse-submodules=yes # introduced 1.7.3 

如果您这样做了,您应该会看到您可能拥有的任何 public 子模块的成功传输,但是一旦遇到 private repo,该过程就会停止你可能会看到。

如果您的子模块中有子模块,则存在无限循环克隆的风险。 This two step method of updating should prevent this.

ssh: Could not resolve hostname bitbucket.org:<USER-NAME>

呼?!

或者,系统可能会提示您输入密码,在这种情况下,您的子模块是 https 格式,并且需要转换为 ssh 路径。

设置.bitbucket/config:

当你第一次检查你的父 repo 时,如果 git 发现有子模块,它会在隐藏文件和目录时创建一个编号来跟踪它们(ls -a 来显示它们)。我们需要做的是编辑(使用 vim、nano 等).git/config 文件,并使用我们之前创建的开发密钥的别名修改此处列出的路径。

配置文件如下所示:

[core]
        repositoryformatversion = 0  
        filemode = true  
        bare = false  
        logallrefupdates = true  
[remote "origin"]  
        url = your_bitbucket_submod:<USER-NAME>/parent-repo.git  
        fetch = +refs/heads/*:refs/remotes/origin/*  
[branch "master"]  
        remote = origin  
        merge = refs/heads/master  
[submodule "plugins/akismet"]  
        url = https://github.com/git-mirror/wordpress-akismet.git    
[submodule "plugins/your-famous-plugin"]
    url = ssh://git@bitbucket.org:<USER-NAME>/your-famous-plugin.git
    . . . 

请注意,[core] 下的 url 已使用别名,从您指定 remote add origin 时开始。稍后对于 akismet 插件,我们看到它在 github 上的公共 repo 通过 https 连接,最后在 Bitbucket 上看到了一个私有 repo。在这里您将更改所有引用,例如:

ssh://git@bitbucket.org:&lt;USER-NAME&gt;/your-famous-plugin.git

收件人:your_bitbucket_submod:&lt;USER-NAME&gt;/your-famous-plugin.git

完成后,我们可以重新更新子模块:

git submodule update --init --recursive
git submodule foreach git pull origin master 

看着他们滚来滚去。 . .

此时的任何故障都可能是您指定子模块时或调整配置文件时出现的某种损坏的路径。或者部署密钥实际上并未分配给 bitbucket 中的存储库。

希望这对一些人有所帮助。

延伸阅读:

【讨论】:

【解决方案2】:

关于

ssh: Could not resolve hostname

许多人遇到的这个问题的一部分,SSH 有两个不同的配置文件:一个系统范围的配置文件和一个用户特定的配置文件。我阅读的说明,包括 Shannon Chou 的说明,都说要将别名添加到位于 ~/.ssh/.config

user-specific 配置文件中

就我而言,我需要将别名添加到 system-wide 配置文件中,在 Windows 10 上使用 Git 时,该文件通常位于:C:\Program Files\Git\etc\ ssh\ssh_config,在 Git 的目录中。

您可以通过运行此命令来确定 SSH 正在使用哪个配置文件,“myalias”可以是任何字符串,我们感兴趣的是这将输出的配置文件路径:

ssh -vv myalias

OpenSSH_7.1p2, OpenSSL 1.0.2d 9 Jul 2015
debug1: Reading configuration data /etc/ssh/ssh_config

在输出中注意文件路径“/etc/ssh/ssh_config”。这告诉我们 SSH 正在那里寻找别名,而不是在 ~/.ssh/.config 文件中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-27
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 2022-10-19
    • 2014-11-27
    • 2021-06-24
    • 1970-01-01
    相关资源
    最近更新 更多