清理克隆上的git子模块的工作流是什么?

清理克隆上的git子模块的工作流是什么?,git,git-submodules,Git,Git Submodules,有一些关于如何“本地”删除子模块的有用答案- 然而,我有一个问题,我有几个机器上的我的回购克隆。我一个月只工作一两次。因此,当我更新这些分支时,尽管子模块不再被跟踪,但文件仍然在.git/modules中的工作分支上。不止一次我不小心登记了一些。在其他情况下,由于存在这些不需要的文件/目录,生成失败 我想我可以保留一个要删除的东西的列表-但这似乎不正确-如果其他人会删除,而我没有git之外的信息,那么删除什么呢 那么,清理克隆的建议方法是什么呢 更新 对于我来说,git--version返回的g

有一些关于如何“本地”删除子模块的有用答案-

然而,我有一个问题,我有几个机器上的我的回购克隆。我一个月只工作一两次。因此,当我更新这些分支时,尽管子模块不再被跟踪,但文件仍然在
.git/modules
中的工作分支上。不止一次我不小心登记了一些。在其他情况下,由于存在这些不需要的文件/目录,生成失败

我想我可以保留一个要删除的东西的列表-但这似乎不正确-如果其他人会删除,而我没有git之外的信息,那么删除什么呢

那么,清理克隆的建议方法是什么呢

更新

对于我来说,
git--version
返回的
git版本2.18.0
似乎是最新版本(它是2018-09-01)

我添加了一个可复制的示例

设置

现在,这两个目录都包含在
javascript-tetris/
中签出文件的子模块
.gitmodules
包含子模块

当我这样做的时候

cd parent
git rm javascript-tetris
git commit -am delete
在父目录中,目录是
javascript-tetris
已消失,
.gitmodules
中的条目已删除。但是仍然有一个填充的
.git/modules/javascript-tetris
目录

在克隆端:

git pull
给出警告:
警告:无法rmdir'javascript tetris':目录不为空
。目录仍然存在,git/modules/javascript-tetris仍然存在。

与中一样,您可以在这些机器上启动工作会话,方法是:

使用force两次清理带有
.git
子目录的目录:
git clean-xfdf

我有一些混乱的子模块,这些子模块只需使用
gitclean-xfd
就不会被删除


git-rm
应该处理所有的脏活,但不能

文档表明您需要手动清理
.git/modules
目录。到目前为止,我找到的最佳选择是基于VonC的答案,通过使用
sed
xargs
对输出进行后处理:

git clean -xfdf | sed 's/Removing /\.git\/modules\//' |xargs rm -rf

我不太喜欢这个选项,因为它非常脆弱,依赖于尚未执行的清理。您最好验证克隆中没有本地提交,然后在其他工作站上从头开始重新克隆。

不幸的是,完全删除Git子模块的直接命令似乎不存在

请参见以下摘录:

已删除子模块:可以通过运行git rm删除子模块 &&git提交。这可以使用git revert撤消

删除将删除超级项目的跟踪数据,这两个数据都是 gitlink条目和.gitmodules文件中的节。这个 子模块的工作目录已从文件系统中删除,但 Git目录一直保留着,因为它使签出成为可能 过去的提交不需要从另一个存储库获取

要完全删除子模块,请手动删除 $GIT_DIR/modules/{name}/

但是,您可以轻松地创建自己的git命令来执行本文中讨论的任务

例如,可以使用以下bash脚本创建文件:

#!/bin/bash
echo "Running git rm ${1}"
git rm $1
echo "Running rm -rf .git/submodules/${1}"
rm -rf .git/modules/$1
exit 0
然后您必须将它放在路径中可见的目录中(例如,在我的例子中,它可能是
C:\Program Files\Git\cmd
),并将其命名为
Git-{my_command\u name}
(例如,
Git rm module

这样,您可以像
git-rm-module{my-submodule-name}
那样使用它。 结果是:

$ git rm-module my-submodule-name
Running git rm-submodule my-submodule-name
Running rm -rf .git/submodules/my-submodule-name

对于复杂的选项,您可以从中获得一些灵感。

这对您有帮助吗

git clean -xfd
git submodule foreach --recursive git clean -xfd
git reset --hard
git submodule foreach --recursive git reset --hard
git submodule update --init --recursive
更新

要删除子模块,您需要:

  • 从.gitmodules文件中删除相关部分
  • 准备.gitmodules更改git add.gitmodules
  • 从.git/config中删除相关部分
  • 运行git rm--cached path_to_子模块(无尾随斜杠)
  • 运行rm-rf.git/modules/path_to_子模块(无尾随斜杠)
  • Commit git Commit-m“已删除子模块”
  • 删除现在未跟踪的子模块文件rm-rf路径\u到\u子模块


该命令很有用,但我认为它不是一个解决方案,因为它不能清除
.git/modules
。另外,由于它不分青红皂白地删除文件,因此如果不先仔细检查repo就运行会感到危险。@bdecaf您是否尝试过它,以进行测试?是的,我不知道所有的开关(尤其是第二个f),这让我很困惑。它确实解决了我的一些问题。仍然希望有一个完整的解决方案。您主要的和克隆的git版本是什么?我用最新的Windows版本做了一些测试,现在子模块的管理似乎好多了。
git--version
返回
git version 2.18.0
奇怪,也许我遗漏了你的克隆。我的玩具例子似乎奏效了。(他们不总是这样!)可能是您错过了git子模块更新--init?这就是我在第一次尝试重现问题时错过的。哇,这真是一团糟-我花了一下午的大部分时间研究git子树是否是一个好的选择-不,我也不喜欢它…奇怪-我也在2.18上,但我留下了垃圾。因为时间变长了,我把它作为可复制的例子添加到问题中。你能确认我们执行了相同的命令吗?我会看一看,当然。不幸的是,我的问题略有不同。基本上,问题是当服务器上的repo上的一个或多个子模块被删除时,我需要在本地清理(但没有明确列出要删除的内容)。是和否。
git clean
已经被建议过了,但我喜欢您将其调整为嵌套repo的方式,并且它似乎完全将其重置为主服务器上的状态
$ git rm-module my-submodule-name
Running git rm-submodule my-submodule-name
Running rm -rf .git/submodules/my-submodule-name
git clean -xfd
git submodule foreach --recursive git clean -xfd
git reset --hard
git submodule foreach --recursive git reset --hard
git submodule update --init --recursive