I have a git repo foo
that has several submodules in their own folders bar
and baz
(the actual repo is eclipse.platform.releng.aggregator). I need to generate patches for changes to those repos.
I can generate a patch with git --no-pager diff > file.patch
which is fine for changes to foo
but doesn't report changes in the bar
or baz
, the submodules.
Using git submodule --quiet foreach --recursive git --no-pager diff > file
(cribbed from this answer) nearly works but the diffs don't include the names of the folders the subrepos live in.
Presently I work round this by hacking the paths into the patches by hand but that only works for simple patches and the scripting solutions I can think of (e.g. getting the subrepo names from git, changing to the folders, generating the patches in folders) mean I can't use a simple git apply
to reapply the patches later.
Is there a way to get git to diff the subrepos directly rather than through foreach so the generated patches can be simply applied?
With the clue offered by @larsks I managed to find the following one liner which does what I need:
git submodule --quiet foreach --recursive 'export NAME="${PWD##*/}"; git --no-pager diff --src-prefix="a/${NAME}/" --dst-prefix="b/${NAME}/"'
This adds the folder name of the subfolders into the patch generated with git diff
so I can just run git apply
in the parent folder even if the patch spans more than one of the submodules. Note however that it only works because my submodules are all one folder below the main repo folder. That could be overcome if needed by changing the code used to set NAME
to something a little more clever.