从分支中提取所有提交,将特定提交推送到另一个提交

时间:2009-05-19 04:20:26

标签: git branch

我有以下分支:

  • master
  • production

以及以下远程分支:

  • origin/master
  • origin/production

我有一个脚本可以获取origin/master分支,并获取上次获取(log -p master..origin/master)后所发生变化的差异。然后我合并origin/master

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

我想将成功的提交 - 只有它们 - 推送到生产分支,然后推送到origin/production

我该怎么办?

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

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

2 个答案:

答案 0 :(得分:288)

我认为你正在寻找的术语是“樱花选择”。也就是说,从一个分支的中间进行一次提交并将其添加到另一个分支:

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 - 它认为存储库是一组补丁,因此樱桃挑选成为基本操作。然而,这有一系列问题,例如非常慢:)

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

答案 1 :(得分:1)

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

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

这是什么样的,其中fA是具有特征A的提交,而fB是具有特征B的提交:

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

拉取请求与GitHub的功能相关联,但实际上我的意思是有人有责任将功能分支合并为主。