Existing issues matching what you're seeing
Git for Windows version
git version 2.54.0.windows.1
Windows version
Windows 11
Windows CPU architecture
x86_64 (64-bit)
Additional Windows version information
Microsoft Windows [Version 10.0.26200.8246]
Options set during installation
Default installation options
Other interesting things
Using git subtree with --rejoin to manage a subdirectory prefix in a repo with ~500 total commits, ~200 touching the subtree prefix. The repo has merge commits from normal git pull operations (not squash merges).
Also tested on Git 2.53.0.vfs.0.7 (Microsoft.Git ARM64) — same behavior. The cs/subtree-split-fixes patch in 2.54.0 (removing should_ignore_subtree_split_commit) does not address this issue.
Terminal/shell
PowerShell 5.1 / Git Bash (MSYS2)
Commands that trigger the issue
1. git subtree push --prefix=<subdir> --rejoin <remote> <branch> # succeeds, creates rejoin marker
2. # make some local commits
3. git pull # creates a merge commit (normal pull merge from origin)
4. # make another commit touching the subtree prefix
5. git subtree push --prefix=<subdir> --rejoin <remote> <branch> # hangs indefinitely
# Also hangs: git subtree split --prefix=<subdir> --rejoin -b test-branch
Expected behaviour
The split should complete in seconds (only a few new commits since the last rejoin). With --ignore-joins (which bypasses rejoin optimization and processes all ~500 commits linearly), it completes in ~5 minutes — confirming the issue is specific to the rejoin recursion path, not the content.
Actual behaviour
The script hangs indefinitely at the process_split_commit stage. With GIT_TRACE=1, the last operation is a git rev-parse <hash>^@ call inside a deeply nested recursive check_parents → process_split_commit chain (~185 levels deep). Bash exhausts its process table for $() subshell spawning and the script stops making progress.
Root cause
When process_split_commit encounters a commit whose parents aren't in the per-run temp cache ($GIT_DIR/subtree-cache/$$), check_parents recursively calls process_split_commit for each uncached parent. Each recursive call spawns subshells for git rev-parse "$rev^@" via $() command substitution.
The pull merge introduces a second parent whose ancestry reaches pre-rejoin commits through a path not covered by the find_existing_splits exclusion (^mainline-parent). This forces recursion through ~200 uncached ancestors. At ~185 levels of nested bash function calls with $() subshells, the process table is exhausted and the script hangs.
The find_existing_splits exclusion ($unrevs) correctly limits the rev-list, but check_parents doesn't consult $unrevs — it only checks the temp cache. So excluded commits that the rev-list skips still trigger recursion when encountered as parents of merge commits in the processing window.
Repository
No response
Existing issues matching what you're seeing
Git for Windows version
Windows version
Windows 11
Windows CPU architecture
x86_64 (64-bit)
Additional Windows version information
Options set during installation
Other interesting things
Using
git subtreewith--rejointo manage a subdirectory prefix in a repo with ~500 total commits, ~200 touching the subtree prefix. The repo has merge commits from normalgit pulloperations (not squash merges).Also tested on Git 2.53.0.vfs.0.7 (Microsoft.Git ARM64) — same behavior. The
cs/subtree-split-fixespatch in 2.54.0 (removingshould_ignore_subtree_split_commit) does not address this issue.Terminal/shell
PowerShell 5.1 / Git Bash (MSYS2)
Commands that trigger the issue
Expected behaviour
The split should complete in seconds (only a few new commits since the last rejoin). With
--ignore-joins(which bypasses rejoin optimization and processes all ~500 commits linearly), it completes in ~5 minutes — confirming the issue is specific to the rejoin recursion path, not the content.Actual behaviour
The script hangs indefinitely at the
process_split_commitstage. WithGIT_TRACE=1, the last operation is agit rev-parse <hash>^@call inside a deeply nested recursivecheck_parents→process_split_commitchain (~185 levels deep). Bash exhausts its process table for$()subshell spawning and the script stops making progress.Root cause
When
process_split_commitencounters a commit whose parents aren't in the per-run temp cache ($GIT_DIR/subtree-cache/$$),check_parentsrecursively callsprocess_split_commitfor each uncached parent. Each recursive call spawns subshells forgit rev-parse "$rev^@"via$()command substitution.The pull merge introduces a second parent whose ancestry reaches pre-rejoin commits through a path not covered by the
find_existing_splitsexclusion (^mainline-parent). This forces recursion through ~200 uncached ancestors. At ~185 levels of nested bash function calls with$()subshells, the process table is exhausted and the script hangs.The
find_existing_splitsexclusion ($unrevs) correctly limits therev-list, butcheck_parentsdoesn't consult$unrevs— it only checks the temp cache. So excluded commits that the rev-list skips still trigger recursion when encountered as parents of merge commits in the processing window.Repository
No response