如何在不破坏未来合并的情况下部分git cherry-pick?

时间:2015-05-12 20:02:56

标签: git

我需要将develop分支的一些错误修正带入master。我希望文件Adevelopmaster中相同。

通常,我会git cherry-pick影响A的提交,但其中一些提交也会影响文件BC,其中Bmaster中存在的文件,但我还不想更改,Cmaster中尚不存在的文件。

在将来某个时间点发布下一个版本时,develop将合并到master。如果我git cherry-pick -n我现在想要的提交,我将不得不取消对B的更改,并在提交之前解决不存在的C的冲突。当从developmaster的真正合并发生时,我会希望对BC进行更改,但我实际上不会得到它们,因为我已经搞砸了cherry-pick期间的那些变化,对吧?

我该怎么做?如果我git checkout <latest_commit_hash> A,这将不会导致将来发生令人讨厌的合并冲突吗?

3 个答案:

答案 0 :(得分:2)

In general avoid $.funcOne = function(x) {document.getElementsByTagName("div").style.backgroundColor = "blue";}; $.funcTwo = function(x) { document.getElementsByTagName("div").style.backgroundColor = "red";}; }); if those branches are merged at any time in the future.

It seems to me that git cherry-pick could actually be helping if the development branch is local and not publicly visible. If other people have seen your changes and those commits have different parents you cannot avoid a merge.

assume you have n commits after mainline in development and you have m1,m2,m3 commits in n that you want to share with mainline.

if you do:

git rebase

you will get an editor window that shows you one commit per line. if you put the commits of m1,m2,m3 to the top of the line and choose git checkout development # go to development branch git rebase -i mainline # reorder all commits in development (instead of edit) pick will reorder your commits as you requested (top commit oldest and the bottom one newest) and it will halt before each commit marked as edit.

you can then do:

git

you can then rebase another time to move the unwanted commits further up in your change history. if you are happy with your log (i.e.: all your commits you need in mainline are on top of changes in mainline and nothing else; hence you can merge doing a fast forward) you pick the furthest commit you want to have from your development branch (by SHA) and merge that.

git add file1
git commit              # commit only file1
git commit -a           # commit the rest
git rebase --continue   # continue rebasing

see also:

答案 1 :(得分:0)

使用git-cherry-pick,没有一种好方法可以避免主题发生的合并冲突,选择的更改与master合并(选择更改的位置)。

我建议您执行cherry-pick操作,然后在本地进行测试合并,并发现在您担心避免冲突之前,Git无法在没有用户干预的情况下管理冲突。

我倾向于模仿部分樱桃选择的一个技巧是:

git cherry-pick <commitish>
git checkout HEAD~ -- <path of unwanted change in file>
git checkout HEAD~ -- <path of unwanted change in file>
git checkout HEAD~ -- <path of unwanted change in file>
git checkout HEAD~ -- <path of unwanted change in file>
git commit -am "squash me"
git rebase -i HEAD~~

挤出樱桃挑选和结帐/一起回复。

答案 2 :(得分:0)

  

如果我git checkout develop - A,那么在未来还会引起一场讨厌的合并冲突吗?

不,不是它自己不会赢。合并的工作原理是将每个提示与合并基础进行比较,然后比较两组更改。如果两个分支都做出相同的更改,那么就没有冲突。

其他更改,在任何一个分支上,或者太接近两个分支上共同更改的行,都可能显示为冲突。阻止这些的方法是通过记录来自公共内容的合并来为git提供准确的合并基础。

# merging master and develop, but there are common changes and 
# also changes that conflict only with those common changes.
# supply git's merge with the common changes as part of the base,
# so it will see that it needs to resolve only those other changes

# check out the current merge base
git checkout $(git merge-base master develop)

# make the changes you're merging
git checkout develop -- file_A
git commit -m "cherrypicking file_A as of develop @ $(git rev-parse develop)"

# (for ensuite)
base=$(git rev-parse HEAD)

# record that both branches have those changes
git checkout develop
git merge -s ours $base -m "recording common content from previous cherry-picks"

git checkout master
git merge -s ours $base -m "recording common content from previous cherry-picks"

# and now this merge will get an accurate base:
git merge develop

现在:这些$base合并的唯一效果是将公共内容记录为两个分支提示的祖先,从而使developmaster的合并成为准确的基础。解决其他变化。

新提交的历史记录与广泛使用的successful git branching model中的实践一致。

如果您的团队如何解释提交,那么将常见内容的来源留在提交消息的文本中是优选的,git也可以解决这个问题。在上面的base作业之后通过结帐和合并永久记录祖先,你也可以

echo $(git rev-parse master  master~)  $base > .git/info/grafts
echo $(git rev-parse develop develop~) $base >>.git/info/grafts
git checkout master
git merge develop

# later, whenever you want -- the ancestry above is strictly repo-local
rm .git/info/grafts

.git/info/grafts中记录的祖先是回复本地的。您的合并命令将看到它,结果将是正确的。唯一的缺点是,由于基数没有被实际记录,其他人在重复它时也会遇到同样的麻烦 - 除非你正在做criss-cross merges或者还要向其他分支机构开玩笑,否则这种情况不太可能发生。