【问题标题】:Pushing only some local commits after merge合并后仅推送一些本地提交
【发布时间】:2013-09-16 22:46:02
【问题描述】:

this question 上的答案显示了如何选择性地推送本地提交,但似乎这些都是提示的本地提交。

如果我已经合并了来自源的新更改,使得它们与我的提交穿插在一起,(最后一次提交是“合并”消息,)我能做些什么来只推送其中一些提交吗?或者我是否需要在合并和重置/存储我想遗漏的提交之前进行分支?

【问题讨论】:

    标签: git git-merge git-push


    【解决方案1】:

    您需要创建一个引用相关提交的 refspec,并推送该 refspec。

    这背后的原因有点混乱。在push(或任何其他对象传输序列)中传输的实际对象集不一定限于您的想法。有时推送会推送“未使用”的 repo 对象,因为客户端(进行推送)和服务器(接收对象包)之间的同步是松散指定的。它保证所有 必需的 对象都会到达那里,但可能会推送一些不是必需的。实际上,要弄清楚“什么是必要的”可能需要更多的沟通,而不仅仅是推送所有内容,尤其是在发送/接收序列中进行所有压缩的情况下。

    因此,“推送”内部发生的情况是客户端发送一个装满对象的大球(特别是“瘦包”),然后——在这些对象被安全地安置在服务器的存储库中之后——发送在一组“参考标签”上:

    refs/heads/zorg = object 00ac1d1f1ab1ec0ffee5c01ec0idf1dd1edeedee
    refs/tags/skin = object 5011d1f1ab1ebac1110515be11e5be111c05ed0e
    

    等等。服务器通过 git pre-receive 和 update 挂钩运行这些 ref-updates 以验证它们是否正常,如果是,则将它们存储在服务器的 refs 中。 (如果需要,钩子可以检查这些对象。这让钩子可以检查标签是否“轻量级”,直接引用提交,或“注释”,引用 repo 中的标签对象,例如。)


    我将在这里补充一点,我认为您的问题暗示了对分支实际工作方式的误解。分支是一种“隐含的”数据结构。 Git 有两个基本概念协调创建一个“分支”:它有分支提示标签,它命名一个单一的提交;它有提交,每个提交都带有零个或多个“父提交”ID。例如,使 master 成为分支的是分支提示名称 (refs/heads/master)。但这只会让你获得一次提交,即分支的尖端。要查找分支“上”的内容,您可以从那里开始查看该提交的父级或父级。在那一刻,每个父提交也“在”master 分支上,并且每个父级的父级都在它上面,依此类推。如果你有:

    M1 -- M2 -- M3 -- M4      <-- master
      \
       B1 -- B2 -- B3         <-- branchB
         \        /
          D1 -- D2            <-- develB
    

    然后提交B3 是“on”branchB 因为它是branchB 的尖端,并且D2B2 也都“on”分支因为B3 具有这两个提交作为它的父母。

    如果您毕竟不想在branchB 上添加D2,但您确实想要在它上面添加D1,您必须做出一个新的(并且完全不同的)提交——让我们打电话它B4——它的父母有B2D1

    M1 -- M2 -- M3 -- M4      <-- master
      \
       |        ------B4      <-- branchB
       |       /       |
       B1 -- B2 -- B3  |      <-- branchB-old [or abandoned entirely]
         \        /    |
          D1 -- D2     |      <-- develB
            \          /
             ----------
    

    同样branchB 只是简单地命名了一个分支提交,但这与B3 不同。

    push上面(B4的烂摊子)实际上可能会push commit B3到服务器,但只要没有标签,就不会有人看到,最终会被垃圾回收关闭服务器。

    【讨论】:

    • 哇,这比我想象的要复杂得多。您介意写出执行此操作的示例命令吗?
    • 弄清楚要运行什么的方法是首先绘制您现在拥有的提交图(使用gitk --allgit log --graph --oneline --decorate --all 或类似的东西来查看您拥有什么),然后找出提交你想要的图表——白板或笔(cil)/纸在这里非常方便——然后才开始考虑运行git ...。这不是微不足道的,因为您正在接受“真正发生的”(实际历史)并想出一个更漂亮的“假装发生了”(新的“历史”)。
    猜你喜欢
    • 2010-10-10
    • 2018-12-17
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 2015-08-12
    相关资源
    最近更新 更多