Git for SVN Devs, Part 3: Recipes

The two major differences between Git and SVN are that it is a distributed VCS (meaning that you have your own local repository as well as the one on GitHub) and the way its internal structure makes merging branches easier.

This post is primarily focused on recipes for getting the latest code into your local repository and keeping it in sync with GitHub. The next post will explain how to get your completed code back into the development branch and provide some other miscellaneous tips.

Why Do I Need Two Repositories?

Personally speaking, I prefer Git mainly for the ease of branching. If your team’s workflow is designed so that you don’t finish up with multiple devs working on the same branch, I can’t think of any particularly compelling bonus that having a local repo gives you. Sure, it enables you to work without the internet if you want to – but how much work are you going to get done without your esteemed colleagues Google and Stack Overflow?

The good news is that having that local repo doesn’t introduce a lot of overhead into the way I work day-to-day. You can treat Git more or less like SVN from that perspective, and just push every commit as soon as you make it.

And on that note … on to the recipes! In this section I’ll cover what you need to know to get the right branch of code in front of you at the right time. Stay tuned for part 4 where I explain how to commit your code and then how it finds its way back into the development branch.

Initial checkout

Find the URL of your project in GitHub. Open a terminal, switch to the parent directory that your projects live in, and …

git clone https://github.com/{myorg}/{myproject}.git

Fetching Remote Branches

Your local repository keeps metadata about all of the branches that are in the remote repository. This will get stale as branches are created and deleted on the remote. A “fetch” updates that list of branches. If you ever want to checkout a remote branch but you can’t find it, a fetch should set you right.

PHPSotrm’s project Git menu

PHPStorm: Right-click on project -> Git -> Repository -> Fetch

Terminal: git fetch

Seeing Available Branches

When closed, the PHPStorm branch switcher shows the name of the current branch

PHPStorm has a handy-dandy branch switcher in the bottom right-hand corner. This will show you a list of all of the remote and local branches.

Clicking on a branch name will give you a menu of options for that branch

Or if you’d rather use the terminal:

See Local branches: git branch or git branch -l

See Remote branches: git branch -r

See All branches (local and remote): git branch -a

The PHPStorm branch switcher handily shows which remote branch each local branch is “tracking”. If you want to see something similar in the terminal, it’s included in the output of git branch -vv.

See what branch I’m on

The current local branch is highlighted and displayed with an asterisk in the output from git branch. In PHPStorm, it’s displayed in the status bar, where you click to open the branch switcher.

Checkout a Remote Branch

If you want to work with a branch locally and you don’t already have it in your repo, you’ll need to check it out from its remote source. In most scenarios there is only one remote, called origin, which is the GitHub repository. You want to create and checkout a local branch which is tracking the origin branch.

PHPStorm: Click on the remote branch in the bottom right-hand branch switcher, and choose “Checkout as new local branch”.

Terminal: git checkout {branchname} origin/{branchname}

With the current version of Git you can skip the second argument if you want your local branch to have the same name as the remote branch, e.g. you can just say git checkout {branchname}. If Git can’t find a local branch with that name, it will look for a remote branch that matches and create a local branch with the same name.

Checkout a Local Branch

The process is very similar if you already have a local branch that you want to checkout. Just choose it from PHPStorm’s branch switcher, or from the terminal:

git checkout {branchname}

Create a new branch

When you create a new branch, the local branch that you already have checked out becomes its “parent”, if you will. Always make sure you have the right branch checked out first, and that it’s up-to-date with the remote if appropriate. Let’s consider a typical scenario where you’re going to start a new feature, so you want a new branch off development.

PHPStorm: checkout the development branch. Pull remote changes from the remote tracking branch (origin/development) by right-clicking on the project and choosing Git -> Repository -> Pull. Now open the branch switcher and choose New Branch (the item right at the top).

The terminal equivalent is:

git checkout development

git pull

git branch -b {newbranchname}

Your branch will only exist in your local repository at this stage – I’ll talk about how to push it to the origin in the next part.

Merge origin into my branch

Your local development branch will get out of date very quickly as new features get merged into the origin. You can update it by switching to the branch and then running git pull in the terminal, or right-clicking on the project and choosing Git -> Repository -> Pull.

Keeping a Feature Branch Up to Date

You should keep your feature branches up to date with development, so that as you develop you are working against the latest state of the code base.

I really prefer to do this in my IDE, as I like to have a UI to help me resolve any conflicts that might arise. In PHPStorm, checkout your feature branch, then open the branch switcher, click on the remote development branch, and choose Merge into Current.

If you’d really rather do it in the terminal, the equivalent is:

git merge origin/development

Deleting local branches

First switch to a different branch – you can’t delete a branch that you’ve currently checked out.

Then either git branch -d {branchname} or in PHPStorm open the branch switcher, click on your local branch, and choose Delete.

This won’t delete the remote tracking branch. That’s a topic for next time…

Pruning Orphaned Branches

After you’ve been working on a project for a while, you are likely to accumulate an impressive collection of orphaned local branches. These are branches that you built a feature in, where that feature has now been merged into development and the remote branch has been deleted.

Output of git branch -vv. “newbranch” is currently checked out. The “katedemo” branch is orphaned.

Personally I just delete them one at a time in the PHPStorm branch switcher every now and then – it’s a nice quick thing I can do while I’m waiting for unit tests to run or for something to download. However, I know that most devs hate doing repetitive work like this and would rather automate it.

Git doesn’t provide a great built-in way to remove the orphaned branches for you. There are a lot of sample scripts on Stack Overflow, and the safest strategy seems to be to check for the “:gone” string appearing in the output from git branch -vv. This will protect any other local branches which have never been pushed to the remote from being nuked as well.

Other Posts in This Series