Automate Your Git Workflow with GitPython

Intro (skippable score: 9/10)

Recently I worked on a project to automate a git workflow. Specifically for any local git repository (whose origin points to some project on GitHub), we wanted to script-ify the following: create a new branch off prod, make some commits, push these, and make a pull request.

This sounded like a simple enough task (and it turned out so thanks to GitPython), but it took quite a few Stack Overflow posts and trial-and-error to put the whole script together. So I’m sharing this in hopes of earning someone out there a well-deserved coffee break.

Actual Steps (skippable score: 1/10)

Oh by the way we are doing this in Python3 (in case GitPython wasn’t a clear enough giveaway) so make sure that’s installed, and:

Don’t forget to import git at the top of your script (sidenote: if you’ve also wondered why the package names (GitPython) are sometimes different from their import counterparts (git), here are some insights from wonderful internet people).

Grab your repo with the latest meta-data from origin:

Create a local branch from latest prod:

Make your changes (for our example here we’ll create a txt file):

Commit them:

Push this branch to origin along with your new commit(s):

Construct a url that leads us to a PR-creation page (this method is hacky but safe for as long as GitHub keeps this convention):

There are other ways to create a pull request as well, one of which is to use the PyGithub library to authenticate with a GitHub token and publish a pull request on behalf of whichever account this token belongs to. I did not experiment with this option as it would introduce more steps than simply clicking on a link.

Closing Remarks (skippable score: 8/10)

The full GitPython documentation lives here, in which the tutorial section contains extensive information with examples like how to create a repo from scratch, but I found it a little difficult to navigate for this particular use case.

One trick that might not be immediately obvious is that many git commands can be achieved with GitPython in the format of repo.git.<the_command_you_need> (for example, git diff -> repo.git.diff()).

If upon trying these out you spot any issues or find a better solution, please drop a comment below and we can edit this/ toss this away accordingly :)