11

I have two tightly related projects (A and B) which share some source code (S). Both of them will be released at the same time and released version should always use the same version of shared code. Shared code S will be changed reasonably often.

So, it will look sometime like this:

  • A version 1 uses S version 1
  • B version 1 uses S version 1
  • A version 2 uses S version 2
  • B version 2 uses S version 2

What is the best way to handle this with git (and/or some tools which use git)?

Here are my concerns:

  • Project A and Project B should be in separate repositories (they are related, but I don't want to have free flow of code between them)
  • If a shared code updated in one project, it should be automatically updated in another one (I don't want to have a situation when a developer forgot to do something and end up having outdate version of shared code).

As I understand one of canonical answers is "use git submodule". However, I read some criticism about this approach. I felt like it was more designed to shared libraries which rarely change.

Another approach which I read was using git subtree

And there are couple of less popular approaches: Repo, GitSlave

What would be the best approach to handle this type of code sharing?

svick
  • 214,528
  • 47
  • 357
  • 477
Victor Ronin
  • 21,310
  • 16
  • 85
  • 171
  • links are not the good ones, I fixed subtree but can't guess the others (use git submodule and criticism) – CharlesB Jan 21 '13 at 18:46
  • Thanks. I fixed all links except one. If I insert it, for some reason it got linked to wrong link. – Victor Ronin Jan 21 '13 at 18:53
  • You can fix it directly in the markdown code – CharlesB Jan 21 '13 at 18:54
  • Take a look at a previous [discussion](http://stackoverflow.com/questions/6500524/git-subtree-or-gitslave-if-switch-away-from-git-submodules), which mentions advantages and disadvantages of different solutions like git subtree, GitSlave and Repo. – harpun Jan 22 '13 at 19:02
  • @VictorRonin which approach did you end up using? I'm having the same dilema ;) – TBE Sep 06 '16 at 09:04
  • @TBE Frankly, I don't remember. It was 3.5 years and 2 companies ago. I believe all of them have downsides. I would probably go with some kind of enforcement and/or automatic updates done on the build machine right now. – Victor Ronin Sep 06 '16 at 13:00

1 Answers1

4

A very simple solution would be to use three repositories: A, B, and S. The project repositories A and B would have a check in their Makefiles to verify that the developer is using the latest code pushed to the repository, e.g.

check:
      git fetch /path/to/S master:tip
      git branch --contains tip | grep -q master

The second line will have a non-zero return value if the developer has an old version of the shared repository. This will abort the compilation with an error. The developer can then go and pull the repository manually to proceed.

Instead of checking the master branch of S, you could also check for some other branch that is defined to be always the one the developers should be using.

Kalle Pokki
  • 4,489
  • 2
  • 14
  • 17
  • This sounds good if you're working on A or B, but imagine you're developing S and should be sure that it works with both A and B. Then you have to keep pushing and pulling intermediate commits to the remote after every minor change. Doesn't sound like a good idea at all. – anishtain4 Apr 16 '20 at 15:36