Git me baby one more time
Long time no see. Nothing new on Android from my side this days. I have mostly been focused in learning some new tech stack and some automation. But today I would like to talk about some basic git commands/concepts and situations.
Let’s immediately jump to some ancient debate: Rebase vs Merge
For any reader who doesn’t know the difference, I am trying to illustrate it in the below diagram. Let’s consider these 2 branches:
Let’s start with merge first. From the official git documentation:
In other words, you don’t care what happened to previous commits of branch B. You just take the last one, and put it together with the current one, as a whole:
Think of the merging point as a huge commit that has basically everything, your current work, including the one you merged. If you think further, that’s what happens after merging a Pull Request (or a Merge Request).
For more information, you can refer to the official documentation.
Let’s try the same scenario, but now talking about rebase. From the official docs:
It is practically vague, from only those two short notations. Therefore, a longer description available can be found here.
How I understand it: Every single commit of the history of your current branch, is put on the top of the branch (latest commit) you are rebasing on. In other words, you have every commit in the stack:
Now the debate: when to use what? Frankly I don’t see any huge difference. However, I personally prefer rebasing, since I can track history while if we use merge, we have no idea who did what and how many small other merges might be inside your own merge. Merge can be super confusing sometimes.
In situations where I know exactly the commit(s) that I screwed up and the last commit that the project was working all right, git reset helps a lot. Let’s first see what it does:
I think this one doesn’t need additional description. Wait? What is the HEAD? HEAD is just the current state. When you pull from remote, the HEAD is already in the same place as develop, when you commit from a new branch, checked out from it, the head shows you exactly where you are. HEAD is the pointer of git (if you want to make a very nerdish comparison).
So, you added a commit that failed your project to build. Good! Pick up the command line and start resetting:
git reset --hard HEAD^
What this one does, is resets your HEAD 1 commit before. Thus now we basically “revert” the previous commit and your project builds again.
Great. But what the git is
--hard means uncommit + unstage + delete the changes. Basically, reset everything from that desired commit. This command is not alone, but I will leave you to explore the rest. A very short and nice explanation can be found here.
Ok, but what if we screwed 4 commits “ago”. We can either do
git reset --hard HEAD~4 or if we are unsure to count backwards, we can always reset to the desired commit just by knowing the commit hash:
git reset --hard 9ece14fdfdeb44ac95fecd8f8abe4bb639100b9d
Every commit has a hash.
More information on
git reset can be found here.
git cherry pick
Cool. Now I’m going to talk about my favorite git command: cherry pick. How cool it is to pick some cherries now that spring is here. But that has nothing to do with real cherries. Although the concept is pretty similar. Once you are eating a plate of apples and kiwis, you might also want to sweaten your taste, very little. So you pick a cherry. First let’s clarify the concept:
Well, to me, the name isn’t telling too much. Let’s see the description as well.
Two are the basic scenarios where I use cherry pick:
1 - I need some unmerged-to-main work from some other branch (Let’s say that my teammate just created a data class that I also need).
2 - When the branch is too old, and rebasing gives you a headache.
Of course that in that scenario, cherry pick is far easier than just struggling and struggling to solve and resolve conflicts quick. Therefore, renaming the old branch, creating a new one on top of
develop and cherry-picking commits from the old one is a real life hack.
When you learn how easy git is, you learn how endless it is. Learning some git tricks would neve hurt and will save you a lot of time. Principal advice: Learn git by command line. This will help you understand every UI tool built for git, and if you switch your company one day, you won’t need to learn another git client tool to use it. However, if you are already experienced on git, probably it doesn’t make too much sense remembering those commands all the time, but rather use a client for that. Anyways, I always combine it. I still commit, add and push from the command line, but when it comes to making a longer command, rather than remembering the syntax, I just open source tree and let it do the magic for me.