简体   繁体   English

在主服务器上将旧的git提交与HEAD合并

[英]Merge old git commit with HEAD at master

I made some mistakes when merging commits of my colleagues. 在合并我的同事的提交时我犯了一些错误。 Now, we have discovered it and we need to apply old commit again, to choose manually the changes in the files. 现在,我们已经发现了它,我们需要再次应用旧提交,手动选择文件中的更改。 The situation looks like this: 情况如下:

A--\       /--F--\
    C--D--E       H--I
B--/^      \--G--/   ^
    |                |
WRONG MERGE       MASTER

I need git to ask me again to merge B with I, like B had never been in the history. 我需要git再次要求我将B与我合并,就像B从未在历史上那样。 In other words, I need git to ask me to choose the merge for all the files which differs in B and I commits. 换句话说,我需要git让我为B和I提交的所有文件选择合并。 What's the best approach to do such thing? 做这种事的最佳方法是什么? Can I achieve this with cherry pick? 我可以用樱桃酱来实现吗? How? 怎么样?

You could use commit duplication trick: 你可以使用提交重复技巧:

# make a branch named B started on the commit B
git checkout -b B <sha1 id of the commit B> 
# it creates a branch which starts at a commit
# right before B and has exact copy of commit as B,
# but with a different sha1 id.
git rebase --no-ff HEAD~1

# now we do simple merge
git checkout master
git merge B

It also allows to make the trick with range of commits and preserves dates, authors, commit messages and so on. 它还允许通过提交范围制作技巧并保留日期,作者,提交消息等。

In fact your scenario is described in documentation : 实际上,您的方案在文档中描述:

--no-ff ... recreates the topic branch with fresh commits so it can be remerged successfully --no-ff ...使用新提交重新创建主题分支,以便可以成功重新合并

Well, I have finally solved this way. 好吧,我终于解决了这个问题。 I created diff from B (against master, I in my example) and manually applied all changes in meld difftool: 我在B创建了diff(在我的例子中反对master, I手动应用了meld difftool中的所有更改):

[master]$ yes | git difftool <B hash> -t meld

Then, added all the changed files and commited. 然后,添加所有已更改的文件并提交。

You could revert the offending merge commit with git revert -m 1 <commit> then simply use git merge <B_branch> again. 您可以使用git revert -m 1 <commit>恢复违规的合并提交,然后再次使用git merge <B_branch> This would add a revert commit to your history. 这会为您的历史记录添加还原提交。 Otherwise you could use git rebase -i to erase B's commits from history. 否则你可以使用git rebase -i从历史记录中删除B的提交。 The latter is more destructive for collaborative work, because all WIP and all collaborators would now have to reset their master branches. 后者对于协作工作更具破坏性,因为所有WIP和所有协作者现在都必须重置其master分支。

If you don't mind the revert commit, I'd strongly recommend it. 如果你不介意还原提交,我强烈推荐它。 It's the easiest way to get what you want. 这是获得你想要的最简单的方法。 If D, E, F, G, H, or I are based on B's change sets though, the revert could get complex. 如果D,E,F,G,H或I基于B的变化集,则恢复可能变得复杂。

Assuming master is checked out 假设主人被检查出来

git branch temp <sha1 of B>

create a reference to the old commit. 创建对旧提交的引用。

git rebase --preserve-merges -i <sha1 of A>

then take out the first line which should be the merge commit. 然后取出应该是合并提交的第一行。

Now all you need to get your B back is to 现在你需要让你的B回来了

git merge temp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM