I am back in my city, Delhi, and the winters are getting really harsh now. Typing on my metallic-bodied Mac is getting tougher day by day. 🥶
So here I am, bringing you today’s newsletter, with shivering hands. Enjoy. 😄
Developers have a love-hate relationship with Git. Git is probably one of those things which are ubiquitous in a developer’s life. Yet it’s something which we don’t really care about when we are starting out as one.
A couple of other things which we take for granted, although being essential are:
Bash scripting
Documenting your software
I will be covering these two topics in the upcoming newsletters. There are a lot of misconceptions regarding Git. I want to write about them in another issue. Let me know if you want to hear about it by replying to this email. 😃
✅ Today let’s discuss the Git workflow I prefer the most
TLDR
The workflow I follow is similar to Gitflow workflow.
Create
master
branch for production,dev
branch for staging andfeature
branches for individual features.When you have to integrate another teammate’s changes into your branch, you can use git-rebase command. But this is a bit dangerous so use it with caution.
release
branches are used to merge a bunch of changes tomaster
branch.hotfix
branches are used to fix issues in the production server.
So, what is a Git workflow?
Git workflow is the strategy that you follow when you are working with Git.
A lone developer’s Git workflow can be as simple as working on a single branch, making commits to it and using it as the single source of truth.
But when it comes to a team, we need a proper branching strategy. Else your colleague’s commits can be overwritten by yours (that’s one among a zillion hazards that can happen).
This post is for those who want to understand the strategy
Some lesser used Git commands
There are great guides out there describing the basic commands of Git, like this, so I won’t dive into that. But lemme introduce you to a few lesser known commands
git-switch & git-restore:
Everyone is familiar with git-checkout. Currently, git-checkout handles 2 things
Restore file contents from index (or other sources) to the working tree
Switch branches
But a couple of years back git engineers realised that one command handling two wildly different functions can be confusing, so they split it into two separate commands
a. git-switch: Handle switching of branches
git switch <branch-name>
b. git-restore: Handle restoration of working tree files
git restore <file-path>
This update was part of the release git 2.23. Release notes for the same can be found here: https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt
git-rebase:
This is considered to be a dangerous command. But it’s very useful in situations. This command is used to apply commits from one branch to another branch.
⚠️ A word of caution: Do NOT use this command to alter history on any public branches.
You can mess with your local branches which doesn’t have a remote-tracking branch. But if you alter the history of a public branch used by other developers, that’s going to cause a lot of confusion.
I will demo how I use this in my own workflow.
My git workflow
Your workflow majorly depends on how many kinds of servers your company has.
Many companies follow the below configuration:
Production server, the public, customer facing server. Deployment to this server is done after testing rigorously on the staging server.
Staging server, where testing is done by the team members before releasing it to the public.
Feature testing servers (usually spun up for each feature), where new features are tested by individual developers before pushing it to the staging server.
The ideal setup is to have a dedicated branch for each of the server types
That means:
master branch → For Production server
dev/staging branch → For staging server
feature branch → For feature testing server
The workflow we follow at our company & which I am going to show here is closely related to the popular Gitflow workflow.
When it comes to comparing git changes, I am not a huge fan of the terminal.
I would rather view the changes on my VS Code editor itself, where I can compare the before and after, effectively.
Check out the below screenshot of my VS Code editor showing changes.
My git workflow consists of various branches and certain rules attached to these branches.
💪🏼 Master branch
This is the main branch and will be considered as the single source of truth.
The changes made to this branch are deployed to the production server.
You are not supposed to make any changes to this branch directly. Creating any branches out of this to create features is also forbidden until it’s a production bug (in which case you will create hotfix branches, which I have explained in detail below).
master branch with 3 commits
🤙🏼 Dev branch
Once you have setup master
branch, you should derive a dev
branch out of it.
This branch is used to test out all features before deploying to production. Changes to this branch are deployed to staging server and tested.
dev branch merged out of master at the M1 commit (first commit on master) & having it’s own commits
🖖🏼 Feature branches
Every feature will have a separate branch.
Feature branches are branched out of the dev
branch and merged back to dev
branch after the feature is completed.
Feature branches can be named according to the feature for better identification.
Let’s take a feature and build a branch for it.
Here, you branched out a feature
branch and created 2 commits on it, F1
& F2
Now suppose, your colleague Raj, who is also working on the same feature, has created 2 commits on his local feature branch.
Hmm, this is getting tricky. How do you integrate his changes into your branch before pushing it to the dev branch?
Here’s where we use the git-rebase command mentioned above. In a way, you are rebasing your changes on to his branch so that the feature branch is in one, linear structure of commits (notice that both your and Raj’s branches are having the same name, and the remote contains only one branch with that name).
On your end, you are going to enter the command
git rebase <Raj's branch>
Let’s see how our branches look now.
Your commits have been ‘appended’ to his commits. Now you have both your changes and Raj’s changes.
Mind that, rebasing this way is okay since you are not editing any of the major branches. As for Raj, he can take a pull from the
feature
branch once you push it to the remote and he can see your commits as well.
The reason we use rebase
command instead of git’s merge
command is to have a linear, simple git branch, which is not achievable using merge.
It’s time to merge the feature
back to dev
, creating a D3
commit with changes in the feature
branch.
Merging feature into dev creating a D3 commit with changes of feature
🤘🏼 Release branches
Once enough features are deployed to the staging server and tested, you can deploy them to the production server by first merging the changes of dev
to master
branch.
To merge into master
, you create a release
branch, out of the dev
branch. This branch will be merged into master
.
After this, you can merge the release
branch into the dev
.
release branch merged into master creating M4 commit
🔥 Hotfix branches
When something breaks in your production server, there is not enough time to branch out of dev
, merge it back, create a release branch, etc.
The simplest way will be to do the following:
Branch out a
hotfix
branch frommaster
Make the required changes to it
Merge the
hotfix
branch back tomaster
Merge the same to
dev
branch
Something like this
Some Git etiquette to keep
When you are working in a collaborative environment, you need to follow some etiquette while using Git.
Every merge to public branches should be reviewed. Whenever you are trying to merge to
dev
branch or master branch, create a pull request and let your team mates know that you want to merge some of your changes. This will help them take a pull and work with the latest code.Do not mess with the history of the branches. Git commits are immutable. But there are certain commands in git which can create commits using the previous commits, making it look like you have reverted to a previous commit. This can cause issues with the working code of other teammates. Do this only if it’s absolutely required. Also, follow tip #1 after you do this.
If you liked my newsletter, please share it with your friends! It would mean the world to me
Connect with me!
You can drop me a “Hi” on Twitter ! Let’s talk tech, my DMs are open for you 🤓
If you need help with your service architecture, you can also email me 💌 : dennysam14@gmail.com
let your shivering hands write more content...;)