Git子模块在结账时移除另一个分支

时间:2014-12-03 06:50:57

标签: git git-submodules

我的Git仓库中有几个功能分支。
每个功能都是一些外国仓库,作为子模块插入 我应该怎么做才能纠正分支之间的切换,有子模块和没有子模块?

示例:

$ git init
$ git commit -m "empty" --allow-empty
$ git checkout -b feature
$ git submodule init
$ git submodule add git://feature.git feature
$ git commit -a -m "add feature"
$ git checkout master
warning: unable to rmdir feature: Directory is not empty

我们的master分支工作目录中有一个功能 如何防止这种情况?

4 个答案:

答案 0 :(得分:4)

似乎最简单的方法是手动删除子模块目录。每次结账后您都需要git submodule init && git submodule update

匹配.gitmodules

中的目录
grep path .gitmodules | sed 's/.*= //'

*来自Prelang/gist/git-submodule-names

删除它:

grep path .gitmodules | sed 's/.*= //' | xargs rm -rf

答案 1 :(得分:3)

git submodule deinit .

可以做到这一点

答案 2 :(得分:2)

使用Git 2.27(2020年第二季度),情况应该会有所改善,并且“ git checkout --recurse-submodules”在嵌套的子模块层次结构中效果更好。

请参见commit 846f34d,请参见commit e84704fcommit 16f2b6bcommit 8d48dd1commit d5779b6commit bd35645Philippe Blain (phil-blain)(2020年2月17日) 。
(由Junio C Hamano -- gitster --commit fe87060中合并,2020年3月27日)

unpack-trees:检查merged_entry

中是否缺少子模块目录

报道者:菲利普·布兰(Philippe Blain)
报告人:达米恩·罗伯特
签名人:Philippe Blain

使用git checkout --recurse-submodules 在没有子模块的分支和具有初始化嵌套子模块的分支之间切换目前会导致致命错误:

$ git checkout --recurse-submodules branch-with-nested-submodules
fatal: exec '--super-prefix=submodule/nested/': cd to 'nested'
       failed: No such file or directory
error: Submodule 'nested' could not be updated.
error: Submodule 'submodule/nested' cannot checkout new HEAD.
error: Submodule 'submodule' could not be updated.
M   submodule
Switched to branch 'branch-with-nested-submodules'

检出成功,但是第一级子模块的工作树和索引留空

$ cd submodule
$ git -c status.submoduleSummary=1 status
HEAD detached at b3ce885
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
      deleted:    .gitmodules
      deleted:    first.t
      deleted:    nested

fatal: not a git repository: 'nested/.git'
Submodule changes to be committed:

* nested 1e96f59...0000000:

$ git ls-files -s
$ # empty
$ ls -A
.git

检出期间发生致命错误的原因是子git进程试图cd进入尚不存在的嵌套子模块目录。

顺序如下:

  1. 主git进程(在超级项目中运行的进程)最终到达entry.c中的write_entry(),这将创建第一级子模块目录,然后在{{ 3}},它会在子模块目录中产生submodule_move_head()

  2. 第一个子git进程(超级项目子模块中的那个)最终在git read-tree处调用check_submodule_move_head(),在空运行模式下调用unpack_trees.c:2021,并产生submodule_move_head在嵌套子模块目录中。

  3. 第二个子git进程尝试在submodule.cgit read-tree的{​​{1}}尚未嵌套的子模块目录中进行chdir(),并在执行前死亡。

第一个孩子而不是在主进程中到达start_command()的原因是它位于check_submodule_move_head()构造内部,并且if(submodule_from_ce())返回有效的struct子模块指针,而它在主git进程中返回空指针。

submodule_from_ce()在主submodule_from_ce()过程中返回空指针的原因是,在{{1}中对git的调用(从{中的cache_lookup_path()调用{1}})返回空指针,因为config_from()的{​​{1}}中的哈希图submodule_from_path()尚未填充。
未填充它是因为run-command.csubmodule_from_ce()中的"for_path"submodule_cache都返回the_repository,在操作的此阶段,超级项目的HEAD都没有也不包含任何repo_get_oid(repo, GITMODULES_INDEX, &oid)文件。

相反,在第一个子节点中填充哈希图,因为repo_get_oid(repo, GITMODULES_HEAD, &oid)返回0,因为第一级子模块的HEAD,即config_from_gitmodules()指向存在-1的提交并将“嵌套”记录为子模块。

通过在.gitmodules分支的repo_get_oid(repo, GITMODULES_HEAD, &oid)中调用.git/modules/submodule/HEAD的{​​{1}}之前检查子模块目录是否存在来修复此错误,即从无子模块的提交变为有子模块的提交礼物。

即使在当前的bug中代码的.gitmodules分支都没有起作用,也可以用更安全的方式保护check_submodule_move_head()中对merged_entry()的另一个调用。< / p>

if(!old)中其他函数中对check_submodule_move_head()的其他调用已经受到程序流中某处对merged_entry()的调用的保护,因此我们不需要对其进行额外的保护。 / p>

else if (!(old->ce_flags & CE_CONFLICTED))机制中的所有命令都将受到影响,即当使用check_submodule_move_head()标志进行调用时,检出,重置和读取树。

此错误是submodule-config.c

答案 3 :(得分:0)

git submodule init在 a git submodule add之前似乎没有多大意义:它应该初始化索引中记录的子模块(通过将子模块名称和网址从.gitmodules复制到.git/config来添加并提交到其他地方

在您的情况下,您只能使用git submodule add,提交和结帐。

无需实际初始化(并在子模块文件夹中克隆子模块库)。