Thread (12 messages) 12 messages, 2 authors, 4d ago

[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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help