Git for SVN Devs, Part 2: A Suggested Workflow

So you’ve moved to Git because all the cool kids are doing it. You’re still doing your old workflow, just with added complexity, and you’re wondering what all the hype is about.

There are lots of different ways of using Git. They all involve a lot of branches, because that is the best way to have lots of people working on the same code base without creating a giant mess. Let’s build a simple workflow for a team of 1-5 people, starting with a simple setup for single-dev teams and tweaking it until it’s enterprise-ready.

Master and Development

Most Git setups will have these two branches. master is the code that lives on your production server. development is the stuff that’s finished and will be included in the next scheduled release.

This is the setup for my one-person hobby projects. I commit new stuff directly to development (often unfinished), and when I’ve got a stable set of stuff I merge it into master and pull it onto the server.

Benefits: Your production code is separate from the new stuff. If you need to fix a bug urgently, you can do it on the master branch and pull that onto production, without simultaneously releasing your new features.

Drawbacks: Your development branch is still a dumping ground for everything that isn’t production-ready. As you add more devs it will become unstable and your team might fall back into the anti-pattern of not being allowed to commit anything just before the release.

Branch Per Feature

As above, but every feature (or improvement or bug fix) is developed in its own branch. Once it’s ready to go, its creator merges it into development or master as appropriate.

If you have to make a production bug fix, you make a branch off master. Give it a meaningful name, like bugfix-1234 (where 1234 is a ticket number) or bugfix-3.2.1 (where 3.2 is your release number and this is the first bug fix). Do your work in this branch, committing as many times as you like, and then merge it into master once you’re done.

For other work, you make a branch off development. Meaningful and consistent names are still very helpful. This is often just a ticket number (1234), or a ticket number with a brief description (1234-new-datatables). Once it’s been approved for the next release, it gets merged back into development.

Benefits: Half-finished code is not in your development branch. If devs are switching between tasks, they can commit what they’ve got without breaking things for others. Ditto if you want to transfer a half-finished task from one dev to another. Devs can check out each other’s completed features to test and review, or to demo to product owners.

Drawback: The review process is informal (a dev might ask a colleague to look at something before merging, but there’s nothing stopping them from skipping this step) and not particularly transparent (difficult to identify whether a task was reviewed, and by who). Useful feedback from reviews is only communicated between the reviewer and reviewee.

Pull Requests

As above, but when a dev has finished a task, they raise a pull request in GitHub to indicate that it is ready for review.

A pull request is an assertion that a piece of code is ready to be merged into development. The list of open pull requests can be seen in the GitHub UI. Senior devs can check this regularly and review the tasks that are waiting to be merged. They make comments on the pull requests which all devs on the team can see. For new features they will probably also want to check the code out and see it in action, but this may not be necessary for minor tweaks and bug fixes.

The dev addresses the reviewer’s comments, pushes their changes, and adds a note to the PR to say that they’ve fixed it. Once the reviewer is happy with the code, they click a button on GitHub and it gets merged into development.

Benefits: Review process becomes asynchronous (devs aren’t privately messaging each other for reviews) and transparent (because everybody can see what’s been said). New devs can learn a lot about the system and the team’s coding conventions by browsing open PRs. The archive of closed PRs doubles as a library of blueprints for future work, which can also be very helpful for juniors and newcomers.

Drawbacks: GitHub PR notification spam (but you can turn down your notification settings so that you only get emails about the stuff that’s relevant to you). Can lead to painful multi-round reviews where the dev deals with one reviewer’s feedback, but then gets more suggestions from another.

Automated Code Quality Checks

The leading Git providers have a range of tools to help prevent low-quality code from making it into your code base.

On GitHub this takes the form of GitHub Actions, which allows you to configure workflows which are triggered automatically by certain events. A common usage of these is to perform automated checks (such as running a linter or a set of unit tests) every time a new pull request is raised.

This is only scratching the surface of what you can do with Actions. There are almost 6000 actions available in the GitHub Marketplace, and a variety of other events you can trigger workflows on – you can even schedule them like cron jobs.

Benefits: Automatic linting saves reviewers from wasting their time pointing out basic style violations. Automatic test builds mean you can be confident that code going into the development branch won’t break anything – although of course this promise is only as good as your test coverage!

Drawbacks: Automated processes are not a substitute for human judgement.

Summary

Git can do a lot to solve common collaboration headaches. You don’t have to change everything about your workflow at once, but if you recognise any of the pain points above hopefully this guide will help you to address them.

Your team’s GitHub workflow should be reviewed regularly, as should the larger process of how a task goes from an idea in somebody’s brain to a completed, deployed feature.

Other Posts in This Series

This Week I Learned: 2020-10-25

  1. How to set up replication in OrientDB.
  2. I’ve been meaning to learn Docker for years, and a brand new Ubuntu install and a need to experiment with replication was the perfect opportunity. I found this video very helpful to get my sandbox OrientDB cluster up and running, although I’m sure there’s much more to explore.
  3. Microsoft Edge is coming to Linux. This feels like the scene in a teen movie where the popular kid starts pretending to be friends with the nerd so that they can betray their confidence later.
  4. A little about the Mongoose ODM JavaScript library and add-ons like restify-mongoose, from this great talk by Andrew Watkins of voluntarily.nz about the dependencies used in his project and how to choose a good library.
  5. How to boot from USB in GRUB after a minor mishap while trying to change the partition structure for my Ubuntu install.

Git for SVN Devs, Part 1: Why Switch?

Like many devs who’ve been round the block a few times, I got my first professional experience using SVN.

