Orbit
Orbit

Reputation: 2395

How to handle nested git repositories?

I have a new project where the entire thing is under version control.

The projects directory looks like this:

/projectname
--/web
   --nodeapp.js
--/mobile
   --androidapp

So currently, .git is in the root of the project in /projectname. Is it possible to also put the two subdirectories into their own repo? For example, the /web directory contains a node app that will be deployed via Heroku, and Heroku deployments use git to deploy, so i need that part to be its own repo as obviously deploying the entire project (android included) to Heroku would be silly.

I think i've read submodules may be good for this use case, but i'm not quite sure if thats correct and if it is how to use them in my case. Thanks!

Upvotes: 4

Views: 3530

Answers (3)

Jeff Puckett
Jeff Puckett

Reputation: 41051

I find a git subtree is simpler to learn how to use than the submodule. This tends to be easier to share with team collaborators instead of dealing with sub modules.

First add the remote for web

git remote add weborigin https://path.to/remotes/plugin.git

create subtree specifying the new folder prefix

weborigin is the remote name, and master refers to the master branch on the subtree's repository. --prefix refers to the folder path to the root of the subtree repository

git subtree add --prefix=web weborigin master

pull normal commits made in weborigin

git subtree pull --prefix=web weborigin master

commits made in superproject to be backported

git commit -am "new changes to be backported"

checkout new branch for merging, set to track subtree repo

git checkout -b backport weborigin/master

cherry-pick backports

git cherry-pick -x --strategy=subtree master

push changes back to plugin source

git push weborigin backport:master

Upvotes: 2

jthill
jthill

Reputation: 60565

Is it possible to also put the two subdirectories into their own repo?

Yes. That's exactly what a submodule is. What happens when you do that is, git add of the subdirectory stores the id of the currently-checked-out commit in that directory.

You don't need to use the git submodule command. There are tasks it does that often need doing, but they're obvious ones, and really almost all of them are straightforward oneliners -- and the ones that aren't, aren't much harder than that. The most useful thing the submodule command does is hoist the actual repository out of the subdirectory and into a handy (and arbitrary) nook in the existing repo, so you can still nuke your worktree with impunity.


Here's how you find all your currently-tracked submodules, regardless of whether you've told the submodule command about them:

git ls-files -s|grep ^16            # ls-files -s output: mode id stage path

All the submodules in a commit, regardless of whether you've told the submodule command about them:

git ls-tree -r $id|grep ^16         # ls-tree -r output:  mode type id path

($id can be e.g. just master, or @ a.k.a. HEAD)

Id the tracked state for a submodule

git rev-parse :path/to/it           # from index i.e. last add/checkout/reset/etc 
git rev-parse $id:path/to/it        # from $id, e.g. `master` or `3fac3`

Find out what's currently checked out in a submodule:

(cd "$submodule"; git rev-parse HEAD)

Check out the right commit in a submodule:

(id=`git rev-parse :"$submodule"` && cd "$submodule" && git checkout $id)

... and so forth.

So, what is the submodule command really doing for you? Aside from the hoisting above, the only thing it doesadds is a handy place to keep notes -- for instance, where's the default spot to find those commits? The git submodule command has settled on .gitmodules as a good place to store stuff like this. As with all things git, the only thing that matters is the commits. Everything else, .gitmodules file included, is just handy-but-dispensable notes.

Upvotes: 2

Klas Mellbourn
Klas Mellbourn

Reputation: 44437

Yes, submodules seems like a good fit for you.

Using submodules you would have one outer repository "projectname", and two inner repositories, "web" and "mobile".

Git submodules will create a strong version relationship between the outer and the inner repository. The outer repository will always point to a specific commit in the inner repository.

Upvotes: 1

Related Questions