【问题标题】:how do I pull to a bare repository?如何拉到裸存储库?
【发布时间】:2011-11-08 15:16:03
【问题描述】:

我有一个“主”裸存储库和一个“个人”裸存储库。我想将更改从“主要”更新为“个人”,所以我运行:

$ git pull
fatal: /home/gimenero/applib/git/libexec/git-core/git-pull cannot be used without a working tree.

如何拉动推送到“main”的更改?

【问题讨论】:

    标签: git


    【解决方案1】:

    git pull 执行 fetch 后跟 merge,如果没有工作树,您将无法合并。 (如果出现合并冲突,将无处可解决。)

    相反,您可以直接获取。假设您的主存储库在您的个人存储库中配置为远程调用源:

    $ git fetch origin master:master
    

    请注意,只有当您的个人存储库的主分支镜像主存储库的主分支时,这才会成功。否则,Git 将拒绝非快进获取。

    【讨论】:

    • 我认为你的意思是 git fetch origin master:master
    • 是的,我认为 fetch 做到了,但是当我写:“git fetch”时,它说:“From /home/rater/gitRepo/src * branch HEAD -> FETCH_HEAD”。 'HEAD->FETCH_HEAD' 让我很困惑。这是什么意思? (看起来好像它被提取到一个 FETCH_HEAD 以供以后合并,就像在一个非裸仓库中一样)。
    • 当我写:“git fetch origin master:master”时它什么也没说。
    • 我不明白。如果我获取本地主分支指针,则不会指向远程主指针的相同提交。它怎么能快进,这不是假设只发生在拉动期间吗?
    • 我认为git fetch --all 会起作用,但它没有给出预期的结果(即,如果你在裸“个人”存储库中执行git fetch --all,那么 cd 进入非裸“个人”存储库并执行git pull 没有从主仓库中提取任何更改)
    【解决方案2】:

    更新:

    $ git fetch origin +refs/heads/*:refs/heads/* --prune
    

    这是做什么的?

    先说一句:当我们谈到一个名为“xyz”的分支时,git 实际上将其称为refs/heads/xyz。但是你可以输入“xyz”的缩写,否则会很疯狂。 (顺便提一下,标签是refs/tags/xyz。)普通的xyz 是模棱两可的,因为它可能是一个分支、一个标签或一个提交哈希的前N 个字母。而refs/heads/xyz 则明确表示一个分支。

    因此,即使您可以键入 git fetch origin foo:bar 来获取存储库中名为 barfoo 分支,您也可以更明确地键入 git fetch origin refs/heads/foo:refs/heads/bar 来执行相同的操作。 (虽然如果foo 实际上是一个标签而不是一个分支,后者将失败,因为它们的refs/heads/foo 不存在。明确性ftw。)

    git fetch origin refs/heads/*:refs/heads/* 表示他们所有的分支都属于我们。该命令的运行就像* 部分被替换为其每个分支的分支名称一样。即git fetch origin refs/heads/abc:refs/heads/abc refs/heads/def:refs/heads/def ...(假设他们有名为abcdef的分支)。

    --prune 选项意味着我们存储库中与refs/heads/* 匹配但在其存储库中不存在的任何分支都将被删除

    最后,+ 前缀是允许非快进提取。没有它,任何需要 force-updates 的分支更新都会被拒绝。

    总而言之,最终结果是您的存储库中的分支最终看起来与他们的完全相同。

    这是一个示例输出:

     - [deleted]               (none)     -> bar
     * [new branch]            foo        -> foo
       4812558a5f..a6aeec6517  abc        -> abc
     + a1b2c3d4e5...1a2b3c4d5e def        -> def  (forced update)
    
    • 这个例子告诉我们他们有分支fooabcdef,而我们有(有)一个额外的:bar
    • 注意bar--prune 删除,def+ 前缀允许强制更新。

    如果不使用 +--prune,会发生以下情况:

     * [new branch]            foo        -> foo
       4812558a5f..a6aeec6517  abc        -> abc
     ! [rejected]              def        -> def  (non-fast-forward)
    

    最后一件事:

    将顶部的命令与以下命令进行比较:

    $ git fetch origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/* [--prune]
    

    这基本上就是我们输入git fetch origin [--prune]时发生的事情!

    【讨论】:

    • 上面的答案可能比另一个更强大和灵活,但它是不可见的。稍微解释一下,这个答案可能会更有趣。我的理解是,这个命令是 git push --mirror 的反面,这是危险的(即使在发生冲突的情况下也会替换,在目标上删除任何不在发件人端的东西)。
    猜你喜欢
    • 1970-01-01
    • 2011-12-15
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2014-08-18
    相关资源
    最近更新 更多