Git repository in a Git repository

I have a Git repository including a Git repository.

repo1/
     .git/
     files
     repo2/
          .git/
          files
     files

Is it possible to work with this architecture?


Solution 1:

You can have nested git repos:
The parent repo will simply ignore nested repo.

jleedev comments and illustrates with this gist script that the parent repo would track the nested repo state through a gitlink.
(gitlink = SHA-1 of the object refering to a commit in another repository. Git links can only be specified by SHA or through a commit mark.
A gitlink has a special mode '160000', used for submodules, but also present for simple nested repos).

However, usual commands would not acknowledge the nested repo: add or commit would apply only in one repo, not the other.

git submodule would allow to reference the nested repo from the parent repo, and keep an exact reference of the child repo.

Another alternative could involve:

  • two separate Git repos (not nested)
  • a symlink from one to a specific part of the other (both Unix, but also Windows Vista+ have symlinks)

Solution 2:

You are trying to accomplish something called a "submodule".

Please check out Git Tools - Submodules to find out how it's working.

Solution 3:

I've used that structure for quite a while, with the sub-repo directories specified in .gitignore in the outer repo.

It confuses the git tool in my editor (PhpStorm), which always wants to commit to the outer repo, but otherwise works fine. I load the whole outer repo (which includes all innner repos) as a single project in the editor. That allows me to easily search for and examine code in the outer repo while working on an inner one.

I do all Git operations from Git bash in whatever repo I'm working on.

Submodules might be a better approach. I haven't had time to investigate whether they would work better with PhpStorm.

Solution 4:

Yes, you can use this pattern. I've used it in the past to bring in SVN externals into a git-svn clone. Submodules may handle this better now, but didn't suit my needs at the time.

You'll want to add the following to repo1/.git/info/exclude to ensure changes in repo2 don't mix with repo1:

repo2