Search My Blog

ruby (4) web (4) ruby on rails (3) security (3) GPG (2) OpenPGP (2) RFC (2) linux (2) rails (2) shell (2) sysadmin (2) Exchange (1) GIT. (1) IMAP (1) RCS (1) SSH (1) SVN (1) bundle (1) cURL (1) command line (1) crack (1) css (1) developer (1) email (1) fail (1) hack (1) http (1) mac (1) network (1) password (1) regular expression (1) script (1) subversion (1) terminal (1) textmate (1) tip (1) vim (1)

Friday, January 27, 2012

How to put any directory under SVN revision control using a self-contained repository

Okay, I've not found this elsewhere so I'm writing a post about how I did it.
The tipical SVN scenario is when you and other people are working on shared files by checking out any number of working copies from a repository,
$ svn checkout http://svn.collab.net/repos/svn/trunk /home/me/src/project4/working_copy3
modifying the files and then committing the changes and let the revision control system manage conflicts and merge the updates.
$ svn commit -m "Corrected number of cheese slices."
In this scenario the best place for the repository is in a dedicated and secured server, it doesn't make any sense to have the repository inside its working copy: you want to feel free to make any kind of disaster and even delete the whole directory because you know you can start all over again by checking out a fresh original copy.

But SVN is so simple and powerful that you can let it track any changes that happens on a directory on your own personal computer, for backup or security purposes (think about /etc) or to study what an application does to the the files; and sometimes it may be convenient to create the repository in the same directory that repository is controlling, so you can always backup and move the directory without worrying to break the relationship between the working copy and the repository.
In my case I had an encrypted volume that I mount and unmount in different computers and I wanted to track the changes on this volume even without a network connection, so it turned out that making a self-contained SVN system was the best choice.

There are some simple initial steps to do this, and once completed you can work on the directory as you do usually with any other working copy. Before proceeding just make sure to make a backup of anything you are touching.


Suppose "/pwd" is the directory you want to put under revision control, and start creating a SVN repository where you want (since it will be moved later, I'll place it under /tmp):
$ svnadmin create /tmp/repo/
then import /pwd in this repository and remove it if successfully imported:
$ svn import /pwd/ file:///tmp/repo/ -m '[/] Start tracking all changes within pwd' && rm -fr /pwd/
Now if you check it out you'll have just put /pwd under revision control:
$ svn checkout file:///tmp/repo/ /pwd/

...but wait! IT'S NOT THAT SIMPLE FOR "LIVE" DIRECTORIES!
If you are working on a "live" directory (such as /etc on a busy system), it's not very safe to simply import and delete it because some files may need to change before you check out. So on a "live" directory we'll do it slightly differently:
$ svnadmin create /tmp/repo/
$ svn import /pwd/ file:///tmp/repo/ -m '[/] Start tracking all changes within pwd'
we'll check out under another temporary path
$ svn checkout file:///tmp/repo/ /tmp/pwd/
and move just the SVN system folders into the "live directory":
$ find /tmp/pwd/ -type d -name ".svn" -exec mv -vi {} /pwd/ \;
NOTE: In a Mac OS environment, use 'ditto' instead of 'mv':
$ cd /tmp/pwd/
$ find . -d -type d -name ".svn" -exec ditto {} /pwd/{} \;
$ cd ~-
Now /pwd is effectively a working copy and you can update the files that changed in the meanwhile, and get rid off the other working copy /tmp/pwd:
$ rm -fr /tmp/pwd/

And here comes the part to move the repository inside the working copy:
Change to /pwd/ and update (only needed if it was a "live" directory)
$ cd /pwd/ && svn update
tell SVN to ignore the folder ".repo" where we will put the repository, and commit.
$ svn propset svn:ignore .repo .
$ svn commit -m '[/] svn propset svn:ignore .repo .'
At this point, instead of just moving the repository in "/pwd/.repo", we make a precautionary step to ensure that if we are working on a "live" directory no changes would be lost when we relocate the repository: first we symlink the repository,
$ ln -s /tmp/repo/ .repo
then we tell what is the new location of the SVN repository
$ svn switch --relocate file:///tmp/repo/ file:///pwd/.repo/
and only after making the switch we effectively move it replacing the symlink all at once
$ rm /pwd/.repo && mv -vf /tmp/repo/ /pwd/.repo/
Now you have a self-contained revision control of the current directory.



If you find this useful please leave a comment ;)

No comments:

Post a Comment

If you find this useful please leave a feedback :)