Putting /etc Under Subversion (SVN)

Instructions taken from here: http://www.barryodonovan.com/index.php/2007/04/25/putting-etc-under-subversion-svn

A Google for the above took some work to locate the exact recipe I wanted for this. The problem is that one really needs to do an ‘in-place’ import. The solution was fromSubversion‘s own FAQs (specifically this) which is reproduced here with some changes:

# svn mkdir svn+ssh://user@host/srv/svn-repository/hosts/host1/etc \
         -m "Make a directory in the repository to correspond to /etc for this host"
# cd /etc
# svn checkout svn+ssh://user@host/srv/svn-repository/hosts/host1/etc .
# svn add *
# svn commit -m "Initial version of this host's config files"

The commit is failing due to propset eol-style errors.  To set the native svn properties for all files under etc you can run this command:

find . -type f -exec svn propset svn:eol-style native {} \;

There was a pre-commit script that was blocking uploading of files with svn:special property set.  Excluding svn:special files out of the check allowed me to commit! Sweet!

Here’s a handy script to add multiple new files to the svn repo by having installed many packages or something that would cause a bunch of files to be added to /etc.

svn st | grep "^?" | awk '{ print $2}' | while read f; do svn add $f; done
svn ci -m "Adding files after extracted tar from prod server"
svn st | grep "^A" | awk '{ print $2}' | while read f; do svn propset svn:eol-style native $f; done

To set svn:special property on a symbolic link:

svn propset svn:special native path/to/symlink

Do NOT set svn:special on actual directories or you will get an:

Svn error: .. has unexpectedly changed special status

To resolve this remove the svn:special property on all directories:

svn st | grep "^~" | awk '{print $2}' | while read f; do svn propdel svn:special $f; done

Remove a directory from subversion control

find /path/to/directory -name .svn -exec rm -rf {} \;

svn fun!

I am just learning how to use svn to move code from dev environments to staging environments to production environments.  Here are some brief explanations of some commonly used svn commands I have learned so far.

For any of the commands listed below, if you need further clarification you can always run the svn help [command] (e.g. svn help merge)


svn co https://URL/path/to/repo 

this will create a directory called repo

If you don’t want the repo directory created, use this

svn co https://URL/path/to/repo .

To rename repo to whatever

svn co https://URL/path/to/repo whatever

In the following examples my svn repositories are located at https://reposerver.com/svn/ Let’s just take on repo for now calling it playing-around. Note for these examples, there is only one svn server so only one location for repos.

Someone deleted the trunk

Recently ran into a situation where someone moved the trunk to create a branch instead of copying. It happens!

# Used svn log -v | more to find the revision where the trunk was deleted.

# Tried to do an svn merge -r revNum:revNum-1 . but kept getting “trunk not under version control” errors.

# Used svn cp to put the trunk back at that revision: svn cp ^/trunk\@revNum ^/trunk

# Run svn up on your working copy.

svn co

svn co is a shortcut for checkout. This will check out a repository. The last argument on the command below is optional and just specifies a name for the checked out repo.  If not specified it will be created with the same name as the repository. I usually like to keep all my repos in a directory called wc so I would cd to wc and run the command.

svn co https://reposerver.com/svn/playing-around play

svn up

For a checked out working copy this updates your working copy to the current repositories HEAD revision. In our example, I would cd to wc/play and run svn up. You may want to run an svn info to see the current revision your working copy has. This is helpful if you need to revert back.

If you needed to revert back the changes pulled down to your working copy you would use the -r option for svn up. Say your current version is revision 1200 (found with svn info) and after and svn up the new revision is 1223.  You would run svn up -r 1200 to undo the changes made from revisions 1201-1223. It is important to note that this does NOT affect the repository ONLY your working copy.

With an svn up -r you cannot commit those changes to the repository. You will need to update to the current revision and use svn merge -r.

svn merge

We work a lot with branching and I am in charge of publishing changes. Developers will create branches to work in and when they are ready, I merge the developers branch into my working copy with svn merge. Note: This command merges changes from one URL into your working copy.

svn up (just good practice to get your working copy up to date first, in addition, you should note the revision number.) Let’s say

svn merge ^/branches/branch_name –dry-run

You can use the –dry-run to see what changes are being made into your working copy.  The ^ is used to merge the changes from that branch INTO your working copy. Once I have seen and am ok with the changes being made to my WC I then run the merge command without the dry run option.

svn merge ^/branches/branch_name

This only makes changes in my working copy though.  I want to then commit these changes to the repository.

If I don’t like the branch or I want to reverse merge it. YOU WILL ONLY WANT TO USE THIS COMMAND IF YOU WANT TO UNDO CHANGES IN THE REPO!

