102

I feel that using Git submodules is somehow troublesome for my development workflow. I've heard about Git subtree and Gitslave.

  • Are there more tools out there for multiple repository projects and how do they compare ?
  • Can these tools run on Windows ?
Mouloud85
  • 3,826
  • 5
  • 22
  • 42
Chau Chee Yang
  • 18,422
  • 16
  • 68
  • 132
  • 3
    Are you talking about the Git subtree merge strategy or [Avery Pennarun's git-subtree](https://github.com/apenwarr/git-subtree)? The two are fundamentally not the same. – kynan Apr 13 '12 at 23:31
  • 1
    A good read here http://codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use-git-submodules/ – nawfal Feb 24 '13 at 00:13
  • 3
    See my [unofficial fork of gitslave](https://github.com/joelpurra/gitslave), hopefully more active than the original has been since 2.0.2. – Joel Purra Jan 04 '17 at 21:44
  • 1
    There is also [git-subrepo](https://github.com/ingydotnet/git-subrepo). – huggie Mar 13 '18 at 03:31

4 Answers4

123

Which is best for you depends on your needs, desires, and workflow. They are in some senses semi-isomorphic, it is just some are a lot easier to use than others for specific tasks.

  • gitslave is useful when you control and develop on the subprojects at more of less the same time as the superproject, and furthermore when you typically want to tag, branch, push, pull, etc all repositories at the same time. gitslave has never been tested on windows that I know of. It requires perl.

  • git-submodule is better when you do not control the subprojects or more specifically wish to fix the subproject at a specific revision even as the subproject changes. git-submodule is a standard part of git and thus would work on windows.

  • git-subtree provides a front-end to git's built-in subtree merge strategy. It is better when you prefer to have a single-repository "unified" git history. Unlike the subtree merge strategy, it is easier to export changes to the different (directory) trees back out to the original project, but it is not as automatic as it is with gitslave or even git-submodule.

  • repo is in theory similar to gitslave, but not as well documented for non-android operations that I have found. It is fairly dedicated to the Google Android development model and only natively supports a handful of git commands (though you can run arbitrary commands) and the limited native support doesn't support, for example, a centralized repository to push to and checking out a branch seems fairly difficult.

  • kitenet's mr is what you would want to use if you have multiple version control systems in use, but is mostly limited for git-only superprojects due to its lowest common denominator approach. There are ways to run arbitrary commands, but they are not as well integrated.

0xC0000022L
  • 20,597
  • 9
  • 86
  • 152
Seth Robertson
  • 30,608
  • 7
  • 64
  • 57
  • 3
    Great breakdown! I'd love to see it amended to differentiate "subtree merge" from git-subtree as @kynan mentions. – BrianTheLion Oct 12 '12 at 03:22
  • mr isn't limited to the lowest-common denominator, all git commands are available (including the ones with no equivalent anywhere). – Tobu Nov 04 '12 at 23:52
  • 1
    @Tobu: I don't consider mr's ability to run arbitrary commands the same as having an integrated git command support. I'm assuming here you are talking about something like `mr run git config ...` or perhaps (even worse) the config file method to alias specific commands to names. Of course, if you are aware of some mr functionality that was not immediately apparent to be from reading the man page, I'd like to know about it. – Seth Robertson Nov 12 '12 at 03:23
  • 4
    @kynan: in addition to your comment. I would like to point out that Avery's Pennarun's git-subtree is now available in git 1.7.11 and higher. – slatunje Nov 13 '12 at 23:06
  • 1
    @sealTrip: available as in it's in `git/contrib`. Install in Ubuntu with `sudo make install install-doc prefix=/usr libexecdir=/usr/lib/git-core` from a Git source tree (does *not* work with the packaged Git). – kynan Nov 22 '12 at 20:00
4

For some use cases, I have liked each of the following two simple approaches:

  • Nested repositories. If your software project has a plugin mechanism, with each plugin in its own sub-directory, it can make sense to git-ignore these plugin directories and, in your local filesystem, to make each of them into its own git repository. This way, all your files form a single directory tree, but are managed in different git repositories. It will not confuse git.

  • Per-package repositories. For software projects where you use some kind of source code package management system (gem / bundler, npm, pear or the like) it can make sense to put your re-used code into separate git repositories, then to make source packages from them, and then to install them with the package management tool into the parent project. Your parent project's git repository would only contain a reference to the required packages and their versions, while the actual code of these packages will be git-ignored as done with all other packages and external libraries as well. Compared to the nested repositories proposed above, this is a more elaborate approach as it allows to specify which package version is to be installed.

tanius
  • 14,003
  • 3
  • 51
  • 63
  • 1
    I've found that the nested repositories approach has worked well for me because the two repos remain independent and ignorant of each other, avoiding many of the pitfalls of integrated repo management. – Mike Godin Feb 07 '23 at 21:56
1

I currently use submodules for development and not just relating 3rd party libraries. There are some ways that you can make life easier with submodules, especially when they are the source of merge or rebase conflicts. Look to ls-tree to get the 2 commits involved on a conflict in the submodule. This is probably the most difficult part of submodules for people to deal with. For now scripting will make this much easier to work with. Future versions of Git should have better native support for dealing with them.

Hope this helps.

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
0

We encountered a similar issue when using Git submodules in projects where we had dependencies in a variety of languages. To deal with them, we built and open-sourced a tool called MDLR ("Modular") that gives you declarative version-controlled Git dependencies with similar functionality to Git submodules, but without the annoying workflow. You can install it and manage your dependencies with the instructions/downloads on the GitHub repo

svarlamov
  • 113
  • 1
  • 9