我可以创建一个内部包含本地存储库的远程git存储库吗?

时间:2020-05-05 09:03:15

标签: git gitlab

大学课程要求我处理每次分配的本地存储库的git文件夹,但我希望将包含所有项目的文件夹作为远程存储库。那可能吗?因为我尝试过,并且gitlab说带有本地存储库的文件夹中的数据不正确。我正在考虑使用.gitignore文件,但我不知道这是否可以完成工作或仅浪费更多时间。

1 个答案:

答案 0 :(得分:1)

您可以靠近,但不能完全靠近。具体来说,存储库不能包含存储库。 (工作树可以,但是存储库不能。)

在正常使用中,Git存储库存储在名为.git的子目录中。让我们定义以下术语:

  • 工作树:您在文件系统中进行工作的位置。
  • 顶层:此工作树的路径,没有任何其他子目录。
  • 路径组件:请参见下文。
  • 嵌套存储库:另一个存储库的工作树下面包含的存储库和工作树。

例如,如果/home/users/fred/projects/proj1是顶层,它将包含一个名为.git的目录。这是存储库本身所在的位置。 /home/users/fred/projects/proj1中的其余内容是此存储库的工作树。如果存在/home/users/fred/projects/proj1/subproj/.git,则此.gitproj1存储库的工作树中的嵌套存储库。

存储库中的提交包含文件。提交中的文件具有路径名。这些路径名从不以斜杠开头,但是可以包含斜杠(即使在Windows上也总是正斜杠),因此文件的名称可能为path/to/file.ext。当Git将文件提取到工作树中时,它会按需创建path/path/to子目录,以便path/to/file.ext可以按照操作系统本身的要求存在(作为文件)在名为{{1}的目录/文件夹中的名为file.ext的目录/文件夹中的名为to的文件)。用斜杠分隔的各个部分是路径组件

Git 不会要做的是存储带有名为path的组件的文件或目录。 1 任何提交都不应包含具有以下内容的文件作为其任何路径组成部分。 2

这意味着克隆存储库,然后提取一些提交,再也不会在工作树中创建任何名为.git的子目录。要包含一个实际的存储库,您必须让Git提取一个名为.git的子目录(不在顶层),然后该子目录将包含新文件.git中的所有文件。复制-除了现在已修复的安全漏洞外,Git不允许这样做。

可以,但是,可以在现有Git存储库的工作树中创建新的Git存储库。您无法执行的操作是添加并提交这些内容,因为添加其中之一需要添加其.git目录,并且禁止使用包含.git的组件名称。 Git将(无论如何在现代中)巧妙地检测到存在.git,因此它必须是某种子项目,并且会在某种程度上自动尝试对事物进行子模块化。 (请参见下文。)


1 在一个安全漏洞类型的错误中,非常老的Git版本没有检查大写变体,这会导致不区分大小写的文件系统出现问题,例如Windows和MacOS上的默认文件系统。也就是说,您可以存储.git.Git.GIT或类似的东西。所有现代的Git版本也禁止这些。

2 由于无法更改现有提交,因此所有现代Gits都会在现有提交中进行检查,并拒绝提取这样的文件。


可以做什么

除了使用第三方插件(例如Google的.gIt)以外,您还可以在这里做两件事。 3 一种方法比另一种方法更明智,并且也更自动化。

可以:

  • 手动创建您的嵌套存储库,即使用工作树创建存储库,然后在该工作树中创建子存储库
  • 然后在包含嵌套存储库的顶级工作树的repogit add之前,重命名 {{1} }子存储库中的目录:

    git commit
  • 然后在提取此提交时,手动进入并将.git重命名为(cd sub; mv .git XGIT); git add .; git commit -m 'add nested fake repo'

现在您在存储库中有一个标准的嵌套存储库。

这不是正确的方法,仅用于说明目的。

或者,您可以:

  • 使用子模块

这是正确的方法,但这意味着您必须拥有多个GitHub或GitLab存储库:每个项目实际上需要一个,另外还有一个“超级项目”存储库只是为了命名所有子项目而存在。

子模块只是让一个Git存储库引用另一个Git存储库的一种方式。超级项目(包含存储库)有一个名为XGIT的文件,其中列出了.git的子项目信息,并包含一系列提交。 超级项目中的每个提交都列出:

  • 子模块Git的路径名,和
  • 超级项目将在子模块中.gitmodules的提交哈希ID。

因此,超级项目将引导Git自动克隆并git clone任意数量的其他Git存储库。子模块有很多缺点,但是它们确实可以立即使用。

要使用子模块,请在超级项目工作树中创建子项目git checkout之后,在超级项目中使用git checkout。这样可以为您正确设置.git文件。如果让Git自动检测嵌套存储库的存在,则Git在 commit 中创建正确的部分,但是克隆子模块所需的数据丢失。


3 Google的git submodule add之所以存在,主要是因为子模块在2005-2012年左右的年代更加失灵。子模块今天工作得更好。