从一个分支拉取所有提交,将指定的提交推送到另一个

Posted

技术标签:

【中文标题】从一个分支拉取所有提交,将指定的提交推送到另一个【英文标题】:Pull all commits from a branch, push specified commits to another 【发布时间】:2010-10-27 05:28:09 【问题描述】:

我有以下分支:

master production

以及以下远程分支:

origin/master origin/production

我有一个脚本,它获取 origin/master 分支并获取与我上次获取 (log -p master..origin/master) 相比变化的差异。然后我合并origin/master

找到的提交被推送到代码审查工具。

我想将成功的提交(并且只有它们)推送到生产分支,然后当然是origin/production

我该怎么做?

另外,我有 2 个脚本正在运行:一个从 origin/master 获取,将提交详细信息推送到数据库并合并,另一个我目前正在编写的脚本必须推送成功的提交。

我希望在避免竞争条件/合并冲突的同时运行这 2 个脚本。由于我只想处理指定的提交,也许有办法摆脱我不想要的提交?

【问题讨论】:

“成功提交”是什么意思? 已审核并标记为成功的那个。在这里并不重要,重要的是我想要保留并推送到另一个分支的提交,以及我想要摆脱/忽略的其他提交。 【参考方案1】:

我认为您正在寻找的术语是“樱桃采摘”。也就是说,从一个分支的中间获取一个提交并将其添加到另一个:

A-----B------C
 \
  \
   D

变成

A-----B------C
 \
  \
   D-----C'

这当然可以使用 git cherry-pick 命令完成。

这个提交的问题是 git 认为提交包含之前的所有历史 - 因此,如果你有三个这样的提交:

A-----B-----C

并尝试摆脱 B,您必须像这样创建一个全新的提交:

A-----------C'

其中 C' 具有不同的 SHA-1 ID。同样,从一个分支选择提交到另一个分支基本上涉及生成一个补丁,然后应用它,因此也会以这种方式丢失历史记录。

这种提交 ID 的更改破坏了 git 的合并功能以及其他功能(尽管如果谨慎使用,会有一些启发式方法可以解决这个问题)。更重要的是,它忽略了函数依赖——如果 C 真的使用了 B 中定义的函数,你永远不会知道。

也许更好的处理方法是拥有更细粒度的分支。也就是说,不仅仅是拥有一个“master”,而是拥有“featureA”、“bugfixB”等。一次对整个分支执行代码审查——每个分支都非常专注于只做一件事——然后合并它完成后一个分支。这是 git 设计的工作流程,也是它擅长的工作:)

如果您坚持在补丁级别处理事情,您可能需要查看 darcs - 它认为存储库是一组补丁,因此樱桃挑选成为基本操作。然而,这有其自身的一系列问题,例如非常慢:)

编辑:另外,我不确定我是否理解您关于两个脚本的第二个问题。也许您可以更详细地描述它,可能作为一个单独的问题来防止事情变得混乱?

【讨论】:

关于我的第二个问题,我只想确保获取更改(第一个脚本)并将给定提交推送到另一个位置(第二个脚本)的过程可以在没有竞争条件/合并冲突的情况下工作,在与不同的分支机构合作时。但最后我想这并不重要,因为我可以将 2 个脚本合并为一个,所以 2 个脚本不能同时工作:) “这种提交 ID 的更改破坏了 git 的合并功能” @bdonlan 请解释合并功能是如何中断的。这是什么意思? @Narek 他可能意味着当您合并第二个分支时,提交 C' 中的更改将与提交 C 中的相同更改发生冲突。这就是在提交 C 后面丢失历史的结果。 “并尝试摆脱 B” - 你为什么要摆脱 B? @user1334007,他的意思是以前是 A-B-C。现在,由于您选择了 C ,您的分支是 A-D-C',不再包含“B”。【参考方案2】:

我意识到这是一个老问题,但在这里引用:How to merge a specific commit in Git

因此,一个更新的答案:使用功能分支和拉取请求。

这是什么样子,其中 fA 是具有功能 A 的提交,而 fB 是具有功能 B 的提交:

            fA   fC (bad commit, don't merge)
           /  \ /
master ----A----B----C
                \  /
                 fB

Pull 请求与 GitHub 的功能相关联,但实际上我的意思是有人负责将功能分支合并到 master 中。

【讨论】:

以上是关于从一个分支拉取所有提交,将指定的提交推送到另一个的主要内容,如果未能解决你的问题,请参考以下文章

git 强制推送到master

git实用的操作命令

将提交的文件拆分并推送到两个不同的分支

将本地提交的更改推送到新分支

我如何将所有提交移至另一个分支?

将提交从一个分支移动到另一个分支