I recently saw a discussion about how very few people actually use the famous gitflow workflow. This makes sense to me. The situation where one might have multiple simultaneous supported releases is relatively rare in software as written, because most software is written with one customer or use case in mind and that use case will run the latest stable version. Your team is likely not working on Ruby, where you’ll want to release 2.5.5 and 2.6.2 at the same time. As a result, there won’t be any release branches the way Gitflow means it, and there won’t be any long-lived feature branches.
I want to discuss something much lower level — how to keep your git history clean, which makes meaningful commit messages possible and gives you a changelog for free. That’s what the git workflow on my team is focused on. We accomplish this by amending one or very few commits while we work on a branch and then rebasing for the Pull Request.
This is different from what I was accustomed to on my previous team, where I would continuously add new commits to a branch and then either merge or squash merge the Pull Request.
The typical sequence of steps is to create a branch:
git checkout -b <initials>/<branch-name>
Create or modify some files, and then indicate your intent to add the new files:
git add --intent-to-add .
Examine the changes and add them interactively:
git add --patch
Initially create a new commit:
Later, amend the existing commit:
git commit --amend
Initially, push your branch to the repo:
git push --set-upstream origin HEAD
Later, push it again with the amended commits without overwriting other people’s changes:
git push --force-with-lease
Finally, Rebase and Merge your pull request for that squeaky clean git history. PRs created this way have the added benefit of being easy to review, so your teammates will get back to you with meaningful feedback faster.
I like to alias all of these commands for economy of typing:
git config --global alias.an 'add --intend-to-add .'
git config --global alias.ap 'add --patch'
git config --global alias.ca 'commit --amend'
git config --global alias.co checkout
git config --global alias.pfwl 'push --force-with-lease'
git config --global alias.st status