Git Cherry-pick 与合并工作流 [英] Git Cherry-pick vs Merge Workflow

查看:31
本文介绍了Git Cherry-pick 与合并工作流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我是一个存储库的维护者,并且我想从贡献者那里获取更改,那么有几种可能的工作流程:

Assuming I am the maintainer of a repo, and I want to pull in changes from a contributor, there are a few possible workflows:

  1. cherry-pick 每次从远程提交(按顺序).在这种情况下,git 将提交记录为与远程分支无关.
  2. 合并分支,拉入所有更改,并添加新的冲突"提交(如果需要).
  3. merge 分别来自远程分支的每个提交(再次按顺序),允许为每个提交记录冲突,而不是将所有提交组合为一个.
  4. 为了完整起见,您可以执行一个 rebase(与 cherry-pick 选项相同?),但我的理解是这可能会给贡献者造成混淆.也许这消除了选项 1.
  1. I cherry-pick each commit from the remote (in order). In this case git records the commit as unrelated to the remote branch.
  2. I merge the branch, pulling in all changes, and adding a new "conflict" commit (if needed).
  3. I merge each commit from the remote branch individually (again in order), allowing conflicts to be recorded for each commit, instead of grouped all together as one.
  4. For completeness, you could do a rebase (same as cherry-pick option?), however my understanding is that this can cause confusion for the contributor. Maybe that eliminates option 1.

在案例 2 和案例 3 中,git 记录了提交的分支历史,与案例 1 不同.

In both cases 2 and 3, git records the branch history of the commits, unlike 1.

使用描述的 cherry-pickmerge 方法之间的优缺点是什么? 我的理解是方法 2 是常态,但我觉得用单个冲突"合并解决大型提交并不是最干净的解决方案.

What are the pro's and con's between using either cherry-pick or merge methods described? My understanding is that method 2 is the norm, but I feel that resolving a large commit with a single "conflict" merge, is not the cleanest solution.

推荐答案

rebase(和 cherry-pick)和 merge 都有它们的的优点和缺点.我在这里主张 merge,但两者都值得理解.(在这里寻找一个替代的、有充分论证的 answer 列举的案例,其中rebase 是首选.)

Both rebase (and cherry-pick) and merge have their advantages and disadvantages. I argue for merge here, but it's worth understanding both. (Look here for an alternate, well-argued answer enumerating cases where rebase is preferred.)

merge 优于 cherry-pickrebase 有几个原因.

merge is preferred over cherry-pick and rebase for a couple of reasons.

  1. 稳健性.提交的 SHA1 标识符不仅可以识别它本身,还可以之前的所有其他提交相关联.这为您提供了一个保证,即给定 SHA1 的存储库状态在所有克隆中都是相同的.(理论上)不可能有人做了看似相同的更改,但实际上正在破坏或劫持您的存储库.您可以挑选个别更改,它们可能相同,但您不能保证.(作为一个次要的次要问题,如果其他人再次在同一个提交中挑选,新的挑选提交将占用额外的空间,因为即使您的工作副本最终相同,它们也会出现在历史记录中.)
  2. 易于使用.人们往往很容易理解merge 工作流程.rebase 往往被认为更高级.最好同时了解两者,但不想成为版本控制专家的人(根据我的经验,其中包括许多非常擅长他们所做的工作,但不想花额外时间的同事)有一个更容易时间刚刚融合.
  1. Robustness. The SHA1 identifier of a commit identifies it not just in and of itself but also in relation to all other commits that precede it. This offers you a guarantee that the state of the repository at a given SHA1 is identical across all clones. There is (in theory) no chance that someone has done what looks like the same change but is actually corrupting or hijacking your repository. You can cherry-pick in individual changes and they are likely the same, but you have no guarantee. (As a minor secondary issue the new cherry-picked commits will take up extra space if someone else cherry-picks in the same commit again, as they will both be present in the history even if your working copies end up being identical.)
  2. Ease of use. People tend to understand the merge workflow fairly easily. rebase tends to be considered more advanced. It's best to understand both, but people who do not want to be experts in version control (which in my experience has included many colleagues who are damn good at what they do, but don't want to spend the extra time) have an easier time just merging.

即使是合并繁重的工作流程,rebasecherry-pick 在特定情况下仍然很有用:

Even with a merge-heavy workflow rebase and cherry-pick are still useful for particular cases:

  1. merge 的一个缺点是历史混乱.rebase 防止一长串提交分散在您的历史记录中,就像您定期合并其他人的更改一样.这实际上是我使用它的主要目的.您要非常注意的是,永远不要rebase 与其他存储库共享的代码.一旦提交被push,其他人可能已经在它之上提交了,而rebase充其量只会导致上面讨论的那种重复.最坏的情况是,您最终会得到一个非常混乱的存储库和细微的错误,您需要很长时间才能发现.
  2. cherry-pick 可用于从您基本上决定放弃的主题分支中抽取一小部分更改,但意识到有几个有用的部分.
  1. One downside to merge is cluttered history. rebase prevents a long series of commits from being scattered about in your history, as they would be if you periodically merged in others' changes. That is in fact its main purpose as I use it. What you want to be very careful of, is never to rebase code that you have shared with other repositories. Once a commit is pushed someone else might have committed on top of it, and rebasing will at best cause the kind of duplication discussed above. At worst you can end up with a very confused repository and subtle errors it will take you a long time to ferret out.
  2. cherry-pick is useful for sampling out a small subset of changes from a topic branch you've basically decided to discard, but realized there are a couple of useful pieces on.

至于更喜欢合并多个更改而不是一个:这要简单得多.一旦您开始拥有大量变更集,合并单个变更集会变得非常乏味.git(以及 Mercurial 和 Bazaar)中的合并解析非常好.大多数情况下,即使合并很长的分支,您也不会遇到重大问题.我通常一次合并所有内容,只有如果出现大量冲突,我才会备份并逐步重新运行合并.即便如此,我还是大块地做.作为一个非常真实的例子,我有一个同事,他有 3 个月的时间进行合并,在 250000 行代码库中遇到了大约 9000 个冲突.我们所做的修复是一次进行一个月的合并:冲突不会线性增加,并且分段进行会导致少于 9000 个冲突.这仍然是很多工作,但没有尝试一次提交一次.

As for preferring merging many changes over one: it's just a lot simpler. It can get very tedious to do merges of individual changesets once you start having a lot of them. The merge resolution in git (and in Mercurial, and in Bazaar) is very very good. You won't run into major problems merging even long branches most of the time. I generally merge everything all at once and only if I get a large number of conflicts do I back up and re-run the merge piecemeal. Even then I do it in large chunks. As a very real example I had a colleague who had 3 months worth of changes to merge, and got some 9000 conflicts in 250000 line code-base. What we did to fix is do the merge one month's worth at a time: conflicts do not build up linearly, and doing it in pieces results in far fewer than 9000 conflicts. It was still a lot of work, but not as much as trying to do it one commit at a time.

这篇关于Git Cherry-pick 与合并工作流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