My first exposure to Git was at a place that was using it exactly like it was SVN, with one master branch that all the devs pushed to, and nobody was allowed to push for two days before a scheduled release in case they broke something. They’d switched because they knew Git was the cool thing that everybody raved about, but they got confused by the overly-detailed tutorials and the new jargon and never worked out how to use it to improve their workflow.

I Googled just enough to learn how to get my code into the master branch, understanding about 10% of what I read and liking even less. Why did I want a localised repository? How was this better than SVN when there were more steps required for me to do the “same thing”?

That was seven or eight years ago now. Since then I’ve worked on a huge variety of projects and seen the difference that a well-designed Git workflow can make to a team. I’ve recently dipped my toes back into a project using SVN and it’s helped to clarify the benefits in my mind.

SVN Devs are terrified of branches

Branches sound all fine and dandy until you need to sync things up again, and in SVN-land that usually seems to go to custard. It’s easy to lose half a day swearing at a bad merge … so they don’t. Everything happens on the trunk.

The first ever commit made by a rookie dev that breaks the build. The urgent bug fix for the production environment. Possibly the stuff somebody was in the middle of when they had to stop and do that urgent bug fix. The regular save-points for a major feature which isn’t ready for production yet. The stuff that’s supposed to go into the next release. The stuff that’s finished, but when you demo it to the business they don’t like it and don’t want it in the next release.

This works OK for a very small team, if everyone is communicating well and know what code they are allowed to commit when. It’s easy, and at first glance there’s no overhead.

As the team gets larger, you finish up with an almost constantly broken branch that makes your devs tear their hair out. They start updating as rarely as possible, and when they do there’s usually a mess of merge conflicts.

Comments, Comments Everywhere

It also leads to a proliferation of comment blocks. Old code gets commented out because devs aren’t confident about how to get it back if they need to revert in a hurry later. Recent code gets commented out by other devs because it’s got bugs and they can’t get their work done. New features live in if (false) blocks or comment blocks until they’re ready to go live.

Your team has to scroll through all of this commented-out stuff every time they scan the codebase. And it gradually rusts because the IDE doesn’t pick it up when you’re refactoring, so then when you do decide you need a relic from the past, it often needs resuscitation first anyway.

How Git Can Help

Git is definitely more complex than SVN. The learning curve to understand everything is huge (I’m nowhere near the top) but it’s not that hard to learn enough to manage a simple workflow in Git.

Branching and merging is easier in Git, so your devs will be more inclined to use branches. It’s not that hard to keep your production code separate from the stuff you plan to release next week, and your incomplete features aside in their own branch.

The major Git hosts (e.g. Github, GitLab, Bitbucket) all have sleek user interfaces that make it easy to explore the code base, review code before it’s merged into your main development branch, and travel back in time to see what changes were made when, by who. This helps with the cargo-cult commented-out code clutter – there’s another place to get that code back on the remote chance that you really do need it, and in the meantime it’s not cluttering up the source code.

A transparent code review process that happens before code makes it into the development branch can lead to big improvements in the quality and consistency of the code. Everyone can see the code that’s up for review and what’s been said about it, which helps to keep the common issues at the front of people’s minds. Newcomers can skim over the pull requests to get a quick idea of how things are formatted now (rather than 5 years ago when the class they’re working on was last changed) and to get a quick overview of how a new feature is put together.

There’s always going to be some disruption when you switch to something new, but the gains in long-term productivity mean that the change will quickly pay for itself.

Other Posts in this Series

This Week I Learned (2020-10-18)

  1. There’s a new kid on the web image format block. It’s called AVIF and it’s derived from the AV1 video format. I’m quite impressed with the size and quality of compressed images compared to other formats like JPEG.
  2. JavaScript’s Number.MIN_VALUE is actually the smallest possible non-negative float value, not the smallest (most negative) possible number.
  3. Chrome Dev Tools has an awesome screenshot tool as well as many other cool features I was already familiar with. And did you know that you can style console.log output?
  4. SQL Server for Linux is a thing. Probably not a thing I would recommend for a production app, but it will be useful for dev work for a project I’m working on where my app needs to connect to a standalone SQL Server instance on Azure.
  5. There is a new HTML element called <portal> in the works. It seems to be a new improved variation on the old <iframe>, and has interesting potential to replace the current fad for making everything a single-page app.

This Week I Learned (2020-10-11)

  1. PHPStorm has a quick definition lookup feature which pops up a window showing the source code definition of a symbol in your code when you press Ctrl + Shift + I. No more switching back to the mouse to Ctrl + Click and then losing my place!
  2. Imagine a world without targeted online advertising. I can’t be the only person who looked at a few articles about coronavirus and is now getting targeted by Southland wedding venues and cut-price tours of Italy. This Wired article explores how banning targeted ads might affect the world, from the quality of our journalism to election results.
  3. OrientDB is an open-source graph database implemented in Java. There’s a free official introduction course on Udemy which does a good job of explaining the concept of what a graph database is, although I think I’ve only grasped a fraction of the potential use cases so far. I hadn’t heard the terms “edge” and “vertex” since maths at uni so I’m glad that linear algebra paper finally came in handy!
  4. Flexbox Froggy is a fun little game to help you learn the CSS flexbox feature set. I’ve learned new properties, particularly order and flex-direction to adjust the order in which elements are displayed.
  5. A lot more about autofill and its behaviour in different browsers. These days the autocomplete property has more potential values than just on/off, and if you specify “new-password” as the value some browsers (e.g. Firefox) will help the user to generate a strong password.