All of lore.kernel.org
 help / color / mirror / Atom feed
From: William Hatfield <whatfield.git@gmail.com>
To: git@vger.kernel.org
Cc: glencbz@gmail.com, avarab@gmail.com, gitster@pobox.com,
	ps@pks.im, William Hatfield <whatfield.git@gmail.com>
Subject: [PATCH 1/5] t7425: add tests for reversive submodule traversal
Date: Sat, 31 Jan 2026 16:43:05 -0500	[thread overview]
Message-ID: <20260131214309.1899376-2-whatfield.git@gmail.com> (raw)
In-Reply-To: <20260131214309.1899376-1-whatfield.git@gmail.com>

Add test suite for the upcoming --reversive flag and its constituent
options: --reverse-traversal and --append-superproject. The --reversive
flag will be shorthand for: --recursive --reverse-traversal
--append-superproject.

Tests are marked as test_expect_failure since the features are not yet
implemented. They will be flipped to test_expect_success as each feature
is added.

Test structure:
 - Tests 1-2: Setup (success - prerequisites)
 - Test 3: --recursive existing behavior (success - already works)
 - Tests 4-5: --reverse-traversal (failure - needs implementation)
 - Tests 6-7: --append-superproject (failure - needs implementation)
 - Tests 8-9: Combined flags (failure - needs both features)
 - Tests 10-12: --reversive shorthand (failure - needs implementation)
 - Tests 13-16: --append-superproject edge cases (failure - needs implementation)

The test creates a multi-branch submodule tree with varying depths to
validate traversal order:

    top
    ├── sub0
    ├── sub1 -> sub2
    ├── sub3 -> sub4, sub5
    └── sub6 -> sub7 -> sub8, sub9

Signed-off-by: William Hatfield <whatfield.git@gmail.com>
---
 t/meson.build                  |   1 +
 t/t7425-submodule-reversion.sh | 329 +++++++++++++++++++++++++++++++++
 2 files changed, 330 insertions(+)
 create mode 100755 t/t7425-submodule-reversion.sh

