Git: Previewing Multiple Branches in a Single Environment

One of the most difficult aspects of web development has little to do with code: it's called workflow management--and it can mean the difference between hitting Go-Live and adding days or weeks to a project. Things can turn uggly quickly when a finite number of development environments come to odds with exponential requests for code changes. When things get ugly like this, though, Git shines not just as a version control system but as a workflow management tool.

Before I dive hard into the meat of this post, let's get some basic assumptions out of the way--I'm gonna assume that:

  1. You're not entirely new to workflow management
  2. You've got a basic understanding of Git and branches
  3. You've got a little experience with environments

Lastly, I'm gonna assume that this isn't the first time this technique has been employed or written about on the internet--it's probably a no-brainer for more experienced Git users. I have a feeling, though, that a lot of devs (myself included) invest so much of their bandwidth on work that workflow takes a back seat. This post is for them.

Background

I usually work with a Production, Staging and Development environment. Additionally, I run a Localhost environment, and have even been known to rely on Virtual environments, such as the one I recently setup for Drupal 9 testing. I follow a couple of basic principles in my workflow: the master branch is kept as clean as possible so that it can be pushed to Production at any given time. I branch out for projects requiring code changes and, due to client needs, often find that Staging is really just another environment for development (as opposed to being a QA/proofing ground); I avoid relying on it solely for development (I try to keep it clean enough to drop a production database into whenever necessary), but sometimes there's no way around it. It can be a non-traditional workflow at times, but given the pace of code changes on my client's site, locking Stage into a proofing ground is often counter productive.

There are times when I will get absolutely battered with code-change requests, often with no clear timeline between development and go-live. This means I've been known to juggle multiple branches in either Development or Staging. Beyond this, often there are multiple stakeholders who will need to rigorously proof and vet changes; some of those changes are subject to strictly enforced government standards. With no single body of proofers, I can wind up with code sitting in one environment or the other while local bureaucracy and revisions play out.

Proofing More than One Branch in a Single Environment

Inevitably this leads to a workflow management conundrum: what do you do when you have multiple stakeholders looking to proof code changes on multiple branches, and only one environment in which to do it? You could ask them to take turns--yes--and this may be the more common answer. I prefer to accommodate, however, and it's actually not difficult to do.

I'll illustrate with a hypothetical that shouldn't be difficult too follow.

  • Let's say I've got some code changes tied to a branch called "bam-update";
  • I've also got some code changes on a branch called "mobile-review2";
  • I don't know when either of these will go to production so I can't simply merge one into the other--they need to stay separate.
  • All I need to do is create a third branch and merge both of these into it. We'll call this third branch "merge-alpha"; this is the branch I'll point my proofing environment to, allowing respective stakeholders to view both branches at the same time.

It seems like a no-brainer, but it took me a surprisingly long time to realize this was a perfectly valid solution. Here's what that would look like when visualized:

visualizing multiple branches merged into a single branch
GitKraken is the boss!

The branches stakeholders need to preview are visualized in Pruple and Blue; the branch sharing their respective code changes is visualized in Teal. The shared branch can come out of either of the branches you intend to share in it; it also could have come out of master, but it doesn't really matter. The great thing about this is that you can continue development on either of the two original branches and just merge them into the shared (in this case, Teal) branch whenever you need to. If you reach a point that it's time to go live with either of the branches, you can just merge them into master and delete the shared branch as necessary.

In my case, I've called my shared branch "merge-alpha" (in case I need to create a "merge-beta" for another environment), but in theory, you could make this shared branch a permanent part of your workflow, much the way master is traditionally used. Traditionally, your various code branches converge on master before moving to Production. There's no reason you couldn't have a dedicated branch like this for your Development environment: a master-dev. I'm literally throwing that out as I work my way through this post, so it probably needs deeper consideration, but it might be a viable solution for anyone struggling to meet the demands of multiple stakeholders/proofers.

Update: After-Notes and a Plug for GitKraken

I ran with that master-dev idea and have been using it for a while now. Here's my biggest take-away: if you intend to use the the shared branch as a means of verifying/checking each change to a branch that converges on it, you won't enjoy the extra commits and pushes necessary to review changes. The best application, then, is to point one environment to the shared branch and another environment (i.e., your localhost) to the branch that converges on it--that way you can preview without having to merge branches. Otherwise, for command line junkies, the extra steps are particularly burdensome.

You'll also want to keep in mind that you may hit merge-conflicts a lot more often if you're merging multiple branches into the shared branch with frequency. I was never a fan of resolving merge conflicts with the command line (just another set of commands to remember), and I've seen devs literally hit the bottle mid-day due to failed merges.

Both of these issues, merge-conflicts and extra steps in the workflow, can be mitigated by having the right tools. I've been using GitKraken for quite a while (no affiliation whatsoever), and it really is my favorite tool for dealing with Git. If you've got a bunch of commits, pushes and merges to make, it'll get it done faster in GitKraken than with the command line. And, for merge-conflicts alone, the investment in the Pro version is more than worth it. There are likely other good tools out there, but GitKraken certainly has the most intuitive merge-tool out of anything I've used; worth a look.