Skip to content

Instantly share code, notes, and snippets.

@abeham
Last active January 23, 2021 09:51
Show Gist options
  • Save abeham/e0251ee4169ad483f77a321811cfcf94 to your computer and use it in GitHub Desktop.
Save abeham/e0251ee4169ad483f77a321811cfcf94 to your computer and use it in GitHub Desktop.
Discusses approaches to structure a git repository for software that is customized for several clients
Consider a software that is customized for each client. It contains common components, modules, and
client-specific customizations thereof. For instance,
Common
+ Common.ClientA
+ Common.ClientB
ModuleA
+ ModuleA.ClientB
ModuleB
+ ModuleB.ClientA
+ ModuleB.ClientB
Main
There are three options for organizing a git repository:
1. Divide the repo into subrepos and pull them together selectively using submodules (in the case above
three repos: Common (+Modules), ClientA, ClientB or 5 repos: Common, ModuleA, ModuleB, ClientA, ClientB)
2. Put everything into one repo, but create separate branches (in the case above: Common (+ Modules),
ClientA, ClientB + for each master, develop, release, feature and hotifx branches [assuming a gitflow approach]).
3. Put everything into one repo and use different solutions or solution configurations to discern the clients
Regarding #1: A lot of discussion about submodule vs subtree. Still, the use case here is to get upstream
changes from ClientA repo back to Common. Otherwise it's very hard to hold "the common" together. Interestingly,
this is hardly discussed on the web where the use case seems to be to get downstream changes. Most agreed use
case for submodules is of embedding an external library that only needs occassional updating.
Advantage: every commit to common will have to be pushed to the common repository and thus those changes can
never diverge creating multiple different "common". Additionally, it allows to progress in different speeds,
e.g. ClientA needs new functionality in Common, but ClientB remains at older version for now.
Disadvantage: submodules are more difficult to work with and require special care (submodule update after pull,
wordy branching in case submodules needs to be branched as well)
Regarding #2: Each branch contains only exactly those projects that are required for each client. This makes
merging upstream changes a little bit more complex, because they'd have to be selective (merge --no-ff --no-commit
and removing client specific parts).
Advantage: Easier to work with because no submodules are involved.
Disadvantage: Lots and lots of branches in one single rep. Changes in the common of ClientA might not get merged upstream.
Regarding #3: A simple solution.
Advantage: Simple.
Disadvantage: Lots of unrelated changes in merges (e.g. branching for ClientA, but having to merge commits for
ClientB from master). Lots of code in e.g. ClientA release branch that is not meant to be compiled (all of
ClientB specialization). Difficult to give only selective access.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment