A Guide to Using Git DMZ Flow

Author

Brandon Bruno

Published

I've recently fallen in love with Git DMZ Flow - a Git workflow that utilizes forking instead of branching to manage code workstreams. I've found documentation on actually using Git DMZ Flow to be lacking, so I'm hoping to fix that with this article.

I originally wrote on this topic on the Perficient Sitecore blog. That article is a longer version of this with a little more theory and explanation. This version gets right to the point: code samples.

Understanding Git DMZ Flow

I recommend starting with a thorough read of Git DMZ Flow. This covers the core concepts very well, but doesn't detail the actual day-to-day usage that most developers will be familiar with.

Developers will generally follow this workflow between the upstream repo and their local fork:

Example Git DMZ workflow a developer would use.

Using Git DMZ Flow

Here's an example of the steps a developer would follow to get started, develop, and create pull requests using Git DMZ Flow.

Step 1: Create Fork and Clone Repo

Create a fork of the upstream repository on your platform of choice. In this case, I'm using GitHub:

Creating a fork on GitHub.

Next, clone your newly-forked remote repository to your local machine:

$ git clone https://github.com/bmbruno/SparkServer.MyFork.git

This is a one-time operation.

Step 2: Set Up Remote Repos

Each developer should ensure they have remotes set up for their fork and the upstream repo. To do this, add the upstream as a remote:

(master)
$ git remote add upstream https://github.com/bmbruno/SparkServer.git

This should be repeated for every fork you want to access. For example, add another developer's fork to review his pull requests:

(master)
$ git remote add johnny https://github.com/bmbruno/SparkServer.johnny.fork.git

Verify that you have the correct remotes set up:

(master)
$ git remote -v

Output:

origin     https://github.com/bmbruno/SparkServer.MyFork.git (fetch)
origin     https://github.com/bmbruno/SparkServer.MyFork.git (push)
upstream   https://github.com/bmbruno/SparkServer.git (fetch)
upstream   https://github.com/bmbruno/SparkServer.git (push)
johnny     https://github.com/bmbruno/SparkServer.johnny.fork.git
johnny     https://github.com/bmbruno/SparkServer.johnny.fork.git

Step 3: Keep Your master Branch In Sync

It is recommended that developers keep their fork's master branch in sync with the upstream master branch at a couple of regular intervals:

  • before creating any branches
  • before creating a PR

In either case, always fast-forward your sync to ensure a new merge commit isn't created and the history remains clean.

To fetch and merge into your master branch:

(master)
$ git fetch upstream
$ git merge upstream/master --ff-only

Step 4: Branch and Develop

Now you're ready to begin work on a feature or bug. Developers should create branches based on their updated master branch:

(master)
$ git checkout -b feature/my-work-branch

Step 5: Create a Pull Request

Merge conflicts should be fixed in the developer's fork before creating a PR.

Pull the latest master from upstream into the forked master branch:

(master)
$ git fetch upstream
$ git merge upstream/master --ff-only

You can consolidate the above commands into one step using pull:

(master)
$ git pull upstream master --ff-only

To keep your branch's history clean, developers should rebase master onto the feature branch:

(feature/my-work-branch)
$ git rebase master

Fix any merge conflicts that arise.

Finally, push your feature branch to your 'origin' remote to make it available on the server.

(feature/my-work-branch)
$ git push

If you haven't pushed the branch before, you may have to identify the remote:

(feature/my-work-branch)
$ git push --set-upstream origin feature/my-work-branch

That's it! Now you can create a pull request that should target the dmz branch of the upstream repository. With proper automation, the PR will complete after review and dmz will be automatically merged into upstream master.