As is especially the case when developing
software, the data that you maintain under version control is often
closely related to, or perhaps dependent upon, someone else's data.
Generally, the needs of your project will dictate that you stay as
up to date as possible with the data provided by that external
entity without sacrificing the stability of your own project. This
scenario plays itself out all the time—anywhere that the
information generated by one group of people has a direct effect on
that which is generated by another group.
For example, software developers might be
working on an application that makes use of a third-party library.
Subversion has just such a relationship with the Apache Portable
Runtime (APR) library (see the section called “The Apache
Portable Runtime Library”). The Subversion source code
depends on the APR library for all its portability needs. In
earlier stages of Subversion's development, the project closely
tracked APR's changing API, always sticking to the “bleeding
edge” of the library's code churn. Now that both APR and
Subversion have matured, Subversion attempts to synchronize with
APR's library API only at well-tested, stable release points.
If your project depends on someone else's
information, you could attempt to synchronize that information with
your own in several ways. Most painfully, you could issue oral or
written instructions to all the contributors of your project,
telling them to make sure they have the specific versions of that
third-party information that your project needs. If the third-party
information is maintained in a Subversion repository, you could
also use Subversion's externals definitions to effectively
“pin down” specific versions of that information to
some location in your own working copy (see the section called
“Externals Definitions”).
But sometimes you want to maintain custom
modifications to third-party code in your own version control
system. Returning to the software development example, programmers
might need to make modifications to that third-party library for
their own purposes. These modifications might include new
functionality or bug fixes, maintained internally only until they
become part of an official release of the third-party library. Or
the changes might never be relayed back to the library maintainers,
existing solely as custom tweaks to make the library further suit
the needs of the software developers.
Now you face an interesting situation. Your
project could house its custom modifications to the third-party
data in some disjointed fashion, such as using patch files or
full-fledged alternative versions of files and directories. But
these quickly become maintenance headaches, requiring some
mechanism by which to apply your custom changes to the third-party
code and necessitating regeneration of those changes with each
successive version of the third-party code that you track.
The solution to this problem is to use vendor
branches. A vendor branch is a directory tree in your own version
control system that contains information provided by a third-party
entity, or vendor. Each version of the vendor's data that you
decide to absorb into your project is called a vendor drop.
Vendor branches provide two benefits. First, by
storing the currently supported vendor drop in your own version
control system, you ensure that the members of your project never
need to question whether they have the right version of the
vendor's data. They simply receive that correct version as part of
their regular working copy updates. Second, because the data lives
in your own Subversion repository, you can store your custom
changes to it in-place—you have no more need of an automated
(or worse, manual) method for swapping in your
customizations.
General Vendor Branch Management
Procedure
Managing vendor branches generally works like
this: first, you create a top-level directory (such as /vendor) to
hold the vendor branches. Then you import the third-party code into
a subdirectory of that top-level directory. You then copy that
subdirectory into your main development branch (e.g., /trunk) at
the appropriate location. You always make your local changes in the
main development branch. With each new release of the code you are
tracking, you bring it into the vendor branch and merge the changes
into /trunk, resolving whatever conflicts occur between your local
changes and the upstream changes.