Yes, baseball season is winding down, but I’m always nostalgic for an evening with 45000 of my closest friends at Busch Stadium here in St Louis. But enough about baseball-I’m not here to offer you overpriced ballpark food and beverages, but rather, some pro tips on using git for the fantastic value price of free! In my last article I covered how to contribute to Github projects, singling out the f5-common-python library I’m contributing to. In this article, I will cover some of the lessons I’ve learned over the past couple of months working with git.

Keep your development branch pristine and synchronized

In working with the f5-common-python library we host on Github, there are many developers with merges occurring frequently. I keep my local development branch updated with the upstream master  whenever I get a notification that the master has been updated. I also don’t touch this branch locally, that way I can use it to compare with from my feature branches and know where my code is in relation to master.

git fetch upstream
git rebase upstream/development development

Use the development branch as the foundation of new branches

Unless there is a need for my newly developed features to be included in another feature before an anticipated merge to master, I always try to create my new branches from the pristine development branch. This makes it simple to merge later, going a long way to avoid potential branch conflicts.

git checkout development
git checkout -b new_branch

But if you need those features...

Sometimes you can’t wait for a merge, so you base your next feature on work from your previous feature. To do this, you can just create a new branch from your current development branch.

# checkout the branch you need to base your new branch on
git fetch upstream
git rebase upstream/development prerequisite_branch
git checkout prerequisite_branch
git checkout -b new_branch

Which as indicated, might lead to conflicts!

If you have two disparate branches and you try to rebase, git won’t know in some cases which lines to maintain for the current head position, so a file or files will be created that allows you to edit and decide what to do. Don’t panic! It can be a little intimidating at first, but git status is your friend. You’ll want to edit each file with conflicts, resolve those conflicts, and then do a git add for those files.

git status
vi $file # where $file is the file list in the status message
git add $file
# Repeat until all conflicts resolved

Stash your changes if you need to checkout another branch

If you aren’t ready to commit changes in the current branch you are working on, but you need to checkout another branch to do some work, you can stash them and recover them later. Each stash will have an identifier and it helps to give it a helpful message for when you want to re-apply your changes.

# currently working in branch_A
git stash save ‘some descriptive message to stash’
git checkout other_branch
# do work to other_branch and then stash or commit
# go back to branch_A
git checkout branch_A
# review stashes
git stash list
# response: stash@{0}: On branch_A: some descriptive message to stash
# apply those changes
git stash apply stash@{0}

Rolling back the ch-ch-changes

Sometimes you get stuck and can’t figure out why things are messed up. I’ve been there. This is where I’ll just cut my losses and do a hard reset back to a particular commit, effectively rolling back to a known “good” place. Note: if you've already pushed to your origin fork on Github, you might need to do a force push at this point.

git reset --hard $commit_number # where $commit_number is the git commit number you wish to restore

Quick checkout for a pull request

Hat tip to Tim Rupp for this one. While working on different features, one of us might want to share work with each other for validation or questions/comments. If a pull request has been created on Github, you can grab it within the framework of your forked project (assuming you have the upstream properly configured) by adding this fancy alias to your git local profile settings. Then from your command line you can do a quick checkout with git copr 458 (where 458 is a pull request in the upstream project.) That will create a branch in your local repository called pr-458. Cool stuff and wildly useful for rapid collaboration.

    copr = !sh -c 'git fetch upstream pull/$1/head:pr-$1 && git checkout pr-$1' –

What else?

So that’s my quick list of git tricks. What have you learned in your git journey you’d like to share with the community?