{"thread":{"id":"66134","subject":"[Feature request] Separate explicit fetch mapping from default fetch selection","startedAt":"2026-08-06T22:26:16Z","lastAt":"2026-08-07T14:55:31Z","messageCount":4,"participants":["Douglas Puchalski (dpuchals)","Junio C Hamano","Phillip Wood"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"549899","messageId":"C47215A6-B86F-4AB2-B20D-54D048B9B2BA@cisco.com","threadId":"66134","inReplyTo":null,"subject":"[Feature request] Separate explicit fetch mapping from default fetch selection","fromName":"Douglas Puchalski (dpuchals)","fromEmail":"dpuchals@cisco.com","sentAt":"2026-08-06T22:26:05Z","receivedAt":"2026-08-06T22:26:16Z","isPatch":false,"body":"Git version: 2.55.0\nEnvironment: macOS 26.6\n\nI configure a remote to fetch only a small default set of branches:\n\n    [remote \"origin\"]\n        fetch = +refs/heads/main:refs/remotes/origin/main\n        fetch = +refs/heads/team/*:refs/remotes/origin/team/*\n\nThis prevents `git fetch origin` from fetching and updating a very large\nnumber of remote branches.\n\nWhen I explicitly request another branch:\n\n    git fetch origin topic/example\n\nGit fetches the branch into FETCH_HEAD but does not create or update:\n\n    refs/remotes/origin/topic/example\n\nConsequently, the natural checkout command fails:\n\n    git checkout -b topic/example origin/topic/example\n\nThe documented behavior couples two separate policies in\n`remote.<name>.fetch`:\n\n1. Which branches an ordinary `git fetch <remote>` selects automatically.\n2. Where an explicitly requested branch is stored locally.\n\nPlease provide a configuration or default behavior under which an explicitly\nnamed remote branch is stored as the corresponding remote-tracking ref, while\nthe remote's automatic fetch set remains restricted.\n\nWith that behavior, this sequence would work:\n\n    git fetch origin topic/example\n    git checkout -b topic/example origin/topic/example\n\nIt should not require fetching every remote branch, repeating the branch name\nin a two-sided refspec, supplying `--refmap`, defining aliases, or handing the\nresult between commands through FETCH_HEAD. FETCH_HEAD is shared mutable state\nand can be overwritten by another fetch between commands.\n\nA backward-compatible opt-in configuration would address existing scripts\nthat rely on source-only fetches remaining temporary.\n\nRelevant documentation:\nhttps://git-scm <https://git-scm/>.com/docs/git-fetch"},{"id":"549906","messageId":"xmqqcxvuhcrg.fsf@gitster.g","threadId":"66134","inReplyTo":"C47215A6-B86F-4AB2-B20D-54D048B9B2BA@cisco.com","subject":"Re: [Feature request] Separate explicit fetch mapping from default fetch selection","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-08-07T02:42:43Z","receivedAt":"2026-08-07T02:42:45Z","isPatch":false,"body":"\"Douglas Puchalski (dpuchals)\" <dpuchals@cisco.com> writes:\n\n> Git version: 2.55.0\n> Environment: macOS 26.6\n>\n> I configure a remote to fetch only a small default set of branches:\n>\n>     [remote \"origin\"]\n>         fetch = +refs/heads/main:refs/remotes/origin/main\n>         fetch = +refs/heads/team/*:refs/remotes/origin/team/*\n>\n> This prevents `git fetch origin` from fetching and updating a very large\n> number of remote branches.\n>\n> When I explicitly request another branch:\n>\n>     git fetch origin topic/example\n>\n> Git fetches the branch into FETCH_HEAD but does not create or update:\n>\n>     refs/remotes/origin/topic/example\n\nI haven't thought things through, but I suspect that what you want\nmight be an opposite of explicitly listing what is tracked on\nremote.*.fetch configuration, but having remotes/origin/* hierarchy\nof refs as the source of the tracking information.\n\nIt was a long ago this was invented, and I haven't used it for\nalmost forever, but shouldn't this\n\n    $ git fetch \\\n            --refmap=\"refs/heads/*:refs/remotes/origin/*\" \\\n            origin topic/example\n\ndo what you want to do?  If so, perhaps it would make a good\nstarting point to make it easier to use (e.g., perhaps a\nconfiguration variable can specify the refmap to be used, or\nsomething).\n\n\n"},{"id":"549994","messageId":"10103c22-af8f-4bf3-b4ab-a3e4ce0491d4@gmail.com","threadId":"66134","inReplyTo":"xmqqcxvuhcrg.fsf@gitster.g","subject":"Re: [Feature request] Separate explicit fetch mapping from default fetch selection","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-08-07T13:08:22Z","receivedAt":"2026-08-07T13:08:32Z","isPatch":false,"body":"On 07/08/2026 03:42, Junio C Hamano wrote:\n> \"Douglas Puchalski (dpuchals)\" <dpuchals@cisco.com> writes:\n> \n>> Git version: 2.55.0\n>> Environment: macOS 26.6\n>>\n>> I configure a remote to fetch only a small default set of branches:\n>>\n>>      [remote \"origin\"]\n>>          fetch = +refs/heads/main:refs/remotes/origin/main\n>>          fetch = +refs/heads/team/*:refs/remotes/origin/team/*\n>>\n>> This prevents `git fetch origin` from fetching and updating a very large\n>> number of remote branches.\n>>\n>> When I explicitly request another branch:\n>>\n>>      git fetch origin topic/example\n>>\n>> Git fetches the branch into FETCH_HEAD but does not create or update:\n>>\n>>      refs/remotes/origin/topic/example\n\nThat annoys me too. There is a similar problem with the push refspec if \nyou want to use it to map the refname rather than specify a default set \nof branches to push.\n\n> I haven't thought things through, but I suspect that what you want\n> might be an opposite of explicitly listing what is tracked on\n> remote.*.fetch configuration, but having remotes/origin/* hierarchy\n> of refs as the source of the tracking information.\n> \n> It was a long ago this was invented, and I haven't used it for\n> almost forever, but shouldn't this\n> \n>      $ git fetch \\\n>              --refmap=\"refs/heads/*:refs/remotes/origin/*\" \\\n>              origin topic/example\n> \n> do what you want to do?  If so, perhaps it would make a good\n> starting point to make it easier to use (e.g., perhaps a\n> configuration variable can specify the refmap to be used, or\n> something).\n\nSo we'd have something like \"remote.<remote>.fetchMap\" and \n\"remote.<remote>.pushMap\" that mapped refnames, but did not affect what \ngets fetched or push by default? That sounds useful (I've not thought \nthrough the interaction with the existing settings though).\n\nOne of my other bugbears about the refspec config is that the first \nmatching one wins, rather than the longest match so you have to edit the \nconfig file rather than use \"git config\" to add a refspec that matches a \nsepcific branch, otherwise the default \"refs/heads/*:...\" that's created \nwhen the remote is added is used instead because it comes first.\n\nThanks\n\nPhillip\n\n"},{"id":"550009","messageId":"xmqqtsp6f09t.fsf@gitster.g","threadId":"66134","inReplyTo":"10103c22-af8f-4bf3-b4ab-a3e4ce0491d4@gmail.com","subject":"Re: [Feature request] Separate explicit fetch mapping from default fetch selection","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-08-07T14:55:26Z","receivedAt":"2026-08-07T14:55:31Z","isPatch":false,"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n>> It was a long ago this was invented, and I haven't used it for\n>> almost forever, but shouldn't this\n>> \n>>      $ git fetch \\\n>>              --refmap=\"refs/heads/*:refs/remotes/origin/*\" \\\n>>              origin topic/example\n>> \n>> do what you want to do?  If so, perhaps it would make a good\n>> starting point to make it easier to use (e.g., perhaps a\n>> configuration variable can specify the refmap to be used, or\n>> something).\n>\n> So we'd have something like \"remote.<remote>.fetchMap\" and \n> \"remote.<remote>.pushMap\" that mapped refnames, but did not affect what \n> gets fetched or push by default? That sounds useful (I've not thought \n> through the interaction with the existing settings though).\n\nAs I said, I do not know what the final system should look like,\nbut the idea behind 'refmap' was to separate (A) the rule\ndescribing the correspondence between reference names on their end\nand those on our end, and (B) the specification of which source\nreferences are transferred to the destination repository.  Since the\ntransfer can work both ways, we would need two sets of maps, one for\neach direction.\n\nOnce established, I suspect that 'git fetch' could learn something\nlike the 'matching' mode that 'git push' has in 'push.default'.\nUsing that mode, the OP's everyday 'git fetch' would then: (1)\ninteract with the default remote; (2) decide which of their\nreferences to fetch by reverse-mapping the remote-tracking branches\nwe already have using the fetch 'refmap'; and (3) update the\nremote-tracking references using those references we decided to\nfetch in the previous step.  If the OP decides to extend the area of\ninterest by fetching a new branch from the remote,\n\n    $ git fetch origin a-new-topic\n\nnaming only the remote and their branch, we would know which\nremote-tracking branch to store the result in and add a new\nrefs/remotes/origin/a-new-topic remote-tracking branch.  This would\nautomatically extend what the next 'git fetch' grabs from them.\n\nOr something like that, perhaps?\n\n"}]}