假设我是一个回购的维护者,我想从一个贡献者的变化来拉,有几个可能的工作流程:
- 我
cherry-pick
每个从远程提交(按顺序)。 在这种情况下的git记录提交的无关的远程分支。 - 我
merge
的分支,拉动所有的变化,并增加了新的“冲突”提交(如果需要)。 - 我
merge
每个从远程分支机构提交单独(再次按顺序),从而可以记录冲突的每一次提交,而不是全部组合在一起作为一个。 - 为了完整起见,你可以做一个
rebase
(同cherry-pick
的选择吗?),但我的理解是,这可能会导致贡献者混乱。 也许这消除了选项1。
在这两种情况下,2和3,git的记录提交的分支历史,不同于1。
什么是亲的和反对的两种使用之间cherry-pick
或merge
方法描述? 我的理解是,方法2是常态,但我觉得解决与一个单一的“冲突”大型提交合并,是不干净的解决方案。
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 to rebase
code that you have shared with other repositories. Once a commit is push
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.
在我看来挑肥拣瘦应该在那里需要极少的情况下,例如保留,如果你做了一些对“主人”分支(主干,开发分支)直接固定,然后意识到,这应该也适用于“MAINT ”。 你应该立足无论是在合并工作流程,或在底垫(或“混帐拉--rebase”)。
请记住,樱桃挑选的或重订提交是从视图GIT中的(具有不同的SHA-1的标识符)比原来的点不同 ,所以它比在远程仓库提交不同。 (再次基于通常可以解决这个问题,因为它会检查补丁ID即变化,而不是提交ID)。
此外,在GIT中你可以一次合并许多分支:所谓的章鱼合并 。 需要注意的是章鱼合并有没有冲突才能成功。 尽管如此,它可能是有用的。
HTH。
调整基线和摘樱桃是你能保持清洁提交历史的唯一途径。 避免使用合并和避免造成合并冲突。 如果您正在使用格里特组一个项目合并,如果有必要,一个项目摘樱桃模式,并尝试自己。