(2003 to 2005)

Managing multiple projects and their dependancies with Subversion.

Wed Dec 15 19:29:00 UTC+1100 2004


I told you nothing was ever easy. Seriously, why is that?

Life is pain. Isn't it? ISN'T IT!?


<jj5> In the v1.0 svn book, figure 4.2 shows two projects, calc and paint. Say paint was a dependancy of calc, so calc 'referenced' it. While you are working on calc, you want to make changes to the truck of paint. Say calc is going to need some new feature in paint, so you implement that feature in paint and start using it from calc. In this case you want that paint feature to be in the trunk...
<PerlJam> Stevie[FP]: svn cat url | diff foo -   #  :-)
<Stevie[FP]> bah
<darix> jj5: branches.
<darix> it cries for branches
<Stevie[FP]> and if the truck of paint crashes into the waffle truck, and you get tasty new Painted Waffles(TM)...
<jj5> could you check out the trunk of paint, to a working copy calc/lib/paint?
<jj5> ok, so branch paint first..?
<sussman> branch them both, if you wish.
<jj5> then where to checkout the paint branch for the calc working copy?
<sussman> then have one project "include" a specific branch of the other project via svn:externals
<sussman> or a specific tag
<darix> yes
<jj5> ah. I'm starting to get it...
<sussman> if calc 'depends' on paint, then a checkout of calc should automatically also checkout 'paint'
<sussman> that's what svn:externals does.
<sussman> it causes a chain of checkouts.
<sussman> when you checkout the main module, it also causes dependent projects to be checked out as well.
<offby1> garoovy
<jj5> so the answer is to manage them both as seperate projects, probably in the same repository (although that 'depends'), then use externals to point to a specific branch?
<sussman> yes.
<jj5> and then to get the updates back into the trunk of paint, I need to merge the paint branch with the trunk?
<darix> yes
<jj5> I'm a sole developer, so it just feels like a lot of work, given that I'm implicitly a 'serial context'...
<jj5> but I do want to do it right..
<darix> jj5: it isnt so much work
<PerlJam> jj5: I know the feeling.  Though I'm not the sole developer here, I'm the most prolific and all the merges are starting to bother me.
<darix> maybe 4-5 commands
<jj5> I have about 60 projects..
<jj5> so, that ends up being a lot of work.
<jj5> I'm used to 'breaking the build' and then fixing it as soon as I can, when the trunk of a dependancy has a breaking change..
<jj5> I need to do the work anyway.
<jj5> so, if i'm creating branches of paint, in my working copy, what is a good way to layout my directories?
<sussman> jj5: is it really necessary to have two separate projects?
<sussman> if your calc depends on paint,
<sussman> do other programs also depend on paint?  is it really a shared component?
<darix> or is it released standalone
<darix> jj5: repos layout?
<jj5> sussman: yes, it's really a shared component, with lots of different projects that use it.
<jj5> for example, I have an 'enterprise framework' that all my big projects use, and a 'common components' project that even little projects, and the 'enterprise framework' use. Then I've got internal, and client specific projects. I've also got personal and company projects.
<jj5> darix: what is it that you're asking about my repository layout?
 Twiun is now known as Twiun[away]
