大学课程要求我处理每次分配的本地存储库的git文件夹,但我希望将包含所有项目的文件夹作为远程存储库。那可能吗?因为我尝试过,并且gitlab说带有本地存储库的文件夹中的数据不正确。我正在考虑使用.gitignore文件,但我不知道这是否可以完成工作或仅浪费更多时间。
答案 0 :(得分:1)
您可以靠近,但不能完全靠近。具体来说,存储库不能包含存储库。 (工作树可以,但是存储库不能。)
在正常使用中,Git存储库存储在名为.git
的子目录中。让我们定义以下术语:
例如,如果/home/users/fred/projects/proj1
是顶层,它将包含一个名为.git
的目录。这是存储库本身所在的位置。 /home/users/fred/projects/proj1
中的其余内容是此存储库的工作树。如果存在/home/users/fred/projects/proj1/subproj/.git
,则此.git
是proj1
存储库的工作树中的嵌套存储库。
存储库中的提交包含文件。提交中的文件具有路径名。这些路径名从不以斜杠开头,但是可以包含斜杠(即使在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 一种方法比另一种方法更明智,并且也更自动化。
您可以:
然后在包含嵌套存储库的顶级工作树的repo
和git 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
的子项目信息,并包含一系列提交。 超级项目中的每个提交都列出:
.gitmodules
的提交哈希ID。因此,超级项目将引导Git自动克隆并git clone
任意数量的其他Git存储库。子模块有很多缺点,但是它们确实可以立即使用。
要使用子模块,请在超级项目工作树中创建子项目git checkout
之后,在超级项目中使用git checkout
。这样可以为您正确设置.git
文件。如果让Git自动检测嵌套存储库的存在,则Git在 commit 中创建正确的部分,但是克隆子模块所需的数据丢失。
3 Google的git submodule add
之所以存在,主要是因为子模块在2005-2012年左右的年代更加失灵。子模块今天工作得更好。