In a project I am working on, we have an ongoing discussion amongst the dev team - should the production environment be deployed as a checkout from the SVN repository or as
I deploy it as a copy. Not manual, of course.
I use 'make' and 'checkinstall'. I create a small Makefile which uses the system command 'install' to copy all the needed files to the appropriate directories on the web server, and I have preinstall and postinstall shell scripts that will be run on the server.
When time for deployment comes, I just run 'checkinstall' which creates a package (RPM, DEB or TGZ, depending on which Linux distribution I target). I install it using regular tools provided by a Linux distribution package manager (rpm, dpkg, pkgtool). Of course, if you want to track dependencies as well, you can use yum, apt-get, etc.
It makes it really easy if you want to distribute a new version of your web app. to multiple target servers. And stuff like uninstall, reverting to an older version, etc. are very easy because you have a ready to use package for each version you deployed.
This might not fit your 'push often' strategy though if you use some stuff that needs compiling. However, for scripting stuff (like PHP that I do), creating a package (of about 300+ PHP files) takes about 20 seconds on my machine. And about as much to install it on any target system.
To separate the code 'for release' from the 'in-development' code, I use branching. With Git, it's really easy, since branching is cheap and fast.
Personally I'm always in doubt about the solution of this problem, I prefer having no ".svn" directories around my production environment, it's very dirty but at the same time, export is very tedious with large web applications (especially if using some 3rd parties "components" like Extjs,FCKeditor etc..).
I think there are not "killer solutions" at this moment.
IMHO you should create a branch/tag where you have the (desired) subset of the dev env which you use for production. Someone should either maintain this manually or automatically using scripts. Then, you should export (rather than checkout). Incremental updates are a non-issue, unless you're changing files on your production environment and you don't want those files to be overwritten.
Just my $0.02
No question - export.
You would not be making updates, so no reason to have a checkout. You would just be deploying junk out.
I would say any environment should be only an export; you only use checkout locally when you are developing. Of course we are also using build scripts, so updating the deployment is as simple as running the script.
As far as the in development code, create branches for any work being done. Only commit to the trunk when ready for deployment to the development environment.
Here are some opinions -
.svn files on production are dirty? If the .svn directories are intact and not corrupt, they are far from dirty, they are actually a lifesaver. For security, you can tell apache to prevent browsing them.
Checkout or export? my approach... I definitely use tags and branches - it is dangerous to attach a production server to trunk and pray that no one runs svn up just after someone commits faulty code into trunk to see what it does on DEV. I have a reusable tag (say _production and _staging) and at the beginning of my setup I checkout each one to the matching server. I then lockout all access to modify the contents of the live and staging server. Thereafter, the DEV server is tied to the trunk head. When code is stable enough for QA/staging, we create a tag and rename it to _staging to allow the staging server to sync to it (script runs 'svn up') whenever it sees changes to that tag. Once we are happy with _staging, we rename it to _production and that makes the code deploy to the live server. Alternatively, you can create tags/branches with different names and use 'svn switch URL' to point the server to a new tag/branch (fixed point). All the above make it very easy to deploy without downtime and if rollback is necessary, you can quickly rename the archived former tag or use 'svn switch OLD_URL' to immediately undo the new changes without worrying about each small file and line-changes.
Permissions & ownership If you understand and know what the permissions should be for the files, you can have your script run after each deployment to set the CHOWN and CHMOD to what you want it to be.
Fear vs Knowledge I have heard of many afraid people ruling out the presence of SVN on the production server. The opposite is actually very scary. How do you assure your product team and customers that the application will not collapse into a big pile or error messages without the ability to do dry-runs or 'svn status -u' to ensure that the deployment will modify just those files that need to change? checking the status allows me even know if anyone forced their way it and made a 'quick change' directly on the server - you know people tend to bypass rules for things that look quick to them.
Imaging there is an error on the live server? with .svn, you can identify the exact version it is sync'd to (svn info) and then check if it is true to that url (sv status -u). Then you can build an honest replica of that setup by checking-out the same tag/version to a sandbox server where you can safely troubleshoot.
The Subversion FAQ seems to advocate deployment as a checkout, autoupdated with post-commit hook scripts. They prevent Apache from exporting .svn folders (probably a good idea) by adding the following in httpd.conf:
# Disallow browsing of Subversion working copy administrative dirs.
<DirectoryMatch "^/.*/\.svn/">
Order deny,allow
Deny from all
</DirectoryMatch>
I'm extremely new to svn myself, but maybe you could trigger a hook script when you create a new tag. That way, when you're ready to update the live site, you just commit your last changes to the trunk, create the new tag, and the script updates your live site with svn update.