On 4/4/2021 7:10 PM, Junio C Hamano wrote: > Derrick Stolee <stolee@xxxxxxxxx> writes: >> On 4/2/2021 5:19 PM, Junio C Hamano wrote: >>> I do not recommend unparsed refspec and textually munging, by the >>> way. Doesn't >>> >>> git fetch master:remotes/origin/master >>> >>> first parse to normalize the src/dst sides to turn it into >>> >>> git fetch refs/heads/master:refs/remotes/origin/master > > I tried to jug my memory in this area a bit by reading the relevant > code. For non-wildcard refspec, e.g. with > > [remote "origin"] > url = ../git.git/ > fetch = master:remotes/origin/master > tagopt = --no-tags > > you'd get > > $ git fetch -v > From ../git > * [new branch] master -> origin/master > $ git for-each-ref > 2e36527f23b7f6ae15e6f21ac3b08bf3fed6ee48 commit refs/remotes/origin/master > > It all happens inside remote.c::get_fetch_map(), I think. I see there that some refs are being matched with some expectation of remote refs inside get_remote_ref() (which calls find_ref_by_name_abbrev() as a helper). There does not appear to be any place that modifies the refs directly in general, and instead refs are matched from the refspec using standard short-ref rules. This is particularly shown in examples like "git push topic" never modifying the push-refspec from having 'src' equal to "topic" and instead the ref machinery discovers that "topic" really means "refs/heads/topic". I took your advice to not munge raw refpsecs and instead worked directly on the 'dst' of the struct refspec_item. This required adding a method that formats a refspec, which I test carefully. I spent about an hour trying to have parse_refspec() add the appropriate "refs/" prefix, but it becomes difficult when we intend to make a distinction between "refs/heads/" and other sub-areas within "refs/". Finally, I punted on that conversion and made the logic in 'prefetch' extremely obvious: 1. If the refspec's 'dst' starts with "refs/", then replace that prefix with "refs/prefetch/". 2. If the refspec's 'dst' does not start with "refs/", then concatenate "refs/prefetch/" and 'dst'. This will keep a roughly-equivalent partition of refs (some might have previously collided that will not any more). I have posted my patch series [1], so please take a look. It builds up the infrastructure to properly test such a refspec expansion, if we wish to do so. [1] https://lore.kernel.org/git/pull.924.git.1617627856.gitgitgadget@xxxxxxxxx/ Thanks, -Stolee