From d755fa0f6d112b6cc488b60d937d8419696e1edb Mon Sep 17 00:00:00 2001 From: agent-exec-transport Date: Tue, 20 Oct 2026 11:50:46 +0000 Subject: [PATCH] agent-exec transport 5faf257d5e2b698a220fe3ecfb2948b0/32c83177850b --- scripts/task.sh | 3 ++- tests/test_task.py | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/scripts/task.sh b/scripts/task.sh index 4cfdccea..c15a0f11 100755 --- a/scripts/task.sh +++ b/scripts/task.sh @@ -1131,7 +1131,8 @@ cmd_finish() { # registered-root, owner, lock, recursive dirt and ignored-file checks have passed. check_worktree finish local -a removal=(worktree remove) - if git ls-files --stage | grep -q '^160000 '; then + # Read the whole listing: an early-exit reader SIGPIPEs git on large indexes and pipefail drops --force. + if git ls-files --stage | awk '$1 == "160000" { found = 1 } END { exit !found }'; then removal+=(--force) fi if ! git -C "$mainrepo" "${removal[@]}" "$root"; then diff --git a/tests/test_task.py b/tests/test_task.py index b6c5a92a..e6a023c4 100644 --- a/tests/test_task.py +++ b/tests/test_task.py @@ -493,6 +493,26 @@ class TaskLifecycleTests(unittest.TestCase): self.assertTrue((self.repo / "component/content").is_file(), result.stdout) self.assertEqual(self.git(self.repo, "config", "--get", "submodule.component.url").stdout.strip(), str(self.root / "component")) + def test_finish_recycles_submodule_when_index_listing_exceeds_pipe_buffer(self): + self.add_submodule() + # Entries sorting after the gitlink must outlast a 64 KiB pipe once an early-exit reader stops. + bulk = self.repo / "zz-bulk" + bulk.mkdir() + for i in range(2000): + (bulk / f"entry-{i:05d}-{'p' * 40}").write_text("") + self.git(self.repo, "add", "zz-bulk") + self.git(self.repo, "commit", "-m", "Add bulk entries") + self.git(self.repo, "push", "origin", "main") + wt = self.worktree() + self.git(wt, "submodule", "update", "--init", "--recursive") + listing = self.git(wt, "ls-files", "--stage").stdout + before_gitlink, after_gitlink = listing.split("\tcomponent\n", 1) + self.assertTrue(before_gitlink.rsplit("\n", 1)[-1].startswith("160000 "), listing[:200]) + self.assertGreater(len(listing.encode()), 64 * 1024) + self.assertGreater(len(after_gitlink.encode()), 2 * 64 * 1024) + result = self.task(wt, "finish") + self.assertFalse(wt.exists(), result.stdout) + def test_finish_requires_writer_exit_confirmation(self): wt = self.worktree() result = self.task(wt, "finish", check=False, env=self.env)