JSS*_*all 3 git git-submodules
我在另一个模块中有一个git子模块,通过git submodule add <...>(从父仓库发出的命令)添加,因此该.gitmodules文件是在父仓库内部自动生成的。
假设我对子模块进行了更改(编辑:并且不提交这些更改),然后导航回到父模块git add -A,然后执行,然后git status,它说“未上演提交更改:子模块目录名称 ...等”。
我以为git会读取.gitmodules文件(父git生成的文件!),意识到它是git子模块目录,因此当我向父请求状态时不提及其未暂存状态吗?
这里发生的是您的子模块存储库处于与超级项目中记录的哈希ID不同的提交。你的git status,在上层项目运行,告诉你这一点,在不改变它,你git add -A显然没有任何改变。
最后一部分似乎是错误的。当我做类似的事情,然后使用时git add -A,我得到:
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: [submodule path]
Run Code Online (Sandbox Code Playgroud)
然后,如果我再运行两个命令,它会像我期望的那样返回:
$ git reset
Unstaged changes after reset:
M [submodule path]
$ git submodule update
Submodule path [path]: checked out '[hash]'
$ git status
On branch ...
nothing to commit, working tree clean
Run Code Online (Sandbox Code Playgroud)
(我怀疑您已经在子模块中进行了一些更改,但从未在此处提交过。)
我们有一个名为超级项目的 Git存储库,它控制着另一个名为submodule的存储库。超级项目实际上具有三个单独的控制旋钮,每个提交中都存在一个控制旋钮,因此也可以在索引中找到它(因为索引控制着下一次提交的内容)。
这些控制旋钮之一是您提到的文件.gitmodules。它告诉超级项目,如果子模块尚未安装,则如何克隆子模块git clone。克隆子模块后,便完成了其主要工作。
第二个是您的.git/config文件。它包含从.gitmodules文件中复制的信息,如果.gitmodules文件不是完全适合您自己的目的(可能与负责该.gitmodules文件的人的信息不同),您可以根据需要进行更新。您中的所有设置都会.git/config覆盖中的设置.gitmodules。否则,这两个放置设置在本质上是等效的。
最后一个是导致问题的原因。为了使子模块能够签入您的工作树并因此对您有用,由超级项目控制的Git旋转了第二组Git命令。通常,您可以运行:
git submodule update --init
Run Code Online (Sandbox Code Playgroud)
以便检出子模块(尽管如果使用git clone --recursive,Git会为您完成此操作)。
至此,超级项目Git已经建立了一个具有正确路径的几乎为空的目录。(该目录包含一个.git文件,该文件为克隆存储库的路径命名,或者是在过去或者使用旧样式的向后兼容模式时,都包含实际的.git目录本身。)超级项目Git chdir进入该目录,并告诉子模块Git:
git checkout hash一旦发生这种情况,路径中就会充满了从ID为的提交中提取的文件hash,这大多会使外部Git(超项目)与文件“完成”。但是有一个副作用,因为子模块本身就是一个完整的Git存储库,包含了这一切。
特别是,子项目具有自己的HEAD。这HEAD是目前分离和子模块的存储库的当前提交的hash,因此,这是辅助模块,这当然是我们想要的索引和工作树:子模块的工作树是在上层项目,所有的路径子模块文件去了。
但是有一个有趣的问题要回答:超级项目Git从哪里获得哈希ID? 答案是:它存储在每一个快照 -嗯,每次使用的子模块,在上层项目,以同样的方式所有快照每个文件的完整,完全复制快照。为此,超级项目的索引包含类型gitlink的特殊条目。
每当超级项目告诉子模块Git时,超级项目索引中的gitlink条目就告诉超级项目哪个哈希ID给予子模块Git:检出一些特定的commit。
如果您手动导航到子模块,git checkout分支名称或任何其他通过哈希ID提交的信息,则子模块存储库的HEAD更改。它要么成为分支名称的附件,要么指向另一个提交,仍处于分离HEAD模式。
此时,子模块和超级项目不同步。超级项目Git对此不做任何事情。您可以控制,选择所需的提交。您甚至可以进行新的提交,git push并将它们提交到上游。完成所需的所有提交和操作后git checkout,并正确安排了所有工作,您应该爬出子模块工作树,回到超级项目。
现在git status,现在git diff,默认情况下-这里也有大量的控制旋钮-告诉您超级项目正在调用一些哈希H,但是子模块还有一些其他哈希S被检出。(如果设置了控制旋钮,它们也可能不会告诉您子模块本身是否需要提交。)如果希望您的下一个超级项目提交在此子模块的gitlink中记录此新的提交哈希S,, 你跑:
git add path-to-submodule
Run Code Online (Sandbox Code Playgroud)
(或者git add -A 应该做同样的事情,这就是令人困惑的原因)。这将更新索引中的gitlink以记录哈希ID S而不是H,以便下一个超级项目提交将在git submodule update命令上告诉子模块Git:检出提交S,作为分离的HEAD。
一旦超级项目中的索引与HEAD实际签出的子模块中的匹配,该子模块就不会在未暂存的更改部分中列出。如果索引中gitlink中的哈希与gitlink中的哈希不匹配HEAD,git status 则将列出要提交的更改中子模块的路径。
| 归档时间: |
|
| 查看次数: |
337 次 |
| 最近记录: |