My Git Workflow
Published: , Updated:
Topics: git
Introduction ¶
I've read different tips & tricks from developers. I've also read different workflows like "git flow". And I've worked with some freelancers and agencies on a dozen of projects.
This post will share my current git workflow that works for all of our clients in all the projects. This includes switching projects and knowing where to continue once you come back. And this also ensures the rest of the team can continue with your work in case you become ill.
Branching ¶
I create a new branch for each new to-do I have to solve. It doesn't matter whether it is a bugfix, hotfix, task, new feature or something else. I do not distinguish, because it doesn't matter for the actual to-do.
The branch name is often created out of an issue system. I use the issue number (which usually exists) as a prefix, followed by some meaningful description in lowercase separated with -
. But the format is not that important. Adding the issue number as prefix makes it easy to autocomplete the branch based on your current task and eases switching. Most systems will interact with each other, allowing to auto link the branch to the issue.
Commits ¶
I might create multiple commits for a single to do. The first one might be an empty commit used to describe the goal and setting the focus.
Further commits might be added leading to a history like (only showing first line of each commit):
- Make copyright year dynamic
- Migrate hardcoded year to TypoScript dynamic year
- Migrate TypoScript year to ViewHelper usage
It doesn't matter too much how many commits I'll have in the end, see Merging.
Different fine-grained commits allow me to rebase, revert, check history of my own ideas to solve a to-do. They also allow teammates to review all in one or step by step. They add extra info for everyone without extra work.
I share every commit with the outer world. That ensures there is a back-up of my work done so far, in case my machine will break. Also, everyone else can have a look how far I've come and can continue the work.
WIP ¶
I sometimes need to switch between to-dos. I then add a WIP commit where I document the current state of the to-do I'm leaving. This commit includes a WIP
prefix, so everyone can see within the git history that this commit is not finished. The commit also includes a list of the open tasks to solve the to-do. E.g.:
WIP: Make copyright year dynamic
In order to not adjust the year every year.
WIP:
* Find location of hard coded year
* Change location to be dynamic
* Add tests to ensure the year will be changed
I then share this commit with everyone else. This ensures that I can read what I've to do next time I'm working on this task. But everyone else within the team also can follow up. E.g., in case I am on holiday or am ill.
Merging ¶
I prefer to squash all commits related to a single to do. Most web UIs support this out of the box. This single squashed commit will then be added to the target branch, leaving a clean history.
Some can be configured to use the first commit message as the final commit message. I'll then add a first empty commit to the branch which is used for the final commit within the project. Empty commits can be created via git commit --allow-empty
. This also allows you to document your focus and goal within git as a first step before even starting to solve a to-do.
Cocnrete example ¶
Let's say I've received a new issue with number 314 that is about adjusting the current year within the copyright of the footer. Here's what I do:
- Fetch the current state of the project via
git fetch
. - Switch over to the latest state to start working via
git checkout origin/main
. Where origin/main is your actual branch where you start new work. Some might use origin/dev or origin/develop instead. - Create a new branch for your changes via
git switch -c 314-fix-copyright-in-footer
. - Do your changes. E.g., make the actual year dynamic, so you do not need to solve the same issue every year. This includes adding automated tests and manual testing.
- Commit your changes to the repository via
git commit -av
. Adding a commit message like:Make copyright year in footer dynamic
This removes the need to adjust the year in future.
Relates: #314 - Share your changes with your team via
git push
. - Open a pull or merge request and wait for feedback.
- Merge your changes once the pull or merge request got approved.
This is the ideal workflow. But sometimes your changes take longer, and you might switch to another to do. I then still follow up to step 4, followed by this workflow, until we can continue with step 5 as we finished our to-do:
- Commit current changed as a WIP (=Work In Progress) commit via
git commit -av
. Adding a commit message like:WIP:Make copyright year in footer dynamic
This removes the need to adjust the year in future.
WIP:
* Find the location of hardcoded year.
* Adjust the source to make this year dynamic.
* Add tests to ensure the year always matches current year.
Relates: #314 - Share your changes with your team via
git push
.
I'll do the following when I come back to a WIP to do:
- Check if others have continued with my work via
git fetch
. - I switch back to the task via
git switch 314-fix-copyright-in-footer
. - Update my local state to the latest state via
git reset --hard origin/314-fix-copyright-in-footer
. - Continue with my work and apply changes.
- Add my changed via git
commit -av --amend
. I'll adjust the WIP list accordingly with each commit, until I am finished and can remove the whole WIP info. - Share my changes with the world via
git push -f
.
Acknowledgements ¶
Thanks to berkes for making me feel to share my current workflow with his post on mastodon: https://fosstodon.org/web/@berkes@bitcoinhackers.org/108876619095503590.
Further reading ¶
Other possible workflows, tips and tricks related to that:
- Mastodon comments: https://fosstodon.org/web/@berkes@bitcoinhackers.org/108876619095503590
- "@INK marker" by Bèr Kessels: https://berk.es/2012/05/30/leave-some-ink-in-the-well/