为 git 回购和子模块生成未提交更改的补丁

Generate patch of uncommitted changes for git repo and submodules

我有一个 git 存储库 foo,在它们自己的文件夹 barbaz 中有几个子模块(实际存储库是 eclipse.platform.releng.aggregator)。我需要为这些存储库的更改生成补丁。

我可以使用 git --no-pager diff > file.patch 生成一个补丁,它适用于 foo 的更改,但不会报告 barbaz 子模块的更改。

使用 git submodule --quiet foreach --recursive git --no-pager diff > file(摘自 this answer)几乎可以工作,但差异不包括子存储库所在文件夹的名称。

目前,我通过手动将路径破解到补丁中来解决这个问题,但这只适用于简单的补丁和我能想到的脚本解决方案(例如,从 git 获取子仓库名称,更改为文件夹,在文件夹中生成补丁)意味着我不能使用简单的 git apply 稍后重新应用补丁。

有没有办法让 git 直接比较 subrepos 而不是通过 foreach 以便可以简单地应用生成的补丁?

使用子模块的想法是每个 repo 都是独立的,它可能由不同的维护者支持,并且有不同的批准过程。此外,repos 可以单独签出,甚至可以作为子模块作为完全不同的 repo 的一部分。

因此,这里的方法是为每个 repo 独立创建补丁集并独立传递它们。如果在使用 git format-patch.

提交后创建补丁会更有意义

根据@larsks 提供的线索,我设法找到了以下一款可以满足我需要的衬垫:

git submodule --quiet foreach --recursive 'export NAME="${PWD##*/}"; git --no-pager diff --src-prefix="a/${NAME}/" --dst-prefix="b/${NAME}/"'

这会将子文件夹的文件夹名称添加到使用 git diff 生成的补丁中,这样我就可以在父文件夹中 运行 git apply 即使补丁跨越多个子模块。但是请注意,它只起作用,因为我的子模块都是主 repo 文件夹下的一个文件夹。如果需要,可以通过将用于设置 NAME 的代码更改为更聪明的代码来克服这一点。