Git Cherry-pick vs合并工作流程 [英] Git Cherry-pick vs Merge Workflow
问题描述
- 我
cherry-pick
每次从远程提交(按顺序)。在这种情况下,git将提交记录为与远程分支无关。 - I
合并
分支,引入所有更改并添加一个新的冲突提交(如果需要)。 - I
merge
每个远程分支单独提交(按顺序)允许为每次提交记录冲突,而不是将所有内容合并为一个。 - 为了保持完整性,您可以做一个
rebase
(与> cherry-pick
选项?),但我的理解是,这可能会导致贡献者混淆。也许这就消除了选项1.
在这两种情况下,git都会记录提交的分支历史记录,而不是1。 p>
使用 cherry-pick
或 merge
方法描述?我的理解是方法2是常态,但我认为用单个冲突合并解决大型提交并不是最干净的解决方案。
选择
)和 merge
有其优点和缺点。我在这里争论 merge
,但是值得理解。 (在这里寻找一个备用的,有争议的答案枚举的情况下)
合并
cherry-pick
和 rebase
出于以下原因。
- 健壮性。提交的SHA1标识符不仅标识它本身,而且还标识它与之前的所有其他提交有关的。这为您提供了一个保证,即给定SHA1中的存储库的状态在所有克隆中都是相同的。 (理论上)有人没有机会做出看起来像是一样的变化,但实际上是腐蚀或劫持你的存储库。你可以挑选个人变化,他们可能是相同的,但你没有保证。 (作为次要的次要问题,如果其他人再次选择同样的提交,那么新的挑选承诺将占用额外的空间,因为即使您的工作副本最终完全相同,它们也会出现在历史记录中。)
- 易用性。人们很容易理解
merge
工作流程。rebase
往往被认为更加先进。最好是了解这两者,但不想成为版本控制专家的人(根据我的经验,包括许多擅长自己的工作但不想花费额外时间的同事)更容易
即使合并工作流程 rebase
和 cherry-pick
对于特殊情况仍然有用:
-
merge
是杂乱的历史。rebase
可以防止在您的历史中散布大量的提交,就像您定期合并其他人的更改一样。事实上,这是我使用它的主要目的。你想成为 ,永远不会与你与其他仓库共享的rebase
代码。一旦提交是push ,其他人可能已经提交了它,而重新绑定最多会导致上面讨论的那种重复。在最糟糕的情况下,您最终会遇到一个非常混乱的存储库和细微的错误,它需要很长时间才能发现。
-
cherry-pick
对从你基本上决定放弃的主题分支中抽出一小部分变化很有用,但是意识到有几个有用的部分。
至于宁愿合并许多变化:它只是简单得多。一旦开始拥有大量变更集合,就会变得非常繁琐。 git(以及Mercurial和Bazaar中)的合并解决方案非常好。大部分时间你都不会遇到长期分支融合的重大问题。我通常一次合并所有内容,只有如果我会收到大量冲突,我才能备份并重新运行合并零碎。即使那样,我也是以大块的方式做到这一点。作为一个非常实际的例子,我有一位同事对合并进行了3个月的修改,并且在250000行代码库中遇到了9000次冲突。我们所要解决的问题是,一次合并一个月的价值:冲突不会线性增加,而且冲突会导致 <9000的冲突。它仍然是很多工作,但不是一次尝试做一次提交。
Assuming I am the maintainer of a repo, and I want to pull in changes from a contributor, there are a few possible workflows:
- I
cherry-pick
each commit from the remote (in order). In this case git records the commit as unrelated to the remote branch. - I
merge
the branch, pulling in all changes, and adding a new "conflict" commit (if needed). - 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. - For completeness, you could do a
rebase
(same ascherry-pick
option?), however my understanding is that this can cause confusion for the contributor. Maybe that eliminates option 1.
In both cases 2 and 3, git records the branch history of the commits, unlike 1.
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.
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
is preferred over cherry-pick
and rebase
for a couple of reasons.
- 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.)
- 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.
Even with a merge-heavy workflow rebase
and cherry-pick
are still useful for particular cases:
- 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 torebase
code that you have shared with other repositories. Once a commit ispush
ed 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. 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.
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 vs合并工作流程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!