git bitbucket私有(private)子模块ssh别名问题

标签 git git-submodules ssh-keys

git版本1.7.1(在此服务器上,我对此无能为力)

我有一个带有几个子模块的私有(private)仓库,其中一些也是私有(private)的。
非私有(private)的子模块可以毫无问题地进入。但是,遇到的第一个私有(private)仓库会返回此ssh: Could not resolve hostname bitbucket.org:username: Name or service not known,该过程在此处停止。

As per the docs,我为登台服务器设置了部署 key ,并创建了~/.ssh/config别名以将bitbucket.org指向该 key 。这是可行的,因为私有(private)父级 repo 协议(protocol)正处于正常运行状态。
登台服务器在我必须解决的环境中有一些锁定文件,因此我要进行如下初始化:

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无法连接,并且该过程在第一个私有(private)存储库上暂停。要访问私有(private)存储库,这并不完全令人惊讶,我们需要关联另一个 key which cannot be the same as the one associated with the account。 (向下滚动到“私有(private)仓库”标题,由Luke Woodward在本文中提供一些有趣的评论)

因此,在制作了单个(我可能只创建了一个) key 并为每个 key (在登台服务器上)创建了ssh别名之后,我陷入了如何正确引用这些 key 的困境。

只是为了确保别名能够正常工作,我们使用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

