Does this situation sound familiar? You start with a simple change and after a few commits you notice that the change is a lot bigger than expected. It will be so big that the code better has its own feature branch. But how do we get our commits from the main
branch to a new feature branch?
As long as you did not push your changes to the central repository, you can fix this problem with a few Git commands.
Make sure that all your work is committed before you continue! Otherwise, you may lose your uncommitted work.
Given we have the 4 commits A, B, C, and D:
We can use the following commands to create a new branch and move the main
branch 3 commits back to commit A:
1 2 3 4 |
git branch newbranch # Create a new branch to save your commits git checkout main # Checkout the branch you want to move back git reset --hard HEAD~3 # Move main back by 3 commits git checkout newbranch # Continue work on the new branch |
Let us look what the different commits do and how everything works.
First, we need to create the new branch. That will protect our already committed changes and allows us to continue our work in a feature branch. If we forget that step, our commits will no longer be reachable, and it gets tricky to get them back:
1 |
git branch newbranch |
This command created the branch newbranch
at commit D:
Make sure that you are still on the main
branch:
1 |
git checkout main |
Second, we need to figure out by how many commits we want to move our main
branch back. In our case it is 3 commits we need to go back from commit D to commit A. We can now tell Git to move our current branch (master) back by these 3 commits:
1 |
git reset --hard</code> HEAD~3 |
The main
branch now points to commit A, while newbranch
still points to commit D:
As you can see, HEAD moved back with the main
branch and our repository now has the files in the state as they were in commit A.
As a final step we switch to newbranch
to continue our work with commit D:
1 |
git checkout newbranch |
The commands from above moved the branch pointer for main
from commit D back to commit A. Our newbranch
contains all our changes that we want to keep but are not yet ready for our main
branch.
I hope this explanation makes it simpler to understand what happens behind the Git commands.