{"thread":{"id":"65146","subject":"[PATCH v2 1/3] contrib/subtree: reduce function side-effects","startedAt":"2026-03-05T23:56:38Z","lastAt":"2026-06-03T09:12:20Z","messageCount":22,"participants":["Colin Stagner","Junio C Hamano","Ben Knoble","Ian Jackson","Johannes Schindelin"],"isPatch":true,"patchVersion":2,"patchTotal":3},"messages":[{"id":"538033","messageId":"20260305-cs-subtree-split-recursion-v2-1-7266be870ba9@howdoi.land","threadId":"65146","inReplyTo":"20260305-cs-subtree-split-recursion-v2-0-7266be870ba9@howdoi.land","subject":"[PATCH v2 1/3] contrib/subtree: reduce function side-effects","fromName":"Colin Stagner","fromEmail":"ask+git@howdoi.land","sentAt":"2026-03-05T23:55:47Z","receivedAt":"2026-03-05T23:56:38Z","isPatch":true,"body":"`process_subtree_split_trailer()` communicates its return value\nto the caller by setting a variable (`sub`) that is also defined\nby the calling function. This is both unclear and encourages\nside-effects.\n\nInvoke this function in a sub-shell instead.\n\nSigned-off-by: Colin Stagner <ask+git@howdoi.land>\n---\n contrib/subtree/git-subtree.sh | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh\nindex 791fd8260c..bae5d9170b 100755\n--- a/contrib/subtree/git-subtree.sh\n+++ b/contrib/subtree/git-subtree.sh\n@@ -373,6 +373,10 @@ try_remove_previous () {\n }\n \n # Usage: process_subtree_split_trailer SPLIT_HASH MAIN_HASH [REPOSITORY]\n+#\n+# Parse SPLIT_HASH as a commit. If the commit is not found, fetches\n+# REPOSITORY and tries again. If found, prints full commit hash.\n+# Otherwise, dies.\n process_subtree_split_trailer () {\n \tassert test $# -ge 2\n \tassert test $# -le 3\n@@ -400,6 +404,7 @@ process_subtree_split_trailer () {\n \t\t\tdie \"$fail_msg\"\n \t\tfi\n \tfi\n+\techo \"${sub}\"\n }\n \n # Usage: find_latest_squash DIR [REPOSITORY]\n@@ -432,7 +437,7 @@ find_latest_squash () {\n \t\t\tmain=\"$b\"\n \t\t\t;;\n \t\tgit-subtree-split:)\n-\t\t\tprocess_subtree_split_trailer \"$b\" \"$sq\" \"$repository\"\n+\t\t\tsub=\"$(process_subtree_split_trailer \"$b\" \"$sq\" \"$repository\")\" || exit 1\n \t\t\t;;\n \t\tEND)\n \t\t\tif test -n \"$sub\"\n@@ -489,7 +494,7 @@ find_existing_splits () {\n \t\t\tmain=\"$b\"\n \t\t\t;;\n \t\tgit-subtree-split:)\n-\t\t\tprocess_subtree_split_trailer \"$b\" \"$sq\" \"$repository\"\n+\t\t\tsub=\"$(process_subtree_split_trailer \"$b\" \"$sq\" \"$repository\")\" || exit 1\n \t\t\t;;\n \t\tEND)\n \t\t\tdebug \"Main is: '$main'\"\n\n-- \n2.43.0\n\n"},{"id":"538034","messageId":"20260305-cs-subtree-split-recursion-v2-2-7266be870ba9@howdoi.land","threadId":"65146","inReplyTo":"20260305-cs-subtree-split-recursion-v2-0-7266be870ba9@howdoi.land","subject":"[PATCH v2 2/3] contrib/subtree: functionalize split traversal","fromName":"Colin Stagner","fromEmail":"ask+git@howdoi.land","sentAt":"2026-03-05T23:55:48Z","receivedAt":"2026-03-05T23:56:46Z","isPatch":true,"body":"`git subtree split` requires an ancestor-first history traversal.\nRefactor the existing rev-list traversal into its own function,\n`find_commits_to_split`.\n\nPass unrevs via stdin to avoid limits on the maximum length of\ncommand-line arguments. Also remove an unnecessary `eval`.\n\nSigned-off-by: Colin Stagner <ask+git@howdoi.land>\n---\n contrib/subtree/git-subtree.sh | 30 +++++++++++++++++++++++++++---\n 1 file changed, 27 insertions(+), 3 deletions(-)\n\ndiff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh\nindex bae5d9170b..c1756b3e74 100755\n--- a/contrib/subtree/git-subtree.sh\n+++ b/contrib/subtree/git-subtree.sh\n@@ -519,6 +519,31 @@ find_existing_splits () {\n \tdone || exit $?\n }\n \n+# Usage: find_commits_to_split REV UNREVS [ARGS...]\n+#\n+# List each commit to split, with its parents.\n+#\n+# Specify the starting REV for the split, which is usually\n+# a branch tip. Populate UNREVS with the last --rejoin for\n+# this prefix, if any. Typically, `subtree split` ignores\n+# history prior to the last --rejoin... unless and if it\n+# becomes necessary to consider it. `find_existing_splits` is\n+# a convenient source of UNREVS.\n+#\n+# Remaining arguments are passed to rev-list.\n+#\n+# Outputs commits in ancestor-first order, one per line, with\n+# parent information. Outputs all parents before any child.\n+find_commits_to_split() {\n+\tassert test $# -ge 2\n+\trev=\"$1\"\n+\tunrevs=\"$2\"\n+\tshift 2\n+\n+\techo \"$unrevs\" |\n+\tgit rev-list --topo-order --reverse --parents --stdin \"$rev\" \"$@\"\n+}\n+\n # Usage: copy_commit REV TREE FLAGS_STR\n copy_commit () {\n \tassert test $# = 3\n@@ -976,12 +1001,11 @@ cmd_split () {\n \t# We can't restrict rev-list to only $dir here, because some of our\n \t# parents have the $dir contents the root, and those won't match.\n \t# (and rev-list --follow doesn't seem to solve this)\n-\tgrl='git rev-list --topo-order --reverse --parents $rev $unrevs'\n-\trevmax=$(eval \"$grl\" | wc -l)\n+\trevmax=\"$(find_commits_to_split \"$rev\" \"$unrevs\" --count)\"\n \trevcount=0\n \tcreatecount=0\n \textracount=0\n-\teval \"$grl\" |\n+\tfind_commits_to_split \"$rev\" \"$unrevs\" |\n \twhile read rev parents\n \tdo\n \t\tprocess_split_commit \"$rev\" \"$parents\"\n\n-- \n2.43.0\n\n"},{"id":"538035","messageId":"20260305-cs-subtree-split-recursion-v2-3-7266be870ba9@howdoi.land","threadId":"65146","inReplyTo":"20260305-cs-subtree-split-recursion-v2-0-7266be870ba9@howdoi.land","subject":"[PATCH v2 3/3] contrib/subtree: reduce recursion during split","fromName":"Colin Stagner","fromEmail":"ask+git@howdoi.land","sentAt":"2026-03-05T23:55:49Z","receivedAt":"2026-03-05T23:56:50Z","isPatch":true,"body":"On Debian-alikes, POSIX sh has a hardcoded recursion depth\nof 1000. This limit operates like bash's `$FUNCNEST` [1], but\nit does not actually respect `$FUNCNEST`. This is non-standard\nbehavior. On other distros, the sh recursion depth is limited\nonly by the available stack size.\n\nWith certain history graphs, subtree splits are recursive—with\none recursion per commit. Attempting to split complex repos that\nhave thousands of commits, like [2], may fail on these distros.\n\nReduce the amount of recursion required by eagerly discovering\nthe complete range of commits to process.\n\nThe recursion is a side-effect of the rejoin-finder in\n`find_existing_splits`. Rejoin mode, as in\n\n    git subtree split --rejoin -b hax main ...\n\nimproves the speed of later splits by merging the split history\nback into `main`. This gives the splitting algorithm a stopping\npoint. The rejoin maps one commit on `main` to one split commit\non `hax`. If we encounter this commit, we know that it maps to\n`hax`.\n\nBut this is only a single point in the history. Many splits\nrequire history from before the rejoin. See patch content for\nexamples.\n\nIf pre-rejoin history is required, `check_parents` recursively\ndiscovers each individual parent, with one recursion per commit.\nThe recursion deepens the entire tree, even if an older rejoin\nis available. This quickly overwhelms the Debian sh stack.\n\nInstead of recursively processing each commit, process *all* the\ncommits back to the next obvious starting point: i.e., either the\nnext-oldest --rejoin or the beginning of history. This is where the\nrecursion is likely to stop anyway.\n\nWhile this still requires recursion, it is *considerably* less\nrecursive.\n\n[1]: https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html#index-FUNCNEST\n\n[2]: https://github.com/christian-heusel/aur.git\n\nSigned-off-by: Colin Stagner <ask+git@howdoi.land>\n---\n contrib/subtree/git-subtree.sh | 56 ++++++++++++++++++++++++++++++++++++++++--\n 1 file changed, 54 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh\nindex c1756b3e74..c649a9e393 100755\n--- a/contrib/subtree/git-subtree.sh\n+++ b/contrib/subtree/git-subtree.sh\n@@ -315,6 +315,46 @@ cache_miss () {\n }\n \n # Usage: check_parents [REVS...]\n+#\n+# During a split, check that every commit in REVS has already been\n+# processed via `process_split_commit`. If not, deepen the history\n+# until it is.\n+#\n+# Commits authored by `subtree split` have to be created in the\n+# same order as every other git commit: ancestor-first, with new\n+# commits building on old commits. The traversal order normally\n+# ensures this is the case, but it also excludes --rejoins commits\n+# by default.\n+#\n+# The --rejoin tells us, \"this mainline commit is equivalent to\n+# this split commit.\" The relationship is only known for that\n+# exact commit---and not before or after it. Frequently, commits\n+# prior to a rejoin are not needed... but, just as often, they\n+# are! Consider this history graph:\n+#\n+#              --D---\n+#             /      \\\n+#         A--B--C--R--X--Y    main\n+#                 /     /\n+#          a--b--c     /      split\n+#              \\      /\n+#               --e--/\n+#\n+# The main branch has commits A, B, and C. main is split into\n+# commits a, b, and c. The split history is rejoined at R.\n+#\n+# There are at least two cases where we might need the A-B-C\n+# history that is prior to R:\n+#\n+# 1. Commit D is based on history prior to R, but\n+#    it isn't merged into mainline until after R.\n+#\n+# 2. Commit e is based on old split history. It is merged\n+#    back into mainline with a subtree merge. Again, this\n+#    happens after R.\n+#\n+# check_parents detects these cases and deepens the history\n+# to the next available rejoin.\n check_parents () {\n \tmissed=$(cache_miss \"$@\") || exit $?\n \tlocal indent=$(($indent + 1))\n@@ -322,8 +362,20 @@ check_parents () {\n \tdo\n \t\tif ! test -r \"$cachedir/notree/$miss\"\n \t\tthen\n-\t\t\tdebug \"incorrect order: $miss\"\n-\t\t\tprocess_split_commit \"$miss\" \"\"\n+\t\t\tdebug \"found commit excluded by --rejoin: $miss. skipping to the next --rejoin...\"\n+\t\t\tunrevs=\"$(find_existing_splits \"$dir\" \"$miss\" \"$repository\")\" || exit 1\n+\n+\t\t\tfind_commits_to_split \"$miss\" \"$unrevs\" |\n+\t\t\twhile read -r rev parents\n+\t\t\tdo\n+\t\t\t\tprocess_split_commit \"$rev\" \"$parents\"\n+\t\t\tdone\n+\n+\t\t\tif ! test -r \"$cachedir/$miss\" &&\n+\t\t\t\t! test -r \"$cachedir/notree/$miss\"\n+\t\t\tthen\n+\t\t\t\tdie \"failed to deepen history at $miss\"\n+\t\t\tfi\n \t\tfi\n \tdone\n }\n\n-- \n2.43.0\n\n"},{"id":"538036","messageId":"20260305-cs-subtree-split-recursion-v2-0-7266be870ba9@howdoi.land","threadId":"65146","inReplyTo":"20260215201748.889866-1-ask+git@howdoi.land","subject":"[PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Colin Stagner","fromEmail":"ask+git@howdoi.land","sentAt":"2026-03-05T23:55:46Z","receivedAt":"2026-03-05T23:56:56Z","isPatch":true,"body":"* cs/subtree-split-recursion: when processing large history\n  graphs on Debian or Ubuntu, \"git subtree\" can die with a\n  \"recursion depth reached\" error. Reduce recursion.\n\nOn Debian's POSIX sh, shell recursion is artificially limited\nto 1000 calls. You can check if your sh has limited recursion\nwith:\n\n    #!/bin/sh\n    recurse() {\n        r=$(( r + 1 ))\n        test \"$r\" -le 1000 || { echo OK; exit; }\n        recurse\n    } && r=0 && recurse\n\nDepending on the history graph, subtree split can recurse deeply\nenough to encounter this limit. Rewrite the rejoin-deepening\nalgorithm to reduce recursive calls.\n\n---\nChanges in v2:\n- Rebase on master\n\n---\nColin Stagner (3):\n      contrib/subtree: reduce function side-effects\n      contrib/subtree: functionalize split traversal\n      contrib/subtree: reduce recursion during split\n\n contrib/subtree/git-subtree.sh | 95 ++++++++++++++++++++++++++++++++++++++----\n 1 file changed, 88 insertions(+), 7 deletions(-)\n---\nbase-commit: 628a66ccf68d141d57d06e100c3514a54b31d6b7\nchange-id: 20260304-cs-subtree-split-recursion-6a7083cf9163\n\nBest regards,\n--  \nColin Stagner <ask+git@howdoi.land>\n\n"},{"id":"538941","messageId":"xmqqldfv1gxc.fsf@gitster.g","threadId":"65146","inReplyTo":"20260305-cs-subtree-split-recursion-v2-0-7266be870ba9@howdoi.land","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-13T22:51:59Z","receivedAt":"2026-03-13T22:52:04Z","isPatch":true,"body":"Colin Stagner <ask+git@howdoi.land> writes:\n\n> * cs/subtree-split-recursion: when processing large history\n>   graphs on Debian or Ubuntu, \"git subtree\" can die with a\n>   \"recursion depth reached\" error. Reduce recursion.\n>\n> On Debian's POSIX sh, shell recursion is artificially limited\n> to 1000 calls. You can check if your sh has limited recursion\n> with:\n>\n>     #!/bin/sh\n>     recurse() {\n>         r=$(( r + 1 ))\n>         test \"$r\" -le 1000 || { echo OK; exit; }\n>         recurse\n>     } && r=0 && recurse\n>\n> Depending on the history graph, subtree split can recurse deeply\n> enough to encounter this limit. Rewrite the rejoin-deepening\n> algorithm to reduce recursive calls.\n>\n> ---\n> Changes in v2:\n> - Rebase on master\n\nWe have seen two iterations of this series without anybody\ncommenting on it.  Is it a sign that the topic, or possibly \"git\nsubtree\" itself, is of interest to nobody?  Or is it that it is so\nwell done that nobody had any comment on it?\n\nI don't use \"git subtree\" myself, and I do not know of anybody who\nwill scream at me if I break it by merging an unreviewed patch, so I\ncan merge it without worrying too much about fallout personally, but\nthat is a tad irresponsible as the maintainer ;-)\n\nSo...?  Any volunteers among those who have a higher stake in the\nprogram than I do (which admittedly is not a high bar to cross)?\n\nThanks.\n\n"},{"id":"538943","messageId":"xmqqbjgr1g9q.fsf@gitster.g","threadId":"65146","inReplyTo":"xmqqldfv1gxc.fsf@gitster.g","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-13T23:06:09Z","receivedAt":"2026-03-13T23:06:12Z","isPatch":true,"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Colin Stagner <ask+git@howdoi.land> writes:\n>\n>> * cs/subtree-split-recursion: when processing large history\n>>   graphs on Debian or Ubuntu, \"git subtree\" can die with a\n>>   \"recursion depth reached\" error. Reduce recursion.\n>>\n>> On Debian's POSIX sh, shell recursion is artificially limited\n>> to 1000 calls. You can check if your sh has limited recursion\n>> with:\n>>\n>>     #!/bin/sh\n>>     recurse() {\n>>         r=$(( r + 1 ))\n>>         test \"$r\" -le 1000 || { echo OK; exit; }\n>>         recurse\n>>     } && r=0 && recurse\n>>\n>> Depending on the history graph, subtree split can recurse deeply\n>> enough to encounter this limit. Rewrite the rejoin-deepening\n>> algorithm to reduce recursive calls.\n>>\n>> ---\n>> Changes in v2:\n>> - Rebase on master\n>\n> We have seen two iterations of this series without anybody\n> commenting on it.  Is it a sign that the topic, or possibly \"git\n> subtree\" itself, is of interest to nobody?  Or is it that it is so\n> well done that nobody had any comment on it?\n>\n> I don't use \"git subtree\" myself, and I do not know of anybody who\n> will scream at me if I break it by merging an unreviewed patch, so I\n> can merge it without worrying too much about fallout personally, but\n> that is a tad irresponsible as the maintainer ;-)\n>\n> So...?  Any volunteers among those who have a higher stake in the\n> program than I do (which admittedly is not a high bar to cross)?\n\nFWIW, I can see that [1/3] is a benign clean-up that should not\nchange any semantics.  [2/3] talks about the variable $sub, which is\nused elsewhere, is not protected from getting overwritten by running\nthe function inside a subprocess, but I do not know if updates to\nother variables (like $b, $sq, $repository, but not $fail_msg,\n$hint1 and $hint2 that are used only in this function) want to be\nseen after the calls to this function outside (and do not want to\nfind out myself---I'd rather want to see somebody else with stakes\nin \"git subtree\" to verify), but otherwise the change looks benigh\nto me.  I have no idea if what [3/3] does is sensible or not (and\nagain, I'd rather want to see somebody with stakes to double check).\n\nThanks.\n"},{"id":"541684","messageId":"xmqqo6jk6r7k.fsf@gitster.g","threadId":"65146","inReplyTo":"xmqqbjgr1g9q.fsf@gitster.g","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-15T17:58:23Z","receivedAt":"2026-04-15T17:58:27Z","isPatch":true,"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>>> Depending on the history graph, subtree split can recurse deeply\n>>> enough to encounter this limit. Rewrite the rejoin-deepening\n>>> algorithm to reduce recursive calls.\n>>>\n>>> ---\n>>> Changes in v2:\n>>> - Rebase on master\n>>\n>> We have seen two iterations of this series without anybody\n>> commenting on it.  Is it a sign that the topic, or possibly \"git\n>> subtree\" itself, is of interest to nobody?  Or is it that it is so\n>> well done that nobody had any comment on it?\n>>\n>> I don't use \"git subtree\" myself, and I do not know of anybody who\n>> will scream at me if I break it by merging an unreviewed patch, so I\n>> can merge it without worrying too much about fallout personally, but\n>> that is a tad irresponsible as the maintainer ;-)\n>>\n>> So...?  Any volunteers among those who have a higher stake in the\n>> program than I do (which admittedly is not a high bar to cross)?\n>\n> FWIW, I can see that [1/3] is a benign clean-up that should not\n> change any semantics.  [2/3] talks about the variable $sub, which is\n> used elsewhere, is not protected ...\n> ... in \"git subtree\" to verify), but otherwise the change looks benign\n> to me.  I have no idea if what [3/3] does is sensible or not (and\n> again, I'd rather want to see somebody with stakes to double check).\n\nSo, yet not any volunteers?\n"},{"id":"541699","messageId":"C049267B-F119-4F27-8267-1B9ECFEC454B@gmail.com","threadId":"65146","inReplyTo":"xmqqo6jk6r7k.fsf@gitster.g","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-04-15T21:39:45Z","receivedAt":"2026-04-15T21:39:57Z","isPatch":true,"body":"\n> Le 15 avr. 2026 à 13:58, Junio C Hamano <gitster@pobox.com> a écrit :\n> \n> ﻿Junio C Hamano <gitster@pobox.com> writes:\n> \n>>>> Depending on the history graph, subtree split can recurse deeply\n>>>> enough to encounter this limit. Rewrite the rejoin-deepening\n>>>> algorithm to reduce recursive calls.\n>>>> \n>>>> ---\n>>>> Changes in v2:\n>>>> - Rebase on master\n>>> \n>>> We have seen two iterations of this series without anybody\n>>> commenting on it.  Is it a sign that the topic, or possibly \"git\n>>> subtree\" itself, is of interest to nobody?  Or is it that it is so\n>>> well done that nobody had any comment on it?\n>>> \n>>> I don't use \"git subtree\" myself, and I do not know of anybody who\n>>> will scream at me if I break it by merging an unreviewed patch, so I\n>>> can merge it without worrying too much about fallout personally, but\n>>> that is a tad irresponsible as the maintainer ;-)\n>>> \n>>> So...?  Any volunteers among those who have a higher stake in the\n>>> program than I do (which admittedly is not a high bar to cross)?\n>> \n>> FWIW, I can see that [1/3] is a benign clean-up that should not\n>> change any semantics.  [2/3] talks about the variable $sub, which is\n>> used elsewhere, is not protected ...\n>> ... in \"git subtree\" to verify), but otherwise the change looks benign\n>> to me.  I have no idea if what [3/3] does is sensible or not (and\n>> again, I'd rather want to see somebody with stakes to double check).\n> \n> So, yet not any volunteers?\n\nI have shared with some folks who I thought would have a stake in the matter, but the dearth of replies is evident :)"},{"id":"541743","messageId":"27104.58166.993109.63505@chiark.greenend.org.uk","threadId":"65146","inReplyTo":"20260305-cs-subtree-split-recursion-v2-0-7266be870ba9@howdoi.land","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Ian Jackson","fromEmail":"ijackson@chiark.greenend.org.uk","sentAt":"2026-04-16T13:25:10Z","receivedAt":"2026-04-16T14:23:40Z","isPatch":true,"body":"Colin Stagner writes (\"[PATCH v2 0/3] contrib/subtree: reduce recursion during split\"):\n> On Debian's POSIX sh, shell recursion is artificially limited\n> to 1000 calls. You can check if your sh has limited recursion\n> with:\n\nFTR Debian supports multiple options for /bin/sh.  The shell in\nquestion, with the limit that's troubling us, is dash.\n\n> Depending on the history graph, subtree split can recurse deeply\n> enough to encounter this limit. Rewrite the rejoin-deepening\n> algorithm to reduce recursive calls.\n\nHi.  I'm a git-subtree user and indeed I was the one who reported the\nbug Colin is trying to fix.  I would be happy to do a code review of\nthese changes.\n\nHowever, before I get stuck into that, which seems like it will\ninvolve some serious staring at shell code, I'd like to ask what seems\nlike a logically prior question:\n\nWhy not run the script under bash in non-POSIX mode instead?  I think\nthat would sidestep the problem.  If you don't want this program to\nalways depend on bash, you could have a little snippet at the top to\nre-exec with bash if (1) it's available (2) we don't seem to be\nrunning under bash already.  (Presumably the Debian package of git\nwould need to Recommend bash then.)\n\nTBH I was quite surprised, when I reported this bug some time ago, to\nfind that git-subtree was written in shell.  If it had been me I would\nprobably have used Rust and libgit2.\n\nIan.\n\n-- \nIan Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.  \n\nPronouns: they/he.  If I emailed you from @fyvzl.net or @evade.org.uk,\nthat is a private address which bypasses my fierce spamfilter.\n"},{"id":"541765","messageId":"xmqq340u1yxv.fsf@gitster.g","threadId":"65146","inReplyTo":"27104.58166.993109.63505@chiark.greenend.org.uk","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-16T19:34:52Z","receivedAt":"2026-04-16T19:34:55Z","isPatch":true,"body":"Ian Jackson <ijackson@chiark.greenend.org.uk> writes:\n\n> TBH I was quite surprised, when I reported this bug some time ago, to\n> find that git-subtree was written in shell.  If it had been me I would\n> probably have used Rust and libgit2.\n\nFWIW, it is my impression that on this mailing list, \"git subtree\"\nis treated as more or less abandonware.  Patches to it often do not\nattract any reviewers--- not the original author, nor those who have\nsubsequently touched it.\n\nIf you want to take it over and rewrite it with firmer commitment to\nmaintain it better (which unfortunately is not a high bar), that may\nbe appreciated by its users.\n"},{"id":"541809","messageId":"a1a07433-224e-4477-ae8a-3875fa98faf8@howdoi.land","threadId":"65146","inReplyTo":"27104.58166.993109.63505@chiark.greenend.org.uk","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Colin Stagner","fromEmail":"ask+git@howdoi.land","sentAt":"2026-04-17T04:50:21Z","receivedAt":"2026-04-17T04:50:37Z","isPatch":true,"body":"On 4/16/26 08:25, Ian Jackson wrote:\n\n> FTR Debian supports multiple options for /bin/sh.  The shell in\n> question, with the limit that's troubling us, is dash.\n\nCorrect, I experience this behavior in dash.\n\n> Why not run the script under bash in non-POSIX mode instead?  I think\n> that would sidestep the problem. \n\nOur coding guidelines favor POSIX constructs over non-POSIX constructs, \nincluding for shell scripts [1]. POSIX helps us stay portable.\n\nI'm not convinced that adding more shell interpreters to the mix would \nbe a net win in terms of stability or consistency. This patch series \naddresses issues that arise from different implementations of sh. Adding \nbash vs sh to the mix will probably just make more bugs.\n\n\n> If it had been me I would probably have used Rust and libgit2.\n\ngit-subtree has been around since 2009, so you would have first needed \nto invent Rust. :-) That said, a native Rust version of \ngit-subtree-split would be much faster and easier to read.\n\n\nThanks for looking at this,\n\nColin\n\n[1]: https://git-scm.com/docs/CodingGuidelines\n\n"},{"id":"541889","messageId":"27109.13129.424068.382997@chiark.greenend.org.uk","threadId":"65146","inReplyTo":"a1a07433-224e-4477-ae8a-3875fa98faf8@howdoi.land","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Ian Jackson","fromEmail":"ijackson@chiark.greenend.org.uk","sentAt":"2026-04-19T19:55:53Z","receivedAt":"2026-04-19T19:56:02Z","isPatch":true,"body":"Colin Stagner writes (\"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split\"):\n> That said, a native Rust version of \n> git-subtree-split would be much faster and easier to read.\n\nI prototyped something along the lines of the algorithm I described\nearlier.  It is very fast, as expected.\n\nThe output looks plausible when I look at it by eye, but there are\nsome things that I need to look at more closely.  I should think some\nmore about invariants and tests.\n\nOverall, I think this is worth pursuing.\n\n\nAlgorithm\n\nI don't think it is going to be possible to precisely reproduce the\noutput of the existing git-subtree split.  Indeed the existing\ngit-subtree split is a bit cavalier with metadata (eg `committer` [1])\nwhich probably ought to be changed in any case.\n\nEven so, it should be possible to avoid foolishly rewriting the whole\nhistory of the subtree, since we can stop at all the merges made by\n\"git-subtree merge\", which are easily detectable by the extra metadata\nkeyword fields in the commit message.\n\n\nPackaging\n\nBefore I go much further, how do we think this would best be packaged?\nCurrently my experiment is a standalone Rust package using\ndependencies (\"crates\" as Rust calls thme) from current Debian stable\n(\"trixie\"). [2]  I haven't tried it with recent deps from upstream\ncrates.io.  There is not currently any entanglement with git.git; the\nrepository is accessed using libgit2 via Rust's git2 wrapper (and there\nare no tests yet).\n\nI'm tempted to continue this way and rewrite the other git-subtree\nsubcommands too, since they don't look that hard.  Using git.git\noffers some packaging and testing continuity but the dependency\nsituation might become annoying.\n\nIt will probably be possible to make a Rust package which will build\nwith both recent upstream dependencies, and (say) Debian stable.\nGoing back much more than that is going to be awkward.\n\nI see there's already some Rust in git.git:contrib/libgit-rs but that\nlooks like a poc.\n\nRegards,\nIan.\n\n[1] I don't think it's justifiable to convert a commit from the\ndownstream, into the subtree split version, and retain the original\ncommitter line.  That can violate many people's expectations.\nHere's an example from another context:\n  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1124226\n\nThat means we need to use a dummy committer in split commits, and put\nthe original committer into the message.  We should name the original\ndownstream commit in the commit message too.\n\nThe dummy committer needs to be a fixed string: changing it would\ncause history proliferation (maybe even leading to unnecessary merge\nconflicts).\n\n[2] I wrote a blog post\n\n   How to use Rust on Debian (and Ubuntu, etc.)\n   https://diziet.dreamwidth.org/18122.html\n\nwhich explains why this is a good approach.\n\n-- \nIan Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.  \n\nPronouns: they/he.  If I emailed you from @fyvzl.net or @evade.org.uk,\nthat is a private address which bypasses my fierce spamfilter.\n"},{"id":"541899","messageId":"14C41D80-ED09-43CF-9C7C-9862BBCEEB33@gmail.com","threadId":"65146","inReplyTo":"27109.13129.424068.382997@chiark.greenend.org.uk","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-04-20T01:09:08Z","receivedAt":"2026-04-20T01:09:20Z","isPatch":true,"body":"I didn’t see bmc on cc, so added. I think they have some thoughts on how to organize Rust code with Git. Might be relevant, even though this is contrib/\n\n> \n> Le 19 avr. 2026 à 15:56, Ian Jackson <ijackson@chiark.greenend.org.uk> a écrit :\n> \n> ﻿Colin Stagner writes (\"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split\"):\n>> That said, a native Rust version of\n>> git-subtree-split would be much faster and easier to read.\n> \n> I prototyped something along the lines of the algorithm I described\n> earlier.  It is very fast, as expected.\n> \n> The output looks plausible when I look at it by eye, but there are\n> some things that I need to look at more closely.  I should think some\n> more about invariants and tests.\n> \n> Overall, I think this is worth pursuing.\n> \n> \n> Algorithm\n> \n> I don't think it is going to be possible to precisely reproduce the\n> output of the existing git-subtree split.  Indeed the existing\n> git-subtree split is a bit cavalier with metadata (eg `committer` [1])\n> which probably ought to be changed in any case.\n> \n> Even so, it should be possible to avoid foolishly rewriting the whole\n> history of the subtree, since we can stop at all the merges made by\n> \"git-subtree merge\", which are easily detectable by the extra metadata\n> keyword fields in the commit message.\n> \n> \n> Packaging\n> \n> Before I go much further, how do we think this would best be packaged?\n> Currently my experiment is a standalone Rust package using\n> dependencies (\"crates\" as Rust calls thme) from current Debian stable\n> (\"trixie\"). [2]  I haven't tried it with recent deps from upstream\n> crates.io.  There is not currently any entanglement with git.git; the\n> repository is accessed using libgit2 via Rust's git2 wrapper (and there\n> are no tests yet).\n> \n> I'm tempted to continue this way and rewrite the other git-subtree\n> subcommands too, since they don't look that hard.  Using git.git\n> offers some packaging and testing continuity but the dependency\n> situation might become annoying.\n> \n> It will probably be possible to make a Rust package which will build\n> with both recent upstream dependencies, and (say) Debian stable.\n> Going back much more than that is going to be awkward.\n> \n> I see there's already some Rust in git.git:contrib/libgit-rs but that\n> looks like a poc.\n> \n> Regards,\n> Ian.\n> \n> [1] I don't think it's justifiable to convert a commit from the\n> downstream, into the subtree split version, and retain the original\n> committer line.  That can violate many people's expectations.\n> Here's an example from another context:\n>  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1124226\n> \n> That means we need to use a dummy committer in split commits, and put\n> the original committer into the message.  We should name the original\n> downstream commit in the commit message too.\n> \n> The dummy committer needs to be a fixed string: changing it would\n> cause history proliferation (maybe even leading to unnecessary merge\n> conflicts).\n> \n> [2] I wrote a blog post\n> \n>   How to use Rust on Debian (and Ubuntu, etc.)\n>   https://diziet.dreamwidth.org/18122.html\n> \n> which explains why this is a good approach.\n> \n> --\n> Ian Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.  \n> \n> Pronouns: they/he.  If I emailed you from @fyvzl.net or @evade.org.uk,\n> that is a private address which bypasses my fierce spamfilter.\n> \n"},{"id":"541900","messageId":"xmqqa4uyv1ql.fsf@gitster.g","threadId":"65146","inReplyTo":"27109.13129.424068.382997@chiark.greenend.org.uk","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-20T01:50:42Z","receivedAt":"2026-04-20T01:50:47Z","isPatch":true,"body":"Ian Jackson <ijackson@chiark.greenend.org.uk> writes:\n\n> Colin Stagner writes (\"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split\"):\n>> That said, a native Rust version of \n>> git-subtree-split would be much faster and easier to read.\n>\n> I prototyped something along the lines of the algorithm I described\n> earlier.  It is very fast, as expected.\n>\n> The output looks plausible when I look at it by eye, but there are\n> some things that I need to look at more closely.  I should think some\n> more about invariants and tests.\n>\n> Overall, I think this is worth pursuing.\n\n;-).\n\n> Before I go much further, how do we think this would best be packaged?\n\nMy preference is (as it has always been)\n\n (1) host it somewhere outside of my tree,\n\n (2) replace contrib/subtree/* with a single file\n     contrib/subtree/README that lead people to the new location.\n\nThe preference is not limited to subtree but generally applies to\nthings in contrib/.  I prefer to see them graduate this project and\nstand on their own, when they do not have storng dependency on the\ngit-core project.  From technical point of view, this is especially\ntrue if your plan is to depend on libgit2, as it is not our\ndependency.  Back when Git was very young, it did make sense to have\nrelated-but-not-quite-Git things (like gitk and git-gui) shipped to\ngive them visibility, but we have passed that stage 15 years ago.\n\nThanks.\n"},{"id":"541952","messageId":"27109.63619.90318.366157@chiark.greenend.org.uk","threadId":"65146","inReplyTo":"27109.13129.424068.382997@chiark.greenend.org.uk","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Ian Jackson","fromEmail":"ijackson@chiark.greenend.org.uk","sentAt":"2026-04-20T09:57:23Z","receivedAt":"2026-04-20T09:57:25Z","isPatch":true,"body":"Ian Jackson writes (\"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split\"):\n> Algorithm\n> \n> I don't think it is going to be possible to precisely reproduce the\n> output of the existing git-subtree split.  Indeed the existing\n> git-subtree split is a bit cavalier with metadata (eg `committer` [1])\n> which probably ought to be changed in any case.\n> \n> Even so, it should be possible to avoid foolishly rewriting the whole\n> history of the subtree, since we can stop at all the merges made by\n> \"git-subtree merge\", which are easily detectable by the extra metadata\n> keyword fields in the commit message.\n\nThis last part turns out to be false.\n\nIt is only `git-subtree add` that puts this metadata in the commit\nmessage; `git-subtree merge` doesn't.  This makes it very hard to\ndistinguish a subtree merge from (say) a merge of a branch that\npredates the subtree add.\n\nI need to think about this some more but I doubt this can be made to\nwork well without more significant changes, including to the data\nmodel.  There would have to be some kind of compatibility arrangement\nto handle existing histories.\n\nColin, is that OK with you?  If you would prefer, I could choose a\ndifferent name for the resulting program.  My preference would be,\nwith your consent, to continue to call it \"git-subtree\", version 2.\n\nRegards,\nIan.\n\n-- \nIan Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.  \n\nPronouns: they/he.  If I emailed you from @fyvzl.net or @evade.org.uk,\nthat is a private address which bypasses my fierce spamfilter.\n"},{"id":"542008","messageId":"cca575ae-e5dd-4a5d-bde2-f493a3e62a87@howdoi.land","threadId":"65146","inReplyTo":"27109.63619.90318.366157@chiark.greenend.org.uk","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Colin Stagner","fromEmail":"ask+git@howdoi.land","sentAt":"2026-04-21T05:07:22Z","receivedAt":"2026-04-21T05:07:46Z","isPatch":true,"body":"On 4/20/26 04:57, Ian Jackson wrote:\n\n> I need to think about this some more but I doubt this can be made to\n> work well without more significant changes, including to the data\n> model.  There would have to be some kind of compatibility arrangement\n> to handle existing histories.\n\nI would take a look at the test-cases for git-subtree.sh, which document \nsome of the kinds of issues you will encounter. They may help you test \ncompatibility.\n\nAnything you can do to limit breakage to \"opt-in\" points-in-time only \nwould be greatly appreciated.\n\n> Colin, is that OK with you?\n\nYou can name it and develop it however you like. No need to ask \npermission here.\n\n(For the record, I'm also not the maintainer of contrib/git-subtree. \nI've just been trying to fix a few issues with it.)\n\n> If you would prefer, I could choose a different name for the\n> resulting program.\n\nIf I were writing it, I would give the new program a different name but \nperhaps provide a \"compile-time\" way to set it to \"git-subtree\" instead. \nMy reason for this is that it may need to exist with the legacy script \nfor awhile, and it's good to be able to tell them apart.\n\nColin\n\n"},{"id":"542100","messageId":"02c82c5c-6bc6-e298-3002-e6d322bdb957@gmx.de","threadId":"65146","inReplyTo":"cca575ae-e5dd-4a5d-bde2-f493a3e62a87@howdoi.land","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2026-04-22T09:43:29Z","receivedAt":"2026-04-22T09:43:35Z","isPatch":true,"body":"Hi Colin & Ian,\n\nOn Wed, 22 Apr 2026, Colin Stagner wrote:\n\n> On 4/20/26 04:57, Ian Jackson wrote:\n> \n> > I need to think about this some more but I doubt this can be made to\n> > work well without more significant changes, including to the data\n> > model.  There would have to be some kind of compatibility arrangement\n> > to handle existing histories.\n> \n> I would take a look at the test-cases for git-subtree.sh, which document \n> some of the kinds of issues you will encounter. They may help you test \n> compatibility.\n> \n> Anything you can do to limit breakage to \"opt-in\" points-in-time only \n> would be greatly appreciated.\n> \n> > Colin, is that OK with you?\n> \n> You can name it and develop it however you like. No need to ask \n> permission here.\n> \n> (For the record, I'm also not the maintainer of contrib/git-subtree. \n> I've just been trying to fix a few issues with it.)\n> \n> > If you would prefer, I could choose a different name for the\n> > resulting program.\n> \n> If I were writing it, I would give the new program a different name but \n> perhaps provide a \"compile-time\" way to set it to \"git-subtree\" instead. \n> My reason for this is that it may need to exist with the legacy script \n> for awhile, and it's good to be able to tell them apart.\n\nI just wanted to chime in to cheer you on, I've been following this\nRust-based `git-subtree` idea with interest. You may know it already, Git\nfor Windows is shipping `git subtree` with its installers for ages, and\ngiven the abysmal performance characteristics of shell-based Git commands\non Windows, it would be really good to replace the shell-scripted version\nwith the Rust version (also to ensure proper error handling, which is\nhard to make comprehensive in Unix shell scripts).\n\nThank you for pushing this forward!\n\nCiao,\nJohannes\n"},{"id":"542148","messageId":"27113.384.389621.34039@chiark.greenend.org.uk","threadId":"65146","inReplyTo":"27109.63619.90318.366157@chiark.greenend.org.uk","subject":"git-subtree rewrite","fromName":"Ian Jackson","fromEmail":"ijackson@chiark.greenend.org.uk","sentAt":"2026-04-22T17:12:32Z","receivedAt":"2026-04-22T17:12:41Z","isPatch":false,"body":"Hi, Avery.\n\ntl;dr:\n  Do you object if I use the name git-subtree for my rewrite?\n\n  I intend it to be forward compatible with existing git-subtree\n  histories and existing command line invocations.\n\n\nI've been looking into your git-subtree program.  Thanks for it;\nit is definitely solving a very real problem reasonably well. [1]\nHowever, I think the existing implementation (in shell) and data model\nneed some work.\n\nI have done some experiments, with enough success that I have more or\nless decided to try to rewrite git-subtree.\n\nI am intending to make my rewrite able to work with existing histories\n(ie, projects which have done git-subtree add and git-subtree merge).\nI intend to support the existing command line interface, although I\nmay improve that later.\n\nI am also hoping to be able to define the data model more formally.\n\nThe git maintainers and others on the git mailing list seem reasonably\nenthusiastic about all this.  My nascent rewrite is a a standalone\nRust package, and the plan would be for it to obsolete the shell\nscript in git.git/contrib, but live outside the git project itself.\n\nI would like to call my new program \"git-subtree\" and have it use\n(and extend) the exisitng `git-subtree-...:` metadata that\n`git-subtree add` puts into its generated commits.\n\nObviously there are compatibility, packaging, and deployment\nconsiderations, which I'm keeping in mind.  I don't want to break\nanyone downstream.  So I will proceed reasonably cautiously.\n\nI hope this is all OK with you.  If not, or if you have questions,\nplease let me know, using reply-all to this email (so the mailing list\ngets a copy).\n\nIf I don't hear from you I will go ahead.  The actual programming work\nis going to take a while so watch this space but not too closely :-).\n\nRegards,\nIan.\n\n[1] See also my blog post\n   Never use git submodules\n   https://diziet.dreamwidth.org/14666.html\n\n-- \nIan Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.  \n\nPronouns: they/he.  If I emailed you from @fyvzl.net or @evade.org.uk,\nthat is a private address which bypasses my fierce spamfilter.\n"},{"id":"544432","messageId":"xmqqv7c13o5l.fsf@gitster.g","threadId":"65146","inReplyTo":"a1a07433-224e-4477-ae8a-3875fa98faf8@howdoi.land","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-06-01T22:13:10Z","receivedAt":"2026-06-01T22:13:15Z","isPatch":true,"body":"Colin Stagner <ask+git@howdoi.land> writes:\n\n> On 4/16/26 08:25, Ian Jackson wrote:\n>\n>> FTR Debian supports multiple options for /bin/sh.  The shell in\n>> question, with the limit that's troubling us, is dash.\n>\n> Correct, I experience this behavior in dash.\n>\n>> Why not run the script under bash in non-POSIX mode instead?  I think\n>> that would sidestep the problem. \n>\n> Our coding guidelines favor POSIX constructs over non-POSIX constructs, \n> including for shell scripts [1]. POSIX helps us stay portable.\n>\n> I'm not convinced that adding more shell interpreters to the mix would \n> be a net win in terms of stability or consistency. This patch series \n> addresses issues that arise from different implementations of sh. Adding \n> bash vs sh to the mix will probably just make more bugs.\n>\n>\n>> If it had been me I would probably have used Rust and libgit2.\n>\n> git-subtree has been around since 2009, so you would have first needed \n> to invent Rust. :-) That said, a native Rust version of \n> git-subtree-split would be much faster and easier to read.\n>\n>\n> Thanks for looking at this,\n>\n> Colin\n>\n> [1]: https://git-scm.com/docs/CodingGuidelines\n\nSo after this message the thread went dark (except for a side\ndiscussion about rewriting subtree in Rust, which I do think it is a\ngood direction to go in the longer term).  Are we still interested in\npolishing the original patch further?\n\nWhile I do agree that avoiding bash-isms in the main part of Git and\nsticking to vanilla POSIX has merit, this particular one seems more\nlike an artificial limit imposed by dash than sticking to the POSIX\nas the common denoninator, at least to me.\n\nI am tempted to mark the topic as stalled, to be discarded for\ninaction, but thought I should ask first before doing so.\n\nThanks.\n\n\n"},{"id":"544485","messageId":"27166.40199.68450.953526@chiark.greenend.org.uk","threadId":"65146","inReplyTo":"xmqqv7c13o5l.fsf@gitster.g","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Ian Jackson","fromEmail":"ijackson@chiark.greenend.org.uk","sentAt":"2026-06-02T09:06:15Z","receivedAt":"2026-06-02T09:41:10Z","isPatch":true,"body":"Junio C Hamano writes (\"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split\"):\n> So after this message the thread went dark (except for a side\n> discussion about rewriting subtree in Rust, which I do think it is a\n> good direction to go in the longer term).\n\nI'm indeed still working on this.  Given other things on my plate it\nwill be months rather than weeks before I have anything anyone one\nmight want to use.\n\n> While I do agree that avoiding bash-isms in the main part of Git and\n> sticking to vanilla POSIX has merit, this particular one seems more\n> like an artificial limit imposed by dash than sticking to the POSIX\n> as the common denoninator, at least to me.\n\nI would be in favour of switching to bash, making bash a dependency\nfor this script.  We could use the env trick to support platforms that\ndon't have it in /bin.\n\nIan.\n\n-- \nIan Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.  \n\nPronouns: they/he.  If I emailed you from @fyvzl.net or @evade.org.uk,\nthat is a private address which bypasses my fierce spamfilter.\n"},{"id":"544568","messageId":"0915b5cc-5cbb-4cce-a832-147f85d4ff1f@howdoi.land","threadId":"65146","inReplyTo":"xmqqv7c13o5l.fsf@gitster.g","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Colin Stagner","fromEmail":"ask+git@howdoi.land","sentAt":"2026-06-03T01:37:16Z","receivedAt":"2026-06-03T01:37:31Z","isPatch":true,"body":"On 6/1/26 17:13, Junio C Hamano wrote:\n\n> I am tempted to mark the topic as stalled, to be discarded for\n> inaction\n\nNo objection. I'd still like to see this reviewed, but we can revisit \nthis later if interest develops.\n\n> While I do agree that avoiding bash-isms in the main part of Git and\n> sticking to vanilla POSIX has merit, this particular one seems more\n> like an artificial limit imposed by dash than sticking to the POSIX\n> as the common denoninator, at least to me.\n\nCorrect, this topic is a workaround for an artificial limit. The limit \nis Debian-specific and was introduced as a downstream patch in 2018 [1], \n[2].\n\nThis git-subtree issue has been reported before in\n\n   <CAN7rbOve-EFOGPjr1wrD77r-3RQ+3+qso82_oV5Qud-skobL7w@mail.gmail.com>,\n\n   <26263.63341.878041.155047@chiark.greenend.org.uk>,\n\nand probably other places. These are old reports, and I haven't found \nanyone there still interested in a fix.\n\n\n\nColin\n\n\n[1]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=579815\n\n[2]: \nhttps://sources.debian.org/patches/dash/0.5.12-12/0009-dash-Fix-stack-overflow-from-infinite-recursion-in-s.patch/\n\n"},{"id":"544594","messageId":"27167.61417.729973.579902@chiark.greenend.org.uk","threadId":"65146","inReplyTo":"0915b5cc-5cbb-4cce-a832-147f85d4ff1f@howdoi.land","subject":"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split","fromName":"Ian Jackson","fromEmail":"ijackson@chiark.greenend.org.uk","sentAt":"2026-06-03T09:12:09Z","receivedAt":"2026-06-03T09:12:20Z","isPatch":true,"body":"Colin Stagner writes (\"Re: [PATCH v2 0/3] contrib/subtree: reduce recursion during split\"):\n> On 6/1/26 17:13, Junio C Hamano wrote:\n> > While I do agree that avoiding bash-isms in the main part of Git and\n> > sticking to vanilla POSIX has merit, this particular one seems more\n> > like an artificial limit imposed by dash than sticking to the POSIX\n> > as the common denoninator, at least to me.\n> \n> Correct, this topic is a workaround for an artificial limit. The limit \n> is Debian-specific and was introduced as a downstream patch in 2018 [1], \n> [2].\n\nI don't think it is correct to say that this is Debian-specific.  The\nlimit is baked into dash, which is a non-distro-specific minimal POSIX\nshell derived from NetBSD's ash:\n  http://gondor.apana.org.au/~herbert/dash/\nI don't know what other distros use it (or can use it) as their\n/bin/sh.  I also haven't checked POSIX to see if the question of\nmaximum recursion level is discussed.\n\nIan.\n\n-- \nIan Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.  \n\nPronouns: they/he.  If I emailed you from @fyvzl.net or @evade.org.uk,\nthat is a private address which bypasses my fierce spamfilter.\n"}]}