Skip to content
  • Jeff King's avatar
    fetch: do not consider peeled tags as advertised tips · 34066f06
    Jeff King authored and Junio C Hamano's avatar Junio C Hamano committed
    Our filter_refs() function accidentally considers the target of a peeled
    tag to be advertised by the server, even though upload-pack on the
    server side does not consider it so. This can result in the client
    making a bogus fetch to the server, which will end with the server
    complaining "not our ref". Whereas the correct behavior is for the
    client to notice that the server will not allow the request and error
    out immediately.
    
    So as bugs go, this is not very serious (the outcome is the same either
    way -- the fetch fails). But it's worth making the logic here correct
    and consistent with other related cases (e.g., fetching an oid that the
    server did not mention at all).
    
    The crux of the issue comes from fdb69d33
    
     (fetch-pack: always allow
    fetching of literal SHA1s, 2017-05-15). After that, the strategy of
    filter_refs() is basically:
    
      - for each advertised ref, try to match it with a "sought" ref
        provided by the user. Skip any malformed refs (which includes
        peeled values like "refs/tags/foo^{}"), and place any unmatched
        items onto the unmatched list.
    
      - if there are unmatched sought refs, then put all of the advertised
        tips into an oidset, including the unmatched ones.
    
      - for each sought ref, see if it's in the oidset, in which case it's
        legal for us to ask the server for it
    
    The problem is in the second step. Our list of unmatched refs includes
    the peeled refs, even though upload-pack does not allow them to be
    directly fetched. So the simplest fix would be to exclude them during
    that step.
    
    However, we can observe that the unmatched list isn't used for anything
    else, and is freed at the end. We can just free those malformed refs
    immediately. That saves us having to check each ref a second time to see
    if it's malformed.
    
    Note that this code only kicks in when "strict" is in effect. I.e., if
    we are using the v0 protocol and uploadpack.allowReachableSHA1InWant is
    not in effect. With v2, all oids are allowed, and we do not bother
    creating or consulting the oidset at all. To future-proof our test
    against the upcoming GIT_TEST_PROTOCOL_VERSION flag, we'll manually mark
    it as a v0-only test.
    
    Signed-off-by: default avatarJeff King <peff@peff.net>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    34066f06