Practical Git: Manipulating branches
Do you mess up sometimes? Not to worry, Git got you covered, whether you committed in the wrong branch or need to delete something for the time being from Production.
Cherry Picking Commits
Just like how a cherry picker picks cherries, you could do with the commits. It is a handy command that saves you or drives you. Imagine working off in a feature branch, your in code, 10 commits ahead of parent branch and your co-engineer wants to implement another feature that shares some boiler plate you did, so what? You can let him re-invent the wheel or you share with him your code. So you decide to share him your common code, but wait how? should he branch off your branch? should he copy your code manually? should he wait for you to finish? None of the above, since you have committed your changes then not to worry, just share with him/her the commit hashes of the code that is common, then let them cherry-pick it!
So that’s practically it, cherry picking allows copying of commits between branches. At the end once both branches were merged, no conflicts will occur because they contain common commits. Cool right. How to do it? Well your co-engineer has to do the following. Easy:
git cherry-pick <Commit hash>
How do I get that commit hash, just look through your Git log and copy the hash string:
git log
One caveat, to not break any code so that everything compiles, then just cherry-pick from oldest commit to newest so that you don’t mess up somewhere. Wow! Note, this is assuming the commits were related.
Ok that is all nice, when to use this:
- Imagine working on a feature branch and you discover a bug, you don’t need to switch branches mid-way that may cause rebuilding the entire project at times, just fix that bug, commit change then create a new branch out of your parent branch and cherry-pick the commit that had the bug fix and push changes immediately to Code Review and release, then go back to your working branch and continue. Although this is not recommended approach, but it works.
- Accidentally worked on the wrong branch whilst having committed, not a problem just hold on to your commit hashes, switch to main development branch, checkout a new branch, cherry-pick.
- Sometimes you want to release certain features and not everything, cherry picking the needed commits is all that’s needed to go to the release branch.
What about adding feature on top of a cherry-picked commit. That is, getting the commit you want to put into your code but then let’s say you want to add comments, not a worry, just do the following:
git cherry-pick <Commit hash> --no-commit
This will treat your changes as being staged not yet committed. In that case you can add your additions not a problem then just do:
git add
to stage your changes, then commit like normal.
Cherry Picking with merge conflicts
Life is all well until you get a merge conflict and you are blocked, this happens too with cherry picking. In fact it will show a message after you cherry-picked that you need to resolve conflicts or abort the operation. To abort:
git cherry-pick --abort
But certainly most of the time you want to move on, so just resolve your conflicts, do stage your changes then:
git cherry-pick continue
And that’s all.
Reverting commits
So a while after some code went through and got merged to the main development branch, you figure out it has a bug and that bug takes a lot of time to fix. So what to do? You can fix that bug or revert that change and fix it later. Neither is a bad choice. Let’s say you went with reverting the change. You can’t just do git reset --hard <Older commit hash>, this is dangerous as well as invasive where it will delete code by other later commits from that destination commit. Reverting is easy and non-invasive, since it just writes on top of history, that is what Git does right? a long tail of history.
Reverting a commit just means, undoing what was changed by that commit we are reverting. Nothing else.
git revert <Commit hash>
That will revert the commit with a new commit that does that. Wait what? Git revert basically makes a new commit reverting the specific commit you want.
What if I don’t want to make a new commit, well just do:
git revert <Commit hash> --no-commit
This will stage all changes so you can add other things.
The process is the same as cherry-picking for when conflicts arise, you will have to fix the merge and stage fix and then do:
git revert --continue
Remarks
Cherry picking and reverting commits are very essential to know. Although not used much, they come in handy when needed. As Git tries to be as easy as possible to use, knowing these commands will make your life as easy as possible.
As Git is a history of changes, reverting commits does not mean the reverted code is gone. You can always see that reverted code or even reuse it by cherry-picking it to a new feature branch.