[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