如何合并一个只导致单个提交的git分支(比如使用--squash),但允许将来的合并没有冲突?

时间:2015-05-24 18:27:13

标签: git git-merge git-commit git-merge-conflict

自创建它以来,我有一个包含许多提交的分支,并且希望进行单个合并提交以将其移回master,只需一次提交即可。因此,我知道的唯一解决方案是使用git merge --squash branchname。这很好用,但如果有人向branchname添加更多提交并再次将其合并到master中,我会从branchname上的初始新提交中获得冲突。如何防止合并冲突,同时仍然只在master中为每次合并保留一次提交?我已尝试使用git merge --no-ff,但仍然将所有提交从branchname移至master

1 个答案:

答案 0 :(得分:0)

echo $(git rev-parse $result $result^ $merged) > .git/info/grafts
git merge topic

where $result is the commit produced by the squash merge and $merged is the commit you merged from (i.e. given git checkout master; git merge topic, $result is master after the merge, and $merged is topic after the merge).

The info/grafts file contains temporary, repo-local ancestry overrides. The echo above records, only in this repo, that the result of the squash merge also has the squash-merged commit as its parent -- i.e. it records an accurate merge history. Unrecorded merges only work so long as subsequent merges of the two branches still see the merged changes the same way.

Don't forget that rebase and filter-branch will also see the grafted ancestry, and if they rewrite the $result commit they'll record that ancestry in the new commit.


It's certainly common to merge feature branches, it's just not common to do it without recording it, because that makes it impossible for git (or any vcs) to always find the correct merge base. Many unrecorded-merges leave no correct merge base at all in the history, you have to make one to get a good merge later. Cherry-picks and squash merges are great so long as the technical debt is paid by a recorded merge before further modifications obscure the matching change hunks.

If the history you're merging is ugly, you're going to love interactive rebase. It lets you create the commit history you would have made if you'd had the foresight to do it that way in the first place. Cleaning up changes for publication is a fundamental part of the workflow in many, many projects.