1. 25 8月, 2017 3 次提交
  2. 03 8月, 2017 2 次提交
    • J
      revision: do not fallback to default when rev_input_given is set · 5d34d1ac
      Jeff King 提交于
      If revs->def is set (as it is in "git log") and there are no
      pending objects after parsing the user's input, then we show
      whatever is in "def". But if the user _did_ ask for some
      input that just happened to be empty (e.g., "--glob" that
      does not match anything), showing the default revision is
      confusing. We should just show nothing, as that is what the
      user's request yielded.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      5d34d1ac
    • J
      revision: add rev_input_given flag · 7ba82629
      Jeff King 提交于
      Normally a caller that invokes setup_revisions() has to
      check rev.pending to see if anything was actually queued for
      the traversal. But they can't tell the difference between
      two cases:
      
        1. The user gave us no tip from which to start a
           traversal.
      
        2. The user tried to give us tips via --glob, --all, etc,
           but their patterns ended up being empty.
      
      Let's set a flag in the rev_info struct that callers can use
      to tell the difference.  We can set this from the
      init_all_refs_cb() function.  That's a little funny because
      it's not exactly about initializing the "cb" struct itself.
      But that function is the common setup place for doing
      pattern traversals that is used by --glob, --all, etc.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      7ba82629
  3. 18 7月, 2017 2 次提交
    • B
      sha1_name: convert GET_SHA1* flags to GET_OID* · 321c89bf
      brian m. carlson 提交于
      Convert the flags for get_oid_with_context and friends to use "OID"
      instead of "SHA1" in their names.
      
      This transform was made by running the following one-liner on the
      affected files:
      
        perl -pi -e 's/GET_SHA1/GET_OID/g'
      Signed-off-by: Nbrian m. carlson <sandals@crustytoothpaste.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      321c89bf
    • B
      sha1_name: convert get_sha1* to get_oid* · e82caf38
      brian m. carlson 提交于
      Now that all the callers of get_sha1 directly or indirectly use struct
      object_id, rename the functions starting with get_sha1 to start with
      get_oid.  Convert the internals in sha1_name.c to use struct object_id
      as well, and eliminate explicit length checks where possible.  Convert a
      use of 40 in get_oid_basic to GIT_SHA1_HEXSZ.
      
      Outside of sha1_name.c and cache.h, this transition was made with the
      following semantic patch:
      
      @@
      expression E1, E2;
      @@
      - get_sha1(E1, E2.hash)
      + get_oid(E1, &E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1(E1, E2->hash)
      + get_oid(E1, E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1_committish(E1, E2.hash)
      + get_oid_committish(E1, &E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1_committish(E1, E2->hash)
      + get_oid_committish(E1, E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1_treeish(E1, E2.hash)
      + get_oid_treeish(E1, &E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1_treeish(E1, E2->hash)
      + get_oid_treeish(E1, E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1_commit(E1, E2.hash)
      + get_oid_commit(E1, &E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1_commit(E1, E2->hash)
      + get_oid_commit(E1, E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1_tree(E1, E2.hash)
      + get_oid_tree(E1, &E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1_tree(E1, E2->hash)
      + get_oid_tree(E1, E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1_blob(E1, E2.hash)
      + get_oid_blob(E1, &E2)
      
      @@
      expression E1, E2;
      @@
      - get_sha1_blob(E1, E2->hash)
      + get_oid_blob(E1, E2)
      
      @@
      expression E1, E2, E3, E4;
      @@
      - get_sha1_with_context(E1, E2, E3.hash, E4)
      + get_oid_with_context(E1, E2, &E3, E4)
      
      @@
      expression E1, E2, E3, E4;
      @@
      - get_sha1_with_context(E1, E2, E3->hash, E4)
      + get_oid_with_context(E1, E2, E3, E4)
      Signed-off-by: Nbrian m. carlson <sandals@crustytoothpaste.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      e82caf38
  4. 10 7月, 2017 3 次提交
    • J
      reflog-walk: apply --since/--until to reflog dates · de239446
      Jeff King 提交于
      When doing a reflog walk, we use the commit's date to
      do any date limiting. In earlier versions of Git, this could
      lead to nonsense results, since a skipped commit would
      truncate the traversal. So a sequence like:
      
        git commit ...
        git checkout week-old-branch
        git checkout -
        git log -g --since=1.day.ago
      
      would stop at the week-old-branch, even though the "git
      commit" entry further back is still interesting.
      
      As of the prior commit, which uses a parent-less traversal
      of the reflog, you get the whole reflog minus any commits
      whose dates do not match the specified options. This is
      arguably useful, as you could scan the reflogs for commits
      that originated in a certain range.
      
      But more likely a user doing a reflog walk wants to limit
      based on the reflog entries themselves. You can simulate
      --until with:
      
        git log -g @{1.day.ago}
      
      but there's no way to ask Git to traverse only back to a
      certain date. E.g.:
      
        # show me reflog entries from the past day
        git log -g --since=1.day.ago
      
      This patch teaches the revision machinery to prefer the
      reflog entry dates to the commit dates when doing a reflog
      walk. Technically this is a change in behavior that affects
      plumbing, but the previous behavior was so buggy that it's
      unlikely anyone was relying on it.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      de239446
    • J
      reflog-walk: stop using fake parents · d08565bf
      Jeff King 提交于
      The reflog-walk system works by putting a ref's tip into the
      pending queue, and then "traversing" the reflog by
      pretending that the parent of each commit is the previous
      reflog entry.
      
      This causes a number of user-visible oddities, as documented
      in t1414 (and the commit message which introduced it). We
      can fix all of them in one go by replacing the fake-reflog
      system with a much simpler one: just keeping a list of
      reflogs to show, and walking through them entry by entry.
      
      The implementation is fairly straight-forward, but there are
      a few items to note:
      
        1. We obviously must skip calling add_parents_to_list()
           when we are traversing reflogs, since we do not want to
           walk the original parents at all.  As a result, we must call
           try_to_simplify_commit() ourselves.
      
           There are other parts of add_parents_to_list() we skip,
           as well, but none of them should matter for a reflog
           traversal:
      
             -  We do not allow UNINTERESTING commits, nor
                symmetric ranges (and we bail when these are used
                with "-g").
      
             - Using --source makes no sense, since we aren't
               traversing. The reflog selector shows the same
               information with more detail.
      
             - Using --first-parent is still sensible, since you
               may want to see the first-parent diff for each
               entry. But since we're not traversing, we don't
               need to cull the parent list here.
      
        2. Since we now just walk the reflog entries themselves,
           rather than starting with the ref tip, we now look at
           the "new" field of each entry rather than the "old"
           (i.e., we are showing entries, not faking parents).
           This removes all of the tricky logic around skipping
           past root commits.
      
           But note that we have no way to show an entry with the
           null sha1 in its "new" field (because such a commit
           obviously does not exist). Normally this would not
           happen, since we delete reflogs along with refs, but
           there is one special case. When we rename the currently
           checked out branch, we write two reflog entries into
           the HEAD log: one where the commit goes away, and
           another where it comes back.
      
           Prior to this commit, we show both entries with
           identical reflog messages. After this commit, we show
           only the "comes back" entry. See the update in t3200
           which demonstrates this.
      
           Arguably either is fine, as the whole double-entry
           thing is a bit hacky in the first place. And until a
           recent fix, we truncated the traversal in such a case
           anyway, which was _definitely_ wrong.
      
        3. We show individual reflogs in order, but choose which
           reflog to show at each stage based on which has the
           most recent timestamp.  This interleaves the output
           from multiple reflogs based on date order, which is
           probably what you'd want with limiting like "-n 30".
      
           Note that the implementation aims for simplicity. It
           does a linear walk over the reflog queue for each
           commit it pulls, which may perform badly if you
           interleave an enormous number of reflogs. That seems
           like an unlikely use case; if we did want to handle it,
           we could probably keep a priority queue of reflogs,
           ordered by the timestamp of their current tip entry.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      d08565bf
    • J
      get_revision_1(): replace do-while with an early return · 7c2f08aa
      Jeff King 提交于
      The get_revision_1() function tries to avoid entering its
      main loop at all when there are no commits to look at. But
      it's perfectly safe to call pop_commit() on an empty list
      (in which case it will return NULL). Switching to an early
      return from the loop lets us skip repeating the loop
      condition before we enter the do-while. That will get more
      important when we start pulling reflog-walk commits from a
      source besides the revs->commits queue, as that condition
      will get much more complicated.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      7c2f08aa
  5. 08 7月, 2017 1 次提交
    • J
      revision: disallow reflog walking with revs->limited · 82fd0f4a
      Jeff King 提交于
      The reflog-walk code doesn't work with limit_list().  That
      function traverses down the real history graph, not the fake
      reflog history that get_revision() returns. So it's not
      going to actually examine all of the commits we're going to
      show, because we'd add them to the pending list only during
      the actual traversal.
      
      In practice this limitation doesn't really matter, because
      the options that require list-limiting generally need
      UNINTERESTING endpoints or symmetric ranges, which already
      are forbidden for reflog walks. Still, there are likely some
      corner cases that would behave oddly. We're better off to
      warn the user that we can't fulfill their request than to
      generate potentially wrong output.
      
      This will also make it easier to refactor the reflog-walking
      code, because it eliminates a whole area of corner cases
      we'd have to consider (that already don't work anyway).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      82fd0f4a
  6. 01 7月, 2017 1 次提交
    • Æ
      grep: remove regflags from the public grep_opt API · 07a3d411
      Ævar Arnfjörð Bjarmason 提交于
      Refactor calls to the grep machinery to always pass opt.ignore_case &
      opt.extended_regexp_option instead of setting the equivalent regflags
      bits.
      
      The bug fixed when making -i work with -P in commit 9e3cbc59 ("log:
      make --regexp-ignore-case work with --perl-regexp", 2017-05-20) was
      really just plastering over the code smell which this change fixes.
      
      The reason for adding the extensive commentary here is that I
      discovered some subtle complexity in implementing this that really
      should be called out explicitly to future readers.
      
      Before this change we'd rely on the difference between
      `extended_regexp_option` and `regflags` to serve as a membrane between
      our preliminary parsing of grep.extendedRegexp and grep.patternType,
      and what we decided to do internally.
      
      Now that those two are the same thing, it's necessary to unset
      `extended_regexp_option` just before we commit in cases where both of
      those config variables are set. See 84befcd0 ("grep: add a
      grep.patternType configuration setting", 2012-08-03) for the code and
      documentation related to that.
      
      The explanation of why the if/else branches in
      grep_commit_pattern_type() are ordered the way they are exists in that
      commit message, but I think it's worth calling this subtlety out
      explicitly with a comment for future readers.
      
      Even though grep_commit_pattern_type() is the only caller of
      grep_set_pattern_type_option() it's simpler to reset the
      extended_regexp_option flag in the latter, since 2/3 branches in the
      former would otherwise need to reset it, this way we can do it in one
      place.
      Signed-off-by: NÆvar Arnfjörð Bjarmason <avarab@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      07a3d411
  7. 24 6月, 2017 1 次提交
  8. 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
  9. 13 6月, 2017 4 次提交
  10. 05 6月, 2017 1 次提交
  11. 02 6月, 2017 3 次提交
  12. 26 5月, 2017 1 次提交
    • Æ
      log: add -P as a synonym for --perl-regexp · 7531a2dd
      Ævar Arnfjörð Bjarmason 提交于
      Add a short -P option as a synonym for the longer --perl-regexp, for
      consistency with the options the corresponding grep invocations
      accept.
      
      This was intentionally omitted in commit 727b6fc3 ("log --grep:
      accept --basic-regexp and --perl-regexp", 2012-10-03) for unspecified
      future use.
      
      Make it consistent with "grep" rather than to keep it open for future
      use, and to avoid the confusion of -P meaning different things for
      grep & log, as is the case with the -G option.
      
      As noted in the aforementioned commit the --basic-regexp option can't
      have a corresponding -G argument, as the log command already uses that
      for -G<regex>.
      Signed-off-by: NÆvar Arnfjörð Bjarmason <avarab@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      7531a2dd
  13. 24 5月, 2017 7 次提交
    • J
      handle_revision_arg: record paths for pending objects · 18f1ad76
      Jeff King 提交于
      If the revision parser sees an argument like tree:path, we
      parse it down to the correct blob (or tree), but throw away
      the "path" portion. Let's ask get_sha1_with_context() to
      record it, and pass it along in the pending array.
      
      This will let programs like git-diff which rely on the
      revision-parser show more accurate paths.
      
      Note that the implementation is a little tricky; we have to
      make sure we free oc.path in all code paths. For handle_dotdot(),
      we can piggy-back on the existing cleanup-wrapper pattern.
      The real work happens in handle_dotdot_1(), but the
      handle_dotdot() wrapper makes sure that the path is freed no
      matter how we exit the function (and for that reason we make
      sure that the object_context struct is zero'd, so if we fail
      to even get to the get_sha1_with_context() call, we just end
      up calling free(NULL)).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      18f1ad76
    • J
      handle_revision_arg: record modes for "a..b" endpoints · 101dd4de
      Jeff King 提交于
      The "a..b" revision syntax was designed to handle commits,
      so it doesn't bother to record any mode we find while
      traversing a "tree:path" endpoint. These days "git diff" can
      diff blobs using either "a:path..b:path" (with dots) or
      "a:path b:path" (without), but the two behave
      inconsistently, as the with-dots version fails to notice the
      mode.
      
      Let's teach the dot-dot range parser to record modes; it
      doesn't cost us anything, and it makes this case work.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      101dd4de
    • J
      handle_revision_arg: add handle_dotdot() helper · 62faad5a
      Jeff King 提交于
      The handle_revision_arg function is rather long, and a big
      chunk of it is handling the range operators. Let's pull that
      out to a separate helper. While we're doing so, we can clean
      up a few of the rough edges that made the flow hard to
      follow:
      
        - instead of manually restoring *dotdot (that we overwrote
          with a NUL), do the real work in a sub-helper, which
          makes it clear that the munge/restore lines are a
          matched pair
      
        - eliminate a goto which wasn't actually used for control
          flow, but only to avoid duplicating a few lines
          (instead, those lines are pushed into another helper
          function)
      
        - use early returns instead of deep nesting
      
        - consistently name all variables for the left-hand side
          of the range as "a" (rather than "this" or "from") and
          the right-hand side as "b" (rather than "next", or using
          the unadorned "sha1" or "flags" from the main function).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      62faad5a
    • J
      handle_revision_arg: hoist ".." check out of range parsing · d89797fe
      Jeff King 提交于
      Since 003c84f6 (specifying ranges: we did not mean to make
      ".." an empty set, 2011-05-02), we treat the argument ".."
      specially. We detect it by noticing that both sides of the
      range are empty, and that this is a non-symmetric two-dot
      range.
      
      While correct, this makes the code overly complicated. We
      can just detect ".." up front before we try to do further
      parsing. This avoids having to de-munge the NUL from dotdot,
      and lets us eliminate an extra const array (which we needed
      only to do direct pointer comparisons).
      
      It also removes the one code path from the range-parsing
      conditional that requires us to return -1. That will make it
      simpler to pull the dotdot parsing out into its own
      function.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      d89797fe
    • J
      handle_revision_arg: stop using "dotdot" as a generic pointer · f632dedd
      Jeff King 提交于
      The handle_revision_arg() function has a "dotdot" variable
      that it uses to find a ".." or "..." in the argument. If we
      don't find one, we look for other marks, like "^!". But we
      just keep re-using the "dotdot" variable, which is
      confusing.
      
      Let's introduce a separate "mark" variable that can be used
      for these other marks. They still reuse the same variable,
      but at least the name is no longer actively misleading.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f632dedd
    • J
      handle_revision_arg: simplify commit reference lookups · 1d6c9381
      Jeff King 提交于
      The "dotdot" range parser avoids calling
      lookup_commit_reference() if we are directly fed two
      commits. But its casts are unnecessarily complex; that
      function will just return a commit we pass into it.
      
      Just calling the function all the time is much simpler, and
      doesn't do any significant extra work (the object is already
      parsed, and deref_tag() on a non-tag is a noop; we do incur
      one extra lookup_object() call, but that's fairly trivial).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      1d6c9381
    • J
      handle_revision_arg: reset "dotdot" consistently · ed79b2cf
      Jeff King 提交于
      When we are parsing a range like "a..b", we write a
      temporary NUL over the first ".", so that we can access the
      names "a" and "b" as C strings. But our restoration of the
      original "." is done at inconsistent times, which can lead
      to confusing results.
      
      For most calls, we restore the "." after we resolve the
      names, but before we call verify_non_filename().  This means
      that when we later call add_pending_object(), the name for
      the left-hand "a" has been re-expanded to "a..b". You can
      see this with:
      
        git log --source a...b
      
      where "b" will be correctly marked with "b", but "a" will be
      marked with "a...b". Likewise with "a..b" (though you need
      to use --boundary to even see "a" at all in that case).
      
      To top off the confusion, when the REVARG_CANNOT_BE_FILENAME
      flag is set, we skip the non-filename check, and leave the
      NUL in place.
      
      That means we do report the correct name for "a" in the
      pending array. But some code paths try to show the whole
      "a...b" name in error messages, and these erroneously show
      only "a" instead of "a...b". E.g.:
      
        $ git cherry-pick HEAD:foo...HEAD:foo
        error: object d95f3ad14dee633a758d2e331151e950dd13e4ed is a blob, not a commit
        error: object d95f3ad14dee633a758d2e331151e950dd13e4ed is a blob, not a commit
        fatal: Invalid symmetric difference expression HEAD:foo
      
      (That last message should be "HEAD:foo...HEAD:foo"; I used
      cherry-pick because it passes the CANNOT_BE_FILENAME flag).
      
      As an interesting side note, cherry-pick actually looks at
      and re-resolves the arguments from the pending->name fields.
      So it would have been visibly broken by the first bug, but
      the effect was canceled out by the second one.
      
      This patch makes the whole function consistent by re-writing
      the NUL immediately after calling verify_non_filename(), and
      then restoring the "." as appropriate in some error-printing
      and early-return code paths.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      ed79b2cf
  14. 21 5月, 2017 1 次提交
    • Æ
      log: make --regexp-ignore-case work with --perl-regexp · 9e3cbc59
      Ævar Arnfjörð Bjarmason 提交于
      Make the --regexp-ignore-case option work with --perl-regexp. This
      never worked, and there was no test for this. Fix the bug and add a
      test.
      
      When PCRE support was added in commit 63e7e9d8 ("git-grep: Learn
      PCRE", 2011-05-09) compile_pcre_regexp() would only check
      opt->ignore_case, but when the --perl-regexp option was added in
      commit 727b6fc3 ("log --grep: accept --basic-regexp and
      --perl-regexp", 2012-10-03) the code didn't set the opt->ignore_case.
      
      Change the test suite to test for -i and --invert-regexp with
      basic/extended/perl patterns in addition to fixed, which was the only
      patternType that was tested for before in combination with those
      options.
      Signed-off-by: NÆvar Arnfjörð Bjarmason <avarab@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9e3cbc59
  15. 20 5月, 2017 1 次提交
    • J
      revision.c: ignore broken tags with ignore_missing_links · a3ba6bf1
      Jeff King 提交于
      When peeling a tag for prepare_revision_walk(), we do not
      respect the ignore_missing_links flag. This can lead to a
      bogus error when pack-objects walks the possibly-broken
      unreachable-but-recent part of the object graph.
      
      The other link-following all happens via traverse_commit_list(),
      which explains why this case was missed. And our tests
      covered only broken links from commits. Let's be more
      comprehensive and cover broken tree entries (which do work)
      and tags (which shows off this bug).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      a3ba6bf1
  16. 08 5月, 2017 7 次提交
  17. 02 5月, 2017 1 次提交