1. 04 7月, 2017 1 次提交
    • M
      repack_without_refs(): don't lock or unlock the packed refs · e5cc7d7d
      Michael Haggerty 提交于
      Change `repack_without_refs()` to expect the packed-refs lock to be
      held already, and not to release the lock before returning. Change the
      callers to deal with lock management.
      
      This change makes it possible for callers to hold the packed-refs lock
      for a longer span of time, a possibility that will eventually make it
      possible to fix some longstanding races.
      
      The only semantic change here is that `repack_without_refs()` used to
      forget to release the lock in the `if (!removed)` exit path. That
      omission is now fixed.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      e5cc7d7d
  2. 24 6月, 2017 27 次提交
  3. 19 6月, 2017 1 次提交
    • M
      for_each_bisect_ref(): don't trim refnames · 03df567f
      Michael Haggerty 提交于
      `for_each_bisect_ref()` is called by `for_each_bad_bisect_ref()` with
      a term "bad". This used to make it call `for_each_ref_in_submodule()`
      with a prefix "refs/bisect/bad". But the latter is the name of the
      reference that is being sought, so the empty string was being passed
      to the callback as the trimmed refname. Moreover, this questionable
      practice was turned into an error by
      
          b9c8e7f2 prefix_ref_iterator: don't trim too much, 2017-05-22
      
      It makes more sense (and agrees better with the documentation of
      `--bisect`) for the callers to receive the full reference names. So
      
      * Add a new function, `for_each_fullref_in_submodule()`, to the refs
        API. This plugs a gap in the existing functionality, analogous to
        `for_each_fullref_in()` but accepting a `submodule` argument.
      
      * Change `for_each_bad_bisect_ref()` to call the new function rather
        than `for_each_ref_in_submodule()`.
      
      * Add a test.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      03df567f
  4. 13 6月, 2017 1 次提交
    • M
      lock_packed_refs(): fix cache validity check · fed6ebeb
      Michael Haggerty 提交于
      Commit 28ed9830 (get_packed_ref_cache(): assume "packed-refs" won't
      change while locked, 2017-05-22) assumes that the "packed-refs" file
      cannot change while we hold the lock. That assumption is
      justified *if* the lock has been held the whole time since the
      "packed-refs" file was last read.
      
      But in `lock_packed_refs()`, we ourselves lock the "packed-refs" file
      and then call `get_packed_ref_cache()` to ensure that the cache agrees
      with the file. The intent is to guard against the possibility that
      another process changed the "packed-refs" file the moment before we
      locked it.
      
      This check was defeated because `get_packed_ref_cache()` saw that the
      file was locked, and therefore didn't do the `stat_validity_check()`
      that we want.
      
      The mistake was compounded with a misleading comment in
      `lock_packed_refs()` claiming that it was doing the right thing. That
      comment came from an earlier draft of the mh/packed-ref-store-prep
      patch series when the commits were in a different order.
      
      So instead:
      
      * Extract a function `validate_packed_ref_cache()` that does the
        validity check independent of whether the lock is held.
      
      * Change `get_packed_ref_cache()` to call the new function, but only
        if the lock *isn't* held.
      
      * Change `lock_packed_refs()` to call the new function in any case
        before calling `get_packed_ref_cache()`.
      
      * Fix the comment in `lock_packed_refs()`.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      fed6ebeb
  5. 24 5月, 2017 1 次提交
    • M
      cache_ref_iterator_begin(): avoid priming unneeded directories · f23092f1
      Michael Haggerty 提交于
      When iterating over references, reference priming is used to make sure
      that loose references are read into the ref-cache before packed
      references, to avoid races. It used to be that the prefix passed to
      reference iterators almost always ended in `/`, for example
      `refs/heads/`. In that case, the priming code would read all loose
      references under `find_containing_dir("refs/heads/")`, which is
      "refs/heads/". That's just what we want.
      
      But now that `ref-filter` knows how to pass refname prefixes to
      `for_each_fullref_in()`, the prefix might come from user input; for
      example,
      
          git for-each-ref refs/heads
      
      Since the argument doesn't include a trailing slash, the reference
      iteration code would prime all of the loose references under
      `find_containing_dir("refs/heads")`, which is "refs/". Thus we would
      unnecessarily read tags, remote-tracking references, etc., when the
      user is only interested in branches.
      
      It is a bit awkward to get around this problem. We can't just append a
      slash to the argument, because we don't know ab initio whether an
      argument like `refs/tags/release` corresponds to a single tag or to a
      directory containing tags.
      
      Moreover, until now a `prefix_ref_iterator` was used to make the final
      decision about which references fall within the prefix (the
      `cache_ref_iterator` only did a rough cut). This is also inefficient,
      because the `prefix_ref_iterator` can't know, for example, that while
      you are in a subdirectory that is completely within the prefix, you
      don't have to do the prefix check.
      
      So:
      
      * Move the responsibility for doing the prefix check directly to
        `cache_ref_iterator`. This means that `cache_ref_iterator_begin()`
        never has to wrap its return value in a `prefix_ref_iterator`.
      
      * Teach `cache_ref_iterator_begin()` (and `prime_ref_dir()`) to be
        stricter about what they iterate over and what directories they
        prime.
      
      * Teach `cache_ref_iterator` to keep track of whether the current
        `cache_ref_iterator_level` is fully within the prefix. If so, skip
        the prefix checks entirely.
      
      The main benefit of these optimizations is for loose references, since
      packed references are always read all at once.
      
      Note that after this change, `prefix_ref_iterator` is only ever used
      for its trimming feature and not for its "prefix" feature. But I'm not
      ripping out the latter yet, because it might be useful for another
      patch series that I'm working on.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f23092f1
  6. 23 5月, 2017 9 次提交