Some days ago we started working on a new feature. But after some days of work, we realized that you were working inside my ‘master’ branch.
As best practice, we should have created a ‘feature branch’ to collect all the commits relevant to the feature we were developing.
So the problem is: how can we create a new branch to collect all those commits, and only those?
Because a picture is worth 1000 words, let us take a look at the schema below. We would like to move from this situation:
to this one:
o-o-X-o-o-o-o-o-o (master) \a-b-c (branch)
hence, collecting the commits
c into a separate feature branch.
What follows is only one of the way of achieving this, given the tools git offer to us to manipulate the history and the organization of our source code; but in my humble opinion is one of the easiest one, if you only have to re-organize few commits.
Let us suppose our Git repository is organized like this:
(origin) (upstream) | / | / (local)
origin is our own remote repository, while
upstream is the main repository storing the production code for our software. And
local is the working copy on our local computer.
Regularly we update our
local to the latest changes in the
'upstream, merging them with our
master branch by using:
then we push the updated master to our
origin repository by using:
git push origin master
As said above, we started working in our
master, so now in our local copy we have few commits in our
master branch, which of course are inter-mixed with all the commits that have been pulled from the
master branch on
As first step, we want to see what commits we created, to be able to separate them from all the others.
The new commits we have created while working in the past few days are, obviously, not present in the
master, since we didn’t create any merge requests with it yet.
For that purpose, we can use the command
This command, in its general form
git cherry -v branch1 branch2, gives you the list of all commits present in
branch2, but not present in
In our example the command gives us this outcome:
$ git cherry -v upstream/master origin/master + 16e9500a28181ad434f0608501faf78e218bab6c fixing old Qt4 commands + e4edd5f3957bd576e92baa235e0845142b6d8b35 removing the REQUIRED option + ef6945d63db50be7abff557819d48807e91178e8 porting the fix to 'DataQualityConfigurations' from r.21 to master + d7a4651335aac0d1f3ef651a39c5d942f4ec5780 porting Joe's fix from r.99 to 'master' + 62bf6354f8ac64e656c0d9698ecf0995a0e11e9e fixing a missing implementation
At this point we know which commits we have to extract from ‘master’, to collect them in a separate branch.
Let us now create a new branch to store all the commits.
master branch on our own
origin repository is “tainted”, we have to create a branch from a clean status. The easiest is to use the
Let us start creating a new branch:
git checkout -b new-feature
This will create a new branch called
new-feature. Now let us reset our new branch to teh clean status of the
master branch stored at the
git fetch usptream git reset --hard upstream/master
The first line collect information about the latest changes in the
upstream repository. The second command reset the local code to the status found in the
upstream master branch.
Now we have a clean branch reflecting the status of the
We can now start collecting the commits from our tainted master branch. For that we can use the command
git cherry-pick 62bf6354f8ac64e656c0d9698ecf0995a0e11e9e
The command above will pick the single commit, uniquely identified from its ID, and apply it on the local code.
Repeat that for all the other commits, and at the end we will have our new branch containing only the commits we wanted to collect. We can verify that by using the command
git log, which shows us the history of the local branch.
Now we can push our new branch to our own remote repository; for that we will use the option
-u which create a new branch on the remote site if the local branch we are trying to pushing is new:
git push -u origin new-feature
We now have the new branch containing only few commits on our own
origin repository; branch which is now ready to be the object of a merge request into the
upstream master branch.