简体   繁体   English

Git存储库中的Git存储库

[英]Git repository in a Git repository

I have a Git repository including a Git repository. 我有一个包含Git存储库的Git存储库。

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

Is it possible to work with this architecture? 是否可以使用这种架构?

You can have nested git repos: 你可以有嵌套的git repos:
The parent repo will simply 父回购将简单 ignore nested repo 忽略嵌套的repo .

jleedev comments and illustrates with this gist script that the parent repo would track the nested repo state through a gitlink . jleedev评论并用这个gist脚本说明父repo将通过gitlink跟踪嵌套的repo状态。
(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. (gitlink =对象的SHA-1引用另一个存储库中的提交.Git链接只能由SHA或通过提交标记指定。
A gitlink has a special mode ' 160000 ', used for submodules, but also present for simple nested repos). gitlink有一个特殊的模式' 160000 ',用于子模块,但也用于简单的嵌套repos)。

However, usual commands would not acknowledge the nested repo: add or commit would apply only in one repo, not the other. 但是,通常的命令不会确认嵌套的repo: addcommit只适用于一个repo而不是另一个repo。

git submodule would allow to reference the nested repo from the parent repo, and keep an exact reference of the child repo. git子模块允许引用来自父repo的嵌套repo,并保留子repo的精确引用。

Another alternative could involve: 另一种选择可能涉及:

  • two separate Git repos (not nested) 两个单独的Git回购(不嵌套)
  • a symlink from one to a specific part of the other (both Unix, but also Windows Vista+ have symlinks) 符号链接从一个到另一个的特定部分(Unix,但也有Windows Vista +都有符号链接)

You are trying to accomplish something called a "submodule". 你正试图完成一个叫做“子模块”的事情。

Please check out Git Tools - Submodules to find out how it's working. 请查看Git Tools - Submodules以了解它是如何工作的。

I've used that structure for quite a while, with the sub-repo directories specified in .gitignore in the outer repo. 我已经使用了那个结构很长一段时间了,在外部仓库中.gitignore中指定了子仓库目录。

It confuses the git tool in my editor (PhpStorm), which always wants to commit to the outer repo, but otherwise works fine. 它混淆了我的编辑器(PhpStorm)中的git工具,它总是想要提交外部仓库,但是其他工作正常。 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. 无论我正在做什么回购,我都会从Git bash做所有Git操作。

Submodules might be a better approach. 子模块可能是更好的方法。 I haven't had time to investigate whether they would work better with PhpStorm. 我没有时间调查他们是否能更好地使用PhpStorm。

Yes, you can use this pattern. 是的,你可以使用这种模式。 I've used it in the past to bring in SVN externals into a git-svn clone. 我过去曾用它来将SVN外部引入git-svn克隆。 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: 您需要将以下内容添加到repo1 / .git / info / exclude以确保repo2中的更改不与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. Git子模块的主要目的是更新从外部世界获取的代码,而不需要在更新修改代码时提交更改。

The Composer package management system does the same. Composer包管理系统也是如此。 Actually they don't recommend to commit those changes either and ignore the vendor folder in .gitignore in the root of project. 实际上, 他们不建议提交这些更改,并忽略项目根目录中.gitignore中的vendor文件夹。

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 . 如果您尝试提交此文件夹,这是一场噩梦,因为某些vendor / some_repo可能是开发版本,因此他们有一个.git文件夹,导致所有这些包成为子模块,即使您不添加他们用git submodule add You could see something like this if you modify some_file in a nested .git repository: 如果在嵌套的.git存储库中修改some_file ,则可以看到类似这样的内容:

~/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. 请注意子模块条目中的已修改内容,并且您在输出some_file不到some_file名称。 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. 相反,您会看到(修改内容)通知,因为root_project .git将vendor / nested_repo视为子模块,并且不跟踪该文件夹中的单个文件。

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. 如果你运行git add --all那么在你提交vendor/nested_repo更改之前你将得不到任何结果,并且只有在那之后才能在根存储库中提交更改。

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存储库(任何,不仅是Composer构建的存储库),这有时非常方便,在初始提交之前将此条目添加到根.gitignore:

.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. 不幸的是,要使整个配方工作,您需要为稍后要单独修改的每个嵌套存储库运行git add命令。 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: 然后修改some_filevendor/some_repo ,看到了差距:

~/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. 这样你就可以像往常一样在project_root运行git add --all然后git commit "Changes ..."

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. 确实,Git子模块允许您使用您描述的架构进行开发,而Git子树提供了许多人喜欢的类似解决方案。

In my opinion, package management software is an integral part of any complex project. 在我看来,包管理软件是任何复杂项目的组成部分。 I like Composer because of the intuitive workflows it supports. 我喜欢Composer,因为它支持直观的工作流程。

Unfortunately Git submodules are not supported by PhpStorm: 不幸的是,PhpStorm不支持​​Git子模块:

Git submodules should be supported (IDEA-64024) 应支持Git子模块(IDEA-64024)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM