Git development
 help / color / mirror / Atom feed
From: William Hatfield <whatfield.git@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
	"Jean-Noël AVILA" <jn.avila@free.fr>,
	"Patrick Steinhardt" <ps@pks.im>, "Glen Choo" <glencbz@gmail.com>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
	"William Hatfield" <whatfield.git@gmail.com>
Subject: [PATCH v2 0/3] submodule: foreach in reverse order, with the superproject
Date: Tue, 27 Oct 2026 20:15:26 -0400	[thread overview]
Message-ID: <20261028001529.81557-1-whatfield.git@gmail.com> (raw)
In-Reply-To: <20260131214309.1899376-1-whatfield.git@gmail.com>

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/

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


  parent reply	other threads:[~2026-10-28  0:15 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-31 21:43 [PATCH 0/5] submodule: add 'reversive' traversal options to foreach William Hatfield
2026-01-31 21:43 ` [PATCH 1/5] t7425: add tests for reversive submodule traversal William Hatfield
2026-01-31 21:43 ` [PATCH 2/5] submodule: teach and plumb reverse-traversal behavior William Hatfield
2026-01-31 21:43 ` [PATCH 3/5] submodule: teach and plumb append-superproject behavior William Hatfield
2026-01-31 21:43 ` [PATCH 4/5] submodule: introduce reversive shorthand mode William Hatfield
2026-01-31 21:43 ` [PATCH 5/5] doc: document reversive traversal and related modes William Hatfield
2026-02-01  9:03   ` Jean-Noël AVILA
2026-02-02 21:10     ` William Hatfield
2026-02-02 18:52 ` [PATCH 0/5] submodule: add 'reversive' traversal options to foreach Junio C Hamano
2026-02-02 21:02   ` William Hatfield
2026-02-02 21:25     ` Junio C Hamano
2026-10-28  0:15 ` William Hatfield [this message]
2026-10-28  0:15   ` [PATCH v2 1/3] submodule: add --reverse-traversal " William Hatfield
2026-10-28  0:15   ` [PATCH v2 2/3] submodule: add --include-superproject " William Hatfield
2026-10-28  0:15   ` [PATCH v2 3/3] submodule: add --reversive shorthand " William Hatfield

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261028001529.81557-1-whatfield.git@gmail.com \
    --to=whatfield.git@gmail.com \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=glencbz@gmail.com \
    --cc=jn.avila@free.fr \
    --cc=ps@pks.im \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox