If you’re a solo developer working on your own projects your Git workflow is usually simple: You work on the main (or master) branch all day every day.
You probably know that professional developer teams don't work like this. Multiple devs all committing to the main branch can quickly become chaotic. And it’s likely that unreviewed or untested code makes it into production eventually. Danger!
Professional teams use processes and workflows to prevent this from happening. And the most common Git workflow used in developer teams (at least from my experience):
Trunk-Based Development (or more correctly Scaled Trunk-Based Development).
If your goal is to find a job as a professional developer I highly recommend getting used to this workflow upfront. The more you know how to work like a professional the less you’ll be overwhelmed on your first job.
I promise: it’s not very difficult if you know the basics of Git. But there is a lot of glossary around it that might confuse you at first.
Watch the video below to see me walk through one cycle of the workflow. Below the video you can find instruction on how to set up branch protection in your GitHub repository to enforce this workflow and a detailed walkthrough based on screenshots.
This series of articles and the application I'm building are part of my upcoming React Job Simulator. Build a project hands-on like a professional team and gain job-like experience.
If this is all sounds like Gibberish, no worries. Have a look at my free course where you can learn and practice this workflow.
I always found the name Pull Request on GitHub confusing. GitLab calls it a Merge Request which is much more descriptive. Basically, a Pull Request is a way to ask for permission to merge your code into the main branch:
“Hey team, can somebody have a look at this code and tell me if it’s any good? I’d like to get it into the main branch so our users can benefit from it.”
You can think of a Pull Request as a feature on top of a Git branch that allows you to get feedback from your teammates. And as mentioned it also allows you to automatically run checks and tests on your code changes before they go to the main branch.
To summarize, Pull Requests are
Processes and workflows are great. But people are lazy and look for workarounds. So ideally we want to force everyone on the team to use Pull Requests instead of committing directly to the main branch.
Luckily GitHub has our back with a feature called “branch protection”. To protect the main branch open your repository’s settings on GitHub, select “Branches” in the left menu, and click on the “Add rule” button.
A few notes about the selected rules:
If a developer now creates a commit on the main branch and tries to push it they will see an error message.
git checkout -b migrate-to-styled-components
Now we write our code, commit and push it to the remote repository on GitHub.
git commit -m "Migrate home page to styled-components"git push origin migrate-to-styled-components
On GitHub, you should now see a banner to create a Pull Request.
Once you click the button you see a form where you can enter a title and description. Next click the “Create Pull Request” button.
Congrats, you opened your first Pull Request! This is what you should see now:
Did you note the status checks at the bottom of the PR?
This is a really handy feature. You can run scripts like npm run lint
or npm run test
within your Pull Requests to decrease the risk of introducing bugs. This is called a Continuous Integration pipeline. I’ll leave it as a cliffhanger for tomorrow’s article. If you can’t wait you can already watch me set it up in the video.
In a real-world team, your code is typically reviewed by at least one teammate. This again prevents bugs and helps keep the codebase clean and consistent. A Pull Request is also a great way of discussing your code in case you’re stuck.
So let’s switch to another account with access to the repository. Here is how our imaginary teammate would review your code.
Our teammate can add comments to the code.
Finally, they submit the review.
As the author of the Pull Request, we can now see the comments.
We have two options now: we can update our code according to the comments or start a discussion.
To adjust our code we simply head back to our local machine, change the code, commit and push it. You can see the new commit below the review comments. You can also add a comment and resolve the conversation.
Finally, you can request a new review:
Once your teammate is pleased they can approve your Pull Request by submitting a review. They might add a useless yet affirmative emoji comment to make you happy.
Finally, it’s time to merge our Pull Request. Now our code changes will be added to the main branch.
Remember that we set the “Require linear history” option in our branch protection rules? That’s why we see a “Squash and merge” button instead of a simple “Merge” button by default.
Let’s see what happens when we push the button:
And once we press the confirmation button we’re all set.
I didn’t explain yet what the “Squash and merge” button does, right? The Pull Request (or our Git branch) contained multiple commits:
When we look at the commit history of our main branch we don’t see these commits anymore. Instead, there’s only a single commit that points to the Pull Request (via the link #6
):
All the commits of our original branch have been squashed into a single commit. The benefit here is that you don’t need to keep the commits in the Pull Request super tidy. For example, commits that are simple fixes during the review process like “Remove unused class name” don’t really need to show up in the history of the main branch.
As the last step (that’s easy to forget) we sync our local main branch with the remote repository. Since the merge happened on GitHub our local machine doesn’t know about these changes in the main branch yet.
git pull origin main
When we work in a team of developers we should actually do this every time we start working on a new branch.
In this article you learned how to set up a GitHub repository with branch protection to enforce a popular Git workflow called Trunk-Based Development. By now, I hope you're less intimidated by Git & GitHub thanks to the detailed walkthrough.