When the Going Gits Tough
So we’ve been programming for a while and we know some basic Git commands.
Perhaps we visualize commits like saving the current version of our project to a file. And perhaps we imagine pushing like copying that file of versions to its counterpart file on Github (which is dubbed repository).
We also know how to retrieve code from someone else’s repo to our repo (fork) and then from our repo to our local machine (clone). Or from someone else’s repo right to our local machine if you so choose.
Then lastly, we have likely come to understand that we create branches so that versions of our project that work and versions of our project that are being worked on are separate from each other. And so we must also know that to move a version from one branch to another, we push the branch up to its repo, open a pull request (to ourselves if it’s our project), review the changes we made, summarize the changes we made, then merge the development branch into our production branch.
If you’re like me, this is sort of how you pieced all this together and used the commands you picked up along the way as needed.
Some of the ways I started using these tools had been counterproductive to the purpose the tool was supposed to be serving. For example, I had a bad habit of committing multiple times for the same change with the same commit message. I’ve also added multiple changes to one commit and listed each change within the same commit subject line. Even worse, I used to push my changes regardless of what the condition of the code was whenever I was ready to break for lunch or go to bed. It was my pause button. I’d just hold off on merging the changes for when the code was in working shape.
For my own sanity and for the well being of all my future team members I want to find the answers to the following questions:
- When should I commit?
- How should my commit look?
- When should I create a new branch?
- When should I push my code?
- Why is it like this?
Before I go into detail on each of those points, it’s important to keep in mind that when you work with a larger team, for a larger organization, or on a larger project, these answers may change slightly. It would be wise to check what kind of workflow your hopping into so you know what to look for(i.e. a larger organization may use Gitflow or an open-source project may be using Githubflow).
Ok, here’s what I’ve learned so far.
When should I commit?
You should commit each change you make to an app. But really think about it. Think about the change you want to make. Are you about to put an entire change into one commit or will that change be spread across multiple commits, because it shouldn’t be.
Take this situation for example. You just opened an app you created a long time ago when you were just learning HTML and CSS. For educational purposes, the tutorial had you put all your styles inline with your HTML but now that you know better than to do that, it hurts your eyes to look at so you want to quickly put all the inline style properties onto a style sheet.
You have a paragraph tag with a style property that turns the text within the paragraph red. To make this change, you have to remove the style tag from the HTML document and add that style to your stylesheet targeting that paragraph to get the same style to appear on your app.
In this case, you would commit after you’ve seen that the changes you made worked.
What you shouldn’t do is:
- Commit when you delete the style tag. Commit when you add the element to the stylesheet, and then possibly even add a third commit if you need to make any adjustments to get the changes to work on the app. That’s 3 commits for 1 change.
- Commit after you’ve replaced all the style tags on the document. The comment would be long and hard to follow in more complex cases and you’ll have to start over if you need to revert to the last commit.
- Commit code that doesn’t work. could you imagine reverting to a commit that breaks your app?
How should my commit look?
I found a great article that collected seven rules to follow to have a great commit message. I will outline and explain them here:
- Separate subject from the body with a blank line. This says that if your commit message needs a body to explain the message, that there should be a space between the message and the body for readability.
- Limit the subject line to 50 characters. This says that your commit message shouldn’t be longer than 50 messages and if it is, that you should either create a body to that message or rethink the size of the change you are committing.
- Capitalize the start of the commit’s subject line. Nothing much to it, the capital letter indicates the start of your commit.
- Do not end the subject line with a period. Real simple, it’s an extra character that isn’t really needed on a subject line that is 50 characters or less.
- Commit subject lines should be written in the imperative mood. If you’ve written your subject line appropriately this sentence should make sense, “If applied, this commit will <your subject line here>”. i.e. “Add styled component to test.js”, not “Added styled component to test.js”.
- Wrap the commit body at 72 characters. Git doesn’t wrap the body text automatically so you should make a new line at 72 characters.
- Use the body to explain what and why vs. how, not all commits need a body. If you feel yours does though, be sure to include why you made the changes, and how the functionality is different from before the change. You can also explain why you changed it as you did and not another way.
When should I create a new branch?
This will in large part be decided by your workflow or your place in a workflow (Hotfix, open issue, new feature). Regardless of your workflow, if you’re using one, the purpose of branches is the same.
You always want to have a working version of your application, your main branch. Then you will want at least one other branch to work on, a development branch. Past a development branch, additional branches are usually added to facilitate collaborations. If you are working alone, they may still be helpful as a way to create a history of features and issues.
When working on a project with collaborators and you are assigned to implement a feature or fix a bug. If you are unsure where to start and you just want a place to try a bunch of different approaches without worrying about accidentally committing or breaking something, you can always create your own branch, name it something like ‘CoreysBranch’ (so others know its a private branch), and work within that branch. That way you can remove it if you want or if your ideas pan out, you can squash your commits and merge it into the pubic branch you’re private branch was created from.
When should I push my code?
Simply, you should push your changes when you have completed the feature or implemented the fix. Also, you should always push working code. You should never push a feature that doesn’t work or any kind of broken code.
It is always best practice to run git pull before you run git push in case anyone else has contributed to the same branch while you were working on it. This will add their changes to yours and then after conflicts have been resolved, you will be able to push all the changes.
Conclusion
The whole idea behind using Git to manage our code is to keep a working history of all the changes made to our application. By having this record of changes, each with their own clear concise messages, we are not only able to keep track of all the changes we made, revert to another change, and compare different versions of our application but also anyone else who’s working with you or your organization can do the same.
Now, that simple idea becomes quite complex when you add in multiple teams working in unison, a large codebase with multiple supported versions, and hotfixes. That’s what git workflows are for. They take the concepts described in this post and combine them into a scalable plan to organize the numerous and concurrent changes being made to a project by many teams.
I hope a glimpse into my Git learning journey was helpful to you. If anyone has any corrections or elaborations I’d love to hear them.
If you would like to learn more, here are some excellent resources I’ve used to cement these concepts into my consciousness:
- https://www.youtube.com/watch?v=Hlp-9cdImSM&ab_channel=KieCodes — Great overview
- https://chris.beams.io/posts/git-commit/#separate — 7 Rules
- https://www.youtube.com/watch?v=1SXpE08hvGs&ab_channel=Devchild — Gitflow in 5min
- https://www.youtube.com/watch?v=0pBUfrLi_Q0&ab_channel=MSFTImagine — DevOps perspective
- https://git-scm.com/docs/git-rebase#_interactive_mode — Squash (git rebase -i (branch))