I have a Git repository including a Git repository.
repo1/
.git/
files
repo2/
.git/
files
files
Is it possible to work with this architecture?
I have a Git repository including a Git repository.
repo1/
.git/
files
repo2/
.git/
files
files
Is it possible to work with this architecture?
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:
160000
or gitlink
in Documentation/
. Here’s an example of how gitlinks behave. –
Maxon git fast-import
man page, which is the only doc in Git mentioning clearly what a gitlink
is. –
Demagogic git add .
or git add inner-repo
the result is a git link, as described here. However, if you do git add inner-repo/
(trailing slash), then it adds the files inside the repo, and starts tracking them as it would any other file (except for inner-repo/.git
, which it ignores). So the result is that the two repos track the files separately, and they don't know about each other. –
Reddin You are trying to accomplish something called a "submodule".
Please check out Git Tools - Submodules to find out how it's working.
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.
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
I also agree with Ronald William's answer. The main purpose of Git submodules is updating the code taken from the outside world without need to commit changes if that code were modified by the update.
The Composer package management system does the same. Actually they don't recommend to commit those changes either and ignore the vendor folder in .gitignore in the root of project.
It is a nightmare if you'd try to commit this folder because some of the vendor/some_repo can be of a development version, and consequently they have a .git folder which results in all those packages become submodules even if you don't add them with git submodule add
. You could see something like this if you modify some_file
in a nested .git repository:
~/project_root $ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
# (commit or discard the untracked or modified content in submodules)
#
# modified: vendor/nested_repo (modified content)
Note the modified content in submodules entry and that you don't see the some_file
name in the output. Instead you see the (modified content) notice, because the root_project .git sees the vendor/nested_repo as a submodule and does not track individual files in that folder.
If you run git add --all
you'll get no result until you commit changes in vendor/nested_repo
and only after that can you commit changes in the root repository.
Don't do this. Instead if you want to keep your project as a whole .git repository (any, not only Composer built repository), which is very convenient sometimes, add this entry to the root .gitignore BEFORE the initial commit:
.git
!/.git
Unfortunately, for the whole recipe to work you need to run the git add
command for each of the nested repositories you want later to modify individually. Notice that trailing slash in paths of repositories is a MUST.
~/project_root $ git add vendor/some_repo/ vendor/another_repo/
Then modify some_file
in the vendor/some_repo
and see the difference:
~/project_root $ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: vendor/some_repo/some_file
That way you can run git add --all
and then git commit "Changes ..."
in the project_root
as usual.
There are also package management solutions.
It is true that Git submodules would allow you to develop with the architecture you described, and Git subtrees provide a similar solution that many people prefer.
In my opinion, package management software is an integral part of any complex project. I like Composer because of the intuitive workflows it supports.
Unfortunately Git submodules are not supported by PhpStorm:
© 2022 - 2024 — McMap. All rights reserved.