Git不存储
目录
.Git商店
文件夹
,或者更准确地说,Git商店
承诺
(然后存储文件——参见下面的挑剔区别)。但在你的情况下,问题是这些文件
已经在另一个Git存储库中
因此Git不会将它们添加到
这
存储库。
这是因为子目录也包含git吗?
更准确地说,这是因为这些子目录
是
Git存储库(有点像;请参阅下面的挑剔区别)。
那么我该怎么解决这个问题呢?
你必须立即(在你真正理解所有后果之前)做出一个具有深远影响的决定:
-
你想用Git的吗
子模块
或
-
你想吗
删除其他存储库
这样你就可以把这些文件直接存储在
这
仓库?
你需要知道的挑剔的区别
笨蛋
存储库
主要是一系列
承诺
.我们通常通过
分支机构名称
,尽管这条规则也有例外。
克隆
存储库复制该存储库的所有(或至少大部分)提交,但
不复制其分支名称
.相反,我们的GitTour软件在创建和填充我们的存储库时,会读取另一个存储库的
树枝
命名并将其更改为
远程跟踪名称
.
因此,存储库本身主要由两个数据库组成(在此之后,添加了许多辅助内容,以使它们更可用)。其中一个,通常是最大的,持有commitsGit称之为
提交对象
有时还会加上Git需要的其他内部Git对象。这个对象数据库是一个简单的
key-value store
其中
钥匙
是
哈希ID:
巨大丑陋的字母和数字字符串,实际上是十六进制数,是加密校验和函数的输出。另一个数据库保存
姓名:
分支名称、标记名称、远程跟踪名称等等。每个名字都适用
一
散列ID;分支机构的名称尤其重要
犯罪
散列ID,因此让我们找到这些特定的提交。
每个
犯罪
反过来又有两件事:
-
每个提交都有一个
每个文件的完整快照
。这些文件以特殊、只读、仅Git、压缩和消除重复的形式存储。它们不是普通文件,它们的名称中嵌入了前斜杠,例如
path/to/file.ext
,甚至在窗户上;它们区分大小写,即使您使用的是不区分大小写的Windows或macOS系统;等等
-
每个提交也包含一些
元数据:
关于那个特别的承诺的信息。这包括提交人的姓名和电子邮件地址。它包括几个日期和时间戳,这有助于使每个提交都是唯一的。而且,对于Git的内部操作来说至关重要的是,每个提交都包含一个
以前的
提交哈希ID。
大多数提交中的前一个提交列表只有一个条目长,因此每个提交只记住其(单个)的原始散列ID
父母亲
犯罪这会将提交形成向后指向的链,其中
最近的
用一些大而丑陋的随机散列ID提交;我们就叫它吧
H
â
指向
一些早期承诺:
<-H
让我们把上一个提交称为“提交”,它的真实名称也是一个大而丑陋的随机散列ID
G
这样我们就可以讨论它,并把它吸引进来:
<-G <-H
犯罪
G
,作为提交,存储一些甚至更早提交的哈希ID
F
,等等:
... <-F <-G <-H
每个提交还具有每个文件的完整快照,尽管有重复数据消除功能,以便
G
与中的文件完全匹配
H
,存储库中实际上只有该文件的一个副本。(Git通过哈希和它所称的
水滴状物体
,但你通常不需要在意。)
通过
比较
中的快照
G
在这方面
H
,Git可以告诉您哪些文件是相同的——可能是大多数——哪些文件是不同的。这个
git diff
,
git show
和
git log -p
命令都可以进行这种比较:它们将显示不同的文件,默认情况下,还会显示一个将左侧文件更改为右侧文件的配方。所以比较
G
vs
H
告诉您哪些文件发生了更改,以及发生了什么
到
那些文件。
H
但仍然存储完整的快照:为了找出发生了什么变化,Git必须找到
G
.它能做到
因为
H
指向
G
.
你不能
使用
直接提交,因为
是
只读,而且实际上只有Git可以读取。你也无法完成任何新工作,因为它是只读的。为了解决这个问题,我们实际上并不直接使用commit。相反,我们使用
git checkout
或
git switch
到
摘录
承诺。这是:
-
从之前的提交中删除所有以前提取的文件,然后
-
从我们要移动的提交中提取所有文件
到
现在我们有了
可用的
每个文件的副本。这些可用的拷贝被Git称为
工作树
或
工作树
简而言之。
这些工作树文件就是您实际需要的文件
看见
和
合作
。它们是普通文件,由您的计算机以普通方式存储,因此它们位于目录中(有些人更喜欢这里的“文件夹”一词;任何一个都可以)。
这些文件不是Git格式的。
他们很可能已经来了
从…里面
吉特,维娅
git签出
但现在他们已经不在Git了。你对他们做的任何事情都不会影响Git。
如果您修改了这些文件,或者删除了一些文件,或者创建了新的文件,那么您最终必须告诉Git这一点。Git会将这些文件复制回它所称的
指数
或
集结区
.关于这一点有很多需要了解(你不能略过这些知识,因为这对理解a的概念至关重要。)
追踪
vs
未追踪
文件,以及如何
.gitignore
真的很管用),但我们这里不讨论这个问题,但你会跑的
git add
,然后最终
git commit
.commit动词将使
新
当文件出现在Git的暂存区域时提交,然后更新当前文件
分支机构名称
将新提交记录为此分支上的最新提交。
这个
存储库本身
通常是
1.
被关在一个
.git
工作树顶层的目录(或文件夹)。也就是说,如果您的存储库处于
/Users/you/work/repo2
,有一个
/Users/you/work/repo2/.git
包含
存储库
,然后是
/用户/你/工作/报告2
这些文件是从
当前提交
你之前和他一起退房的
git签出
或
git交换机
.
1.
形容词
正常地
这是因为子模块和添加的工作树以及其他一些特殊情况会导致
文件
命名的
吉特先生
.Git在有令人信服的理由时就会使用这个技巧
移动
这个
吉特先生
目录
离开
从工作树上。子模块需要为一些其他丑陋的情况这样做;见下文。
子模块
Git的子模块在这张相对简单的图片上添加了一个褶皱。A.
子模块
在很大程度上,它只是一个包含在另一个存储库中的存储库。也就是说,有一个
吉特先生
某个Git存储库的工作树的子目录之一中的目录(或文件,如脚注1所示)。
如果Git存储库正在使用子模块,我们将该Git存储库称为
超级项目
超级项目和子模块仍然具有Git存储库的所有常规属性:它们在
吉特先生
目录(或在中找到的路径)
吉特先生
文件),以及签出提交的工作树。但是超级项目需要包含一些额外的内容,我们马上就会看到。
同时,子模块是
由超级项目控制
.子模块
是
仍然是一个存储库和工作树,所以仍然有提交,您可以签出一个。除了:通常
你
不要结账。你有
超级项目
那样做。
假设您克隆了一些Git存储库
R
,然后您现在查看您将使用的第一个提交
在里面
R
,以分支命名
B
.以及
文件夹
这与承诺有关
B
,有一条指令,存储在commit for
B
也就是说,实际上:
现在克隆并使用另一个Git存储库
这
另外
存储库是
s
,子模块。
R
现在是
超级项目
,顾名思义。
为了克隆
s
,Git需要:
-
要克隆的存储库的URL;
-
工作树中用于签出的路径名
R
; 和
-
提交哈希ID到
git checkout --detach
在里面
s
一旦制作完成
s
.
Git从名为
gitlink
,并从同一gitlink获取提交哈希ID。gitlink来自commit
B
然后进入索引/暂存区
R
,以及克隆
s
,Git在文件中查找gitlink的路径
.gitmodules
在commit中可以找到
B
.此文件具有URL,因此超级项目Git能够运行正确的
git clone
命令:
git clone <url-for-S> path/to/s
例如,在你的情况下:
git clone <url> Child_folder_1
要使子模块克隆工作,必须有
.Git模块
用正确的信息归档。
这个
git submodule
命令是构建和维护这个
.Git模块
文件因此
Child_folder_1
像
作为子模块,必须运行:
git submodule add <repository-url> Child_folder_1
这将负责创建或更新
.Git模块
文件,这样克隆说明就会出现;这个
repository-url
你提供的就是
git克隆
我会晚一点回来。
如果你只是
git add Child_folder_1
Git补充道
gitlink
后期克隆所需指令集的一半。但这并没有增加
.Git模块
条目。这就是为什么会出现以下错误消息:
warning: adding embedded git repository: Child_folder_1
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint: git submodule add <url> Child_folder_1
[snip]
这是在告诉您,您错误地添加了子模块。
为什么我们需要子模块?
我们没有。
然而,我们确实需要理解,Git存储库是
不允许包含另一个Git存储库
吉特先生
不会
添加名为
吉特先生
(或
.Git
或
.GIT
或
.giT
,或任何其他类似拼写)。更准确地说,
吉特先生
禁止将大写或小写字母混合作为名称组件。所以如果你
做
在存储库中有一个存储库,
git添加
不会添加
文件夹
在这里相反,它将添加Git称之为
gitlink
,这将为您提供子模块样式的行为。Git的其他部分,包括
git status
,也不会抱怨这些文件未被跟踪(尽管它可能会提到
子模块存储库本身
在状态中)。
你可以,如果你愿意,
去除
这个
吉特先生
每个子模块工作树中的文件或目录。如果你这么做了,你就不再是这样了
是
对应Git存储库的工作树。相反,这些文件
还
计算机普通格式的普通文件现在是普通的,但是
未追踪
存储库工作树中的文件。我们可以用这个短语
这个
存储库,因为只有一个存储库。当你有子模块时,你正在使用两个或更多的存储库,所以每次有人说“存储库”,你必须停下来问:“等等,
哪一个
仓库?"
但是:
如果完全删除子模块存储库,则子模块存储库中不再有提交。
没有子模块存储库,因此没有提交。所以你的未追踪文件
这个
(顶层)存储库工作树是
只有副本
你所有的那些文件。你有
扔掉
所有的
另外
,提交,这些文件的副本。
现在可以添加并提交
子文件夹1
保存当前工作目录(包括子目录)的(单个)存储库中的文件
子文件夹1
.但你只能
这个版本
这些文件的一部分。作为一个子模块,你会得到一个
gitlink
也就是说:
检查克隆后的提交(用哈希ID填写空白)
,以及
git克隆
副本
全部的
提交来自其他存储库,因此每个文件都有多个版本。
当你有一个子模块时,你可以
更新说明
在超级项目中。你可以说:
签出提交第二页(这次用一个不同的哈希ID填空)
这个
git submodule update
命令在超级项目中运行时,将切换到
那个
犯罪工作树文件将与其他提交文件匹配。
你甚至可以说
去除
那个子模块。这个
git子模块更新
命令将完全删除工作树文件。(以避免移除
吉特先生
目录,实际的
存储库
住在超级项目里
吉特先生
目录,这样就可以安全地删除它
吉特先生
文件。)
所以,你必须做出决定
子模块非常不方便,以至于很多人称它们为“哭泣模块”,因为它们让用户哭泣。但是他们做了一些没有他们你做不到的事情。你想做这件事吗?或者,您想要一个更简单的操作,在该操作中放弃
另外
Git存储库,只需
这是这些文件的一个版本
如果将子模块作为子模块添加到超级项目中,会是什么?
最简单快捷的方法就是放弃所有的历史。如果您今天不需要它,明天也不需要它,那么这会让您回到单一Git存储库的情况,而不需要子模块的复杂性。明天你就不会叫他们哭泣模块了。但如果你
将
如果你明天需要它,将来可能会因为昨天没有使用这些子模块而哭泣。
你现在有了我能给你的尽可能多的信息来做出这个决定。要么使用
git submodule add
将这些模块制作成适当的子模块,或移除
吉特先生
并将其添加为普通文件。