1. 28 7月, 2015 2 次提交
    • J
      refs: loosen restriction on wildcard "*" refspecs · cd377f45
      Jacob Keller 提交于
      Loosen restrictions on refspecs by allowing patterns that have a "*"
      within a component instead of only as the whole component.
      
      Remove the logic to accept a single "*" as a whole component from
      check_refname_format(), and implement an extended form of that logic
      in check_refname_component().  Pass the pointer to the flags argument
      to the latter, as it has to clear REFNAME_REFSPEC_PATTERN bit when
      it sees "*".
      
      Teach check_refname_component() function to allow an asterisk "*"
      only when REFNAME_REFSPEC_PATTERN is set in the flags, and drop the
      bit after seeing a "*", to ensure that one side of a refspec
      contains at most one asterisk.
      
      This will allow us to accept refspecs such as `for/bar*:foo/baz*`.
      Any refspec which functioned before shall continue functioning with
      the new logic.
      Signed-off-by: NJacob Keller <jacob.keller@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      cd377f45
    • J
      refs: cleanup comments regarding check_refname_component() · 53a8555e
      Jacob Keller 提交于
      Correctly specify all characters which are rejected under the '4: a
      bad character' disposition, which did not list all characters that
      are treated as such.
      
      Cleanup comment style for rejected refs by inserting a ", or" at the
      end of each statement.
      Signed-off-by: NJacob Keller <jacob.keller@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      53a8555e
  2. 22 7月, 2015 4 次提交
  3. 30 6月, 2015 1 次提交
    • J
      convert "enum date_mode" into a struct · a5481a6c
      Jeff King 提交于
      In preparation for adding date modes that may carry extra
      information beyond the mode itself, this patch converts the
      date_mode enum into a struct.
      
      Most of the conversion is fairly straightforward; we pass
      the struct as a pointer and dereference the type field where
      necessary. Locations that declare a date_mode can use a "{}"
      constructor.  However, the tricky case is where we use the
      enum labels as constants, like:
      
        show_date(t, tz, DATE_NORMAL);
      
      Ideally we could say:
      
        show_date(t, tz, &{ DATE_NORMAL });
      
      but of course C does not allow that. Likewise, we cannot
      cast the constant to a struct, because we need to pass an
      actual address. Our options are basically:
      
        1. Manually add a "struct date_mode d = { DATE_NORMAL }"
           definition to each caller, and pass "&d". This makes
           the callers uglier, because they sometimes do not even
           have their own scope (e.g., they are inside a switch
           statement).
      
        2. Provide a pre-made global "date_normal" struct that can
           be passed by address. We'd also need "date_rfc2822",
           "date_iso8601", and so forth. But at least the ugliness
           is defined in one place.
      
        3. Provide a wrapper that generates the correct struct on
           the fly. The big downside is that we end up pointing to
           a single global, which makes our wrapper non-reentrant.
           But show_date is already not reentrant, so it does not
           matter.
      
      This patch implements 3, along with a minor macro to keep
      the size of the callers sane.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      a5481a6c
  4. 23 6月, 2015 12 次提交
  5. 13 6月, 2015 1 次提交
    • M
      Allow to control where the replace refs are looked for · 58d121b2
      Mike Hommey 提交于
      It can be useful to have grafts or replace refs for specific use-cases while
      keeping the default "view" of the repository pristine (or with a different
      set of grafts/replace refs).
      
      It is possible to use a different graft file with GIT_GRAFT_FILE, but while
      replace refs are more powerful, they don't have an equivalent override.
      
      Add a GIT_REPLACE_REF_BASE environment variable to control where git is
      going to look for replace refs.
      Signed-off-by: NMike Hommey <mh@glandium.org>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      58d121b2
  6. 09 6月, 2015 1 次提交
  7. 04 6月, 2015 1 次提交
  8. 28 5月, 2015 5 次提交
  9. 26 5月, 2015 5 次提交
  10. 15 5月, 2015 1 次提交
    • M
      lock_packed_refs(): allow retries when acquiring the packed-refs lock · f4ab4f3a
      Michael Haggerty 提交于
      Currently, there is only one attempt to acquire any lockfile, and if
      the lock is held by another process, the locking attempt fails
      immediately.
      
      This is not such a limitation for loose reference files. First, they
      don't take long to rewrite. Second, most reference updates have a
      known "old" value, so if another process is updating a reference at
      the same moment that we are trying to lock it, then probably the
      expected "old" value will not longer be valid, and the update will
      fail anyway.
      
      But these arguments do not hold for packed-refs:
      
      * The packed-refs file can be large and take significant time to
        rewrite.
      
      * Many references are stored in a single packed-refs file, so it could
        be that the other process was changing a different reference than
        the one that we are interested in.
      
      Therefore, it is much more likely for there to be spurious lock
      conflicts in connection to the packed-refs file, resulting in
      unnecessary command failures.
      
      So, if the first attempt to lock the packed-refs file fails, continue
      retrying for a configurable length of time before giving up. The
      default timeout is 1 second.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f4ab4f3a
  11. 13 5月, 2015 7 次提交
    • M
      ref_transaction_commit(): fix atomicity and avoid fd exhaustion · cf018ee0
      Michael Haggerty 提交于
      The old code was roughly
      
          for update in updates:
              acquire locks and check old_sha
          for update in updates:
              if changing value:
                  write_ref_to_lockfile()
                  commit_ref_update()
          for update in updates:
              if deleting value:
                  unlink()
          rewrite packed-refs file
          for update in updates:
              if reference still locked:
                  unlock_ref()
      
      This has two problems.
      
      Non-atomic updates
      ==================
      
      The atomicity of the reference transaction depends on all pre-checks
      being done in the first loop, before any changes have started being
      committed in the second loop. The problem is that
      write_ref_to_lockfile() (previously part of write_ref_sha1()), which
      is called from the second loop, contains two more checks:
      
      * It verifies that new_sha1 is a valid object
      
      * If the reference being updated is a branch, it verifies that
        new_sha1 points at a commit object (as opposed to a tag, tree, or
        blob).
      
      If either of these checks fails, the "transaction" is aborted during
      the second loop. But this might happen after some reference updates
      have already been permanently committed. In other words, the
      all-or-nothing promise of "git update-ref --stdin" could be violated.
      
      So these checks have to be moved to the first loop.
      
      File descriptor exhaustion
      ==========================
      
      The old code locked all of the references in the first loop, leaving
      all of the lockfiles open until later loops. Since we might be
      updating a lot of references, this could result in file descriptor
      exhaustion.
      
      The solution
      ============
      
      After this patch, the code looks like
      
          for update in updates:
              acquire locks and check old_sha
              if changing value:
                  write_ref_to_lockfile()
              else:
                  close_ref()
          for update in updates:
              if changing value:
                  commit_ref_update()
          for update in updates:
              if deleting value:
                  unlink()
          rewrite packed-refs file
          for update in updates:
              if reference still locked:
                  unlock_ref()
      
      This fixes both problems:
      
      1. The pre-checks in write_ref_to_lockfile() are now done in the first
         loop, before any changes have been committed. If any of the checks
         fails, the whole transaction can now be rolled back correctly.
      
      2. All lockfiles are closed in the first loop immediately after they
         are created (either by write_ref_to_lockfile() or by close_ref()).
         This means that there is never more than one open lockfile at a
         time, preventing file descriptor exhaustion.
      
      To simplify the bookkeeping across loops, add a new REF_NEEDS_COMMIT
      bit to update->flags, which keeps track of whether the corresponding
      lockfile needs to be committed, as opposed to just unlocked. (Since
      "struct ref_update" is internal to the refs module, this change is not
      visible to external callers.)
      
      This change fixes two tests in t1400.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      cf018ee0
    • M
      ref_transaction_commit(): remove the local flags variable · cbf50f9e
      Michael Haggerty 提交于
      Instead, work directly with update->flags. This has the advantage that
      the REF_DELETING bit, set in the first loop, can be read in the second
      loop instead of having to be recomputed. Plus, it was potentially
      confusing having both update->flags and flags, which sometimes had
      different values.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      cbf50f9e
    • M
      ref_transaction_commit(): inline call to write_ref_sha1() · 61e51e00
      Michael Haggerty 提交于
      That was the last caller, so delete function write_ref_sha1().
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      61e51e00
    • M
      rename_ref(): inline calls to write_ref_sha1() from this function · ba43b7f2
      Michael Haggerty 提交于
      Most of what it does is unneeded from these call sites.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      ba43b7f2
    • M
    • M
      write_ref_to_lockfile(): new function, extracted from write_ref_sha1() · e6fd3c67
      Michael Haggerty 提交于
      This is the first step towards separating the checking and writing of
      the new reference value to committing the change.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      e6fd3c67
    • M
      ref_transaction_commit(): fix atomicity and avoid fd exhaustion · 6c34492a
      Michael Haggerty 提交于
      The old code was roughly
      
          for update in updates:
              acquire locks and check old_sha
          for update in updates:
              if changing value:
                  write_ref_to_lockfile()
                  commit_ref_update()
          for update in updates:
              if deleting value:
                  unlink()
          rewrite packed-refs file
          for update in updates:
              if reference still locked:
                  unlock_ref()
      
      This has two problems.
      
      Non-atomic updates
      ==================
      
      The atomicity of the reference transaction depends on all pre-checks
      being done in the first loop, before any changes have started being
      committed in the second loop. The problem is that
      write_ref_to_lockfile() (previously part of write_ref_sha1()), which
      is called from the second loop, contains two more checks:
      
      * It verifies that new_sha1 is a valid object
      
      * If the reference being updated is a branch, it verifies that
        new_sha1 points at a commit object (as opposed to a tag, tree, or
        blob).
      
      If either of these checks fails, the "transaction" is aborted during
      the second loop. But this might happen after some reference updates
      have already been permanently committed. In other words, the
      all-or-nothing promise of "git update-ref --stdin" could be violated.
      
      So these checks have to be moved to the first loop.
      
      File descriptor exhaustion
      ==========================
      
      The old code locked all of the references in the first loop, leaving
      all of the lockfiles open until later loops. Since we might be
      updating a lot of references, this could result in file descriptor
      exhaustion.
      
      The solution
      ============
      
      After this patch, the code looks like
      
          for update in updates:
              acquire locks and check old_sha
              if changing value:
                  write_ref_to_lockfile()
              else:
                  close_ref()
          for update in updates:
              if changing value:
                  commit_ref_update()
          for update in updates:
              if deleting value:
                  unlink()
          rewrite packed-refs file
          for update in updates:
              if reference still locked:
                  unlock_ref()
      
      This fixes both problems:
      
      1. The pre-checks in write_ref_to_lockfile() are now done in the first
         loop, before any changes have been committed. If any of the checks
         fails, the whole transaction can now be rolled back correctly.
      
      2. All lockfiles are closed in the first loop immediately after they
         are created (either by write_ref_to_lockfile() or by close_ref()).
         This means that there is never more than one open lockfile at a
         time, preventing file descriptor exhaustion.
      
      To simplify the bookkeeping across loops, add a new REF_NEEDS_COMMIT
      bit to update->flags, which keeps track of whether the corresponding
      lockfile needs to be committed, as opposed to just unlocked. (Since
      "struct ref_update" is internal to the refs module, this change is not
      visible to external callers.)
      
      This change fixes two tests in t1400.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      6c34492a