On Fri, Mar 8, 2013 at 4:35 PM, Stefan Zumwiese <dreimal_at_abwesend.de> wrote:
> Am 11.02.2013 22:08, schrieb Stefan Zumwiese:
>
>> I'm planning on setting up a repository which looks like this:
>>
>> \common
>> \common\folder1
>> \common\folder2
>> \project1
>>
>> project1 would include folder1 and folder2 via relative svn:externals
>> properties. Other projects in the same repository could include the same
>> and/or other common folders.
>
>
> Maybe I should give some more background about what we want to achieve: our
> goal is to have the code of multiple projects/products and all common parts
> in one repository, without the need to specify explicit revisions for the
> common parts which are pulled into single projects via svn:externals. For
> each project/product a branch would be created once it is put into
> maintenance mode. This means that also the common parts are branched. Each
> project is therefore free to make changes to common parts, but does not see
> changes made to common parts by other products (unless explicitly merged).
>
> \trunk\common
> \trunk\common\folder1
> \trunk\common\folder2
> \trunk\project1
> \trunk\project2
> \branches\project1_v1 <-- complete branch of \trunk
> \branches\project2_v3 <-- complete branch of \trunk
>
> To keep the size of a checkout at a reasonable size, only the relevant
> common parts should be pulled in via externals. One would than check out
> e.g. \trunk\project1.
Sorry for the late reply, but better late than never I suppose ...
We have a similar setup, where multiple interrelated projects and
sub-projects are next to each other, below trunk. We also create
complete branches of the entire trunk, for every release of a project.
But we only introduce externals for those release branches (the
externals are not defined on trunk -- that's because developers
usually have some mix of projects they're working on, and then they
don't want 'common1' checked out twice, below project1 and project2).
To be a bit more concrete, our layout looks as follows (suppose
project1 depends on common1 and common2, and project2 only depends on
common1):
/trunk/common1
/trunk/common2
/trunk/project1
/trunk/project2
/branches/project1/v1 <-- complete branch of /trunk
/branches/project1/v2 <-- complete branch of /trunk
/branches/project1/v3 <-- complete branch of /trunk
/branches/project1/try <-- dummy dir with externals definition
/branches/project1/prod <-- dummy dir with externals definition
/branches/project2/v1 <-- complete branch of /trunk
/branches/project2/v2 <-- complete branch of /trunk
/branches/project2/try <-- dummy dir with externals definition
/branches/project2/prod <-- dummy dir with externals definition
So:
- At any time we have two "active branches", called "try" (release
which is undergoing QA) and "prod" (current production version -- this
branch only gets urgent fixes merged from trunk, which need to be put
into production as urgent patches).
- The directory "try" contains nothing but an svn:externals property,
which refers to the concrete subdirs of the release branch that's
currently considered the try-branch (we use repository-relative
externals for that).
For example, the svn:externals of /branches/project1/try might look like this:
^/branches/project1/v3/project1 project1
^/branches/project1/v3/common1 common1
^/branches/project1/v3/common2 common2
And the svn:externals of project2/prod might look like this:
^/branches/project2/v1/project2 project2
^/branches/project2/v1/common1 common1
Our build server can just keep a checkout of ^/branches/project1/try
or ^/branches/project2/prod, or ..., and this checkout only contains
what's needed. It will also switch automatically to the new release
upon 'svn update', when the externals are changed to a new version.
The externals definitions in those "try" and "prod" dirs are updated
automatically by a script during our release process.
> When experimenting with this planned repository layout and testing some use
> cases, I ran into these issues:
>
>
>> When viewing the log of project1, I can see only the direct changes of
>> project1, not the changes that were made in the relative externals.
>>
>> Since I'm currently deciding on the repository structure: how good are
>> chances that something like --include-externals or
>> --include-local-externals might be added as an option to svn log in the
>> future?
>
> (Choose a name for the flag as you see fit.)
Okay, might be interesting, but I'm not sure if this is easily doable
given the current design of externals. Externals are a pure
client-side concept ... the server just sees this as another property
but doesn't do anything special with it. Maybe some other dev can
comment more on this ... (if you hear nothing, feel free to file a
feature request in the issue tracker --- regardless of how realistic
this is with the current design, I feel this is still a legitimate
user request).
During our release process, we solve this problem with a little script
(actually, we automatically create release notes based on the commit
messages): in a checked out "try" or "prod" (with externals just below
it), we iterate over the subdirs and 'svn log' them individually (and
collect them in a set so as to eliminate duplicate log entries, before
processing them further). Of course, this depends heavily on our
standard layout, where we always know that the first level below such
a checkout is a list of external subdirs.
>>
>>
>> Also, do you think a similar feature could also be added to svn update,
>> such that when specifing an explicit revision, relative externals from
>> the same repository will be updated to this revision number as well
>> (instead of HEAD)?
>>
>> So
>> svn update --revision 123 --include-local-externals
>
> (Choose a name for the flag as you see fit.)
>
>> would update all relative externals which do not explicitly specify a
>> revision to revision 123 as well, while
>> svn update --revision 123
>> stays the same, e.g. updates the externals to HEAD.
I think this feature was recently requested by another user. See issue
#4286 [1].
There is nobody actively working on this though, so I'm not sure if
this feature will arrive soon. Patches / discussions are always
welcome of course [2] :-).
> Are there others who might need the same functionality? Do you think these
> features could make it into SVN?
>
> Are there better ways to accomplish the same result? Instead of using
> externals, we might as well use a checkout depth of 'empty' for the common
> folder and explicitly specifying the checkout depth for each required common
> part only. However, since this would require the use of a batch file or
> shell script for every fresh checkout, I'm rather looking for a way to use
> the possibilities built into SVN already.
Ah yes, I've also been considering switching our build system more to
"sparse checkouts", instead of using externals. But the problem is
indeed that there are no core features in SVN for handling a certain
configured "sparse view" of the repository.
There is a python script in the "tools" directory of the subversion
repository for some basic operations, working with so-called "viewspec
files" [3], but other than that, you'll have to roll your own.
[1] http://subversion.tigris.org/issues/show_bug.cgi?id=4286 (Relative
Revision Peg On Relative Path Externals)
[2] http://subversion.apache.org/docs/community-guide/general.html#patches
[3] https://svn.apache.org/repos/asf/subversion/trunk/tools/client-side/svn-viewspec.py
--
Johan
Received on 2013-04-14 02:38:06 CEST