[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Vendor branch with customization, to be used in multiple projects

From: Stefan Sperling <stsp_at_elego.de>
Date: Tue, 24 Apr 2012 18:48:44 +0200

On Tue, Apr 24, 2012 at 12:25:22PM -0400, Ryan Lange wrote:
> Hello,
>
> I hope this is appropriate for the mailing list—and I apologize if it
> isn't—but I have a repository design issue that I haven't been able to
> find discussed elsewhere and was wondering if anyone would be willing
> to offer their thoughts.
>
> I'm using a single repository to hold multiple projects. Each of these
> projects uses third party code from a particular vendor. They may use
> different versions of that code, but this is handled well using vendor
> branches as described in the SVN book, with a slight twist to
> accomodate multiple projects.
>
> - / (repository root)
> - projects/
> - ProjectA/
> - VendorA/ (svn:externals "^/vendors/VendorA/1.1/")
> - ProjectB/
> - VendorA/ (svn:externals "^/vendors/VendorA/1.0/")
> - vendors/
> - VendorA/
> - 1.0/
> - 1.1/
> - current/
>
> I've so far had no need for project-specific customizations, which is
> why I'm using svn:externals. Now, I also maintain a couple of local
> bug fixes for VendorA's code. Since they're bug fixes, they should be
> available to all projects. The part I'm struggling with is just
> figuring out the cleanest way of handling this situation. My first
> thought was to load up the initial drop, patch it, and tag it in some
> way indicating that it has been customized. Something like this:
>
> - vendors/
> - VendorA/
> - 1.0-custom1/
> - current/
>
> Then I realized that svn_load_dirs (or Ubuntu's equivalent, at least:
> svn-load) doesn't actually merge changes; it's just an import. That
> means any customizations in "current" would be overwritten and I would
> have to reapply my patches for each new vendor drop.
>
> Another option is to keep the customizations separate:
>
> - vendors/
> - VendorA/
> - 1.0/
> - current/
> - vendors-custom/
> - VendorA/
> - 1.0-custom1/
> - current/
>
> Maybe a combination of the two:
>
> - vendors/
> - VendorA/
> - 1.0/
> - 1.0-custom1/
> - current/
> - current-custom/
>
> But with the extra merging and tagging that would be needed to keep
> this custom branch up-to-date, it might actually be easier to just
> re-patch each new vendor drop.
>
> Any thoughts, advice, and suggestions would be very welcome.
>
> Thanks,
> Ryan

The extra merging and tagging buys you one very important thing:
It allows you to cleanly see the difference between the vendor's
version of the code and your own simply by comparing two URLs.
If you commit your own changes directly on the vendor branch you
don't have clean separation of histories of their and your own
change and telling apart changes coming from either side becomes
a bit messy.

It is not actually that complicated once you get used to it.

The usual approach would be to leave the 'vendor' branch unmodified,
and create a branch off this 'vendor' branch which you modify freely.
This modified branch can be used in your own projects (e.g. via an
external, as you do now).

Using svn_load_dirs you keep loading unmodified vendor drops on the
unmodified branch whenever you want to catch up with new vendor releases.

Visualising this in a graph where time flows from left to right
and each line represents a branch it looks like this:

                              your commits go on this branch
            /custom/VendorA +-------------------------------
                           /
                          / copy
                         /
/vendors/VendorA -------+------------------------------------
            initial drop new vendor drops go here (via svn_load_dirs)
            imported here

Now, each time you import a new drop, you can merge the incoming
changes into your custom branch, on top of your own local changes:

            /custom/VendorA +--------------+-----------------
                           / /
                          / copy / merge r10-r200 vendor->custom
                         / /
  /vendors/VendorA -----+----------r200----------------------------
                       r10 new vendor drop X imported in r200

The commands to run this merge would be:

  svn checkout http://svn.example.com/svn/custom/VendorA
  cd VendorA
  svn merge ^/vendors/VendorA
  # fix any conflicts
  svn commit -m "merged vendor drop X with custom changes"

You don't need to specify revision numbers because merge-tracking
takes care of that for you.
Received on 2012-04-24 18:49:22 CEST

This is an archived mail posted to the Subversion Users mailing list.