I'm a member of the copyleft FFFFF.AT Lab and study the science of the internets at Rocketboom.
I teach the Internet Famous Class at Parsons, where your grade depends on your online popularity.
As seen on
NBC,
TIME,
CNN,
Gawker,
BuzzFeed
, ArtNews
Pretty much assumed you already know version control (at least in theory) and are just looking to get started with Subversion (SVN) specifically.
This tutorial will be done assuming all your SVN hosting is done locally, with file:/// URL’s. It’s trivial to translate it for a remote repository hosting situation — just replace “file:///svn/” with “http://myserver.com/svn”
Excellent hosting provider TextDrive does subversion, or roll your own: see Exposing SVN w/ Apache+DAV.
Mac OS X
Windows
Find a place for all your repositories to live. On my Mac I put it in ~/Library/svn; on my FreeBSD server it is /usr/local/svn. Use whatever you’re comfortable with. I make a symlink from “/svn’ to it so that I can just type stuff like “file:///svn/” no matter where I am which is what I’ll reference the repo as from now on.
We’re going to setup a repository for an amazing new app called paint!
cd /svn svnadmin create paint
Get out of the svn dir, which is where all the svn database metadata is. Go to where all your current paint code lives:
svn import . file:///svn/paint
Now it’s all imported, but you need to check out a working copy to start making changes.
Go to where you do your code business. I use ~/dev.
svn checkout file:///svn/paint paint
Get in the habit of syncing with the main repository before you start adding your latest and greatest features. ‘svn update’ (or just ‘svn up’) brings your working copy in sync with the main repository.
cd paint svn update
OK, now we can hack. Change stuff liberally. Or add some files:
touch awesome-thing.c svn add awesome-thing.c
Send all your changes back to the repo:
svn commit -m "just hacked some code and added this really awesome thing"
You can omit -m and it’ll pop open your EDITOR and you can fill in the change description it in there. But that’s super annoying, so use -m
Two days later…
How’s yer hacks doin’? Pop out a list of changed files:
svn status
Want to see actual changes to the code, or even compile a patch?
svn diff svn diff > my-awesome-changes.diff
(you’d import that with
patch -p0 < my-awesome-changes.patch, by the way)
When you run
svn updateyou’ll see something like:
$ svn update C foo.c Updated to revision 31. $ ls foo.c foo.c.mine foo.c.r30 foo.c.r31
C is for conflict. U is for updated, A is for added, that kind of thing. Here’s the master list of codes:
A -- scheduled to be added C -- in state of conflict (resolve it) D -- scheduled to be deleted M -- file has been modified R -- scheduled to be replaced (delete-then-add) ? -- file not under version control(1) ! -- file is under version control but is missing or incomplete ~ -- versioned file has been replaced by directory (?) I -- file is ignored (this only shows up if you use --no-ignore, obviously)
This conflict will produce several files: a “quasi-merged” foo.c, with markers delineating the diff sections, your original version, the previously synced version (r30) and the newly synced version (r31). You won’t be able to commit your sweet changes until this conflict is resolved!
So what do you do? I pop open open all of them in TextMate, God’s gift to text editing, like so:
mate foo.c*
Mostly you only need to really look at foo.c, which will have “conflict marker” showing contested areas stuff like this:
<<<<<<<<< print "this is the debug info *I* put here" ===== print "this is what the other dude changed this line to that's conflicting." >>>>>>>>>
Pick your favorite line of code, delete the markers, and continue. This is kind of ghetto, really. Perforce is way nicer, very “visual” and interactive, showing both copies and then asking you which one you want or if you want to edit it. SVN figures you can tough it out.
Then when you’re done say:
svn resolved foo.c
Feel free to safely continue hacking, commiting, etc.
You can give directories myriad properties. Use svn propget ., svn propedit ., or change the . to a dir, like vendor which I use a lot on Rails apps
$ svn propget svn:ignore . tmp pkg
$ svn propget svn:externals vendor rails http://dev.rubyonrails.org/svn/rails/tags/rel_1-1-6/ radius svn://rubyforge.org//var/svn/radius/tags/rel_0-5-1/radius/ redcloth http://code.whytheluckystiff.net/svn/redcloth/tags/RELEASE_3_0_4/
Pluses & minuses of svn:externals…
A great workaround is to use Piston, which is an, uh, external externals manager. It checks out the code and you have to explicitly update it with a “piston update” which is nice when there are externals you want that don’t use tags, like small plugins and the like. Piston also lets you use externals with svk, which I’ll discuss more below.
sudo gem install -y piston
(TODO: Piston website link and sample usage.)
Standard svn repo structure:
/branches <-- forks of the main trunk, for bugfixes or experimentation /tags <-- copies of main code that have been "tagged" as a release (e.g. 0.6, 0.7) /trunk <-- main development, sometimes called "head"
Generally this is done using the bulky ‘svn smerge’ command to copy one repository, then one manually merges changes from the branch into the trunk when needed. svnmerge.py facilitates auto-merging changes.
Automated branching & tagging can be achieved using a small utility like sc or SubversionAutomation . This is life changing for any large project, can’t recommend it enough.
SVK is a layer on top of svn designed to facilitate “offline” hacking of another repository, allowing you to still grab updates from that repository and maintain your own local branch.
This wouldn’t be super necessary if svn allowed you to branch from a remote repository, but alas.
GETTING STARTEDsvk has a rich command line interface that can be somewhat daunting at
first. the following few commands are all you’ll need for day to day
operation.svk mirror
First, you’ll need to mirror a remote repository. This sets up a local copy of that repository for you to branch from, merge to and otherwise poke at. The local path is sometimes called a “depot path.” # This command sets up the mirror directory for your local # mirrors of remote repositories svk mkdir //mirror svk mirror svn://svn.example.com/project_x //mirror/project_xsvk sync
When you’ve set up a new mirror or want to get some work done without a network connection, sync your local repository with upstream repositories. svk sync //mirror/project_xsvk copy
After that, it’s easy to copy remote branches to create local branches. (svk branches are simply directories, just like Subversion branches.) # This command sets up a directory for your local branches. # Local branches can’t live inside mirrored paths svk mkdir //local svk copy //mirror/project_x //local/project_xsvk checkout
When you want to get some work done, you can checkout a working copy to make local changes. cd ~/svk-checkouts svk co //local/project_xsvk add, svk delete and svk move
As you work on the files in your working copy, feel free to add new files, delete existing files and move files around. cd ~/svk-checkouts/project_x svk add Changelog svk move badly_named_file.c well_named_file.c svk delete .README.swpsvk commit
When you’re done, just commit your changes to your local repository, whether or not you have network. If you commit to a mirrored path, rather than a local branch, you’ll need to be able to access the path’s upstream subversion server, but the commit will be sent to the server instantly. svk commitsvk pull
Life doesn’t stop when you make a local branch. From time to time, pull down changes from the upstream repository. svk pull //local/project_xsvk push
When you’re ready to share your changes with the world, push them to the upstream repository. svk push //local/project_xTo see a full list of svk’s commands, type svk help commands. For help
with a specific command, just type svk help command.The svk wiki (http://svk.elixus.org) is a great place to find the
latest svk tips, tricks and updates. If you run into trouble using svk,
the wiki’s the right place to start looking for help.
Web stuff:
Commenting is closed for this article.