<jj5> I wasn't asking about my repository layout. Assume that I'm using the repository from Fig 4.2, and working with the paint and calc projects. I need to reference (what I'd prefer was the trunk, but that you suggest is a branch) paint from calc. Should I check out paint (either a branch, or trunk) to a subdirectory of the calc working copy, or should I check out to a 'trunk' or 'branch name' subdirectory of paint, effectively mimicing the repos in
<jj5> my working copy?
<jj5> is my question lame for some reason? or too hard to answer briefly? I have tried to rtfm, but haven't found enough guidance wrt my situation.
<PerlJam> jj5: read the book on svn:externals.
<PerlJam> jj5: but the answer is "yes" I think
<jj5> yes for lame?
<PerlJam> no, yes for that's how you should do it.
<jj5> yes for subdirectory, or mimic repository?
<PerlJam> subdir
<jj5> ah, subdir with externals..
<jj5> and if I want to, I can use svn:externals to reference the trunk, and just break whatever I feel like.. ;)
<PerlJam> indeed
<jj5> thanks
<PerlJam> heh ... I still catch myself saying things like "is it in CVS?" when we use subversion.
<darix> !a jj5 repos layout
<ayita> jj5:
<jj5> say I'm still using the Fig 4.2 repos. And using externals to 'include' the trunk (or a branch) of paint in calc/lib/paint in my working copy. Say I start a new project calendar and do a similar thing to reference paint, calendar/lib/paint. If I modify paint while working on calc, then checkin calc, and manually cheking the paint subdir, then the next update of calendar wouldn't ask me to resolve conflicts with /calendar/lib/paint...
<jj5> It'd just update and possibly break calendar until I fixed it?
<jj5> I guess if I made changes to both calendar/lib/paint, and calc/lib/paint, then I'd get ask to resolve conflicts...
<jj5> why do I keep getting refered to the repos layout chapter? I've read it a few times. I'm pretty sure I understand it. What I'm really trying to understand is how to juggle directories in my *working copy*.
<darix> jj5: it was just to show you why i asked you about it. =)
<darix> normally people say thank you to ayita after she replied
<jj5> OK. But like I tried to say, I'm talking about a 'hypothetical' and I'm referring to the 'text book' repository. So, I shouldn't have to talk about that. The feedback I got from sussman and PerlJam indicated that I should probably keep multiple copies of the 'same' project (trunk or branch) in my working copy, and manage those multiple working copies of 'the same thing' with externals..
<jj5> Are we all in agreeance? :)
<sussman> I'm not sure I understand all these complex things...
<sussman> my gut tells me that you're thinking waaaay too hard about the problem.
<jj5> I need to think hard so that I get it right. I've got nearly 100,000 source files to manage.. :(
<jj5> suggests I'll be in the 'frustrated' camp if I use svn:externals and need to tag a version...
<darix> jj5: right
<darix> that is usefull in general
<darix> and it is not really frustrating
<jj5> darix: I don't understand what you're telling me...
<darix> jj5: tagging in general is usefull
<jj5> of course
<darix> and svn:externals arent really frustrating
<jj5> but if I tag calc, and use svn:externals to link paint, then my tagged calc will forever reference the trunk of paint
<jj5> that's frustrating
<darix> hmm
<darix> jj5: you can change tags ;)
<jj5> yeah..
<darix> to reference the correct tag of paint
<jj5> I realised that.. thus the frustration.. that's a lot of maintenance work.
<darix> or better do it before
<darix> right
<darix> jj5: but your setup is rather comples
<darix> complex
<jj5> but if I reference the correct tag of paint, then I can't change it, and I'm generally going to want to be able to do that..
<jj5> perhaps I can write a script to help me manage the svn:externals properties..
<darix> jj5: tags are normally snapshots
<jj5> and just flip them to a tag before I tag a 'higher up' version.
<darix> not meant to be edited
<jj5> darix: yes, I understand that
<darix> so
<darix> im gone now
<jj5> :)
<darix> have fun with svn jj5
<darix> :)
<darix> have to catch the shops for some food
<jj5> get me a beer
<PerlJam> jj5: Why do you want to change the tag of paint?
<PerlJam> jj5: What model do you use for your repositories?  Must the trunk be always-compilable and ready to run?
<jj5> PerlJam: nope. It can have breaking changes. (That's what it's for, right! ;)
<jj5> offby1: Thanks. :)
<PerlJam> jj5: So why would you change the tag in svn:externals?
<jj5> PerlJam: What I meant by changing the 'tag of paint' was that in calc I'd svn:externals paint/trunk generally. But when I tag calc, I need to update the properties on the tag of calc to point to a specific tag of paint taken at the same time.
<PerlJam> jj5: presumably you'd tag the version that isn't broken and just use that.
<PerlJam> "at the same time"?
<jj5> My thing is that I really want to be able to work on paint directly while working on calc. So while I'm working on the trunk of calc, I want to also be working on the trunk of paint.
<sussman> jj5: another idea is to avoid svn:externals altogether.  just treat the projects as separate entitites.
<sussman> and write a build system that checks out nested working copies of the 'correct' versions of things
<jj5> Yeah, that was kind of my original question.. I think.. :P
<sussman> :-)
<sussman> that's what we do.
<seberino_> will svn cp (copy) make any needed subdiretories like linux's mkdir -p???
<seberino_> svn cp svn://mypc/myproject svn://mypc/a/b/c/c/d/e/f  <---will it create all new levels if a doesn't exist?
<seberino_> s/a/'a'/
<sussman> no.
<sussman> it will not.
<seberino_> sussman: svn mkdir first? :)
<jj5> what do you use for your build system sussman? make?
<sussman> so run 'svn mkdir URL' as needed.
<sussman> it's complex.  :-)
<sussman> we use ant.
<sussman> but we have a python script that does the initial checkout
<seberino_> sussman: will 'svn mkdir' create all subdirs? a/b/c/d/e/f/... etc?
<jj5> what is a good 'branching convention' for such a setup?
<sussman> seberino_: can't remember
<sussman> jj5: let me tell you how our system works
<jj5> sussman: shoot!
<seberino_> bang!
<sussman> we have a python script that takes a branch or tagname as an argument.
<sussman> it checks out a working copy of the 'master' project, which is basically a skeleton of empty dircs
<sussman> dirs
<sussman> each empty dir represents a component/module
<sussman> then, based on a local .INI file,
<sussman> the python script proceeds to 'svn switch' each empty dir to an appropriate branch/tag/source/prebuilt directory
<sussman> in our system, each component can either be in 'source mode' (lots of .java files) or in 'prebuilt mode' (some .jar files)
<sussman> and of course, a component can come from a particualar branch as well.
<Tlaloc> seberino svn mkdir won't recursively make parent directories.  It behaves like normal unix mkdir, not like mkdir -p.
<exarkun> I deleted a branch I didn't mean to.  I'm trying to copy it back to HEAD: "svn cp -r 6635 svn+ssh:// ./" but this fails with "svn: Working copy '.' locked \n svn: run 'svn cleanup' to remove locks (type 'svn help cleanup' for details)".  Running svn cleanup doesn't change anything (the cp command seems to be what's dirtying things).
<sussman> anyway, the python script does an 'svn switch' of each empty dir to an appropriate repository dir.
<sussman> the result is a single working copy... 'svn up' works on it, so does 'svn commit', and so on.
<sussman> no use of svn:externals at all.
<jj5> sussman: cool. thanks. I guess I could do something similar with nant (not in a hurry though..)
<sussman> if you want to flip a component to a different branch, or from prebuilt to source mode, just tweak an INI file, and rerun the python script.
<sussman> and it will 'svn switch' appropriately.
<niv> nice :)
<sussman> I didn't write it.   but fitz dreamed it up.
<jj5> nice indeed.
<sussman> CEE is a complex beast.
<niv> CEE?
<ayita> The CollabNet Enterprise Edition version 3.0 is out featuring full Subversion support.
<sussman> ha
<niv> ah.
<sussman> good bot.

Copyright © 2003-2005 John Elliot