从一个分支拉取所有提交,将指定的提交推送到另一个
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 中。
【讨论】:
以上是关于从一个分支拉取所有提交,将指定的提交推送到另一个的主要内容,如果未能解决你的问题,请参考以下文章