views:

66

answers:

1

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, thinking I'm on A, commiting a change for feature A)

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

+4  A: 

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)
VonC
@VonC, +1 for clear play-by-play. On the git rebase --onto... command, did you mean first_SHA-1-of-commits-for-rightBranch~1 ?
Wayne Conrad
@Wayne: doh! right, the range of commit replayed for a `rebase --onto` begin *after* the specified commit. Yet another off-by-one error.
VonC