[PATCH v2 0/3] submodule: foreach in reverse order, with the superproject
flat view
COOLING4d
From: William Hatfield <hidden>
Date: 2026-10-28 00:15:32
Subsystem:
documentation, the rest · Maintainers:
Jonathan Corbet, Linus Torvalds
Some commands need to visit nested submodules before the repositories that contain them. For example, when committing changes throughout a project, a superproject can record a submodule's new commit only after that commit exists. "git submodule foreach --recursive" visits each submodule before descending into it, so it cannot do that in one pass. This adds three options to "git submodule foreach": - --reverse-traversal visits submodules in the reverse of their usual order. With --recursive, each submodule is visited after the submodules nested in it. - --include-superproject also runs the command in the superproject, after all the submodules. - --reversive is a shorthand for --recursive --reverse-traversal --include-superproject. Take a project "top" with a submodule "mods/a" that has a nested submodule "inner", and uncommitted changes in all three. After git submodule foreach --reversive 'git commit -a -m update || :' "git status" shows nothing modified in any of them. With --recursive instead of --reversive, "inner" is committed after "mods/a", which still records its old "inner" and shows it as modified. t7427 checks both outcomes. (The "|| :" is there because "git commit" fails where there is nothing to commit. What a failure means is left to the command, as it is for "git submodule foreach" today: a non-zero exit status stops the traversal, and the superproject is only visited if every submodule succeeded.) This is a new version of "[PATCH 0/5] submodule: add 'reversive' traversal options to foreach" [1], reworked after the review by Junio and Jean-Noel: - Tests are part of the commits that add the behavior they test, instead of a separate first commit with test_expect_failure. - --append-superproject is now --include-superproject, which says what it does: the command is run in the superproject too, last. Of the variables a command can use in a submodule, Git sets only $displaypath there, to the name of the superproject's directory. The others are not cleared and may come from the environment. - The command run in the superproject keeps the environment that selects the repository, such as GIT_DIR and GIT_INDEX_FILE, because it is the repository "git submodule foreach" itself runs in, not another one being entered. The tests cover a detached worktree and an alternate index, also from a subdirectory. - --reverse-traversal keeps its name, but the manual now says what the order it reverses is: the submodules by path, each one immediately followed by the submodules nested in it. That was the missing piece in the objection that there is no "natural" order. I do not think of it as a walk of a tree, for which "bottom-up" or "post-order" would be better names: those say nothing without --recursive, and reversing also reverses the order of siblings, which "bottom-up" does not promise. Please tell me if it still reads as unclear. - With --recursive and --reverse-traversal, the submodules nested in a submodule are looked for before the command runs in it, so a command that checks out nested submodules itself does not get them visited, unlike in the usual order. This is documented and tested. - The documentation follows the synopsis style that git-submodule.adoc has been converted to, describes each option by what it does first, and has an example of the resulting order. The usage message, the synopsis and the completion are updated too. Because the series is organised differently from v1 (three patches instead of five, with the tests moved), a range-diff against v1 would only show it as replaced, so there is none. [1] https://lore.kernel.org/git/20260131214309.1899376-1-whatfield.git@gmail.com/ (local) William Hatfield (3): submodule: add --reverse-traversal to foreach submodule: add --include-superproject to foreach submodule: add --reversive shorthand to foreach Documentation/git-submodule.adoc | 41 ++- builtin/submodule--helper.c | 103 ++++-- contrib/completion/git-completion.bash | 5 +- git-submodule.sh | 17 +- t/meson.build | 1 + t/t7427-submodule-foreach-reversive.sh | 429 +++++++++++++++++++++++++ 6 files changed, 573 insertions(+), 23 deletions(-) create mode 100755 t/t7427-submodule-foreach-reversive.sh base-commit: 37b3475fb530c14109211faca33716a173db61ed -- 2.56.0