我需要用我创建的项目切换项目的子模块。新的子模块在我拥有的存储库中。
.gitmodules
文件。git submodule sync
。git submodule init
。git submodule update --recusrsive
。该工作文件适用于所有未修改的子模块,但对于我修改过的子模块,它将返回:
fatal: reference is not a tree: 3062d287c322fabf1b41b8e33518eb449d4ac6ed
这是因为主存储库已经指向原始子模块的提交3062d287c322fabf1b41b8e33518eb449d4ac6ed
,但是在我的子模块中没有这样的提交。
该提交指针存储在哪里,子模块为什么这样工作?我该如何解决?
答案 0 :(得分:2)
提交指针存储在哪里...
有两份副本:
一个永久冻结在超级项目的 commit 中。就是说,超级项目提交本身对读取提交的任何人说:此提交应与子模块提交3062d287c322fabf1b41b8e33518eb449d4ac6ed
一起使用。显然,如果子模块提交,则此提交作为一个整体就可以使用3062d287c322fabf1b41b8e33518eb449d4ac6ed
存在;但是,由于所有提交都是完全只读的,因此此超级项目提交将永远(或只要超级项目提交继续存在)就声明为永久。由于您无法更改它,因此您也不必担心它。
超级项目提交中的条目称为 gitlink 。
另一个副本位于您的 index 中。它可能是通过从提交复制到索引而达到的。索引也称为临时区域,此索引/临时区域具有提交中的每个文件的副本。也就是说,您做了某件事(可能运行了git checkout
),告诉Git提取了一些超级项目提交。该超级项目提交包含许多文件,例如README.md
,.gitmodules
等。它还包含gitlink条目,该条目表示子模块X应该执行git checkout 3062d287c322fabf1b41b8e33518eb449d4ac6ed
。
当Git对所有这些文件(README.md
,.gitmodules
等)进行检出时,它会将它们复制到索引和工作树中。它还将gitlink复制到您的索引。因此,gitlink 3062d287c322fabf1b41b8e33518eb449d4ac6ed
现在位于子模块路径下的索引中,并且git submodule update
将进入子模块并运行git checkout 3062d287c322fabf1b41b8e33518eb449d4ac6ed
。
索引gitlink是您需要更改的索引。要更改它,请自己手动输入子模块,然后git checkout
您要索引命名的提交。然后退出子模块,返回到超级项目,然后运行git add path/to/submodule
。这样会将 在子模块中检出的提交哈希复制到索引中的gitlink条目中。
由于Git在运行git commit
时会根据索引中的所有内容进行所有 new 次提交,因此您现在可以进行新的提交了这与上一次提交非常相似,它具有相同的README.md
和.gitmodules
等等,只是它具有所需的gitlink而不是旧的3062d287c322fabf1b41b8e33518eb449d4ac6ed
。当然,您可以git add
进行更多操作,以在提交之前将它们从工作树复制到索引中:例如,也许您在工作树中将URL更改为.gitmodules
我也想加入新的提交。
还有其他方法可以更改索引中的gitlink,但是上面的方法也许是最简单的一种,因为您可以确切地看到自己在做什么。