Let’s say the revision previous to the merge command was 1500 and after it was 1505.  To back out the changes you would run (from wc/play):

svn merge . -r 1505:1500

The . says this working copy, the 1505 is the current revision and 1500 is the revision you want to revert back to.  Now you are able to commit the backed out changed to the repository with a commit command similar to the section below.

If you want to just back put the last change you can use the following command:

svn merge . -r 1505:1504

In this command you just subtract 1 from the current revision number to back out the last change.

Let’s say you ACCIDENTALLY ran a svn merge . -r when you wanted to run a svn up -r. You would use svn revert command. See below.

svn revert

So I ran a svn merge -r when I wanted to run svn up -r. To get my working copy back I needed to run a revert command to merges the changes I had reversed back into my working copy.

svn revert –recursive .

The . (dot) say this working copy and the recursive option

svn revert – gets rid of hand edits from a working copy

svn commit

Now I am ready to commit changes to the repository.  I use svn commit, you must provide a comment! Make sure it is explanatory! From the trunk of your repository, (e.g. wc/play)

svn commit -m “ticket# svn merge command”

I learned it by using the requesting ticket number and svn merge command. This will be easier to revert if something breaks in the future.

Backing out a specific changeset. Let’s say there was a commit performed on the trunk at revision 1250 and another commit was performed from a different branch at revision 1350.  I want to back out the changes from the commit at revision 1250.  I would use svn merge with the -r option to backout the changes made to the trunk in the 1250 changeset. Before I run this command, let’s say the HEAD revision is 1500.

svn merge  -r 1250:1249 .

Now the changes only from that one commit are removed from the trunk.  Next I would commit the changes. Now let’s say the commit updates the HEAD to 1501.  Now I want to undo the backout I just performed on the trunk.   I would again use svn merge -r to put the changes back.

svn merge -r 1500:1499 .

This will undo the undo! Gotta love it!

Delete a branch

svn delete https://url.subversionhost.com/svn/reponame/branches/branch_name -m “A very descriptive message for why you deleted the branch”

This will delete from the repo immediately.  If you want to delete from your working copy first, you will then need to commit in order to delete the branch from the repo as well.

svn delete ^/reponame/branches/branch_name

svn commit -m “Deleted branche_name description”

Recover a deleted branch

svn cp https://svn.example.com/repo/branches/branchname@RevNum https://svn.example.com/repo/branches/newbranchname

Where RevNum is the revision just before the branch was deleted.

svn local add, incoming add upon merge & svn: warning: Tree conflicts can only be resolved to ‘working’ state

I recently ran into an issue where I was trying to merge  an old branch into the trunk and was getting the above 2 error messages.  The issue was one user had copied another users branch.  The first user committed her changes and now trying to merge the original branch in was showing a tree conflict.  I found from google searching you can resolve this with the svn resolve command:

svn resolve --accept=working code/bar.c

But the issue was I wanted to keep the more current copy from the trunk instead of the old copy in the branch so this didn’t work for me.

I had to delete the files in my working copy and then merge down the trunk into the old branch.

local edit, incoming delete upon update

svn resolve –accept working ls-isrunning.sh

svn delete path/to/file(s)

svn merge -r RevNum:HEAD https://host.example.com/svn/repo/trunk

You can find the revision that the branch was checked out on with the svn log command:

svn log -v ^/branches/branch_name –stop-on-copy  | more

Replace trunk with branch

# Move to a checkout of the uk.proactiv.com site: cd /home/username/wc/websites/

# Move trunk into branches just to keep a backup: svn mv ^/example.com/trunk/ ^/example.com/branches/www.backup.date -m “Creating a copy of trunk before I delete it”

# Move the branch to the trunk: svn mv ^/example.com/branches/branch_name ^/example.com/trunk -m “Replacing the trunk with “branch_name” for a site redesign”

NOTE: SVN move works like filesystem move. If the directory exists, the move will create the new directory under it. For example, if I didn’t delete trunk, the above command would create branch_name under the trunk instead of creating a new trunk directory.

# If everything comes up ok in trunk and looks good you can delete the backup of the trunk: svn delete ^/example.com/branches/www.backup.date -m “Deleting copy of trunk since replace went well”

Remove directory from subversion control

find directory_name -type d -name .svn -exec rm -rf {} \;

Re-add a directory to version control

mv directory_name /tmp
svn up directory_name

svn: E200012: Error running ‘diff3_program (diff3, gdiff3, etc.)’: exitcode was 255, args were:

in directory ‘.’, basenames:

I thought this error was caused by my upgrade to SVN 1.7 client.  Turns out I had added under [helpers] section diff programs.  By commenting this out in .subversion/config it resolved the issue