无法理解 git 子模块摘要
Trouble understanding git submodule summary
我在理解 究竟 git submodule summary
做什么时遇到了一些问题?我们如何以及何时使用此命令?我也无法理解 --files
选项的重要性。对我来说,不使用标签似乎与使用它一样。
此外,它与 git submodule status
有何不同?我非常困惑。如果有帮助,我一直在阅读命令的 Documentation。
非常感谢您的帮助! :)
对于git submodule status
:
$ git submodule status
hash-1 path-1 (describe-output-1)
hash-2 path-2 (describe-output-2)
:
hash-n path-n (describe-output-n)
这会告诉您,对于每个子模块路径,在该子模块路径中检出的提交的哈希 ID,以及在该子模块中 运行ning git describe
的结果。例如,如果您看到
51ebf55b9309824346a6589c9f3b130c6f371b8f foo (v2.25.0-462-g51ebf55b93)
作为输出,但随后在 foo
目录中做了一个 git checkout v2.15.0
:
(cd foo; git checkout v2.15.0)
和 运行 再一次,你会看到:
+cb5918aa0d50f50e83787f65c2ddc3dcb10159fe foo (v2.15.0)
代替。 (+
符号表示它不同步;见下文。)
哈希ID只是每个子模块中运行宁git rev-parse HEAD
的结果。 describe 输出只是每个子模块中 运行ning git describe
的结果。中间的路径是您需要提供给 cd
(更改目录)命令以从超级项目切换到给定子模块的参数。
对于git submodule summary
,细节稍微复杂一些。不过,这基本上 运行 在每个子模块中都有一个 git log
。
子模块基础知识
请记住,子模块只不过是另一个 Git 存储库——Git 调用 子模块 的存储库——再加上一点点this Git 存储库中的胶水,Git 调用 超级项目。超级项目中的"glue"由极少数项目组成:
git clone
子模块所需的信息,存储在名为 .gitmodules
的文件中。这仅在您第一次告诉超级项目 Git 进行克隆时使用,例如,通过 git submodule update --init
.
子模块的路径名,与出现在超级项目中的一样。超级项目 Git 将创建一个空目录/文件夹(无论您喜欢哪个术语)来保存此子模块的工作树。1
A 提交哈希 ID。超级项目 Git 将采用此提交哈希 ID,实际上,运行 (cd <em>path</em>; git checkout <em>hash</em>)
将子模块 Git 置于 detached HEAD 模式,并检出该特定提交。
最后两项存储在您在超级项目中所做的每个新提交中(并且已经存储在现有提交中)。2 为了 get 存储,路径名和提交哈希 ID 必须存储在 Git 的 索引 中,因为 Git 从索引进行所有新提交.
(如果您不清楚 Git 的 index 和您的 work-tree 之间的区别,参见 What's the difference between HEAD, working tree and index, in Git? and 。)
1在现代Git中,将出现在该路径中的子模块的.git
是一个普通文件,其内容将是下面的路径子模块 Git 可以找到存储库。超级项目 Git 会将存储库数据库移出子模块。 Git 调用这个 absorbing 子模块。在旧版本的 Git 中,子模块将拥有自己的 .git
directory/folder,其中包含子模块 Git 存储库数据库。
2事实上,第一项——.gitmodules
文件——也应该在所有这些提交中,但由于它是一个普通文件,没有什么特别的关于它:您只需像处理任何普通文件一样处理它。由于超级项目只真正 需要 一次,因此在克隆子模块时,如果您不小心或故意将其排除在新提交之外,您将不会注意到,直到其他人尝试使用该提交作为超级项目的全新克隆的起点。
因为 更改 一个 .gitmodules
文件是非常罕见的,并且它像任何其他文件一样进行提交,所以这很少成为问题。仅当您首先使用 git submodule add
以外的其他内容创建子模块时,这才是主要问题。
读 gitlinks,vs 直接弄乱子模块
记录路径和哈希 ID 的超级项目实体,准备好进入下一次提交,称为 gitlink。它只存在于Git的索引中,所以很难看到。 (您可以使用 git ls-files --stage
转储索引内容,但这通常过于冗长。)但它始终存在:它说 使用 this commit ,检查,作为分离的 HEAD,this hash ID in this submodule.
假设在路径 sub
处有一个子模块(在索引中,如 :sub
或 :0:sub
——这里的数字是暂存槽)。当您在超级项目中提交时,此 gitlink 进入提交。可以从索引中读出来:
git rev-parse :sub
或者从当前提交中读出:
git rev-parse HEAD:sub
或从任何提交中读取它:
git rev-parse <hash>:sub
从给定的提交哈希 ID 中为 sub
获取存储的 gitlink 哈希 ID。
如果您在您的超级项目中 运行 git submodule update
,那么 Git 将根据当前索引中的哈希 ID 执行适当的 (cd sub; git checkout <hash>)
。如果子模块存储库是 "clean",那么 git checkout
将干净地检出该特定提交。
但是每个子模块 是 一个 Git 存储库——一个工作树、一个索引和一个底层存储库数据库。 你可以cd sub
和git checkout
任何你想要的,或者弄脏它(sub
的) index and/or 它的工作树。而且,该子模块可以有自己的 b运行ch 名称——它是一个 Git 存储库,每个 Git 存储库都有 b运行ch 名称,对吧?例如,假设您 cd sub; git checkout master
。现在该子模块 on a b运行ch,而不是 detached HEAD 模式。您可以进行新的提交、运行 git merge
、and/or 运行 各种其他命令。您可以从一些上游存储库中获取新的提交。您可以做任何您想做的事情:它是一个 Git 存储库,所有 Git 命令都可用。
那么,假设您已经对一些 Git 存储库做了一些事情——这并不重要,该存储库充当某个超级项目的子模块。现在你return到超级项目(cd ..
),在超级项目,你问它:which commit did you recommend be checked out ? 也就是说,您从超级项目的索引或提交中读取了超级项目中的 gitlink 条目。
您有两个哈希 ID。他们可能是一样的!也许子模块 中的 master
是 存储在超级项目的 gitlink 中的哈希 ID。或者,也许它们是不同的。如果您刚才在子模块中进行了新的提交,它们肯定是不同的,因为每个新的提交哈希 ID 都是唯一的。
如果两者不同,git submodule status
会打印+<hash>
;它打印的散列值是 sub
中实际签出的散列值。如果两者相同,它会打印不带 +
.
的(单个)哈希 ID
同时,如果您 运行 git submodule summary
,您的超级项目 Git:
- 获取推荐的哈希ID
- 获取实际签出哈希ID
- 在子模块中使用
git log
来查找哪些提交是"between"这两个哈希ID。
具体来说,它使用 git log --oneline --left-right <hash1>...<hash2>
(注意这里的 --oneline
和三个点;它还会强制提供更多选项,但这些是关键选项)。 hash1
值是 recommended 哈希,hash2
值是实际签出 哈希。此列表的结果是显示可以从 hash1
访问但不能从 hash2
访问的提交(前缀为 <
) 和可以从 hash2
访问但不能从 hash1
访问的提交(前缀为 >
).
(有关 可达性 的更多信息,请参阅 Think Like (a) Git。)
git submodule summary
:--files
对比 --cached
I am also not able to understand the significance of the --files
option
--files
选项是默认选项。 --cached
选项更改 git submodule summary
获取其两个哈希 ID 的位置。它不是从索引 (:sub
) 中获取第一个哈希,然后进入子模块并读取第二个的 HEAD
值,而是从 current 中读取第一个 ID commit (HEAD:sub
) 并从索引 (:sub
) 中获取 second。其操作的其余部分是相同的:输入子模块和 运行 git log
适当的选项。
我在理解 究竟 git submodule summary
做什么时遇到了一些问题?我们如何以及何时使用此命令?我也无法理解 --files
选项的重要性。对我来说,不使用标签似乎与使用它一样。
此外,它与 git submodule status
有何不同?我非常困惑。如果有帮助,我一直在阅读命令的 Documentation。
非常感谢您的帮助! :)
对于git submodule status
:
$ git submodule status
hash-1 path-1 (describe-output-1)
hash-2 path-2 (describe-output-2)
:
hash-n path-n (describe-output-n)
这会告诉您,对于每个子模块路径,在该子模块路径中检出的提交的哈希 ID,以及在该子模块中 运行ning git describe
的结果。例如,如果您看到
51ebf55b9309824346a6589c9f3b130c6f371b8f foo (v2.25.0-462-g51ebf55b93)
作为输出,但随后在 foo
目录中做了一个 git checkout v2.15.0
:
(cd foo; git checkout v2.15.0)
和 运行 再一次,你会看到:
+cb5918aa0d50f50e83787f65c2ddc3dcb10159fe foo (v2.15.0)
代替。 (+
符号表示它不同步;见下文。)
哈希ID只是每个子模块中运行宁git rev-parse HEAD
的结果。 describe 输出只是每个子模块中 运行ning git describe
的结果。中间的路径是您需要提供给 cd
(更改目录)命令以从超级项目切换到给定子模块的参数。
对于git submodule summary
,细节稍微复杂一些。不过,这基本上 运行 在每个子模块中都有一个 git log
。
子模块基础知识
请记住,子模块只不过是另一个 Git 存储库——Git 调用 子模块 的存储库——再加上一点点this Git 存储库中的胶水,Git 调用 超级项目。超级项目中的"glue"由极少数项目组成:
git clone
子模块所需的信息,存储在名为.gitmodules
的文件中。这仅在您第一次告诉超级项目 Git 进行克隆时使用,例如,通过git submodule update --init
.子模块的路径名,与出现在超级项目中的一样。超级项目 Git 将创建一个空目录/文件夹(无论您喜欢哪个术语)来保存此子模块的工作树。1
A 提交哈希 ID。超级项目 Git 将采用此提交哈希 ID,实际上,运行
(cd <em>path</em>; git checkout <em>hash</em>)
将子模块 Git 置于 detached HEAD 模式,并检出该特定提交。
最后两项存储在您在超级项目中所做的每个新提交中(并且已经存储在现有提交中)。2 为了 get 存储,路径名和提交哈希 ID 必须存储在 Git 的 索引 中,因为 Git 从索引进行所有新提交.
(如果您不清楚 Git 的 index 和您的 work-tree 之间的区别,参见 What's the difference between HEAD, working tree and index, in Git? and
1在现代Git中,将出现在该路径中的子模块的.git
是一个普通文件,其内容将是下面的路径子模块 Git 可以找到存储库。超级项目 Git 会将存储库数据库移出子模块。 Git 调用这个 absorbing 子模块。在旧版本的 Git 中,子模块将拥有自己的 .git
directory/folder,其中包含子模块 Git 存储库数据库。
2事实上,第一项——.gitmodules
文件——也应该在所有这些提交中,但由于它是一个普通文件,没有什么特别的关于它:您只需像处理任何普通文件一样处理它。由于超级项目只真正 需要 一次,因此在克隆子模块时,如果您不小心或故意将其排除在新提交之外,您将不会注意到,直到其他人尝试使用该提交作为超级项目的全新克隆的起点。
因为 更改 一个 .gitmodules
文件是非常罕见的,并且它像任何其他文件一样进行提交,所以这很少成为问题。仅当您首先使用 git submodule add
以外的其他内容创建子模块时,这才是主要问题。
读 gitlinks,vs 直接弄乱子模块
记录路径和哈希 ID 的超级项目实体,准备好进入下一次提交,称为 gitlink。它只存在于Git的索引中,所以很难看到。 (您可以使用 git ls-files --stage
转储索引内容,但这通常过于冗长。)但它始终存在:它说 使用 this commit ,检查,作为分离的 HEAD,this hash ID in this submodule.
假设在路径 sub
处有一个子模块(在索引中,如 :sub
或 :0:sub
——这里的数字是暂存槽)。当您在超级项目中提交时,此 gitlink 进入提交。可以从索引中读出来:
git rev-parse :sub
或者从当前提交中读出:
git rev-parse HEAD:sub
或从任何提交中读取它:
git rev-parse <hash>:sub
从给定的提交哈希 ID 中为 sub
获取存储的 gitlink 哈希 ID。
如果您在您的超级项目中 运行 git submodule update
,那么 Git 将根据当前索引中的哈希 ID 执行适当的 (cd sub; git checkout <hash>)
。如果子模块存储库是 "clean",那么 git checkout
将干净地检出该特定提交。
但是每个子模块 是 一个 Git 存储库——一个工作树、一个索引和一个底层存储库数据库。 你可以cd sub
和git checkout
任何你想要的,或者弄脏它(sub
的) index and/or 它的工作树。而且,该子模块可以有自己的 b运行ch 名称——它是一个 Git 存储库,每个 Git 存储库都有 b运行ch 名称,对吧?例如,假设您 cd sub; git checkout master
。现在该子模块 on a b运行ch,而不是 detached HEAD 模式。您可以进行新的提交、运行 git merge
、and/or 运行 各种其他命令。您可以从一些上游存储库中获取新的提交。您可以做任何您想做的事情:它是一个 Git 存储库,所有 Git 命令都可用。
那么,假设您已经对一些 Git 存储库做了一些事情——这并不重要,该存储库充当某个超级项目的子模块。现在你return到超级项目(cd ..
),在超级项目,你问它:which commit did you recommend be checked out ? 也就是说,您从超级项目的索引或提交中读取了超级项目中的 gitlink 条目。
您有两个哈希 ID。他们可能是一样的!也许子模块 中的 master
是 存储在超级项目的 gitlink 中的哈希 ID。或者,也许它们是不同的。如果您刚才在子模块中进行了新的提交,它们肯定是不同的,因为每个新的提交哈希 ID 都是唯一的。
如果两者不同,git submodule status
会打印+<hash>
;它打印的散列值是 sub
中实际签出的散列值。如果两者相同,它会打印不带 +
.
同时,如果您 运行 git submodule summary
,您的超级项目 Git:
- 获取推荐的哈希ID
- 获取实际签出哈希ID
- 在子模块中使用
git log
来查找哪些提交是"between"这两个哈希ID。
具体来说,它使用 git log --oneline --left-right <hash1>...<hash2>
(注意这里的 --oneline
和三个点;它还会强制提供更多选项,但这些是关键选项)。 hash1
值是 recommended 哈希,hash2
值是实际签出 哈希。此列表的结果是显示可以从 hash1
访问但不能从 hash2
访问的提交(前缀为 <
) 和可以从 hash2
访问但不能从 hash1
访问的提交(前缀为 >
).
(有关 可达性 的更多信息,请参阅 Think Like (a) Git。)
git submodule summary
:--files
对比 --cached
I am also not able to understand the significance of the
--files
option
--files
选项是默认选项。 --cached
选项更改 git submodule summary
获取其两个哈希 ID 的位置。它不是从索引 (:sub
) 中获取第一个哈希,然后进入子模块并读取第二个的 HEAD
值,而是从 current 中读取第一个 ID commit (HEAD:sub
) 并从索引 (:sub
) 中获取 second。其操作的其余部分是相同的:输入子模块和 运行 git log
适当的选项。