diff --git a/t/meson.build b/t/meson.build
index 459c52a489..d3a5e17ff7 100644
--- a/t/meson.build
+++ b/t/meson.build
@@ -887,6 +887,7 @@ integration_tests = [
   't7422-submodule-output.sh',
   't7423-submodule-symlinks.sh',
   't7424-submodule-mixed-ref-formats.sh',
+  't7425-submodule-reversion.sh',
   't7450-bad-git-dotfiles.sh',
   't7500-commit-template-squash-signoff.sh',
   't7501-commit-basic-functionality.sh',
diff --git a/t/t7425-submodule-reversion.sh b/t/t7425-submodule-reversion.sh
new file mode 100755
index 0000000000..06c3ab6294
--- /dev/null
+++ b/t/t7425-submodule-reversion.sh
@@ -0,0 +1,329 @@
+#!/bin/sh
+#
+# Copyright (c) 2026 William Hatfield
+#
+
+test_description='Test "git submodule foreach --reversive"
+
+This test suite validates the --reversive flag and its constituent options:
+--recursive, --reverse-traversal, and --append-superproject. Tests confirm
+flags are correctly parsed and set non-zero integral values. Additional tests
+verify post-order traversal, superproject inclusion, and flag combinations.
+The --reversive flag is shorthand for: --recursive --reverse-traversal
+--append-superproject.
+'
+
+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+
+. ./test-lib.sh
+
+# Helper: create content and initial commit in a submodule
+# Usage: create_submodule_content <name> <content>
+create_submodule_content () {
+	echo "$2" >"$1/file" &&
+	git -C "$1" add file &&
+	test_tick &&
+	git -C "$1" commit -m "$1 commit"
+}
+
+# Helper: add submodules to a parent and commit
+# Usage: add_submodules <parent> <child1> [child2 ...]
+add_submodules () {
+	parent=$1 &&
+	shift &&
+	for child in "$@"; do
+		git -C "$parent" submodule add ../"$child" "$child" || return 1
+	done &&
+	test_tick &&
+	git -C "$parent" commit -m "add $*"
+}
+
+test_expect_success 'setup - enable local submodules' '
+	git config --global protocol.file.allow always
+'
+
+test_expect_success 'setup reversive sandbox (full multi-branch tree)' '
+	mkdir reversive &&
+	(
+		# Tree structure created in this sandbox:
+		#
+		#     top
+		#     ├── sub0
+		#     │
+		#     ├── sub1
+		#     │   └── sub2
+		#     │
+		#     ├── sub3
+		#     │   ├── sub4
+		#     │   └── sub5
+		#     │
+		#     └── sub6
+		#         └── sub7
+		#             ├── sub8
+		#             └── sub9
+		#
+		# This structure provides:
+		#   - Four top‑level siblings (sub0, sub1, sub3, sub6)
+		#   - Mixed branch depths (1‑deep, 2‑deep, 3‑deep)
+		#   - Multiple nested sibling sets (sub4+5 and sub8+9)
+		#   - A leaf‑only sibling (sub0)
+		#   - Ideal coverage for traversal tests
+
+		cd reversive &&
+
+		# Create all repositories
+		test_create_repo top &&
+		test_create_repo sub0 &&
+		test_create_repo sub1 &&
+		test_create_repo sub2 &&
+		test_create_repo sub3 &&
+		test_create_repo sub4 &&
+		test_create_repo sub5 &&
+		test_create_repo sub6 &&
+		test_create_repo sub7 &&
+		test_create_repo sub8 &&
+		test_create_repo sub9 &&
+
+		# Create leaf submodules first (no children)
+		create_submodule_content sub0 zero &&
+		create_submodule_content sub2 two &&
+		create_submodule_content sub4 four &&
+		create_submodule_content sub5 five &&
+		create_submodule_content sub8 eight &&
+		create_submodule_content sub9 nine &&
+
+		# Build sub1 branch (sub1 -> sub2)
+		create_submodule_content sub1 one &&
+		add_submodules sub1 sub2 &&
+
+		# Build sub3 branch (sub3 -> sub4, sub5)
+		create_submodule_content sub3 three &&
+		add_submodules sub3 sub4 sub5 &&
+
+		# Build sub7 (sub7 -> sub8, sub9)
+		create_submodule_content sub7 seven &&
+		add_submodules sub7 sub8 sub9 &&
+
+		# Build sub6 branch (sub6 -> sub7)
+		create_submodule_content sub6 six &&
+		add_submodules sub6 sub7 &&
+
+		# Build top (top -> sub0, sub1, sub3, sub6)
+		create_submodule_content top root &&
+		add_submodules top sub0 sub1 sub3 sub6 &&
+		git -C top submodule update --init --recursive
+	)
+'
+
+test_expect_success '--recursive parses and prints(runs), existing behavior' '
+	(
+		cd reversive/top &&
+		git submodule --quiet foreach --recursive "echo \$displaypath"
+	) >actual &&
+
+	cat >expect <<-\EOF &&
+sub0
+sub1
+sub1/sub2
+sub3
+sub3/sub4
+sub3/sub5
+sub6
+sub6/sub7
+sub6/sub7/sub8
+sub6/sub7/sub9
+EOF
+
+	test_cmp expect actual
+'
+
+test_expect_failure '--recursive and --reverse-traversal parses' '
+	(
+		cd reversive/top &&
+		git submodule foreach --recursive --reverse-traversal "true"
+	)
+'
+
+test_expect_failure '--recursive and --reverse-traversal runs' '
+	(
+		cd reversive/top &&
+		git submodule --quiet foreach --recursive \
+			--reverse-traversal "echo \$displaypath"
+	) >actual &&
+
+	cat >expect <<-\EOF &&
+sub6/sub7/sub9
+sub6/sub7/sub8
+sub6/sub7
+sub6
+sub3/sub5
+sub3/sub4
+sub3
+sub1/sub2
+sub1
+sub0
+EOF
+
+	test_cmp expect actual
+'
+
+test_expect_failure '--recursive and --append-superproject parses' '
+	(
+		cd reversive/top &&
+		git submodule foreach --recursive --append-superproject "true"
+	)
+'
+
+test_expect_failure '--recursive and --append-superproject runs' '
+	(
+		cd reversive/top &&
+		git submodule --quiet foreach --recursive \
+			--append-superproject "echo \$displaypath"
+	) >actual &&
+
+	cat >expect <<-\EOF &&
+sub0
+sub1
+sub1/sub2
+sub3
+sub3/sub4
+sub3/sub5
+sub6
+sub6/sub7
+sub6/sub7/sub8
+sub6/sub7/sub9
+../top
+EOF
+
+	test_cmp expect actual
+'
+
+test_expect_failure '--reverse-traversal and --append-superproject parses' '
+	(
+		cd reversive/top &&
+		git submodule foreach \
+			--recursive --reverse-traversal --append-superproject "true"
+	)
+'
+
+test_expect_failure '--reverse-traversal and --append-superproject runs' '
+	(
+		cd reversive/top &&
+		git submodule --quiet foreach --recursive \
+			--reverse-traversal --append-superproject "echo \$displaypath"
+	) >actual &&
+
+	cat >expect <<-\EOF &&
+sub6/sub7/sub9
+sub6/sub7/sub8
+sub6/sub7
+sub6
+sub3/sub5
+sub3/sub4
+sub3
+sub1/sub2
+sub1
+sub0
+../top
+EOF
+
+	test_cmp expect actual
+'
+
+test_expect_failure '--reversive parses' '
+	(
+		cd reversive/top &&
+		git submodule foreach --reversive "true"
+	)
+'
+
+test_expect_failure '--reversive runs' '
+	(
+		cd reversive/top &&
+		git submodule --quiet foreach --reversive "echo \$displaypath"
+	) >actual &&
+
+	cat >expect <<-\EOF &&
+sub6/sub7/sub9
+sub6/sub7/sub8
+sub6/sub7
+sub6
+sub3/sub5
+sub3/sub4
+sub3
+sub1/sub2
+sub1
+sub0
+../top
+EOF
+
+	test_cmp expect actual
+'
+
+test_expect_failure '--reversive stops on command failure' '
+	(
+		cd reversive/top &&
+		git submodule foreach --reversive "true" &&
+		test_must_fail git submodule foreach --reversive \
+			"test \$name != sub7 || exit 1"
+	)
+'
+
+test_expect_failure '--append-superproject with no submodules runs only superproject' '
+	test_create_repo empty_repo &&
+	(
+		cd empty_repo &&
+		git submodule --quiet foreach --append-superproject \
+			"echo \$displaypath"
+	) >actual &&
+
+	cat >expect <<-\EOF &&
+../empty_repo
+EOF
+
+	test_cmp expect actual
+'
+
+test_expect_failure '--append-superproject sets all expected variables' '
+	(
+		cd reversive/top &&
+		git submodule --quiet foreach --append-superproject \
+			"echo name=\$name path=\$path displaypath=\$displaypath" |
+			tail -n 1
+	) >actual &&
+
+	cat >expect <<-\EOF &&
+name=top path=../top displaypath=../top
+EOF
+
+	test_cmp expect actual
+'
+
+test_expect_failure '--append-superproject from nested submodule appends correct superproject' '
+	(
+		cd reversive/top/sub6 &&
+		git submodule --quiet foreach --recursive --append-superproject \
+			"echo \$displaypath"
+	) >actual &&
+
+	cat >expect <<-\EOF &&
+sub7
+sub7/sub8
+sub7/sub9
+../sub6
+EOF
+
+	test_cmp expect actual
+'
+
+test_expect_failure '--quiet suppresses Entering message for superproject' '
+	(
+		cd reversive/top &&
+		git submodule foreach --quiet --append-superproject "true"
+	) >actual 2>&1 &&
+
+	! grep "Entering" actual
+'
+
+test_done
-- 
2.53.0-rc0


  reply	other threads:[~2026-01-31 21:43 UTC|newest]

Thread overview: 11+ 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 ` William Hatfield [this message]
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

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=20260131214309.1899376-2-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=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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.