1. 10 9月, 2016 36 次提交
  2. 21 6月, 2016 4 次提交
    • M
      for_each_reflog(): reimplement using iterators · 2880d16f
      Michael Haggerty 提交于
      Allow references with reflogs to be iterated over using a ref_iterator.
      The latter is implemented as a files_reflog_iterator, which in turn uses
      dir_iterator to read the "logs" directory.
      
      Note that reflog iteration doesn't correctly handle per-worktree
      reflogs (either before or after this patch).
      Signed-off-by: NRamsay Jones <ramsay@ramsayjones.plus.com>
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      2880d16f
    • M
      dir_iterator: new API for iterating over a directory tree · 0fe5043d
      Michael Haggerty 提交于
      The iterator interface is modeled on that for references, though no
      vtable is necessary because there is (so far?) only one type of
      dir_iterator.
      
      There are obviously a lot of features that could easily be added to this
      class:
      
      * Skip/include directory paths in the iteration
      * Shallow/deep iteration
      * Letting the caller decide which subdirectories to recurse into (e.g.,
        via a dir_iterator_advance_into() function)
      * Option to iterate in sorted order
      * Option to iterate over directory paths before vs. after their contents
      
      But these are not needed for the current patch series, so I refrain.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0fe5043d
    • M
      for_each_reflog(): don't abort for bad references · d24b21e9
      Michael Haggerty 提交于
      If there is a file under "$GIT_DIR/logs" with no corresponding
      reference, the old code was emitting an error message, aborting the
      reflog iteration, and returning -1. But
      
      * None of the callers was checking the exit value
      
      * The callers all want to find all legitimate reflogs (sometimes for the
        purpose of determining object reachability!) and wouldn't benefit from
        a truncated iteration anyway.
      
      So instead, emit an error message and skip the "broken" reflog, but
      continue with the iteration.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      d24b21e9
    • M
      do_for_each_ref(): reimplement using reference iteration · 4c4de895
      Michael Haggerty 提交于
      Use the reference iterator interface to implement do_for_each_ref().
      Delete a bunch of code supporting the old for_each_ref() implementation.
      And now that do_for_each_ref() is generic code (it is no longer tied to
      the files backend), move it to refs.c.
      
      The implementation is via a new function, do_for_each_ref_iterator(),
      which takes a reference iterator as argument and calls a callback
      function for each of the references in the iterator.
      
      This change requires the current_ref performance hack for peel_ref() to
      be implemented via ref_iterator_peel() rather than peel_entry() because
      we don't have a ref_entry handy (it is hidden under three layers:
      file_ref_iterator, merge_ref_iterator, and cache_ref_iterator). So:
      
      * do_for_each_ref_iterator() records the active iterator in
        current_ref_iter while it is running.
      
      * peel_ref() checks whether current_ref_iter is pointing at the
        requested reference. If so, it asks the iterator to peel the
        reference (which it can do efficiently via its "peel" virtual
        function). For extra safety, we do the optimization only if the
        refname *addresses* are the same, not only if the refname *strings*
        are the same, to forestall possible mixups between refnames that come
        from different ref_iterators.
      
      Please note that this optimization of peel_ref() is only available when
      iterating via do_for_each_ref_iterator() (including all of the
      for_each_ref() functions, which call it indirectly). It would be
      complicated to implement a similar optimization when iterating directly
      using a reference iterator, because multiple reference iterators can be
      in use at the same time, with interleaved calls to
      ref_iterator_advance(). (In fact we do exactly that in
      merge_ref_iterator.)
      
      But that is not necessary. peel_ref() is only called while iterating
      over references. Callers who iterate using the for_each_ref() functions
      benefit from the optimization described above. Callers who iterate using
      reference iterators directly have access to the ref_iterator, so they
      can call ref_iterator_peel() themselves to get an analogous optimization
      in a more straightforward manner.
      
      If we rewrite all callers to use the reference iteration API, then we
      can remove the current_ref_iter hack permanently.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      4c4de895