编辑:如评论所述,建议更新链接,此时git submodule sync将同步已完成 pull 的所有子模块。此操作中不会列出任何私有(private)存储库。因此,令人遗憾的是,此操作似乎无法解决缺少私有(private)存储库的问题。
  • 更改ssh键别名的路径.gitmodules

  • Result: ssh: Could not resolve hostname bitbucket.org:username



    看起来别名正在解析,但是有什么东西阻止了 key ?
  • 更改.git/config中ssh键别名的路径。

  • Result: ssh: Could not resolve hostname <alias>:username



    显然,别名根本无法解析。

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

    更新:经过一番思考

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

    如果对子服务器无效,则为每个子服务器设置 key ,然后在服务器上为每个子服务器设置别名,但保持父存储库 key 与以前相同。到目前为止,我一直在寻找在.gitmodules.git/config中引用这些别名键的方法。但这根本行不通,可以识别父键,但不能识别子模块键的别名。

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

    现在,当我在大量输出之后使用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.
    在这一点上我看不到森林,别在乎树木。有什么想法吗?

    最佳答案

    如何在仓库中使用公共(public)和私有(private)子模块

    我需要为使用私有(private)子模块存储库的wordpress创建部署策略。互连网上已经有一些good source了,但是它们没有直接解决私有(private)子模块。因此,我正在记录为使Bitbucket正常工作而采取的步骤。尽管我仅在Bitbucket上进行了测试,但其中一些可能也适用于其他服务。如果您使用的是Github,则可能对n this answer too感兴趣。

    只是作为序言,我是在我的登台服务器上使用git stuck1.7.1,据我所知,它是2011年初发布的,现在才几年。也许这会使我的情况复杂化,但是如果您看到我使用command x而不是command Y,这可能就是原因。我试图指出我所理解的是更现代的方法,并且当然会使用任何反馈进行更新。我还尝试过在路标上标出危险,但我认为问题或解决方案并非我的特定主持人所独有。

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

    对于那些已经知道的人

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

    基础工作:设置SSH key

    首先,您将需要能够使用终端将ssh插入服务器,一旦到达该位置,您将需要为要 pull 出的模块建立一个(或多个) key 。 Bitbucket允许您在存储库之间共享ssh key ,因此您的用例可能需要一个以上的 key 。但是,为简单起见,我将举例说明“一键统治所有人”的方法。

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

    另外,由于此过程将仅使用部署 key ,因此我们只能 pull 出。如果您拥有父存储库,则可以将其推回上游,但需要该存储库的单独别名。但是,我的用例是用于测试网站的登台服务器,因此对我而言,pull仅够用。

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

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

    注意:我发现从~/.ssh目录中运行keygen以后会导致权限问题。这可能对我的服务器来说是唯一的,但是为了安全起见,只需从主目录之类的地方开始该过程即可。

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

    说明在这里:https://confluence.atlassian.com/display/BITBUCKET/Use+deployment+keys

    创建SSH别名

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

    您可能已经猜到了,我们将对所有私有(private) repo 连接使用ssh,而不是https。

    普通的git ssh路径应如下所示:ssh://git@bitbucket.org:<USER-NAME>/repo-name,尽管Bitbucket will accept the path with or withoutssh://
    SSH别名相对简单,在~/.ssh/config/中指定。

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

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

    这是我们所需要的肉,或者至少是其中的主要一块。

    只是一个失败:
  • Host是ssh将在发送到它的路径中寻找的别名关键字。可以是任何东西,但是我经常将其命名为所生成的 key 。
  • HostName是别名指向的域,在本例中为bitbucket.org。
  • IdentityFile指向 key 的私有(private)部分(请注意,没有.pub),通过这两个部分,ssh可以验证 session 。
  • User指定ssh用户http://unixhelp.ed.ac.uk/CGI/man-cgi?ssh+1请参见环境
  • User?现在,这与您将要找到的其他一些说明有所不同。事实证明,使用ssh,Git将其自身指定为user,并将托管 repo 协议(protocol)的git帐户(即您的Bitbucket用户名)放在分号后。这一行花了我几天head scratching的时间,直到我重新阅读Jochen Kupperschmidt的这篇文章并最终了解他的理解。这是我发现的唯一一篇文章,在此上下文中专门引用了User参数,因此对Jochen进行了技巧性的介绍。

    测试别名

    值得检查您的别名是否正在连接,以及 key 是否已分配给期望的所有存储库。为了检查,请运行以下命令:
    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的专家,所以关于如何最好地完成下一部分,可能会有不同的看法。我的用例是将存储库放入目录中,目录中包含将不被跟踪的预先存在的内容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
    

    请注意,我们在这里使用别名,因为我的父存储库也是私有(private)的,并且我还具有与其关联的部署 key 。

    在这里,您可以设置另一个别名来指向您的主帐户 key 。尽管我尚未对此进行测试,但这应该可以将流推向除子模块以外的所有内容,即使它们与您的配置文件的ssh主 key 位于同一帐户下也是如此。

    因此,如果到此为止,我们的别名和 key 可以使用,并且父存储库也已建立。在这一点上,您可能会想插入类似以下内容的子模块:
    # 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)存储库,该过程就会停止,您可能会看到。

    如果子模块中有子模块,则存在无限循环克隆的风险。 This two step method of updating should prevent this
    ssh: Could not resolve hostname bitbucket.org:<USER-NAME>
    

    ??!

    另外,系统可能会提示您输入密码,在这种情况下,您的子模块为https格式,需要将其转换为ssh路径。

    设置.bitbucket/config:

    初次 checkout 父仓库时,如果git发现有子模块,那么如果 stash 文件和目录可以跟踪它们(如果用ls -a来显示它们),它将产生一个数字。我们需要做的是编辑(使用vim,nano等).git/config文件,并使用别名将此处列出的路径修改为之前创建的开发 key 。

    配置文件如下所示:
    [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]开始,remote add origin下的url已经被别名。稍后,对于akismet插件,我们在github上看到其公共(public)仓库通过https连接,最后在Bitbucket上有一个私有(private)仓库。在这里,您将更改所有引用,例如:
    ssh://git@bitbucket.org:<USER-NAME>/your-famous-plugin.git
    至:your_bitbucket_submod:<USER-NAME>/your-famous-plugin.git
    完成此操作后,我们可以重新更新子模块:
    git submodule update --init --recursive
    git submodule foreach git pull origin master 
    

    看着他们滚来滚去。 。 。

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

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

    进一步阅读:
  • https://chrisjean.com/git-submodules-adding-using-removing-and-updating/
  • https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407
  • 关于git bitbucket私有(private)子模块ssh别名问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29331153/

    相关文章:

    推送 : object 15abe3addde5ad5f7d25e8f0f220d2e9faf3cb22:contains entries pointing to null 时出现 Git 错误

    bash - 在容器内运行 shell 脚本

    json - 仅获取 json 中每个提交的内容? (git 差异 json)

    node.js - 如何在每次 pm2-restart 之前运行 "npm install"?

    Git:将 repo 创建为子模块

    git - 高度耦合的 git 子模块

    ssh-keys - 自动化 ssh-keygen -t rsa 因此它不会要求输入密码

    jenkins - 无法通过 ssh 连接到主机 : Host key verification failed

    git 推送被拒绝

    git - 更改所有提交的 git 作者信息对我的一个存储库有效,但对其他存储库无效,为什么?