[ILUG] Tip of the day: svn hackery

Stephen Shirley diamond at skynet.ie
Fri Aug 18 00:04:25 IST 2006


Morning,

Say you have all of /etc stored in svn (say at file:///root/svn/etc).
It works nicely, you can trivially see if files have changed, revert
to any previous version, sleep well at night. Great. Then you decide
that you should also store /boot in svn (say at
file:///root/svn/boot). Also great. However, now in order to check if
anything has changed, you have to do:

    cd /etc; svn status
    cd /boot; svn status

If you add any more top-level directories to svn, it quickly becomes a
pain to do this. So, you want to store / in svn also (with the
appropriate svn:ignore properties set so that all the non-svn'd
top-level dirs don't show up in 'svn status'). If however you try

    svn co file:///root/svn/ /

it won't work as svn will try to also check out /etc and /boot, and
will complain that those directories already exist. Hurm. If you try
the non-recursive checking

    svn co -N file:///root/svn/ /

it will check out file:///root/svn/ into / alright, but /etc and /boot
will show up as unknown in svn status:

    fluff# svn status /
    ?    /boot
    ?    /etc

Fixing this requires some minor hackery of the .svn/ special
directory. If you open /.svn/entries in a text editor, you'll see
something like:

<?xml version="1.0" encoding="utf-8"?>
<wc-entries
   xmlns="svn:">
<entry
   committed-rev="226"
   name=""
   committed-date="2006-08-17T22:34:00.835159Z"
   url="file:///root/svn"
   last-author="root"
   kind="dir"
   uuid="18f6e95b-a6ff-0310-910f-8823210a8ec4"
   revision="226"/>
</wc-entries>

It contains a single <entry ... /> tag, with the name attribute set to
"". This is the svn entry for / itself. If you open /etc/.svn/entries
in a text editor, you'll find a very similar <entry... name=""... />
tag:

<entry
   committed-rev="25"
   name=""
   committed-date="2005-09-22T20:33:37.949298Z"
   url="file:///root/svn/etc"
   last-author="root"
   kind="dir"
   uuid="18f6e95b-a6ff-0310-910f-8823210a8ec4"
   revision="25"/>

So, to make svn consider /etc to be part of the / working directory,
what you need to do is this: copy the above <entry.../> tag from
/etc/.svn/entries into /.svn/entries, placing it just before the
closing </wc-entries> tag. Then, change the 'name' attribute from ""
to "etc". The complete finished /.svn/entries file should look like
this:

<?xml version="1.0" encoding="utf-8"?>
<wc-entries
   xmlns="svn:">
<entry
   committed-rev="226"
   name=""
   committed-date="2006-08-17T22:34:00.835159Z"
   url="file:///root/svn"
   last-author="root"
   kind="dir"
   uuid="18f6e95b-a6ff-0310-910f-8823210a8ec4"
   revision="226"/>
<entry
   committed-rev="25"
   name="etc"
   committed-date="2005-09-22T20:33:37.949298Z"
   url="file:///root/svn/etc"
   last-author="root"
   kind="dir"
   uuid="18f6e95b-a6ff-0310-910f-8823210a8ec4"
   revision="25"/>
</wc-entries>

Now when you check the svn status of /, it no longer considers /etc to
be a foreign object:

    fluff# svn status /
    ?    /boot

Bingo. If you repeat the process again for /boot (i.e. copy the
<entry... name=""... /> tag from /boot/.svn/entries into /.svn/entries
before the closing </wc-entries> tag, and set the name attribute to be
"boot") and any other applicable dirs, svn will then start treating
them as proper checked-out subdirs of the working dir.

As your reward, a single 'svn status /' will now check all of the
top-level dirs that are stored in subversion, making it much easier to
keep track of things.

Steve
-- 
"You are technically correct, the best kind of correct."
- Bureaucrat 1.0, Futurama



More information about the ILUG mailing list