Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing code between two or more rails apps... alternatives to git submodules?

We have two separate rails_app, foo/ and bar/ (separate for good reason). They both depend on some models, etc. in a common/ folder, currently parallel to foo and bar.

Our current svn setup uses svn:externals to share common/. This weekend we wanted to try out git. After much research, it appears that the "kosher" way to solve this is using git submodule. We got that working after separating foo,bar,common into separate repositories, but then realized all the strings attached:

  1. Always commit the submodule before committing the parent.
  2. Always push the submodule before pushing the parent.
  3. Make sure that the submodule's HEAD points to a branch before committing to it. (If you're a bash user, I recommend using git-completion to put the current branch name in your prompt.)
  4. Always run 'git submodule update' after switching branches or pulling changes.

All these gotchas complicate things further than add,commit,push. We're looking for simpler ways to share common in git. This guy seems to have success using the git subtree extension, but that deviates from standard gitand still doesn't look that simple.

Is this the best we can do given our project structure? I don't know enough about rails plugins/engines, but that seems like a possible RoR-ish way to share libraries.

Thanks in advance.

like image 486
jtgameover Avatar asked Apr 19 '10 17:04

jtgameover


People also ask

Should you use git submodules?

In most cases, Git submodules are used when your project becomes more complex, and while your project depends on the main Git repository, you might want to keep their change history separate. Using the above as an example, the Room repository depends on the House repository, but they operate separately.

When should you use submodules?

Submodules are for when you want to have two separate repositories with one used inside the other. Subtree is for when you have two repos and you want to make one repo's contents a permanent part of the first repo.

Why do we need git submodule?

Git submodules allow you to keep a git repository as a subdirectory of another git repository. Git submodules are simply a reference to another repository at a particular snapshot in time. Git submodules enable a Git repository to incorporate and track version history of external code.

How do submodules work in Git?

Git allows you to include other Git repositories called submodules into a repository. This allows you to track changes in several repositories via a central one. Submodules are Git repositories nested inside a parent Git repository at a specific path in the parent repository's working directory.


1 Answers

I think that the git submodule system have a great advantage over svn:externals or symbolic links (and it is also that makes them more difficult to use): the actual submodule version is stored for each superproject version. So is is quite safe to make changes in the submodule that breaks backward-compatibility: it will be possible to checkout any version of the superproject(s) with the proper submodule version, because the superproject will contain a reference to the proper submodule code. You may also maintain two branches of the submodule (v1.0.x and v2.0.x, for example) and use different branches in different projects without a problem.

So I think it is really worth to use submodules even if they are a bit complicated. Git 1.7 has some major improvements on this area, for example git status now indicates the uncommitted modifications in submodules, so you probably don't forget to commit submodules first. A good GUI may also be a help (I have a small pet project about this, see here).

If you really don't want to care about submodule versions (you never make backward-incompatibile changes in the common code) then I also suggest using symbolic links. Although committing and fetching won't be much easier than for a submodule...

like image 195
gyim Avatar answered Oct 10 '22 05:10

gyim