How to fix committing to the wrong Git branch?
GitGit CommitGit Problem Overview
I just made a perfectly good commit to the wrong branch. How do I undo the last commit in my master branch and then take those same changes and get them into my upgrade branch?
Git Solutions
Solution 1 - Git
If you haven't yet pushed your changes, you can also do a soft reset:
git reset --soft HEAD^
This will revert the commit, but put the committed changes back into your index. Assuming the branches are relatively up-to-date with regard to each other, git will let you do a checkout into the other branch, whereupon you can simply commit:
git checkout branch
git commit -c ORIG_HEAD
The -c ORIG_HEAD
part is useful to not type commit message again.
Solution 2 - Git
4 years late on the topic, but this might be helpful to someone.
If you forgot to create a new branch before committing and committed all on master, no matter how many commits you did, the following approach is easier:
git stash # skip if all changes are committed
git branch my_feature
git reset --hard origin/master
git checkout my_feature
git stash pop # skip if all changes were committed
Now you have your master branch equals to origin/master
and all new commits are on my_feature
. Note that my_feature
is a local branch, not a remote one.
Solution 3 - Git
If you have a clean (un-modified) working copy
To rollback one commit (make sure you note the commit's hash for the next step):
git reset --hard HEAD^
To pull that commit into a different branch:
git checkout other-branch
git cherry-pick COMMIT-HASH
If you have modified or untracked changes
Also note that git reset --hard
will kill any untracked and modified changes you might have, so if you have those you might prefer:
git reset HEAD^
git checkout .
Solution 4 - Git
If you already pushed your changes, you will need to force your next push after resetting the HEAD.
git reset --hard HEAD^
git merge COMMIT_SHA1
git push --force
Warning: a hard reset will undo any uncommitted modifications in your working copy, while a force push will completely overwrite the state of the remote branch with the current state of the local branch.
Just in case, on Windows (using the Windows command line, not Bash) it's actually four ^^^^
instead of one, so it's
git reset --hard HEAD^^^^
Solution 5 - Git
I recently did the same thing, where I accidentally committed a change to master, when I should have committed to other-branch. But I didn't push anything.
If you just committed to the wrong branch, and have not changed anything since, and have not pushed to the repo, then you can do the following:
// rewind master to point to the commit just before your most recent commit.
// this takes all changes in your most recent commit, and turns them into unstaged changes.
git reset HEAD~1
// temporarily save your unstaged changes as a commit that's not attached to any branch using git stash
// all temporary commits created with git stash are put into a stack of temporary commits.
git stash
// create other-branch (if the other branch doesn't already exist)
git branch other-branch
// checkout the other branch you should have committed to.
git checkout other-branch
// take the temporary commit you created, and apply all of those changes to the new branch.
//This also deletes the temporary commit from the stack of temp commits.
git stash pop
// add the changes you want with git add...
// re-commit your changes onto other-branch
git commit -m "some message..."
NOTE: in the above example, I was rewinding 1 commit with git reset HEAD1. But if you wanted to rewind n commits, then you can do git reset HEADn.
Also, if you ended up committing to the wrong branch, and also ended up write some more code before realizing that you committed to the wrong branch, then you could use git stash to save your in-progress work:
// save the not-ready-to-commit work you're in the middle of
git stash
// rewind n commits
git reset HEAD~n
// stash the committed changes as a single temp commit onto the stack.
git stash
// create other-branch (if it doesn't already exist)
git branch other-branch
// checkout the other branch you should have committed to.
git checkout other-branch
// apply all the committed changes to the new branch
git stash pop
// add the changes you want with git add...
// re-commit your changes onto the new branch as a single commit.
git commit -m "some message..."
// pop the changes you were in the middle of and continue coding
git stash pop
NOTE: I used this website as a reference https://www.clearvision-cm.com/blog/what-to-do-when-you-commit-to-the-wrong-git-branch/
Solution 6 - Git
For multiple commits on the wrong branch
If, for you, it is just about 1 commit, then there are plenty of other easier resetting solutions available. For me, I had about 10 commits that I'd accidentally created on master
branch instead of, let's call it target
, and I did not want to lose the commit history.
What you could do, and what saved me was using this answer as a reference, using a 4 step process, which is -
- Create a new temporary branch
temp
frommaster
- Merge
temp
into the branch originally intended for commits, i.e.target
- Undo commits on
master
- Delete the temporary branch
temp
.
Here are the above steps in details -
-
Create a new branch from the
master
(where I had accidentally committed a lot of changes)git checkout -b temp
Note:
-b
flag is used to create a new branch
Just to verify if we got this right, I'd do a quickgit branch
to make sure we are on thetemp
branch and agit log
to check if we got the commits right. -
Merge the temporary branch into the branch originally intended for the commits, i.e.
target
.
First, switch to the original branch i.e.target
(You might need togit fetch
if you haven't)git checkout target
Note: Not using
-b
flag
Now, let's merge the temporary branch into the branch we have currently checkout outtarget
git merge temp
You might have to take care of some conflicts here, if there are. You can push (I would) or move on to the next steps, after successfully merging.
-
Undo the accidental commits on
master
using this answer as reference, first switch to themaster
git checkout master
then undo it all the way back to match the remote using the command below (or to particular commit, using appropriate command, if you want)
git reset --hard origin/master
Again, I'd do a
git log
before and after just to make sure that the intended changes took effect. -
Erasing the evidence, that is deleting the temporary branch. For this, first you need to checkout the branch that the
temp
was merged into, i.e.target
(If you stay onmaster
and execute the command below, you might get aerror: The branch 'temp' is not fully merged
), so let'sgit checkout target
and then delete the proof of this mishap
git branch -d temp
There you go.
Solution 7 - Git
So if your scenario is that you've committed to master
but meant to commit to another-branch
(which may or not may not already exist) but you haven't pushed yet, this is pretty easy to fix.
// if your branch doesn't exist, then add the -b argument
git checkout -b another-branch
git branch --force master origin/master
Now all your commits to master
will be on another-branch
.
Sourced with love from: http://haacked.com/archive/2015/06/29/git-migrate/
Solution 8 - Git
To elaborate on this answer, in case you have multiple commits to move from, e.g. develop
to new_branch
:
git checkout develop # You're probably there already
git reflog # Find LAST_GOOD, FIRST_NEW, LAST_NEW hashes
git checkout new_branch
git cherry-pick FIRST_NEW^..LAST_NEW # ^.. includes FIRST_NEW
git reflog # Confirm that your commits are safely home in their new branch!
git checkout develop
git reset --hard LAST_GOOD # develop is now back where it started
Solution 9 - Git
If you run into this issue and you have Visual Studio, you can do the following:
Right-click on your branch and select View History
:
Right-click on commit you want to go back to. And Revert or Reset as needed.
Solution 10 - Git
For me, this was solved by reverting the commit I had pushed, then cherry-picking that commit to the other branch.
git checkout branch_that_had_the_commit_originally
git revert COMMIT-HASH
git checkout branch_that_was_supposed_to_have_the_commit
git cherry pick COMMIT-HASH
You can use git log
to find the correct hash, and you can push these changes whenever you like!
Solution 11 - Git
If the branch you wanted to apply your changes to already exists (branch develop, for example), follow the instructions that were provided by fotanus below, then:
git checkout develop
git rebase develop my_feature # applies changes to correct branch
git checkout develop # 'cuz rebasing will leave you on my_feature
git merge develop my_feature # will be a fast-forward
git branch -d my_feature
And obviously you could use tempbranch or any other branch name instead of my_feature if you wanted.
Also, if applicable, delay the stash pop (apply) until after you've merged at your target branch.
Solution 12 - Git
In the common case where you forgot to switch from master
to your feature
branch before commiting:
git checkout -B feature
git branch -f master origin/master
Replace origin/master
with the commit you want your master
branch to point to. For example, use HEAD~3
if you want it to point 3 commits behind HEAD
, or a1b2c3d
if you want it to point to the commit with that hash.
The idea is to recreate the feature
branch on the current commit and switch to it. Then make the master
branch point to the same commit as origin/master
.
General case
In the general case where you want to replay the commits done on master
on your feature
branch, like the following diagram:
A---B---C---D $old_master A---B---C---D master
| \ | \
| G---H---I master <- HEAD => | G---H---I
| |
`-E---F feature `-E---F---G'--H'--I' feature <- HEAD
Then cherry-pick the commits you made on master
on your feature
branch using the following commands. Replace $old_master
by the hash of the commit master
was pointing to before you made your changes.
git checkout feature
git cherry-pick $old_master..master
git branch -f master $old_master
If needed, stash your local changes using git stash --include-untracked
, and then unstash them later using git stash pop
.
Without rewriting history
Instead of resetting the master
branch into the past, you need to git revert
the changes, in addition to cherry-picking the changes on the feature
branch.
git checkout feature
git cherry-pick $old_master..master
git checkout master
git revert $old_master..
git checkout feature
Make sure not to git merge
your commits into feature
. Those changes will be ignored if you try to merge your feature
branch back into master
, because we just reverted them.
Here's what the result would look like, with rD
and rC
the revert commits of D
and C
respectively:
A---B---C---D---rD--rC master
| \
| G---H---I
|
`-E---F---G'--H'--I' feature <- HEAD