0

这个问题的答案显示了如何选择性地推送本地提交,但似乎这些是提示的本地提交。

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

4

1 回答 1

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

然后 commitB3是“on” branchB,因为它是 , and 的尖端branchB,并且D2B2也是“on”分支,因为B3这两个 commit 都作为其父项。

如果你根本不想要D2branchB但你确实想要D1它,你必须做出一个新的(而且完全不同的)提交——让我们称之为——它B4有它B2D1父母:

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

再次branchB简单地命名一个分支提交,但这个不同于B3.

推送上述内容(带有 的混乱B4)实际上可能会将提交推B3送到服务器,但只要没有标签,就不会有人看到它,并且最终会被服务器垃圾收集。

于 2013-09-17T00:10:28.217 回答