We often have common code that we’d like to share across different projects. (For example, our Utility library is useful in both the desktop software and in an ASP.NET website.)
One way of sharing code is to place it in its own repository, and add it as
a submodule to all repos
that need it. But submodules are a bit of a pain to work with on a daily
basis (for example,
git checkout doesn’t automatically update submodules
when switching branches; you have to remember to do this every time, or
create an alias).
Submodules also make it difficult to “compose” libraries. For example, App1
and App2 might both use Utility, but they might also both use Framework,
a desktop application framework that’s not general-purpose enough to live in
Utility, but is in its own repo. If Framework itself uses Utility as a
submodule, then the App1 and App2 repos might contain both
/ext/Framework/ext/Utility. This is a maintenance nightmare.
Our choice at Logos is to clone all necessary repositories as siblings of
each other. In the App1 example above, we might have
C:\Code\Utility as independent repos. Dependencies
are expressed as relative paths that reference files outside the current
..\..\..\Utility\src\Utility.csproj. We’ve written a shell script
that clones all necessary repos (for a new developer) or updates all
C:\Code (to get the latest code).
By convention, developers are working on the
master branch on each repo
(or possibly a
feature branch in one or more repos for a complex feature).
It’s theoretically possible for someone to push a breaking change to
Utility and forget to push the corresponding change to App1 (a problem
that submodules do prevent), but this happens very infrequently.
Posted by Bradley Grainger on November 17, 2012