문제

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. In other words, I need git to ask me to choose the merge for all the files which differs in B and I commits. What's the best approach to do such thing? Can I achieve this with cherry pick? How?

도움이 되었습니까?

해결책 2

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:

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

Then, added all the changed files and commited.

다른 팁

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

You could revert the offending merge commit with git revert -m 1 <commit> then simply use git merge <B_branch> again. This would add a revert commit to your history. Otherwise you could use git rebase -i to erase B's commits from history. The latter is more destructive for collaborative work, because all WIP and all collaborators would now have to reset their master branches.

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.

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

git merge temp
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top