By Corey Quinn — Senior Technical Consultant
Earlier last week, the fine folks from SaltStack conducted on-site training for us at Taos. For those who are unaware, Salt is a remote execution/configuration management system written in Python, and a project to which I’ve been a contributor for several years.
As often happens during such training, someone asked a question about how to achieve a certain goal. The answer was “that’s a good idea; we can’t do it yet, but patches are welcome!”
Fast-forward twelve hours.
At 3 AM the following morning I received an email from a class attendee with a patch that neatly solved the problem. “The code was easy– but how do I get this accepted into Salt?”
So without further ado, allow me to present a crash course in git workflow for submission to projects on Github. Note that every project is slightly different, so these steps may not map exactly to a given project’s workflow. I’ll endeavor to point out these edge cases as they arise.
It starts with forking the upstream repository. Visit https://github.com/saltstack/salt, sign in (taking care to create an account if you don’t have one already) and hit the “Fork” button in the upper right.
At this point, you’ll want to set up your system to use git; details on this are available athttps://docs.github.com/en/github/getting-started-with-github/set-up-git. Be sure to set up anssh keypair as well.
At this point, you’ll want to check out your fork of Salt onto your local system. Since my username on Github is KB1JWQ, I would simply:

When working on a new feature, it makes the most sense to work in a feature branch. This way, you can sanely work on multiple features concurrently if inspiration strikes. In this example, I’ll update a bit of the documentation to reflect a change I made to the Salt installation process on OS X.

At this point, I’m working on the “docfix” branch, as can be shown:

(Note that Salt’s upstream branch is called “develop”, as opposed to the more frequently encountered “master” for most projects.)
At this point I’ll go ahead and make some changes, committing after each one. Soon, I’m pretty happy with my changes, and “git log” looks like this:

I’m pretty happy with this, but as far as the upstream project is concerned, I’m only fixing one issue; they don’t need to see the “grizzly” details. At this point I’ll squash my three commits into one:

This uses git’s rebase command. The -i flag indicates I want to do it interactively, and HEAD~3 states I want it to operate from the current latest commit (called HEAD) to the three most recent commits. This drops me into my editor, where I see:

I save and quit, at which point git fires up a new editor session:

I edit this file to simply contain the first commit message and save it.
Now git log shows:

At this point, I can “git push origin docfix”, and git will push my local changes back to my fork on Github.
At this point, if I visit my fork on Github in my web browser, it will let me know that I can submit a pull request. I include a descriptive title, and then hit Send Pull Request.
At this point, the clock is ticking. If more than 45 seconds elapse without the pull request being accepted upstream, this means that the upstream developers are being lazy. The correct solution here is to join #salt on irc.freenode.net and loudly berate them for this. What’s the fun in contributing to open source projects if you can’t be belligerent about it?
Going forward, you can continue to edit on your fork, but updating it requires a slightly different workflow than a simple “git pull.”
At this point, your fork is updated locally (git push to your fork will update it on Github)
Ideally, this has been somewhat educational. Feel free to reach out to me either here in the comments or on irc.freenode.net (my username is Corey).