Subversion notes

From Helpful
(Redirected from Subversion)
Jump to navigation Jump to search

📃 These are primarily notes, intended to be a collection of useful fragments, that will probably never be complete in any sense.



Types of reference/access to a repository

  • SSH:
URL looks like svn+ssh://username@example.com/home/username/fishesrepos
The URLs contains an absolute path on that host, and regularly also a username to log in as
My preferred method, because use of SSH authentication and copying means no extra setup (if you and all intended users had accounts already) and it's secure to boot


  • (DAV over) HTTP or HTTPS:
URL looks like http://example.com/fishrepos/ (path depends on your config, you probably want it deeper if you serve many)
...or https://
subversion's protocol is an extension on DAV, which is itself based on HTTP (and you can use SSL/TLS).
Typically this means using an apache module that speaks SVN. Which takes fairly simple setup.
authentication can be apache's -- which can be nice, or bothersome, depending on your case, and on whether you want to have a read/write distinctions, and on whether it meets your security standards


  • svnserve as daemon:
URL looks like svn://example.com/fishrepos
More involved to set up:
Set up the svnserve standalone server (via xinetd, or run in --daemon mode from service management
Figure out firewalling for its port (3690)
figure out its access control (may be handy if you don't want to mess with SSH and/or accounts - and more annoying when you do)
Generally, SSH or HTTP(S) is preferred because they are more secure, and are over ports likelier to be open ( / to be opened by your IT department).


  • Local filesystem:
URL looks like file:///home/repository/fishrepos
URLs have file:// prepended (which, yes, typically means three slashes in a row, because absolute paths)
useful for local-only versioning.
also a slightly easier way to to peek at contents of a repository normally accessed another way



See pages like [1], [2]

You can also do this on Windows, as a service if you wish; take a look at pages like [3] and [4].



Introduction by example

Starting a repository

A repository exists under a particular path. Repository paths are basically partly a real path to where the repository is stored, and partly a virtual path within the repository contents

For example, say I

  • have an account pisces (at /home/pisces) on host example.com
  • want a repository named fishesrepos


I would first have to login and create the repository: svnadmin create ~/fishesrepos The directory (~/fishrepos) must either not exist yet, or be empty.

A repository doesn't look useful on the filesystem - the content to come will be stored in a file-based database, and there's a bunch of admin-ish shate around it.

To see what it actually stores - nothing at this point - you need to use a client. If you insist to do this locally (just to poke around) you can do

svn list file:///home/pisces/fishesrepos


But you'ld generally use the access method (you chose) that works from anywhere, e.g.

svn list svn+ssh://pisces@example.com/home/pisces/fishesrepos

...or, to actually start using, it, check it out elsewhere:

svn co svn+ssh://pisces@example.com/home/pisces/fishesrepos

Everyday use

Subversion is specifically a centralized text versioning system, typically used for source code.

It is centered on a single central repository.

You can check out any amount of working copies, which themselves can synchronize the changes (only) with the repository they came from.


Note that most svn commands can be abbreviated. For example, co is an abbreviated form of checkout, ls for list, st for stat, etc.


Checking out a copy

checkout means creating a working copy from a specified repository's HEAD (by default).

svn co repositorypath

creates a working copy under the cwd.


If you want to avoid unnecessarily deep directory structures, keep in mind that the specific command matters.

Considering the example above, and assuming the repository contains only a directory called statcollect:

  • svn co file:///home/pisces/fishesrepos/ would create ./fishesrepos/statcollect/files...
  • svn co file:///home/pisces/fishesrepos/statcollect would create ./statcollect/files...
  • svn co file:///home/pisces/fishesrepos/statcollect dir would put statcollect's files in the given directory (only if this target directory is empty)


Notes:

  • It's common enough to have repositories that have distinct projects as the top directories, and a 'trunk' as a main branch within each. This makes it easy to say "get the current source via svn co svn://svn.audioscrobbler.net/player/trunk
  • You can later use svn info in a working copy to get the URL you once fetched it from

Incoming synchronization: getting the latest (update)

Given a working copy that you think may be out of date, use update to fetch the changes made to the repository to your working copy. This doesn't synchronize both ways - nothing is sent yet.

svn update

It will signal what sot of changes happened. Some of the most common:

  • U means file was updated (changed)
  • A means file was added
  • D means file was deleted
  • G means the file will be merged (there are also local edits to this file, but they do not conflict with what came in)
  • C means the file's changes conflict with local edits you have made


If you work on precarious code, you may like to check "what would an update change" without doing it:

svn diff -r HEAD

Adding, removing, and renaming files

When you create new files in the working copy, they are not automatically versioned. This avoids clutter in the repository, as well as cases like 'stupid svn, that has my password in it'.

Start versioning a file or directory If you want to start versioning a file:

svn add path


Note that directories are added recursively by default. If you do not want that:

svn add --non-recursive dir

(Note that when you do want almost all files, you may want to add recursively, then use svn revert as a "no, don't add that one, actually")


Similarly, deleting files from the working copy with plain old rm won't affect the repository. It will be consindered missing, won't commit as a delete, and will be restored from the repository's copy with the next update. To delete it both from versioning and locally:

svn delete localpath


There are also (for both files and directories):

svn copy
svn move

They are convenience functions, but useful as they will preserve an item's history.



Inspecting changes (stat and diff)

  • svn st (status) lists which files we would commit, and how the changed
  • svn diff (status) lists the differences within these files
Useful when writing the commit message, in which case you care about outgoing changes, between working copy current, and the current state at the time of last update.
(sometimes you instead want to compare to the repository-right-now, i.e. HEAD: svn diff -r HEAD filename)


The status signaling is more detailed than update's - there are actually six columns there, but you'll rarely see them.

The first column is most interesting:

  •   no change
  • M modified
  • C conflicting file differences
  • ? not under version control (shown to suggest that you may want to add it)
  • A added using svn command
  • D deleted via svn del; deletion will be committed
  • ! item is missing (removed by non-svn command) or incomplete, will be updated from repository
  • R replaced
  • ~ versioned item became a different kind (e.g. between file, directory, link, etc.)
  • X item is unversioned, but is used by an externals definition
  • I ignored (when using svn st --no-ignore to shows ignored items; without it, these are not listed)
  • L locked - either you have another terminal where you are e.g. editing a commit message, or something was broken off uncleanly and you want a svn cleanup(verify)



Outgoing synchronisation: sending in your edits (commit)

When you are happy with your changes, this will send them to the repository as the next version:

svn commit             # implies 'all local subtree changes' , or:
svn commit file.c      # specific file(s)


Resolving conflicts
File conflicts

Say that you checked out version 6 of README and are editing it

Other people commited various versions and the repository is now up to version 12, and they changed some of the same lines as you did -- differently.

When you update, the changes conflict with yours, and svn not allow you to commit that file until you resolve this.


Resolving means

  • edit the file with what the next repos version should be
  • svn resolved README to telling svn you have done so
this also cleans up the files svn created to help.


The files that it created are:

README.mine    # your own new version

README.v6      # repository revision 6:
               #   how it was before your edits. usually the least relevant, 
               #   but sometimes useful to compare to .mine to remember what you were doing

README.v12     # repository revision 12:
               #   the latest repository version, with edits that are new to you

README         # the difference between .mine and .v12  (diff format)
               #  it can make sense to edit this one, 
               #  as the conflicts sit in context of the rest of the code
               #  (it really helps if your editor understands diffs)


Methods of resolving for this example include:

  • "yours was better, throw away mine": svn revert README

or

  • "Just use my version": cp README.mine README:
throws away all repository difference between r6 and r12

or

  • manually edit README to taste
quickest when the differences are minor and simple to oversee
e.g. search for the bits that diff marked, e.g. search for <<<<

or

  • Use an interactive merger
e.g. (sdiff README.v12 README.mine -o README) will produces each difference as side-by-side sections, and ask which one you want.
Simpler when the differences are easy to understand.

or

  • use a tool like meld, kompare, diffmerge, diffuse, kdiff3 (which can compare two or three)
can be nicer at highlighting the differences and showing context, can be necessary for code


Tree conflicts
This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

A tree conflict happens when content alterations happen on files (or dirs) that were moved/deleted.


It's distinct because in many of these cases, it is not clear (...enough for fully automatic resolution...) where the content change should go to.


Regularly solved by a "accept my version after I did some manual checkup and/or merging", though the fact that more files are involved means it's often a little harder to fit in your head.


Like content conflicts, the brute force method is "everyone else be damned, I want to force the stuff in my working copy":

svn resolve --accept=working dirorfile


If you want to avoid destroying stuff, think about your case and read up. For example:



  • "local edit, incoming delete upon update"
this workingcopy has changes, another copy has committed the delete/rename of the file
if you just agree with the delete, a svn delete --force filename may be easiest (verify)
if if not, you'll need to see if it was a move, or other case


  • "local file unversioned, incoming file add upon update"
means the repository has a newly versioned file, this is the first update that would fetch it into this working copy, yet a file with this name is already present for some reason.
e.g. two people independently had the same idea to add a README
One resolution is: svn resolve --accept working filename


  • local file moved away, incoming file edit upon update
basically because svn can't tell whether it is a move or a delete.



Resolving via svn resolve --accept ARG

  • base - file as it locally was before the conflicted update made things confusing
  • working - file as it currently stands in your working copy (after possible editing)
  • mine-conflict - for conflicting files, prefer version that came from my working copy (verify)
  • theirs-conflict - for conflicting files, prefer version that came from repository (verify)
  • mine-full - for all files (even those with non-conflicting changes), prefer version that came from my working copy (verify)
  • theirs-full - for all files (even those with non-conflicting changes), prefer version that came from repository (verify)


During an interactive update you also get:

  • shorthands:
(mc) for mine-conflict, (tc) for theirs-conflict, (mf) and (tf) for the -full variants
  • (p) postpone - mark the conflict to be resolved later (can't commit until you do)
  • (r) resolved - accept merged version of file (usually done after editing it)
  • (df) diff-full - show all changes made to merged file
  • (e) edit - change merged file in an editor
  • (l) launch - launch external tool to resolve conflict

Other

To see information about a directory or file, such as what version it is at, and where the repository is, use:

svn info

Further notes

Occasionally useful commands

Listing/extracting repository contents

To list what is in a respository:

svn list

When you want to do this locally, without the svn client, on a repostiory directory instead of via a repository URL, use svnlook.


To show you a file's contents:

svn cat


To fetch files without versioning information or checking out:

svn export

Merging

Restoring old copies of a file

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


See history of a single file

https://stackoverflow.com/questions/282802/how-can-i-view-all-historical-changes-to-a-file-in-svn



To overwrite a single file from a specific old version:

svn copy -r revision repositoryurltofile localfilename

More generally, you can remove changes made at some time by applying the diffs between those versions in reverse. For example, I had once deleted files between revision 2 and 3 that I actually wanted to keep. What I want is to reverse all changes made in that revision change:

svn update -r 3:2 .


To fetch old versions of directories, you have to use merge. Note that this will revert all changes (or rather, those you specify), to all files, since that time.


Dumping and restoring repositories

svnadmin dump will dump all data (all revisions separately - you may want to use -deltas to dump the changes) in text format, to stdout. svnadmin load can be used to load in such a dump file into another repository. This can be handy when you want to move, merge, or back up repositories, or perhaps to create a new repository with only recent history.


# dumping repository in the subdir ./medusa:
svnadmin dump medusa/ > medusa.svndump
 
# loading it into the ./merged repository, in a repository subdir
svnadmin load merged/ < medusa.svndump

The load will expect the same directory structure - which makes it east to merge the content on top of already existing content. For this, reason, --parent-dir is useful, letting you load the dump into its own directory, meaning you can organize later. It does expect the mentioned directory to exist, so you'll need to go into a working copy, create and commit it. (Or you'll get a File not found error)

Notes on

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


...revision model (repository, elements), revision references

Many subversion commands can take a --revision / -r, for example diff-ing specific versions, checking out an old versions, and so on.

You can generally hand in version integers, as well as named symbol references (HEAD, etc.)


The revision number refers to a state of the repository as a whole.

In each revision, you often see only a subset of the files change, so most files will have last been changed only in some previous revision.


In many places where a revision specification can be filled in, you can use:

  • a number, referring to the state in a specific revision
  • HEAD: the latest version in the repository (regardless of whether you've updated to know about it)
  • BASE: the revision you checked out (latest locally known version, pristine in working copy)
  • COMMITTED: The most recent commit from this working copy, and per element(verify)
  • PREV: COMMITTED-1, in other words, the version before the one we commited last.
  • a date, referring to the state at a specific date (format?(verify))


Many commands can take a range (sometimes a range is implied - comparison to HEAD), which imply differences between states, as a diff. Examples for viewing them as such differences:

  • svn diff -r 2:15 filename displays all changes made between revision 2 and revision 15.
  • svn diff -r 15:2 filename displays the same, but in a form that implies its removal/reverse:
  • svn diff -r PREV:COMMITTED means 'what changes did I last commit?'(verify)
  • svn diff -r BASE:HEAD means 'what happened since I last updated?'

(Note that a working copy won't know about the latest revisions until you update; a commit does not update that information)

This can also be useful to reverse specific changes, and is also interesting when you start using merge.




...implied repository and directory arguments

Many commands take sensible defaults depending on the directory that you are in, saving a lot of typing:

  • repository URL: the one the working copy came from -- a working copy knows from whence it came.
  • directory argument: current directory

Almost any commands takes a path, but implies the directory it's run from and works on it, and often its subdirectories. This applies to things like svn status and svn diff but also to svn update and svn commit.

Behaviour usually changes depending on what sort of argument you give. For example, update updates the current directory (and subdirs) to HEAD, unless you give it a specific directory or even single file to work on, and/or you give it a specific old revision to update to.


...projects/directories

There is no first-order concept of a project, but since you can check out directories, directories inside repositories serve that purpose quite simply.

(You could of course put things directly in the repository directory, but it will only serve one project that way.)


...out-of-dateness

The separation of update and commit can be helpful since it doesn't force you to always work with the repository version - sometimes you don't, say, want to update to someone else's half-working code but want to test your own code with the older, featureless, but guaranteed-to-work version. Of course you can always check out such an older version anyway - it's a versioning system after all.

That separation means it is possible to have a working copy consist of files from different revisions.


Note that a working copy's log and info may not be up to date until you do an update. Also, some operations, (particularly delete), cannot be done from a version that isn't up to date.


A file can locally changed or locally unchanged, and (independently of that) be current or out of date with the repository.

This gives four situations, which are handled as sensible as possible:

  • current, unchanged: update and commit naturally do nothing
  • current, changed: update does nothing, commit updates the repository
  • out of date, unchanged: commit does nothing, update will get a newer version
  • out of date, changed: the interesting case. You cannot commit until you have updated.

In this last case, updating will be automatic if it can be. If two programmers worked on different sections of the same file -- that is, someone else committed a change and you want to commit a different change that doesn't conflict, you'll merge their change into your copy, after which you can commit.

If there is a conflict, chances are you need to talk with the other programmers working on the project, since you probably edited the same thing.

...partial updates vs. branching

When you are the only programmer working on something, you can leave a lot of code uncommitted locally, only committing what you are done with.

This means you can work on a lot without breaking the repository code - but when you want that and work with many people, you at some point want to think about branching, because keeping own copies around for a long time is bound to lead to edit collisions.

...repository access

You use full paths in the URLs, which also means you can use access other repositories on the host, as permissions allow. This may involve a general subversion group, project groups, project accounts or so.


If you're annoyed by having to type your password/passphrase every update/commit you can use something like (passphraseless/agented) SSH keypair logins, or of course filesystem repositories (mounted/authorized another way, though be aware of NFS-related details).

Other details

shorthands

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

A number of commands have shorthands, including:

status stat st
update up
list ls
copy cp
move mv
checkout co

...and others.


Properties

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Properties are named values that are seen as metadata for versioned files.


Subversion-specific metadata properties have the svn: prefix, e.g.

  • svn:executable - executability on unix systems
(automatically picked up if it was executable when it was added, but can be useful to add later)
  • svn:ignore - set on directories, mainly to not clutter status with ? entries
  • svn:keywords - tells svn to automatically replace things like $Author$, $Date$ in files, useful e.g. for "last updated" lines (based on revision metadata), see e.g. [5]
  • a few more useful exposed things
  • and a bunch of reserved/internal stuff, sometimes interesting to inspect


Free-form properties is anything not svn:, for example

svn propset copyright '(c) 2008 Example Inc.' dir/some_file.c
svn propset license -F GPL.txt


Command-wise:

  • propset, useful for simple values
e.g. svn propset svn:keywords "Date Author" the_file.c
e.g. svn propset svn:executable on app_mine
(note: on is meant as a boolean, not as "set this on the following files")
or "set from file", see license example above
  • propedit, uses the EDITOR; useful for complex or multi-line values
e.g. svn propedit svn:ignore . edits the ignore properties for the current directory
  • proplist shows all (sometimes you want propget to show just a specific property)
  • propdel

See also

http://svnbook.red-bean.com/en/1.7/svn.ref.svn.c.propset.html


Ignoring files (in status and similar)
This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

You may have a lot of extra files in your working copy that you wouldn't ever want to add to the repository, such as bytecode compilations, logs, editors' temporary files, and such.

An svn status will show many of these with a ?, basically signaling that these may be interesting to version, since they are in the working copy.

A portion of them will just be clutter, and you can make subversion ignore these in stat listings by editing your subversion config (~/.subversion/config in *nix, %APPDATA%\Subversion\config in windows), finding the [miscellany] header and setting something like:

global-ignores = *.o *.lo *.la #*# .*.rej *.pyc *.pyo *.class .*~ *~ .#* .DS_Store Thumbs.db *.elf


You can also do this for a specific (part of a) working copy, using the svn:ignore property, often using propset or propedit.

With propedit you specify the directory to edit the filter for, with propedit you specify both a filter and the directory to set it in.


For examples, to ignore a subdirectory by name:

svn propset svn:ignore dirname .

To have a directory in the repository (e.g. to ensure a cache directory exists but ignore all local content) but ignore all of its contents:

svn propset svn:ignore '*' dirname/

To ignore specific files or lists using wildcards:

svn propset svn:ignore "*.log" log/

Note that you generally want to quote anything with a *, to avoid that your shell from expanding that star to the current on-filesystem names.


Keep in mind that you cannot ignore entries that are already versioned.

This is somewhat obvious for files, but when you can't seem to ignore a directory, this is often why.

Avoiding commits for files

Use case:

  • database connection details in a config file
  • htaccess references to .htpasswd files

Structurally these will be part of the app, but you wouldn't want to commit the changes.


The common suggestion is to store only a template in the repository. Someone who does a checkout would need to do a (non-svn) copy, say, config.template config then edit the config.

This is cleanest, in that you can still commit changes to the template, but you won't accidentally save personal settings in the repository.

Listing files changed in the repository

To get a list of "all files changed since revision 3700" would be:

svn diff --summarize -r 3700:HEAD 


If you want to see the changes in a specific commit, you may want:

svn log --verbose -r 3705


I've also used a script listing file changes in recent revisions. See https://github.com/scarfboy/various something along the lines of:

Errors

Killed by signal 15

tl;dr: Edit ~/.subversion/config file, [tunnels] section, make sure -q is in the ssh command

https://serverfault.com/questions/120886/i-get-killed-by-signal-15-when-im-using-svn



Node filename has unexpectedly changed kind

most often when changing between file and symlink

A symlink is kept as such, and not as its contents. Meaning this kind change make no sense in a content versioning system.

Remove the old thing, commit, add the new thing.


svn: E000002: Can't create temporary file from template '/path/to/.svn/tmp/svn-XXXXXX': No such file or directory

For me, the tmp directory within .svn was not present. Creating it fixed this.

Not sure why this happened.


Can't open file txn-current-lock: Permission denied

Sometimes means you're using the wrong username to access that repository.


Sometimes points to directory permission problems on the server end. Depending on the setup, the admin should be able to tell which chown -R or chmod g+w likely sets things back thow they should be. Sometimes you need a little more care.


Out of date: '/file/name' in transaction 'number'

The repository version is newer than the local version.

You haven't done an svn update in a while, and one or more of the files you are committing is newer in the repository.

You need to apply the differences made to the repository to your copy, before you can commit your own changes (given those changes do not conflict).


You could do a svn diff -r HEAD /file/name to look at the changes and estimate whether that will be a problem.

Checksum mismatches
Repository
svn: Checksum mismatch on rep ...

Old versions of Subversion had a bug in how it used the BDB backend, which sometimes led to corruption. This error once likely originates in that.

It's unlikely to still have that version anymore(which one?(verify)) but if you do, use the fsfs backend instead (which apparently also deals better with being stored on NFS).

To fix the repository, see:


working copy
svn: Checksum mismatch for 'filename'
Checksum mismatch while updating

The hash value in the metadata of your working copy is wrong.

Most googled reports point to either a client bug, or file corruption in the working copy. (I'm unsure what the real common reasons are.)


It seems that the hash mentioned in the relevant .svn/entries and the file's copy in the .svn/text-base need to match. If the latter is corrupted, you can test this with an md5sum. If it's the metadata that's at fault, them editing that with the right value may solve it. I'm not sure whether it also need to match something in communication.


The overly-large-hammer approach is to move your working copy and check out a new one, copying in any uncommitted files into this new working copy -- being careful to avoid copying the .svn directories. (This may be somewhat bothersome for you, either because the tree is large, or because your IDE's svn integration does not take kindly to the programmer doing, well, anything)

A similar but simpler workaround would be to do a checkout elsewhere (of the same revision!), and copy in the good metadata from there.

If this problem is isolated to one many sub-directories, a simpler fix may be to remove the sub-directory with the offending metadata, and get it back via an update (won't work on root dir(verify)).

Most of these things depend on how many uncommitted things there were, because it may be a bunch of work to copy all uncommitted data -- specifically avoiding the old metadata.

Entry for ... has no URL

You probably deleted the .svn metadata for a sub-directory in your working copy.

svn update may well help (verify), as may svn cleanup

Moved repository URL

If a working copy refers to an URL that isn't accurate anymore, you don't need to do a new checkout to fix that.

Since 1.7:

svn relocate oldurl newurl [path]

Before that

svn switch --relocate oldurl newurl [path]

See http://svnbook.red-bean.com/en/1.7/svn.ref.svn.c.relocate.html

Moving between repositories

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

When you find that you want to copy data between repositories -- to split off independent projects, or to merge the -- then you probably want to keep the history, and other metadata (if not, just copying files and svn add will do).


'svnadmin dump + svnadmin load

Slowish, deals with a lot of data, but seems to be less fragile than most alternatives.


To dump an entire repository and all its revisions:

svnadmin dump --incremental repo_path > source.dump

Notes:

  • Using --incremental means the eventual load won't complain if the repository already has content.
  • Using --deltas can make the dump smaller, sometimes much smaller, but don't use it if you want to use svndumpfilter


You often want only part of a repository's contents, so you want to filter the dump, typically via paths. You use svndumpfilter, and either include or exclude paths.

You may wish to pipe svnadmin to svndumpfilter to avoid storing unnecessarily large intermediate files. Example:

svnadmin dump --incremental repo_path | \
   svndumpfilter include projects/source --drop-empty-revs --renumber-revs --preserve-revprops \
   > source-filtered.dump

Notes:

  • --drop-empty-revs is mostly seems relevant if you exclude directories, because that can mean a lot of revisions that no longer have changes. There's no point in having a lot of no-change revisions in your new repository -- unless you have log messages that refer to rev numbers.
  • --renumber-revs - if you drop empty revs, this also renumbers them so there are no missing numbers in the sequence.
  • --preserve-revprops - by default, filtered revs will have a note from svndumpfilter. If you use this parameters, they'll contain the original log message, author, date, custom properties, etc.


And load the dumped revisions into the new, possibly empty repository

svnadmin load repo_path < source-filtered.dump


Other options

TODO

svnsync, svn2svn (*2)


Setup, authentication, authorization

Debugging SSH

Subversion calls ssh itself, how is controlled by configuration (look at ~/.subversion/config and /etc/subversion/config)

By default it's something like

$SVN_SSH ssh -q -o ControlMaster=no

...and when SSH doesn't seem to do much you may wish to remove -q (possibly add -v) in the [tunnels] section.


Apache setup
This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


Notes:

  • The docs seem to say that if you use Dav to access a repository, you should not access it by other means.
  • For more than one or two people, auth can be a bit of a pain. At least, you have to have a model to keep authentication and authorization manageable.


Relevant apache modules (and the conf.d vars that tend to make them load via apache IfDefine):

  • mod_dav (dependency for various others), usually enabled by -D DAV
  • mod_dav_fs (if present), enabled by -D DAV (or sometimes -D DAV_FS)
  • mod_dav_lock (if present), used by mod_dav_svn. Also usually loaded via the same define.
  • mod_dav_svn. Depends on mod_dav. Included via -D SVN (depends on DAV)
  • perhaps mod_authz_svn (via -D SVN_AUTHZ) if you want fine-tunable access control (the module mostly lets you point to an ACL-ish file)

See also:


The most basic configuration (often under a sensible virtualhost):

<Location /myrepository>
Dav svn
SVNPath "/path/to/myrepository"
</Location>

If you use just that, the repository will be unsecured (publicly writable).


The mod_dav documentation recommends against using basic auth over non-SSL - probably because basic auth sends (Base64'd) plain-text passwords. It recommends use of either digest auth (most dav/svn clients support it), or basic auth over SSL.



Sites providing subversion

I should make a proper list - as of now this is horribly incomplete.

The following seem to be free of charge:


There are also a number of paid-for subversion servers and general webspace-and-project hosting solutions that offer subversion, which is probably interesting for for larger projects.

See e.g.:


Cleaning up a very large .svn

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Most of the space in a working copy will typically be in .svn/pristine.

You have two versions of everything - more precisely, you have BASE in pristine, and you have copies on the filesystem that you may have altered.

You need pristine for things like revert and diff (against the latest checked out version).


It seems like since 1.7 the pristine storage change that may make certain cases better (duplicates only get stored once). ...but at the same time leaves it valid to leave behind old files, so depending on the client, unnecessary pristine copies are a thing and svn cleanup removes those (side note: whether --vacuum-pristines was implied or not in a cleanup varied with versions). Yet doing that more than never rarely removes much.


Given this, consider whether you want to version larger data files or not. Most of my large pristine is data, and since I use it as backup, I consider that a feature.

And argument against that would be that data just sits there twice doing nothing.


See also

Cheat sheets:


Unsorted: