I'm Paul Bissex, and e-scribe.com is my consulting business. I build web applications using open source software, especially Django. In the '90s I did graphic design for newspapers and magazines. Then I wrote technology commentary and reviews for Wired, Salon.com, Chicago Tribune, and lots of little places you've never heard of. Feel free to email me.
I'm co-author of "Python Web Development with Django", an excellent guide to my favorite web framework. Published by Addison-Wesley, it is available from Amazon and your favorite technical bookstore as well.
Built using Django, served by Apache and mod_wsgi. The database is SQLite. The operating system is FreeBSD, on a VPS hosted at Johncompanies.com. Comment-spam protection by Akismet. Vintage topo imagery from the Maptech archive. The markup engine is Markdown.
Akismet, bitbucket, del.icio.us, Django, Emacs, FreeBSD, Git, jQuery, LaunchBar, Markdown, Mercurial, OS X, Postfix, Python, Review Board, S3, SQLite, TextMate, Ubuntu Linux
At least 95836 pieces of comment spam killed since January 2008, mostly via Akismet.
At work I still mostly use Subversion for version control. Its main selling points: stable, performs as expected, integrates nicely with Trac, holds all our old stuff (legacy inertia).
Note that "pain-free branching and merging" is not on that list. (And don't give me the old "branching is cheap in svn!" line. It's not about the branching, it's about the merging.) A couple years ago I started also using Mercurial and plan to eventually replace svn with it entirely. The aspect of Mercurial that made my life better recently is its support for branching and merging.
The scenario: an important internal web app (in use all day every school day) needed some significant changes on a short timetable. Normally I'd work on the app thus: edit the staging copy, commit, update the live copy. I didn't want to take that approach here. I knew that during the development window there might arise unrelated urgent change requests; I wanted to keep the new code isolated during development, but also deploy and track those unrelated urgent changes. Branching seemed like the right approach.
I could have made a full clone of the app (hg clone mainrepo newrepo). However, handling environment dependencies (web server, PythonPath, database) would have added time and fussiness to the job, and time was in short supply. So, using Mercurial's named-branches feature, I made a new branch (hg branch newstuff) right inside the fully-functional staging copy of the app. That way I was able to develop and test as usual, secure that my unproven work-in-progress was not "polluting" the current app's revision history.
To handle "unrelated urgent changes" as mentioned above, I'd:
hg update -r default)hg update -r newstuff)It took me a couple tries to understand how branch-switching worked, but it's simple: you really are updating your working directory to a new revision, it just happens to be a revision stored in a different branch from the current one.
It was fun looking at the graph (via HgWeb) and seeing my two parallel branches with their individual commits.
The moment of truth came at the end of the day Friday, when it was time to merge the tested and complete "newstuff" code with the current live codebase. It was dead simple, and effectively instantaneous. Condensed version: hg update -r default; hg merge -r newstuff; hg ci -m "merged new stuff". Followed by: update live copy and let out a big sigh.
Sorry for the confusion. The challenge in writing a post like this is giving enough detail about the working setup to make the story clear, but not descending into uninteresting details. Anyway, your suppositions are correct.
How would one bring forward the changes in default into newstuff branch to test before merging into default?
It's neat stuff huh! I was very wary of branching/merging when I used SVN, but I find it to be very easy and reliable with Mercurial. Mercurial FTW!
Chris -- for my purposes "bring forward the changes" and "merge" mean the same thing. So, the command sequence in the last paragraph of my post is the answer to your question as I understand it. After I've tested the merged code on the staging side, I update the live side by doing an `hg fetch` from staging.
Paul, I was thinking more along the lines of: working on a new feature newstuff but want to bring in the bugfixes being made in default. I'm not done with newstuff yet, I just want to make sure it tests against the default bugfixes.
If I'm reading right your last paragraph is merging into default, whereas I wasn't to merge into newstuff from default. Do I just need to reverse the commands in the last paragraph?
Chris: Sorry for the delay in responding, but: yes. Swapping "default" and "newstuff" in the last paragraph's example will do exactly what you want.
(Just had occasion to do that very thing a few minutes ago, in fact, which reminded me to come here and reply to you!)
Just wanted to follow up to note that, many months later, this workflow continues to please. At times I've had three separate branches underway, but never any confusion. Subversion is only a legacy system for me now and I look forward to leaving it behind.
Thanks for reading! Please note: Your comment will not appear until approved, which may take a few hours or more. Spammers will be torpedoed.
Booktools
2 comments
A different kind of URL shortener
4 comments
The syncbox
2 comments
Branching and merging in real life
8 comments
Summer Spam
1 comment
malpaso
Understanding tuples vs. lists in Python
10 days ago
vj100
Understanding tuples vs. lists in Python
10 days ago
scott
Bicycle Repair Man bundle for TextMate
16 days ago
Jasmine
Trying to send eBay a message?
53 days ago
Smok Cigs
Let's play a game: BASIC vs. Ruby vs. Python vs. PHP
90 days ago
Copyright 2012
by Paul Bissex
and E-Scribe New Media
You haven't made it terribly clear, but I guess you were making the significant changes on the staging server as it already had the infrastructure ready. Was why it was important to be able to switch between branches and make changes on the original branch?
Is this correct?