{"thread":{"id":"65155","subject":"[git/contrib/subtree] Remote-ref unexpectedly deleted if pushing subtree commit twice","startedAt":"2026-03-06T17:53:07Z","lastAt":"2026-03-06T17:53:07Z","messageCount":1,"participants":["joerg.gambihler@gmx.de"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"538097","messageId":"946173d6-3872-4b5c-93a1-08134b6483cc@gmx.de","threadId":"65155","inReplyTo":null,"subject":"[git/contrib/subtree] Remote-ref unexpectedly deleted if pushing subtree commit twice","fromName":"","fromEmail":"joerg.gambihler@gmx.de","sentAt":"2026-03-06T17:53:07Z","receivedAt":"2026-03-06T17:53:07Z","isPatch":false,"sender":{"key":"joerg.gambihler@gmx.de","avatar":null},"body":"Thank you for filling out a Git bug report!\nPlease answer the following questions to help us understand your issue.\n\nWhat did you do before the bug happened? (Steps to reproduce your issue)\n\n# setup main and subtree repo\n$ git init main && git init subtree\n$ cd main && git remote add subtr ../subtree/.git\n\n# populate main repo\n$ mkdir dir && echo hello > dir/hello.txt\n$ git add . && git commit -m \"Commit dir\"\n\n# split/push subtree 'dir'...\n$ git subtree push --prefix=dir --rejoin --squash subtr subtrbranch\n# ...and again\n$ git subtree push --prefix=dir --rejoin --squash subtr subtrbranch\n\nWhat did you expect to happen? (Expected behavior)\n\n- No change on 2nd  git subtree push\n\nWhat happened instead? (Actual behavior)\n\n- Remote-ref unexpectedly deleted on 2nd git subtree push:\n > git push using:  subtr subtrbranch\n > Subtree is already at commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.\n > To ../subtree/.git\n >  - [deleted]         subtrbranch\n\nWhat's different between what you expected and what actually happened?\n\n- No change vs deleted remote-ref on 2nd  git subtree push.\n\nAnything else you want to add:\n\n- Root cause in contrib/subtree/git-subtree.sh (branch next, 3824d2c):\n   In the scenario above:\n   cmd_push calls cmd_split in a subshell:\n         localrev=$(cmd_split \"$localrev_presplit\" \"$repository\") || die\n   cmd_split calls cmd_merge.\n   cmd_merge exits 0 without writing to stdout\n         if test \"$sub\" = \"$rev\"\n         then\n             say >&2 \"Subtree is already at commit $rev.\"\n             exit 0\n         fi\n   With exit 0 only the subshell is exited. Instead of dying this \nassignement\n         localrev=$(cmd_split \"$localrev_presplit\" \"$repository\") || die\n   becomes\n         localrev=\n   yielding a refspec  :refs/heads/$remoteref  pushed to the remote \nrepository:\n         git push \"$repository\" \"$localrev\":\"refs/heads/$remoteref\"\n\n- Proposed fix (I can try to submit a patch if desired):\ndiff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh\nindex 791fd8260c..0951a5aadd 100755\n--- a/contrib/subtree/git-subtree.sh\n+++ b/contrib/subtree/git-subtree.sh\n@@ -1102,7 +1102,11 @@ cmd_push () {\n\n                 echo \"git push using: \" \"$repository\" \"$refspec\"\n                 localrev=$(cmd_split \"$localrev_presplit\" \n\"$repository\") || die\n-               git push \"$repository\" \"$localrev\":\"refs/heads/$remoteref\"\n+               # Validate localrev. It maybe empty if cmd_split exits \nwith 0.\n+               if test -n \"$localrev\"\n+               then\n+                       git push \"$repository\" \n\"$localrev\":\"refs/heads/$remoteref\"\n+               fi\n         else\n                 die \"fatal: '$dir' must already exist. Try 'git subtree \nadd'.\"\n         fi\n\n\n\nPlease review the rest of the bug report below.\nYou can delete any lines you don't wish to share.\n\n\n[System Info]\ngit version:\ngit version 2.53.0.windows.1\ncpu: x86_64\nbuilt from commit: a5512bdee37ed7142c233d21e2d347ffc4860ff3\nsizeof-long: 4\nsizeof-size_t: 8\nshell-path: D:/git-sdk-64-build-installers/usr/bin/sh\nrust: disabled\nfeature: fsmonitor--daemon\ngettext: enabled\nlibcurl: 8.18.0\nOpenSSL: OpenSSL 3.5.5 27 Jan 2026\nzlib: 1.3.1\nSHA-1: SHA1_DC\nSHA-256: SHA256_BLK\ndefault-ref-format: files\ndefault-hash: sha1\nuname: Windows 10.0 26100\ncompiler info: gnuc: 15.2\nlibc info: no libc information available\n$SHELL (typically, interactive shell): C:\\Program Files\\Git\\usr\\bin\\bash.exe\n\n\n[Enabled Hooks]\n\n"}]}