9

I currently have an svn repository on my hosted web server. I work locally, commit my changes to the repository on my server, and then run an "svn update" via ssh in my live folder when I am ready to push the changes live.

I am now adding a staging site, which will reside on the same server. It will simply be another folder on the same server.

The issue is that I will be working on somewhat larger changes to the site on the staging server that may take up to a week of testing. During that time, I may want to make a small cosmetic change to the live site that requires no testing. Let's take an example:

  1. Assume my local, staging, and live site all begin on revision 1.
  2. I make major changes locally, commit them, and update my staging server. Local and staging are on revision 2, live is still on 1.
  3. Someone asks for a simple text change on the live site.
  4. Ugh. Now I have to revert my local copy to revision 1, make the small change and commit it. Now I update to the live site to revision 3, which has the small change.
  5. I want to keep working on my major changes, so I update my local copy back to revision 2, and keep working.
  6. And so on....

This forces me to keep track of revsions and constantly be updating and reverting. Is there a better way? I feel like I am supposed to be using branching and tags here, but I don't understand how exactly.

Thanks, Jonah

Jonah
  • 15,806
  • 22
  • 87
  • 161

2 Answers2

9

I manage a development shop consisting of 5 developers. We utilize SVN in the following way for our website:

  • Developers commit all enhancements or bug fixes to our 'dev' branch before marking a job as complete.
  • Jobs are tested on a staging box running the latest code in the dev branch.
  • Once a job passes testing, the revisions for that job are merged to our trunk branch.
  • Our live web servers run the trunk branch. Periodically, they are updated via a 'publish' script which updates SVN on the live servers and does some other things as well (such as obfuscates and minimizes CSS and JavaScript).

This allows small bugs to get through the pipeline quickly and larger jobs to take as much time as they need in development and testing.

Since each developer is responsible for merging their own jobs and each merge consists of a smaller set of code changes, they go pretty smoothly. It is a lot less hectic than the older pattern of having a merge manager create a major enhancement branch for a set of enhancements. Since other developers typically work together on a set of enhancements, you would end up with a merge manager who merged code they didn't write, which becomes particularly frustrating when you have merge conflicts.

In fact, this method kind of mirrors the methods that versioning systems like Git and Mercurial attempt to promote by way of how they structure their repositories. With those versioning systems, each developer has their own 'local' repository. When they want changes from another 'repository', they have to merge them with their local code, then commit a valid 'merged' version.

You can also use tagging as Andy mentioned in his answer to this question. It may work for you, but I prefer to put the responsibility of merging on the developers who write the code rather than a central senior developer or publish manager. They tend to go more smoothly that way.

Shaun
  • 4,789
  • 3
  • 22
  • 27
  • +1 for your method. I think your method is probably more suitable for websites. I use tagging a lot because it is critical that my team can always get the exact code for anything that was ever released, but I can see that this isn't really a such a hard requirement for most websites. – Andrew Skirrow Jan 19 '11 at 20:25
  • @Andy: Indeed. An active website sees so many tweaks and publishes over its lifespan that isolating bug fixes with branches causes substantially more overhead. Your method is more suitable for projects that have distinct 'versions' that could be out in the field, of course. However, for a project that sees many small changes and for which there is only ever one 'version', the distinction of tagging and branching each bugfix is less useful. – Shaun Jan 19 '11 at 21:10
1

As you already identified the best way to do this is using branching and tagging. A good example of how to do this would be as follows.

Major development

  1. You do your major development on the trunk.
  2. Whenever you release a copy of your software to live you create a tag from the trunk, and switch your website to point at the new tag.

When you need to make a small change to live you can now do the following:

  1. Create a branch from the live tag, and do the work here.
  2. Once your happy with this change you create a new tag from this branch and switch your live working copy to the new tag.
  3. You could also merge this change from the branch into the trunk so that this change is also in your next major version.

There is a really good fee book on subversion that explains this all in excruciating detail here:

http://svnbook.red-bean.com/

If you can find the time I'd strongly suggest a read.

Andrew Skirrow
  • 3,402
  • 18
  • 41
  • Andy, will the actual local copy I am working with on my latptop be constantly changing from one branch to another, depending on what I'm working on? – Jonah Jan 19 '11 at 19:29
  • With Andy's method, you would need to create and make changes to a new branch on your local system for each small change, then merge it up. Your major changes would occur in trunk, and you would 'release' by tagging trunk, then updating your production servers to that tag. – Shaun Jan 19 '11 at 19:31
  • @Jonah: you'd have more than one working copy checked out. For example If I've got a project `foo` then I might have `C:\Projects\Foo\Trunk`, and `C:\Projects\Foo\v1.1-Bugfix` checked out at the same time (where `c:\Projects\Foo` is not itself under version control). – Andrew Skirrow Jan 19 '11 at 20:23