【问题标题】:What is the workflow to clean git submodules on clones?清理克隆上的 git 子模块的工作流程是什么?
【发布时间】:2018-08-22 09:30:52
【问题描述】:

有一些有用的答案如何“本地”删除子模块 - How do I remove a submodule?

但是我有一个问题,我在几台机器上克隆了我的 repo。二 我每个月只工作一两次。因此,当我更新这些分支时,尽管不再跟踪子模块,但文件仍在工作分支上以及 .git/modules 中。在不止一次的情况下,我不小心签入了一些文件。在其他情况下,由于这些不需要的文件/目录的存在,我的构建失败了。

我想我可以保留要删除的内容列表 - 但这似乎不对 - 另一个人会执行删除操作,而我在 git 之外没有要删除的信息吗?

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

更新

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

我添加了一个可重现的示例。

设置

mkdir parent
cd parent 
git init
git submodule add https://github.com/jakesgordon/javascript-tetris.git
git commit -am add

cd ..
git clone parent clone
cd clone
git submodule update --init

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

当我这样做时

cd parent
git rm javascript-tetris
git commit -am delete

在父目录中,javascript-tetris 已消失,.gitmodules 中的条目已删除。但仍有一个填充的.git/modules/javascript-tetris 目录。

在克隆端:

git pull

给出警告:warning: unable to rmdir 'javascript-tetris': Directory not empty。而且目录还在,.git/modules/javascript-tetris 也还在。

【问题讨论】:

  • 你的主要版本和克隆版本使用的是什么版本的 git?我用最新的 Windows 版本做了一些测试,现在子模块的管理似乎好多了。
  • git --version 返回git version 2.18.0
  • 奇怪,也许我错过了关于你的克隆的一些东西。我的玩具示例似乎有效。 (他们不总是!)
  • 难道你错过了git submodule update --init?这就是我在第一次尝试重现问题时错过的。
  • 哇,这真是一团糟——我花了下午的大部分时间来研究 git subtree 是否是一个好的选择——不,我也不喜欢它......

标签: git git-submodules


【解决方案1】:

这对您有帮助吗?

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_submodule(没有尾部斜杠)。
  • 运行 rm -rf .git/modules/path_to_submodule(没有尾部斜杠)。
  • 提交 git commit -m "删除的子模块"
  • 删除现在未跟踪的子模块文件 rm -rf path_to_submodule

    Source

【讨论】:

  • 是和不是。 git clean 已经被建议了,但我喜欢你如何将它改编为嵌套回购,它似乎将它彻底重置为主回购上的状态。我主要担心的是我不想在不检查它删除的内容的情况下在开发机器上运行它。第二个问题是它没有清除.git/modules 目录。
  • 不,你误会了——这无济于事,因为我需要弄清楚我的同事在过去几个月中删除了哪个(几个)path_to_submodule。这没有记录,因为我们假设 git submodule 会处理这个问题。
【解决方案2】:

有点像this gist,你可以在那些机器上用git clean开始你的工作会话:

git clean -xfdf

使用两次强制清除具有.git 子目录的目录:git clean -xfdf。
我有一些纠结的子模块不会被 git clean -xfd 删除。

【讨论】:

  • 该命令很有用,但我不认为这是一个解决方案,因为它不会清理.git/modules。此外,由于它会不加选择地删除文件,因此如果不先仔细检查 repo,就感觉很危险。
  • @bdecaf 你试过了吗,为了测试?
  • 是的 - 我不知道所有的开关(尤其是第二个 f 让我很困惑)。它绝对解决了我的一些问题。仍然希望有一个完整的解决方案。
【解决方案3】:

git rm 应该处理所有脏活,但没有。

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

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

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

【讨论】:

  • 奇怪 - 我也在 2.18,但我留下了垃圾。由于它变得更长,我将此作为可重现的示例添加到问题中。你能确认我们执行了相同的命令吗?
  • 我去看看,当然。
【解决方案4】:

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

请看下面Git Submodules Documentation的摘录:

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

删除删除了超级项目的跟踪数据,它们都是 gitlink 条目和 .gitmodules 文件中的部分。这 子模块的工作目录已从文件系统中删除,但 Git 目录被保留,以便结帐 过去的提交,而不需要从另一个存储库中获取。

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

但是,您可以轻松创建自己的 git 命令来执行answer 中讨论的此类任务。

例如,您可以使用以下 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

然后,您必须将其放在 PATH 中可见的目录中(例如,在我的情况下,它可能是 C:\Program Files\Git\cmd)并将其命名为 git-{my_command_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 activity command得到一些启发。

【讨论】:

  • 不幸的是,我的问题略有不同。基本上问题是当服务器上的 repo 上删除一个或多个子模块时,我需要在本地清理(但没有明确列出要删除的内容)。
猜你喜欢
  • 2021-10-11
  • 1970-01-01
  • 2010-12-08
  • 2012-07-06
  • 1970-01-01
  • 2017-02-25
  • 1970-01-01
  • 2012-03-13
  • 1970-01-01
相关资源
最近更新 更多