{"thread":{"id":"63343","subject":"Potential bug in for-each-ref handling of fetch/push refspec","startedAt":"2025-04-24T20:57:45Z","lastAt":"2025-04-24T20:57:45Z","messageCount":1,"participants":["Sam Harwell"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"516690","messageId":"SJ1PR21MB3504FBA7658CA100C90387F6F9852@SJ1PR21MB3504.namprd21.prod.outlook.com","threadId":"63343","inReplyTo":null,"subject":"Potential bug in for-each-ref handling of fetch/push refspec","fromName":"Sam Harwell","fromEmail":"sam.harwell@microsoft.com","sentAt":"2025-04-24T20:57:43Z","receivedAt":"2025-04-24T20:57:45Z","isPatch":false,"sender":{"key":"sam.harwell@microsoft.com","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\nI attempted to use fetch and push refspec to make an Azure DevOps repository (no forks) behave more like a GitHub contributor model (with forks). For example, the 'main' and 'rel/*' branches are considered upstream, and 'dev/user/branch' is the format used by each user for working branches. Here's an example configuration showing three remotes: 1) origin maps every local branch 'name' to remote branch 'dev/sharwell/name'; 2) devdiv does not rename branches but restricts the view to just main and rel/*; 3) partner maps local branch 'name' to 'dev/partner/name', representing the work done by username partner.\n\n[remote \"origin\"]\n\turl = https://path/to/repo\n\tfetch = +refs/heads/dev/sharwell/*:refs/remotes/origin/*\n\tpush = refs/heads/*:refs/heads/dev/sharwell/*\n[remote \"devdiv\"]\n\turl = https://path/to/repo\n\tfetch = +refs/heads/main:refs/remotes/devdiv/main\n\tfetch = +refs/heads/rel/*:refs/remotes/devdiv/rel/*\n[remote \"partner\"]\n\turl = https://path/to/repo\n\tfetch = +refs/heads/dev/partner/*:refs/remotes/partner/*\n\tpush = refs/heads/*:refs/heads/dev/partner/*\n\nWhat did you expect to happen? (Expected behavior)\n\nI expected get-for-each-ref to consider refspecs for newly-created local branches than are not pushed. For example, consider the following command:\n\ngit for-each-ref --format=\"%(push:track,nobracket)::%(upstream:track,nobracket)::%(push)::%(upstream)::%(refname:short)\" refs/heads/newLocalBranch\n\nI expected this to print out:\n\n::::::::newLocalBranch\n\nWhat happened instead? (Actual behavior)\n\nThe command printed out:\n\ngone::::refs/remotes/origin/newLocalBranch::::newLocalBranch\n\nWhat's different between what you expected and what actually happened?\n\nThe command printed 'gone' instead of the empty string for '%(push:track,nobracket)'.\nThe command printed 'refs/remotes/origin/newLocalBranch' instead of the empty string for '%(push)'.\n\nAnything else you want to add:\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.49.0.windows.1\ncpu: x86_64\nbuilt from commit: cca1f38702730b35f52c29efd62864b85e85ddcc\nsizeof-long: 4\nsizeof-size_t: 8\nshell-path: D:/git-sdk-64-build-installers/usr/bin/sh\nfeature: fsmonitor--daemon\nlibcurl: 8.12.1\nOpenSSL: OpenSSL 3.2.4 11 Feb 2025\nzlib: 1.3.1\nuname: Windows 10.0 26100 \ncompiler info: gnuc: 14.2\nlibc info: no libc information available\n$SHELL (typically, interactive shell): <unset>\n\n\n[Enabled Hooks]\n"}]}