Reputation: 435
I have a question of how to fix a mistake I did when committing and pushing my code to our repo at bitbucket. The situation was that I had finished working on a previous feature branch(Branch1) and it was pulled into the master branch. Then i proceeded to create a new branch(Branch2) for a new feature.
What ended up happening is that I created the Branch2, but did not check it out so my updates ended up being committed to branch1.
How can i transfer these changes from Branch1 to Branch2 ?
Awesome paint picture included:
Upvotes: 2
Views: 2171
Reputation: 390
This happens to me all the time and I always have to lookup how to fix it.
One of our projects is simple with 2 branches, master and devel. Master is where we build releases from, commit backports, etc. devel is where most of the work happens. I'm usually the guy who builds the production releases, so after a release I often have master checked out when I'm expecting to have devel checked out.
Basically I end up with this:
o---o---o---o---o origin/master
| / \
| / o'--o'--o' *master*
\ /
o---o---o---o---o origin/develop
And what I want is:
o---o---o---o---o origin/master master
| /
| /
\ /
o---o---o---o---o origin/develop
\
o'--o'--o' *develop*
So long as you haven't pushed*, the best way I've found to fix this is as follows:
$ git checkout develop
$ git rebase --onto develop origin/master master
Think of this as git rebase --onto DESTINATION STARTING_FROM ENDING_AT
. This gives me almost what I want, but the branch name "master" has been moved and the branch name "develop" hasn't been advanced. "master" is currently checked out.
o---o---o---o---o origin/master
| /
| /
\ /
o---o---o---o---o origin/develop develop
\
o'--o'--o' *master*
So then just move the branch names. Make the current commit develop and reset master to point to origin/master:
$ git branch -f develop
$ git checkout origin/master
$ git branch -f master
$ git checkout develop
* If you've pushed, then the best thing to do is usually use git cherry-pick
to clone those commits to the proper branch. Then you can use git revert
to undo the commits you pushed on the wrong branch.
Note A lot of times you'll see people tell you to make temporary branch names before doing the rebase. This would let you avoid the git branch -f develop
, because you could use merge to fix that and then delete the temporary branch before you push. But you'll still have to git branch -f master
cause you already advanced that improperly with commits... Ultimately the temporary branches have just caused me confusion and I already have the origin/FOO
refnames which match how I'm already thinking about things, so I prefer to use those directly.
Upvotes: 0
Reputation: 70853
Use git rebase --onto:
git branch tmp-branch branch1
git rebase --onto branch2 tmp-branch^ tmp-branch
git branch -f branch2 tmp-branch
git branch -f branch1 branch1^
git checkout branch2
git branch -d tmp-branch
Upvotes: 2
Reputation: 62489
If you haven't pushed branch2
yet, this would be one way to go about it:
git checkout branch1 # make sure to be on the wrongly-modified branch1
git branch -d branch2 # remove the current branch2
git branch branch2 # create a new branch2 at the current spot
git fetch # make sure we're up-to-date on origin's pointers
git reset --hard origin/branch1 # reset branch1 back to what origin thinks it should be
git checkout branch2 # switch to branch2
# continue working on branch2
I know it's a lot to type, but it should be conceptually fairly easy to follow. I find that sometimes, even if I could find a smaller set of commands to accomplish something, following a logical easy to understand approach is better, especially when I'm working with something I don't exactly consider myself expert in yet...
Upvotes: 4