开发者

How to undo a commit and commit the changes into the other branch in Git?

The common mistake I make in git is

  1. not check on which branch I am
  2. commit changes to a wrong branch (on branch B, th开发者_如何转开发inking I'm on A, commiting a change for feature A)

How do I get back, and commit the edits to the proper branch?


rebase --onto can help here, especially if you have a range of commits to move back.

Do not forget a git stash to save any current uncommitted changes which are relevant to "wrongBranch" (the one where commits were appropriately applied), in order to pop them back at the end of the process.

Basically, you need to apply a commit or range of commits to another branch (called here "rightBranch"):

# Checkout the right branch where the commit should have been applied
git checkout rightBranch

# Checkout a new temporary branch at the current location
git checkout -b tmp

# Move the rightBranch branch to the head of patchset which should have been on rightBranch
git branch -f rightBranch last_SHA-1_of_commits_for_rightBranch

# Rebase the patchset onto tmp, the old location of rightBranch 
git rebase --onto tmp first_SHA-1_of_commits_for_rightBranch~1 rightBranch 

(first_SHA-1_of_commits_for_rightBranch~1 is the parent commit of first_SHA-1_of_commits_for_rightBranch, that is the commit on top of which all the commits for rightBranch have been incorrectly applied)

rightBranch will be again at the top of:

  • all the old commits of right branch (pointed by the tmp branch)
  • plus all the relevant commits range from wrongBranch, which have just been replayed on top of tmp (tmp being the previous rightBranch HEAD).

Then you can reset wrongBranch to some previous commits.

git checkout wrongBranch
git reset --hard some_older_commit

# if needed, re-apply what you were working on vefore this all proccess
git stash pop

Caveat:

  • cherry-picking or rebase --onto have consequences (see this question)
  • if wrongBranch has already been published (pushed to a public repo), that can be awkward for the people pulling for that repo (having to rebase all their changes on top of that "new" branch)


Simple answer?

git checkout branch_with_wrong_tip
git reset HEAD~1 (or whatever number of commits you want to go back)
git checkout correct_branch
git commit ...etc

Note the important part, which is the soft reset (retaining changes) as opposed to any hard reset, which might let you lose the place of changes.

This will also turn all those commits that you reset back into changes that you'd then have to recommit individually or as a group. E.g. if you git reset HEAD~10, you're going to have to make commits to all those files that were committed in the 10 commits, or else lump them into a totally new commit. That's just if you use this approach, of course.


Checkout the wrong branch where the commit is

git checkout wrong_branch

In the wrong branch, reset to the previous commit:

git reset --hard HEAD^

NOTE: the ^ operator indicating the previous commit, to remove multiple commits use ~N where N is the number of commits

Checkout to the branch where the commit should be

git checkout right_branch

Re-apply the commit using cherry-pick

git cherry-pick wrong_branch@{1}

NOTE: wrong_branch@{1} is the last commit of wrong_branch before the git reset command was executed, for example, HEAD@{2} could be used too in this case

To move multiple commits you could use multiple calls to git cherry-pick or only one execution of git rebase:

git rebase --onto right_branch wrong_branch@{1}~N wrong_branch@{1}

(and the corresponding parameter to reset will be HEAD~N in this case)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