Git Workflow easily solved in 4 simple steps

Bulletproof Git Workflow is a small 4 step guide. It is a set of constraints that keeps you in a safe working area of Git.

bulletproof git workflow banner image

Bulletproof Git Workflow is a small four-step guide. It is part of my series of Bulletproof Workflow guides. It contains a set of constraints that will keep your team in a safe area of Git.

If you're working in a team, you'll need to agree on a few things regardless of your opinion. It doesn't mean your opinion doesn't count. It doesn't mean you're wrong.

However, for the good of the business, the team, the products, the projects, and the future people that will replace you, make things work by compromising and respecting. As a result, your Git workflow will be more predictable, cleaner and more manageable when you have to resolve conflicts.

This simple guide has been refined over ten years and proven to keep git workflow very simple and manageable through many teams as they evolved with personnel changes. And as it says in the guide, there may be other git workflows - faster, more relaxed, fancier or more efficient - however, this way has proven safe and reliable.

The Agreement

Dear New Coding Colleague,

If you're working in a team, you'll need to agree on a few things, regardless of your opinion. It doesn't mean your opinion doesn't count. It doesn't mean you're wrong. However, for the good of the business, the interest of the products, the interest of the projects, the appeal of your team and the good of the future people that will replace you when you move on make things work by compromising and respecting.

One of the things you are required to agree on in our team is a git workflow. If you're an expert, we agree you're more than capable of doing your own thing. If you're not an expert, you can also do your own something. However, there's nothing worse than someone asking for your help with a git conflict or rebase mess, and you don't know what's what and how you got there. Or looking at a git log to get up to speed on recent changes, and it is an inconsistent stream of meaningless messaging.

Agree to use your clearest workflow, and many things will improve.

Sure, there might be more straightforward, faster, wiser or more fancy ways to get things done, but this continues to prove to teams that it works.

Thanks for your cooperation.

Love from your Coding Team.

1. Do Work

mkdir my-project && cd "$_"
git checkout main
git pull
git checkout -b feature/my-work
# do some work, edit your files
git add changed-file-a.js
git commit -m 'added my work'

2. Do More Work

git add changed-file-b.js
git commit -m 'fixed the broken thing'
git add changed-file-c.js
git commit -m 'made the thing better'

3. Tidy up

Tidy up your commits by interactively (-i) rebasing your branch.

During the rebase you will reword the top commit and fix up other commits as appropriate.

(<n> is the number of commits to return - you know how many commits you've done, right? If not, git log)

git rebase -i HEAD~<n>
# eg. git rebase -i HEAD~3

4. Sync

Get the latest from the primary.

git checkout main
git pull

Rebase your Work on the latest main.

git checkout feature/my-work
git rebase -i main

Resolve conflicts and:

git add my/resolved/file.js

...

git rebase --continue

...until done.

If you get stuck:

git rebase --abort

To try again, or phone a friend, don't phone a friend until you've done this.

Bonus #1 - Code Review

Share your branch on the remote, go to Github/Gitlab, and create your pull request.

git push origin feature/my-work

Bonus #2 - Review Feedback

Use all previous workflows to apply updates to your branch from feedback in the pull request.

As you've already pushed your branch to the remote and re-tidied up, you must force-push a newly rebased & modified history to the remote.

Force pushing is dangerous as it will completely replace the remote copy of your branch with your local copy of your unit. If others have pushed to your remote branch, their commits will be lost. Before force-pushing, fetch and rebase your remote to collect any updates, just in case. As an added measure of protection, use the --force-with-lease option, which makes sure the remote is in the expected state.

git pull --rebase origin feature/my-work
git push --force-with-lease origin feature/my-work

Done

That's it. Use the merge button in the pull request to merge to the main, squash and rename commits as necessary, and delete the feature branch.