Skip to content

Resolve git workflow

ClemsonRSRG edited this page Sep 28, 2012 · 8 revisions

We have a half dozen people actively making changes to our code repository. This creates the necessity for version control.

Unfortunately, in such a situation, with people making concurrent changes to the code base, nothing is going to allow the process of keeping everything up-to-date and working to be simple.

This is why we establish a workflow. Since the process can't be as simple as we like, we at least make it consistent, so that you can master it once. This also ensures that everyone has basic competency in the workflow, thus ensuring that any problems we run into are the same sorts of problems over and over again, maximizing the likelihood that someone will know how to fix your problem.

Read this document carefully, and remember that I'm not trying to make it complicated for you--we're just doing something inherently complicated, and so there's some overhead that comes along with that. Any complexity that isn't on you doesn't "disappear", it would just be on somebody else instead.

Overview

This section is just trying to give you the big picture. We'll go over the commands in a bit.

We have a git repository on github.com called ClemsonRSRG/RESOLVE (here's a link). This is the upstream repository, because it is the repository from which, ultimately, all changes start and trickle down to all the forks and clones.

Each developer forks this repository on github. So, for example, my fork is called hamptonsmith/RESOLVE (here's another link). Note that "fork" is a github term, not a git term. Behind the scenes this is a git clone operation.

My developer fork affords me some nice things:

  • I can use it to sync my work between multiple computers without cluttering ClemsonRSRG/RESOLVE.
  • I can use it as a staging area from which others can inspect, pull down, and run my code so we can talk about it before deciding if it's the direction we want to take

Each developer then locally clones either their developer fork or ClemsonRSRG/RESOLVE (doesn't matter which, since at this point they're exactly the same. For a number of small convenience reasons, I prefer to clone ClemsonRSRG/RESOLVE). This puts a copy of the entire repository and all its history locally on your computer. For purposes of clarity and discussion, we'll call this local/RESOLVE.

The developer is now free to make any changes because local/RESOLVE is private. All operations are fast and easy because the entire repository and all history is local.

To start work, she branches from local/RESOLVE's branch master, making a kind of branch called a feature branch, and giving it a name that reflects what it's trying to accomplish. Maybe, proverGUI. Branching in git is a cheap, easy operation, so do it as often as you like.

This is a "feature branch" because it is a short-lived branch for an individual thing the developer is implementing. This sort of behavior will make your life much easier--unrelated changes are on different branches and thus you're never slowed down because a change in the VCGenerator conflicts with some upstream change while you're working on the ProofChecker.

The developer is never making changes to master, except to pull new changes that may have occurred on ClemsonRSRG/RESOLVE since she cloneed. This means she always has the current, untouched RESOLVE code locally, which is very useful.

The developer does any work she wants to do, making one or more commits to her feature branch, which takes snapshots of the directory structure and saves them to local/RESOLVE. Note that, unlike SVN, commit does not move any code to any other computer. It simply adds a new snapshot to your local history. "The code looked like this at this time."

As she's developing on her branch, it's possible that other changes are being made in parallel on ClemsonRSRG/RESOLVE. Rather than work for many days and then make one big merge when she's ready to get her code back into the upstream repository, she makes many small merges as she works--preferably at least once per day. She pulls master down from ClemsonRSRG/RESOLVE into her local master, then performs a special kind of merge called rebase to merge the code from her local master into her feature branch.

Because she does this daily, she still remembers what all her changes from yesterday do and why they're there. If there's a conflict, it's easy to track down the person who changed the code in parallel and they also will remember what the changes they made yesterday did and why they're there, and they can chat about how to resolve the conflict.

When she's satisfied with her work, she pushes her code to her developer fork. This provides a place for other developers to look at the code and perform code review. (For small changes, this is mostly just a place for the code to sit while a pull request is pending--see the next paragraph.)

When she's ready to officially move her changes into ClemsonRSRG/RESOLVE, she logs onto github, selects her branch and performs a pull request, which will alert the other developers that someone wants to move code into the upstream repository.

Another developer reviews the change and either submits comments to request changes, or merges the code in. The other developer never has to do any manual merging because the first developer has been keeping up to date with the code on a daily basis. This means that the programmer who wrote the code is the one doing the merging, which makes the most sense.

While she's waiting for her pull request to go through, she looks to see if there are any other pull requests pending (developers should never merge their own pull requests!). If so, she looks them over and submits her own comments or performs the merge if everything looks good.

When her original pull request goes through, the changes she made are now on master in ClemsonRSRG/Resolve. The next time each developer pulls the code down (which is frequently), they will get the new changes. The developer who made the change doesn't need to do anything special to move the changes from her local branch to her local master, because those changes will simply "appear" the next time she pulls from ClemsonRSRG/Resolve.

The basic process looks like this: