How do I move my recent commits on master to a new branch, and reset master to before those commits were made? e.g. From this:
master A - B - C - D - E
To this:
newbranch C - D - E
/
master A - B
How do I move my recent commits on master to a new branch, and reset master to before those commits were made? e.g. From this:
master A - B - C - D - E
To this:
newbranch C - D - E
/
master A - B
Here's a far simpler solution for commits to the wrong branch. Starting on branch master that has three mistaken commits:
git reset HEAD~3
git stash
git checkout newbranch
git stash pop
master master, yet leaves all working files intactmaster working tree exactly equal to the HEAD~3 statenewbranchYou can now use git add and git commit as you normally would. All new commits will be added to newbranch.
The OP stated the goal was to "take master back to before those commits were made" without losing changes and this solution does that.
I do this at least once a week when I accidentally make new commits to master instead of develop. Usually I have only one commit to rollback in which case using git reset HEAD^ on line 1 is a simpler way to rollback just one commit.
Don't do this if you pushed master's changes upstream
Someone else may have pulled those changes. If you are only rewriting your local master there's no impact when it's pushed upstream, but pushing a rewritten history to collaborators can cause headaches.
1. Rename master branch to your newbranch (assuming you are on master branch):
git branch -m newbranch
2. Create master branch from the commit that you wish:
git checkout -b master <seven_char_commit_id>
e.g. git checkout -b master a34bc22
NOTE:
The upstream for newbranch would be origin/master.
How can I go from this
A - B - C - D - E
|
master
to this?
A - B - C - D - E
| |
master newbranch
With two commands
giving
A - B - C - D - E
|
newbranch
and
giving
A - B - C - D - E
| |
master newbranch
If you just need to move all your unpushed commits to a new branch, then you just need to,
create a new branch from the current one :git branch new-branch-name
push your new branch: git push origin new-branch-name
revert your old(current) branch to the last pushed/stable state: git reset --hard origin/old-branch-name
Some people also have other upstreams rather than origin,
they should use appropriate upstream
TLDR
git checkout branch_to_remove_commits
git reset --hard ${hash_of_new_tip}
git checkout -b branch_to_store_commits
# Move commits (single hash, list of hashes or range ffaa..ffoo)
git cherry-pick ${commit_hash}
git push --set-upstream origin branch_to_store_commits
# Switch back to last branch
git checkout -
git push -f
For me
git log --pretty=oneline -n ${NUMBER}
works best to identify the commit hashes in question.
You can do this is just 3 simple step that i used.
1) make new branch where you want to commit you recent update.
git branch <branch name>
2) Find Recent Commit Id for commit on new branch.
git log
3) Copy that commit id note that Most Recent commit list take place on top. so you can find your commit. you also find this via message.
git cherry-pick d34bcef232f6c...
you can also provide some rang of commit id.
git cherry-pick d34bcef...86d2aec
Now your job done. If you picked correct id and correct branch then you will success. So before do this be careful. else another problem can occur.
Now you can push your code
git push
1) Create a new branch, which moves all your changes to new_branch.
git checkout -b new_branch
2) Then go back to old branch.
git checkout master
3) Do git rebase
git rebase -i <short-hash-of-B-commit>
4) Then the opened editor contains last 3 commit information.
...
pick <C's hash> C
pick <D's hash> D
pick <E's hash> E
...
5) Change pick to drop in all those 3 commits. Then save and close the editor.
...
drop <C's hash> C
drop <D's hash> D
drop <E's hash> E
...
6) Now last 3 commits are removed from current branch (master). Now push the branch forcefully, with + sign before branch name.
git push origin +master
Most of the solutions here count the amount of commits you'd like to go back. I think this is an error prone methodology. Counting would require recounting.
You can simply pass the commit hash of the commit you want to be at HEAD or in other words, the commit you'd like to be the last commit via:
(Notice see commit hash)
To avoid this:
1) git checkout master
2) git branch <feature branch> master
3) git reset --hard <commit hash>
4) git push -f origin master
I was surprised that nobody recommended this way:
git checkout master
git checkout <commit hash from which you want to split>
git checkout -b new_branch
git rebase master
git checkout master
git reset --hard <commit hash you splitted>
to explain:
Using Emacs' git porcelain Magit, you can do this simply by hitting b s (magit-branch-spinoff). You'll be asked to enter a name for your new branch and once you hit enter, voila.
From the Magit documentation:
This command creates and checks out a new branch starting at and tracking the current branch. That branch in turn is reset to the last commit it shares with its upstream. If the current branch has no upstream or no unpushed commits, then the new branch is created anyway and the previously current branch is not touched.
This is useful to create a feature branch after work has already began on the old branch (likely but not necessarily "master").
I got to move 7 commits from one old-branch to a new-branch.
git checkout old-branch # in the example, master
git reset --hard h4sh # h4sh is the hash for the commit
git checkout -b new-branch
git push origin new-branch
After that, both branches were related to the 7 commits I have done. After git checkout new-branch, I was getting fine git log and git status, but, when accessing the old-branch (git checkout old-branch), I'd got the message "git is behind by 7 commits and can be fast-forwarded". What worked for me to erase this message was the followind:
git checkout old-branch
git status
> git is behind by 7 commits and can be fast-forwarded
git push origin old-branch -f
After that step, the last 7 commits was referenced only for the new-branch and the previous ones were referenced as old-branch and new-branch in the Bitbucket tree.
If you are a UI person like me and you are using Visual Studio. Then you can do the following: In my case, I want to take the latest commit to another branch.
So all commit changes will appear in the Git Changes pane.
Now, stash your changes
From "Git Changes" double click on your latest Stash.
"Stash details" pane will be opened. Click on "Pop", then resolve conflicts (if exists).
Taking some ideas from other posts, avoiding anything to do with reset, and being ultra paranoid, my solution is:
I'm not proud, but I kept my data ;)