Skip to content

Instantly share code, notes, and snippets.

@andrewsosa
Last active July 2, 2018 18:06
Show Gist options
  • Save andrewsosa/77090b96d61b849c3fc3ecb974b6a568 to your computer and use it in GitHub Desktop.
Save andrewsosa/77090b96d61b849c3fc3ecb974b6a568 to your computer and use it in GitHub Desktop.
Recommended Git workflow for Open Source/Multi-Contributor Projects

Recommended Workflow

Good for Open Source/Multi-contributor projects

Table of contents:
  1. Overview
  2. Step Details
  3. Important Details/Warnings
Key terms
  • Upstream: The original, organization-based repo (e.g. fsu-acm/contest-suite).
  • Origin: The remote Github repository of one person (e.g. andrewsosa/contest-suite).
  • Fork: Creating a copy of a repository while maintaining association.
  • Pull Request: Github-specific feature for merging accross Github repositories

Overview

The steps of the process are as follows:

  1. Fork the Upstream
  2. Create a working branch
  3. Commit your changes.
  4. Pull Request your fork to the upstream
  5. Update your master to the upstream's master
  6. goto 2

The goal of this workflow is to create a cyclical flow of changes. Each contributor's own master branch represents a mirror of the upstream's, which is used for keeping the working versions up to date in the event the upstream changes.

Details

1. Fork the Upstream

When working on open-source/multi-contributor projects, each project member should have their own copy of the repository associated with their Github account. The only exception would be if two people are working very closely on implementing the same changes, in which case they can work off one of their forks.

2. Create working branch

These branches are typically associated with a specfic additional feature, but in cases where there's a significant rewrite of the project, the entire rewrite can be on one branch. These feature branches should be specifically named, such as "add-admin-account", "remove-user-profile", "patch-captization-bug".

Do not work on your master branch.

3. Make Your Changes

Make your commits. Commits should typically be as close to atomic as possible, i.e. you want to commit your changes in the smallest increments that logically make sense. If you add some new files, that's a commit. If you make a change specific to one file, that's a commit. If you change a whole bunch of files at once, commit them togther. Commit's don't need to each be a working copy of the project, but should represent incremental steps in development. However, the final commit before merging back into the upstream should be functional.

Also, do not work on the master branch. You want to always have a mirror to the upstream. If the upstream master changes while you are developing, you can take the following steps to make sure you have an up-to-date copy to work on:

  1. Fast forward your master branch to the upstream's master.
  2. Rebase your working branch onto your updated master.

4. Create a Pull Request to Upstream/master

This is how your changes get incorporated into the project. You can create your pull request, which will try and merge on Github the changes on your change branch back into the upstream master. Make sure you've pushed your changes to your own repo first.

Typically during the PR process any continuous integration (CI) will run on your pull request, so it will check for things like passing tests, making sure the build runs, or the code style matches project standards.

Finally, if you make more commits to your development branch, your Pull Request will automatically be updated to include those changes.

Also, request reviewers from fellow maintainers -- code review is a real thing, and it really does matter.

5. Update Your Master

Once your changes from the PR are accepted into the upstream master branch, you can update your fork's master branch. Do not merge your development branch into your master locally. This will screw up the Git tree and create havok for everyone.

Usually you can just delete your working branch, or you when you perform the pull Git will automatically recognize that the branch was merged.

Now, you don't need to create a new fork every time. You already have a copy of the repo, and new development branches can come from your updated master branch.

Key Details

These are the most important things to watch out for, as touched on earlier in this guide:

Do not work on the master branch

This always seems like a minor detail, but it has the highest potential to wreck the commit graph for the whole project. Having a perfect mirror of the upstream master is absolutely critical for staying up-to-date with other contributor's changes.

Do not merge your development branch into your master locally.

Again, this is another great way to screw up the commit graph for the whole project. If Github is merging the branches, that creates a commit. If you merge the branches, that creates another commit. These commits are not the same commits, and everyone will see what you've done.

You don't need to create a new fork every time.

This one is a bit more obvious -- once you have a copy of the repository, you don't need another one. Heck, Github won't let you make another one without deleting the one you already have. Just make sure you update your master.

Keep your master branch up to date

Basically, if the project gets new changes while you're working and you don't update your copy to have these new changes, this will cause merge conflicts when you try and reincorporate the changes. Rebase is hard, but you need to learn how to use it.

Good IDE tools (IDEA products, VSCode, Atom) have good extensions to make things easier on fixing merge conflicts which may arise from Rebases.

Updating the upstream master directly

Sort version: Don't do this.

Long version: If you're the primary project maintainer, and you know what you're doing, and you're only making small changes like updating the readme, maybe it's okay to commit directly. Just make sure everyone on the project knows to update their master before doing anything. If you're actually making real changes, make a branch you dummy.

Conclusion

The main thing is that communication is key. Follow the guidelines, make sure your fellow contributors follow them, and make sure you're communicating with your contributors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment