From this, it sounds like Jenkins is automatically picking up new topic branches, running the tests, and reporting on the results. Any suggestions on how to set something like this up? In my (very limited) experience with Hudson/Jenkins, this sounds like it wouldn't be possible without manually setting up a project for each branch.
edit: more details here -- this is what Relevance uses for our CI: https://wiki.jenkins-ci.org/display/JENKINS/Github+Plugin
One simple (perhaps too simple) way to implement this would be to run a script which enumerates branches and exports the name of the most recently touched branch to an environment variable. Then, parameterize the build on that environment variable.
"For teams that have to do formal releases on a longer term interval (a few weeks to a few months between releases), and be able to do hot-fixes and maintenance branches and other things that arise from shipping so infrequently, git-flow makes sense and I would highly advocate it’s use.
For teams that have set up a culture of shipping, who push to production every day, who are constantly testing and deploying, I would advocate picking something simpler like GitHub Flow."
So if you fall in the second category, this is a read for you.
hubot deploy github/ghost-down to production
If you think about it, this is completely the example of "master is production-ready" idea. We care so much about keeping master deployable, that if we have code that may have issues and need to be rolled back, we deploy just the branch. That way if things break, you can "roll back" to master and everything is good again.
I think the most important thing to note from either method, though, is not to develop on master/trunk. Have a separate branch, or further branches off an entire "develop" branch. The tip of master should always be a stable build.
git branch new_topic_branch && git reset --hard origin/master
There have been some articles recently on the downsides of feature branching that my experience agrees with (http://continuousdelivery.com/2011/07/on-dvcs-continuous-int...). I'm curious if the GitHub people have hit the same issues.
So if 2 people are working on the same feature, they're probably working off the same named branch.
Are there any race conditions with merging to master? I'm assuming that only one head is allowed in master, correct? So that before a pull request is accepted and merged into master, the latest master must first be merged into the feature branch and have CI run all tests successfully on it before the pull request can go. Does GitHub stop you from merging into master if someone else just merged into master and you're about to create a new head?
Then you have to merge the latest master into your feature branch, run CI on it again and then merge to master after CI is successful (assuming someone else didn't beat you to merging to master again).
(I've got a lot more experience with Mercurial than Git so my mental model could be a little off)
One useful thing to keep in mind for this explanation is that GitHub doesn't do anything really, it's just one more git repo with a bunch of sugar.
Yes, there is only one HEAD for a branch in any given repo. When you push it expects that your local HEAD is a direct descendant of the remote HEAD. If this is not the case (due to someone pushing since you last pulled) then it won't do anything (you can force it, but that's almost always a bad idea). In practice though this is not a big issue. You don't have to remerge into the topic branch. Instead you can just reset your master HEAD to origin/master and then remerge the topic branch into master and then push.
If you are just working on changes locally directly on master, it's even easier, you just do git pull --rebase and all your local changes are rebased to the latest HEAD.
the article you mention seems to think that you can either have short lived feature branches or integrate them into master all the time, where we (and most people, i think) do the opposite - integrate master into the feature branches so they're never that far behind and then do the opposite to fast forward the feature branch into master when it's ready to deploy.
and yes, your mental model is off a bit - a branch in git is more like a bookmark in hg - multiple heads for a branch doesn't really make sense - every head is a branch, there is no such thing as an unnamed head.
My main reasons are that git history gets messy, builds don't run on feature branches (although github seems to have a work around here), and refactoring is harder.
My opinions are largely based on working on larger projects (more than 10 devs working in the same codebase).
Lack of builds is something about which you and your CI server need to have a chat, and refactoring is something about which you and your people need to have numerous chats before, during, and afterwards.
Also, if you have too many developers on the same project, break the project up into smaller pieces. We have various systems in separate repos that can be rolled out independently.
They spin up new instances of the app and let the old instances finish serving requests before killing them.
Jenkins has a crummy UI, but it is very powerful and has a lot of useful plugins. If you are moving to any sort of continuous deployment setup, as Github is close to, you really need something as powerful as Jenkins.
In the weeks before a new site is launched, we work to our own feature branches and merge into master when a feature is complete. In the run up to the site launch, when there's just CSS tweaks and the odd bug fix, people start working on directly master and deploying straight to staging servers.
When a site has been launched we normally keep working just on master, though occasionally creating feature branches for bigger changes.
This seems to work well for us as our DVCS needs change over time. I'd be interested to hear how other web agencies manage the different stages of developing clients' websites.
Make sure your commits are cohesive to the change you are making. I think that is a good rule of thumb.
On the other hand, some changes are big and messy. In this case I sometimes do intermediate commits, especially if it's at the end of a day just so I can keep yesterdays changes conceptually separate from todays. In the end I may rebase -i the whole thing and clean things up before pushing, but only if there are some obvious and quick ways to split it up.
I do this so I can cherry pick commits into other branches (e.g., fixing a bug in my current branch and merging it back to master).
Other than that, if you felt like you've taken a decently-sized chunk out of whatever problem or feature you're currently working on, commit.
How do they manage deployment to staging? At my company we typically deploy topic branches directly to staging, but we have fewer developers and slower pace. If multiple people need to deploy topic branches we set up an ephemeral staging branch that merges the multiple topic branches together, but I can imagine that getting super hairy on a team the size of GitHub's.
Do they just mostly deploy directly to production, thus severely minimizing staging contention?
this is also one of the benefits of deploying via a chat room - you can ask if you're going to be stepping on anyone before you do it.
Anyone know of ideas for doing code reviews for the whole pull request, commit, or a single line like GitHub? This is probably the most beneficial part for us.
(disclosure: I work on Kiln at Fog Creek)
I'll look into if the issues feature works for us, but me might have to roll something of our own.
Doesn't mean I won't make the pitch for Git yet again.