Git is a tool, and like any tool, there is a big difference between using it and using it properly. I will describe in this article the workflow I’m using in my day-to-day developer’s job.
When I start working on a Bug, on a User Story, on a Task or on whatever, I always start by checkout a branch containing my name, a short description of the issue and ticket number. It looks like :
git checkout -b tan/fix-event-crash-MIC-1831 origin/master
After a few minutes or a few hours, depending on the complexity of the task, I end up to commit my modifications. I rarely use command line for commit, but use git gui instead:
And I systematically push my branch, also with git gui push button. This has 2 advantages:
- If I screw up my repos, I can still reset on the last time I pushed by branch.
- If my computer crash for any reason, I have a backup of my work. I also use gitk a lot to see current status of my branch:
Here I can see that I’m based on master, thanks to the remote/origin/master label. I have 3 commits in my branch and my branch is currently pushed, thanks to the remotes/origin/tan/feat2 label being the same as local tan/feat2. So my work is saved.
I really commit/push A LOT. I push several times a day, and sometime up to several times per minutes for very short modifications.
I regularly rebase my branch on current master to retrieve other’s work and address conflicts as soon as possible.
git fetch git rebase origin/master
Note that I rebase, and not merge master into my branch. I want my history to be linear, and the only merge points that appear in history are merged of feature branches into the master branch.
Whatever the status of my code, I always commit my work at the end of the day and push it. I never know what can happen. If I’m in a draft state, I just put everything in a commit and prefix commit message with “WIP”:
After a good night, I wake up and wonder what the hell I was doing yesterday. I clean up my mess and want to do a clean commit. But I commit an ugly “WIP” commit yesterday. Here comes the awesome “Amend Last Commit” git gui checkbox:
This checkbox let you modify the last commit, rewrite commit message, stage/unstage files etc… So I really have no reasons to not commit a WIP work.
I often do intermediates WIP commit, to explore a path until it leads to something concrete. I also frequently do small dumb fixes or typo correction that should go on older commit. To avoid having a lot of intermediate commits that goes back and forth, I practice interactive rebase. Interactive rebase is a wide topic. You can have a look here to have more details.
In the example below, while fixing a crash, I fix a typo in documentation I previously wrote. To indicate it, I prefix the commit message with an f for fixup. I would like this commit to be squashed with the 2nd add doc commit, and then I would like to squash the WIP commits with the fix feat 1 commit.
To do so, I do an interactive rebase:
git rebase -i origin/master
And go from this:
Now my branch is clean, I can publish the merge request and ask for review.
This workflow is well adapted to Trunk based development, but can also be used for any git branching models. The most important points are:
- Rebase your branch on master instead of merging master in your branch.
- Always push your work, even draft and work in progress branches.
- Learn interactive rebase.