1. 23 12月, 2014 1 次提交
  2. 13 12月, 2014 1 次提交
  3. 05 12月, 2014 2 次提交
  4. 05 11月, 2014 1 次提交
    • J
      ignore stale directories when checking reflog existence · 9233887c
      Jeff King 提交于
      When we update a ref, we have two rules for whether or not
      we actually update the reflog:
      
        1. If the reflog already exists, we will always append to
           it.
      
        2. If log_all_ref_updates is set, we will create a new
           reflog file if necessary.
      
      We do the existence check by trying to open the reflog file,
      either with or without O_CREAT (depending on log_all_ref_updates).
      If it fails, then we check errno to see what happened.
      
      If we were not using O_CREAT and we got ENOENT, the file
      doesn't exist, and we return success (there isn't a reflog
      already, and we were not told to make a new one).
      
      If we get EISDIR, then there is likely a stale directory
      that needs to be removed (e.g., there used to be "foo/bar",
      it was deleted, and the directory "foo" was left. Now we
      want to create the ref "foo"). If O_CREAT is set, then we
      catch this case, try to remove the directory, and retry our
      open. So far so good.
      
      But if we get EISDIR and O_CREAT is not set, then we treat
      this as any other error, which is not right. Like ENOENT,
      EISDIR is an indication that we do not have a reflog, and we
      should silently return success (we were not told to create
      it). Instead, the current code reports this as an error, and
      we fail to update the ref at all.
      
      Note that this is relatively unlikely to happen, as you
      would have to have had reflogs turned on, and then later
      turned them off (it could also happen due to a bug in fetch,
      but that was fixed in the previous commit). However, it's
      quite easy to fix: we just need to treat EISDIR like ENOENT
      for the non-O_CREAT case, and silently return (note that
      this early return means we can also simplify the O_CREAT
      case).
      
      Our new tests cover both cases (O_CREAT and non-O_CREAT).
      The first one already worked, of course.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9233887c
  5. 16 10月, 2014 16 次提交
  6. 02 10月, 2014 8 次提交
  7. 20 9月, 2014 1 次提交
    • D
      refs: make rev-parse --quiet actually quiet · c41a87dd
      David Aguilar 提交于
      When a reflog is deleted, e.g. when "git stash" clears its stashes,
      "git rev-parse --verify --quiet" dies:
      
      	fatal: Log for refs/stash is empty.
      
      The reason is that the get_sha1() code path does not allow us
      to suppress this message.
      
      Pass the flags bitfield through get_sha1_with_context() so that
      read_ref_at() can suppress the message.
      
      Use get_sha1_with_context1() instead of get_sha1() in rev-parse
      so that the --quiet flag is honored.
      Signed-off-by: NDavid Aguilar <davvid@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c41a87dd
  8. 13 9月, 2014 1 次提交
    • J
      refs: speed up is_refname_available · cbe73331
      Jeff King 提交于
      Our filesystem ref storage does not allow D/F conflicts; so
      if "refs/heads/a/b" exists, we do not allow "refs/heads/a"
      to exist (and vice versa). This falls out naturally for
      loose refs, where the filesystem enforces the condition. But
      for packed-refs, we have to make the check ourselves.
      
      We do so by iterating over the entire packed-refs namespace
      and checking whether each name creates a conflict. If you
      have a very large number of refs, this is quite inefficient,
      as you end up doing a large number of comparisons with
      uninteresting bits of the ref tree (e.g., we know that all
      of "refs/tags" is uninteresting in the example above, yet we
      check each entry in it).
      
      Instead, let's take advantage of the fact that we have the
      packed refs stored as a trie of ref_entry structs. We can
      find each component of the proposed refname as we walk
      through the trie, checking for D/F conflicts as we go. For a
      refname of depth N (i.e., 4 in the above example), we only
      have to visit N nodes. And at each visit, we can binary
      search the M names at that level, for a total complexity of
      O(N lg M). ("M" is different at each level, of course, but
      we can take the worst-case "M" as a bound).
      
      In a pathological case of fetching 30,000 fresh refs into a
      repository with 8.5 million refs, this dropped the time to
      run "git fetch" from tens of minutes to ~30s.
      
      This may also help smaller cases in which we check against
      loose refs (which we do when renaming a ref), as we may
      avoid a disk access for unrelated loose directories.
      
      Note that the tests we add appear at first glance to be
      redundant with what is already in t3210. However, the early
      tests are not robust; they are run with reflogs turned on,
      meaning that we are not actually testing
      is_refname_available at all! The operations will still fail
      because the reflogs will hit D/F conflicts in the
      filesystem. To get a true test, we must turn off reflogs
      (but we don't want to do so for the entire script, because
      the point of turning them on was to cover some other cases).
      Reviewed-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      cbe73331
  9. 11 9月, 2014 1 次提交
    • J
      refs: write packed_refs file using stdio · 9540ce50
      Jeff King 提交于
      We write each line of a new packed-refs file individually
      using a write() syscall (and sometimes 2, if the ref is
      peeled). Since each line is only about 50-100 bytes long,
      this creates a lot of system call overhead.
      
      We can instead open a stdio handle around our descriptor and
      use fprintf to write to it. The extra buffering is not a
      problem for us, because nobody will read our new packed-refs
      file until we call commit_lock_file (by which point we have
      flushed everything).
      
      On a pathological repository with 8.5 million refs, this
      dropped the time to run `git pack-refs` from 20s to 6s.
      Signed-off-by: NJeff King <peff@peff.net>
      Reviewed-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9540ce50
  10. 04 9月, 2014 8 次提交