Posts tagged with “Source Control”
At Viddler, we’re now using Git for projects, and it’s going really well so far. While we haven’t figured out the perfect workflow just yet, we’re doing some things I really like, and one of them is treating branches like patches.
Often, people think of Git branches as a full copy of the parent branch, but it’s better to treat them as a simple collection of new commits, to be applied to the parent branch later. This might not seem too revolutionary, but this small change in thinking can really improve your workflow.
For example, at Viddler we use Trac to manage tickets, and in Git. For each ticket in Trac, we create a branch, called something like
3241-fix-embed-codes. We have two permanent branches:
dev, which reflects current development, and
master, which is considered always production-ready. So,
master are going to have different code to reflect their reflective stability. To get started with a fix, we first create a feature branch from
git checkout -b 3241-fix-embed-codes master
This simply creates a new branch of
3241-fix-embed-codes and checks it out. When the ticket is completed and the code has been committed, the patch thinking really comes into play. Since this now needs to be tested in the
dev environment, the branch first gets applied to the
git checkout dev git merge —no-ff 3241-fix-embed-codes
—no-ff option on
git merge is important for this patch mindset: it creates a separate commit for the merge itself, which allows you to
git revert the entire thing (if necessary), rather than having to undo each individual commit within it.
Once we’ve decided this fix is read for production, it’s time to move the code over to
master. Without the patch mindset, you might consider merging
master, but that means you’d be copying anything that’s applied to
dev, some of which might not yet be ready. When you think of your feature branch as a patch, however, it’s easy to only apply the one you need. To apply this patch to
master, just use a similar method as before:
git checkout master git merge --no-ff 3241-fix-embed-codes
Now you’ve only moved the safe commits over, leaving any buggy code safely in
This method may seem obvious, but the mindset has really changed the way I use Git, and I think it makes it a much more powerful tool, especially when you’re working across multiple environments (like production and staging). I’ve skipped over some additional considerations, like merging
dev into your feature branch, but those are topics for a future post.
A few months ago, I started investigating Git, and I fell in love with how much easier it made managing my code. I’m managing the source code to this site with Git, and along the way I’ve come up with a pretty good workflow for myself. The basic steps are:
Let’s go through each one to see how it all works together.
With SVN, I found myself hating branching–it was always a complicated procedure, and I could never remember how to do it. In Git it’s as easy as
git checkout -b <branch-name>, and you’re ready to go. Once you have a branch, you can modify it however you want, and you don’t have to worry about interfering with the master branch. In order to keep your master branch bug free, commit only to branches, not to master itself.
In addition to creating new branches for major features, I always have a few branches around that I pop into for certain things:
- “design” - any changes I want to make to the design go here
- “optimize” - optimizations to the site
- “bugfixes” - a place to work on minor bugfixes
Having these branches allows me to make small fixes to the site, and if it turns out it’s more than just a small fix, it doesn’t interfere with anything else.
In the Subversion world, it’s a pretty common practice to make very large commits, consisting of many changes. With Git, you should constantly be committing. By making many commits, you make it easier to find bugs you may have introduced, and it makes it a lot easier to track your progress. If you don’t like the thought of wading through long lists of commits in your logs, don’t worry–before bringing it over to the master branch, you can consolidate things with interactive rebasing, but while you’re hacking away on a branch, it really is advantageous to have many small commits.
Rebasing is one of the harder things to grasp when you’re first learning about Git. For in-depth coverage of the topic, check out the Rebasing page in the Git Community Book. In a nutshell, doing
git rebase master takes any commits to
master and inserts them into your current branch, so you can then make sure your new code still works, and it’s a lot less hazardous than doing a merge. Rebasing your branch before putting into
master is really important because it allows you to deal with any merge issues before the code goes to your main branch. To rebase, just run
git rebase master.
After rebasing the branch, it’s safe to merge it into master. Since I’ve already dealt with any merge issues with the previous step, it’s as simple as checking out the master branch and running
git merge <branch-name>
I use Capistrano to deploy my code, so I’m constantly typing
git push followed by
cap deploy to deploy changes to my server. To make it easier, I just put both commands into one git alias:
deploy = !git push && cap deploy
Now I just need to run
git deploy and it automatically pushes all of my changes to the remote Git repository and then deploys the site using Capistrano. Here’s some more information about Git aliases.
Though I primarily use Git through the command line, I really like using GitX to visualize branches. To host my repositories on my server, I use Gitosis, though if I had a few more projects, I’d dole out the money for a paid account at GitHub.
Have a great Git workflow? Think mine’s terrible? Let me know in the comments!