I have a number of client projects, each of which has it's own repo. Let's call them Repos 1-3.
Each client project shares the same base framework/template. Let's call it Repo A. I want every client repo to be able to pull the latest changes from Repo A.
I then have a number of features which I have set up as separate repos. Let's call them Repos i-iii. I want every client repo to be able to pull the latest changes from Repo i, ii or iii, depending on which features the client project has.
Example:
- Client Repo 1 would pull from Repo A and also say Repo i and iii
- Client Repo 2 would pull from Repo A and Repo ii
- Client Repo 3 would pull from Repo A, Repo ii and iii
The client projects never need to push back up to any of the repos "feeding them" but I obviously want to be able to create branches on my client project repos so that I can build, test, merge, etc.
With some help from a somewhat-more-git-experienced friend I currently have the following workflow, which works - to an extent.
After setting up a new client repo, I run the following:
git remote add template [Repo A location]
git remote add [feature repo name] [feature repo location]
git checkout –b [project branch name]
git pull template master --allow-unrelated-histories
git pull [feature repo name] master --allow-unrelated-histories
(do this for each feature included in this client project)
Using this workflow I am able to:
- keep my base template, features and client projects all separate which is nice from a development perspective
- keep my client projects up to date with the base template and features by periodically running commands 4 and 5 from the list above
Obviously though, I end up with a combined history which isn't ideal.
Is there a better way of doing this?
Important additional info: The repos share folder structure, i.e. I can't contain Repo A in its own folder and each feature repo in its own folder, etc.
Example:
Repo A (Template) Repo 1 (Client Proj.) Repo i (Feature)
| | |
+-- dir 1 +-- dir 1 +-- dir 1
| | | | | |
| +-- dir 1a | dir 1a | +-- dir 1a
| | | | | | .
| | +-- dir 1ai | +-- dir 1ai | .
| | | | | | | .
| | +-- file a | | +-- file a | +-- dir 1aii
| | +-- file b | | +-- file b | |
| | | | +-- file c | +-- file x
| | | | |
| +-- dir 1b | +-- dir 1b |
| | | | |
| +-- file m | +-- file m |
| +-- file n | +-- file n |
| | +-- file o |
| | |
+-- dir 2 +-- dir 2 +-- dir 2
| | |
+-- dir 2a +-- dir 2a +-- dir 2a
| | | | | |
| +-- file t | +-- file t | + file u
| | +-- file u |
| | +-- file v |
| | |
+-- dir 2b +-- dir 2b +-- dir 2b
| | |
+-- file p +-- file p +-- file r
+-- file q +-- file q
+-- file r
+-- file s
I believe this rules out Git Submodules, but thank you @ElpieKay for the suggestion.