• Vicent Marti's avatar
    add `ignore_missing_links` mode to revwalk · 2db1a43f
    Vicent Marti authored
    When pack-objects is computing the reachability bitmap to
    serve a fetch request, it can erroneously die() if some of
    the UNINTERESTING objects are not present. Upload-pack
    throws away HAVE lines from the client for objects we do not
    have, but we may have a tip object without all of its
    ancestors (e.g., if the tip is no longer reachable and was
    new enough to survive a `git prune`, but some of its
    reachable objects did get pruned).
    
    In the non-bitmap case, we do a revision walk with the HAVE
    objects marked as UNINTERESTING. The revision walker
    explicitly ignores errors in accessing UNINTERESTING commits
    to handle this case (and we do not bother looking at
    UNINTERESTING trees or blobs at all).
    
    When we have bitmaps, however, the process is quite
    different.  The bitmap index for a pack-objects run is
    calculated in two separate steps:
    
    First, we perform an extensive walk from all the HAVEs to
    find the full set of objects reachable from them. This walk
    is usually optimized away because we are expected to hit an
    object with a bitmap during the traversal, which allows us
    to terminate early.
    
    Secondly, we perform an extensive walk from all the WANTs,
    which usually also terminates early because we hit a commit
    with an existing bitmap.
    
    Once we have the resulting bitmaps from the two walks, we
    AND-NOT them together to obtain the resulting set of objects
    we need to pack.
    
    When we are walking the HAVE objects, the revision walker
    does not know that we are walking it only to mark the
    results as uninteresting. We strip out the UNINTERESTING flag,
    because those objects _are_ interesting to us during the
    first walk. We want to keep going to get a complete set of
    reachable objects if we can.
    
    We need some way to tell the revision walker that it's OK to
    silently truncate the HAVE walk, just like it does for the
    UNINTERESTING case. This patch introduces a new
    `ignore_missing_links` flag to the `rev_info` struct, which
    we set only for the HAVE walk.
    
    It also adds tests to cover UNINTERESTING objects missing
    from several positions: a missing blob, a missing tree, and
    a missing parent commit. The missing blob already worked (as
    we do not care about its contents at all), but the other two
    cases caused us to die().
    
    Note that there are a few cases we do not need to test:
    
      1. We do not need to test a missing tree, with the blob
         still present. Without the tree that refers to it, we
         would not know that the blob is relevant to our walk.
    
      2. We do not need to test a tip commit that is missing.
         Upload-pack omits these for us (and in fact, we
         complain even in the non-bitmap case if it fails to do
         so).
    Reported-by: default avatarSiddharth Agarwal <sid0@fb.com>
    Signed-off-by: default avatarVicent Marti <tanoku@gmail.com>
    Signed-off-by: default avatarJeff King <peff@peff.net>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    2db1a43f
pack-bitmap.c 25.1 KB