patchbugfix git subtree split
2 messages between May 24, 2026 and May 24, 2026, from Roland Conybeare.
Plain Markdown or JSON for tools and agents. Diffs are folded; open one to read it.
Roland ConybeareMay 24, 2026, 21:23 UTC on loreI have a project that combines multiple independent repos into an unmbrella repo, relying on git subtree. Encountered a unrecoverable fatal error from 'git subtree split' with error
fatal: cache for <hash> already exists!
Problem arises because history to be split contains merge commits that cause DAG traversal to consider the same umbrella commit on multiple paths. The fatal triggers when 'git subtree split' tries to cache the same commit twice; enclosed patch prunes these duplicate paths.
Roland Conybeare (1):
subtree: fix cache_set failure on commit reachable by multiple paths
contrib/subtree/git-subtree.sh | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
base-commit: 6a4418c36d6bad69a599044b3cf49dcbd049cb45 -- 2.50.1
[PATCH 1/1] subtree: fix cache_set failure on commit reachable by multiple paths
When splitting a subtree, committs that do not intersect prefix receive identity mapping (oldrev -> oldrev). If such commit is reachable by multiple paths in the revision DAG, the cache_set() function may be called twice for the same (oldrev -> newrev) pair.
This triggers fatal error "cache for <hash> already exists"
Bugfix is to make cache_set() idempotent when the same (oldrev -> newrev) pair appears multiple times.
Signed-off-by: Roland Conybeare <rconybeare@gmail.com>
---
contrib/subtree/git-subtree.sh | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
Show changes to contrib/subtree/git-subtree.sh +7 −1
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 791fd8260c..64590e05e0 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -343,7 +343,13 @@ cache_set () {
test "$oldrev" != "latest_new" &&
test -e "$cachedir/$oldrev"
then
- die "fatal: cache for $oldrev already exists!"
+ existing=$(cat "$cachedir/$oldrev")
+ if test "$existing" = "$newrev"
+ then
+ return
+ else
+ die "fatal: cache for $oldrev already exists!"
+ fi
fi
echo "$newrev" >"$cachedir/$oldrev"
}
--
2.50.1