1. 05 4月, 2014 1 次提交
    • V
      add `ignore_missing_links` mode to revwalk · 2db1a43f
      Vicent Marti 提交于
      When pack-objects is computing the reachability bitmap to
      serve a fetch request, it can erroneously die() if some of
      the UNINTERESTING objects are not present. Upload-pack
      throws away HAVE lines from the client for objects we do not
      have, but we may have a tip object without all of its
      ancestors (e.g., if the tip is no longer reachable and was
      new enough to survive a `git prune`, but some of its
      reachable objects did get pruned).
      
      In the non-bitmap case, we do a revision walk with the HAVE
      objects marked as UNINTERESTING. The revision walker
      explicitly ignores errors in accessing UNINTERESTING commits
      to handle this case (and we do not bother looking at
      UNINTERESTING trees or blobs at all).
      
      When we have bitmaps, however, the process is quite
      different.  The bitmap index for a pack-objects run is
      calculated in two separate steps:
      
      First, we perform an extensive walk from all the HAVEs to
      find the full set of objects reachable from them. This walk
      is usually optimized away because we are expected to hit an
      object with a bitmap during the traversal, which allows us
      to terminate early.
      
      Secondly, we perform an extensive walk from all the WANTs,
      which usually also terminates early because we hit a commit
      with an existing bitmap.
      
      Once we have the resulting bitmaps from the two walks, we
      AND-NOT them together to obtain the resulting set of objects
      we need to pack.
      
      When we are walking the HAVE objects, the revision walker
      does not know that we are walking it only to mark the
      results as uninteresting. We strip out the UNINTERESTING flag,
      because those objects _are_ interesting to us during the
      first walk. We want to keep going to get a complete set of
      reachable objects if we can.
      
      We need some way to tell the revision walker that it's OK to
      silently truncate the HAVE walk, just like it does for the
      UNINTERESTING case. This patch introduces a new
      `ignore_missing_links` flag to the `rev_info` struct, which
      we set only for the HAVE walk.
      
      It also adds tests to cover UNINTERESTING objects missing
      from several positions: a missing blob, a missing tree, and
      a missing parent commit. The missing blob already worked (as
      we do not care about its contents at all), but the other two
      cases caused us to die().
      
      Note that there are a few cases we do not need to test:
      
        1. We do not need to test a missing tree, with the blob
           still present. Without the tree that refers to it, we
           would not know that the blob is relevant to our walk.
      
        2. We do not need to test a tip commit that is missing.
           Upload-pack omits these for us (and in fact, we
           complain even in the non-bitmap case if it fails to do
           so).
      Reported-by: NSiddharth Agarwal <sid0@fb.com>
      Signed-off-by: NVicent Marti <tanoku@gmail.com>
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      2db1a43f
  2. 25 10月, 2013 1 次提交
  3. 04 9月, 2013 1 次提交
  4. 05 8月, 2013 1 次提交
    • T
      log: use true parents for diff when walking reflogs · 838f9a15
      Thomas Rast 提交于
      The reflog walking logic (git log -g) replaces the true parent list
      with the preceding commit in the reflog.  This results in bogus commit
      diffs when combined with options such as -p; the diff is against the
      reflog predecessor, not the parent of the commit.
      
      Save the true parents on the side, extending the functions from the
      previous commit.  The diff logic picks them up and uses them to show
      the correct diffs.
      
      We do have to be somewhat careful about repeated calling of
      save_parents(), since the reflog may list a commit more than once.  We
      now store (commit_list*)-1 to distinguish the "not saved yet" and
      "root commit" cases.  This lets us preserve an empty parent list even
      if save_parents() is repeatedly called.
      Suggested-by: NJeff King <peff@peff.net>
      Signed-off-by: NThomas Rast <trast@inf.ethz.ch>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      838f9a15
  5. 02 8月, 2013 1 次提交
    • T
      log: use true parents for diff even when rewriting · 53d00b39
      Thomas Rast 提交于
      When using pathspec filtering in combination with diff-based log
      output, parent simplification happens before the diff is computed.
      The diff is therefore against the *simplified* parents.
      
      This works okay, arguably by accident, in the normal case:
      simplification reduces to one parent as long as the commit is TREESAME
      to it.  So the simplified parent of any given commit must have the
      same tree contents on the filtered paths as its true (unfiltered)
      parent.
      
      However, --full-diff breaks this guarantee, and indeed gives pretty
      spectacular results when comparing the output of
      
        git log --graph --stat ...
        git log --graph --full-diff --stat ...
      
      (--graph internally kicks in parent simplification, much like
      --parents).
      
      To fix it, store a copy of the parent list before simplification (in a
      slab) whenever --full-diff is in effect.  Then use the stored parents
      instead of the simplified ones in the commit display code paths.  The
      latter do not actually check for --full-diff to avoid duplicated code;
      they just grab the original parents if save_parents() has not been
      called for this revision walk.
      
      For ordinary commits it should be obvious that this is the right thing
      to do.
      
      Merge commits are a bit subtle.  Observe that with default
      simplification, merge simplification is an all-or-nothing decision:
      either the merge is TREESAME to one parent and disappears, or it is
      different from all parents and the parent list remains intact.
      Redundant parents are not pruned, so the existing code also shows them
      as a merge.
      
      So if we do show a merge commit, the parent list just consists of the
      rewrite result on each parent.  Running, e.g., --cc on this in
      --full-diff mode is not very useful: if any commits were skipped, some
      hunks will disagree with all sides of the merge (with one side,
      because commits were skipped; with the others, because they didn't
      have those changes in the first place).  This triggers --cc showing
      these hunks spuriously.
      
      Therefore I believe that even for merge commits it is better to show
      the diffs wrt. the original parents.
      Reported-by: NUwe Kleine-König <u.kleine-koenig@pengutronix.de>
      Helped-by: NJunio C Hamano <gitster@pobox.com>
      Helped-by: NRamsay Jones <ramsay@ramsay1.demon.co.uk>
      Signed-off-by: NThomas Rast <trast@inf.ethz.ch>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      53d00b39
  6. 16 7月, 2013 3 次提交
  7. 10 7月, 2013 1 次提交
    • N
      Convert "struct cache_entry *" to "const ..." wherever possible · 9c5e6c80
      Nguyễn Thái Ngọc Duy 提交于
      I attempted to make index_state->cache[] a "const struct cache_entry **"
      to find out how existing entries in index are modified and where. The
      question I have is what do we do if we really need to keep track of on-disk
      changes in the index. The result is
      
       - diff-lib.c: setting CE_UPTODATE
      
       - name-hash.c: setting CE_HASHED
      
       - preload-index.c, read-cache.c, unpack-trees.c and
         builtin/update-index: obvious
      
       - entry.c: write_entry() may refresh the checked out entry via
         fill_stat_cache_info(). This causes "non-const struct cache_entry
         *" in builtin/apply.c, builtin/checkout-index.c and
         builtin/checkout.c
      
       - builtin/ls-files.c: --with-tree changes stagemask and may set
         CE_UPDATE
      
      Of these, write_entry() and its call sites are probably most
      interesting because it modifies on-disk info. But this is stat info
      and can be retrieved via refresh, at least for porcelain
      commands. Other just uses ce_flags for local purposes.
      
      So, keeping track of "dirty" entries is just a matter of setting a
      flag in index modification functions exposed by read-cache.c. Except
      unpack-trees, the rest of the code base does not do anything funny
      behind read-cache's back.
      
      The actual patch is less valueable than the summary above. But if
      anyone wants to re-identify the above sites. Applying this patch, then
      this:
      
          diff --git a/cache.h b/cache.h
          index 430d021..1692891 100644
          --- a/cache.h
          +++ b/cache.h
          @@ -267,7 +267,7 @@ static inline unsigned int canon_mode(unsigned int mode)
           #define cache_entry_size(len) (offsetof(struct cache_entry,name) + (len) + 1)
      
           struct index_state {
          -	struct cache_entry **cache;
          +	const struct cache_entry **cache;
           	unsigned int version;
           	unsigned int cache_nr, cache_alloc, cache_changed;
           	struct string_list *resolve_undo;
      
      will help quickly identify them without bogus warnings.
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9c5e6c80
  8. 12 6月, 2013 2 次提交
    • J
      log: --author-date-order · 81c6b38b
      Junio C Hamano 提交于
      Sometimes people would want to view the commits in parallel
      histories in the order of author dates, not committer dates.
      
      Teach "topo-order" sort machinery to do so, using a commit-info slab
      to record the author dates of each commit, and prio-queue to sort
      them.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      81c6b38b
    • J
      toposort: rename "lifo" field · 08f704f2
      Junio C Hamano 提交于
      The primary invariant of sort_in_topological_order() is that a
      parent commit is not emitted until all children of it are.  When
      traversing a forked history like this with "git log C E":
      
          A----B----C
           \
            D----E
      
      we ensure that A is emitted after all of B, C, D, and E are done, B
      has to wait until C is done, and D has to wait until E is done.
      
      In some applications, however, we would further want to control how
      these child commits B, C, D and E on two parallel ancestry chains
      are shown.
      
      Most of the time, we would want to see C and B emitted together, and
      then E and D, and finally A (i.e. the --topo-order output).  The
      "lifo" parameter of the sort_in_topological_order() function is used
      to control this behaviour.  We start the traversal by knowing two
      commits, C and E.  While keeping in mind that we also need to
      inspect E later, we pick C first to inspect, and we notice and
      record that B needs to be inspected.  By structuring the "work to be
      done" set as a LIFO stack, we ensure that B is inspected next,
      before other in-flight commits we had known that we will need to
      inspect, e.g. E.
      
      When showing in --date-order, we would want to see commits ordered
      by timestamps, i.e. show C, E, B and D in this order before showing
      A, possibly mixing commits from two parallel histories together.
      When "lifo" parameter is set to false, the function keeps the "work
      to be done" set sorted in the date order to realize this semantics.
      After inspecting C, we add B to the "work to be done" set, but the
      next commit we inspect from the set is E which is newer than B.
      
      The name "lifo", however, is too strongly tied to the way how the
      function implements its behaviour, and does not describe what the
      behaviour _means_.
      
      Replace this field with an enum rev_sort_order, with two possible
      values: REV_SORT_IN_GRAPH_ORDER and REV_SORT_BY_COMMIT_DATE, and
      update the existing code.  The mechanical replacement rule is:
      
        "lifo == 0" is equivalent to "sort_order == REV_SORT_BY_COMMIT_DATE"
        "lifo == 1" is equivalent to "sort_order == REV_SORT_IN_GRAPH_ORDER"
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      08f704f2
  9. 07 6月, 2013 1 次提交
    • J
      clear parsed flag when we free tree buffers · 6e454b9a
      Jeff King 提交于
      Many code paths will free a tree object's buffer and set it
      to NULL after finishing with it in order to keep memory
      usage down during a traversal. However, out of 8 sites that
      do this, only one actually unsets the "parsed" flag back.
      Those sites that don't are setting a trap for later users of
      the tree object; even after calling parse_tree, the buffer
      will remain NULL, causing potential segfaults.
      
      It is not known whether this is triggerable in the current
      code. Most commands do not do an in-memory traversal
      followed by actually using the objects again. However, it
      does not hurt to be safe for future callers.
      
      In most cases, we can abstract this out to a
      "free_tree_buffer" helper. However, there are two
      exceptions:
      
        1. The fsck code relies on the parsed flag to know that we
           were able to parse the object at one point. We can
           switch this to using a flag in the "flags" field.
      
        2. The index-pack code sets the buffer to NULL but does
           not free it (it is freed by a caller). We should still
           unset the parsed flag here, but we cannot use our
           helper, as we do not want to free the buffer.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      6e454b9a
  10. 03 6月, 2013 1 次提交
    • M
      object_array_entry: fix memory handling of the name field · 31faeb20
      Michael Haggerty 提交于
      Previously, the memory management of the object_array_entry::name
      field was inconsistent and undocumented.  object_array_entries are
      ultimately created by a single function, add_object_array_with_mode(),
      which has an argument "const char *name".  This function used to
      simply set the name field to reference the string pointed to by the
      name parameter, and nobody on the object_array side ever freed the
      memory.  Thus, it assumed that the memory for the name field would be
      managed by the caller, and that the lifetime of that string would be
      at least as long as the lifetime of the object_array_entry.  But
      callers were inconsistent:
      
      * Some passed pointers to constant strings or argv entries, which was
        OK.
      
      * Some passed pointers to newly-allocated memory, but didn't arrange
        for the memory ever to be freed.
      
      * Some passed the return value of sha1_to_hex(), which is a pointer to
        a statically-allocated buffer that can be overwritten at any time.
      
      * Some passed pointers to refnames that they received from a
        for_each_ref()-type iteration, but the lifetimes of such refnames is
        not guaranteed by the refs API.
      
      Bring consistency to this mess by changing object_array to make its
      own copy for the object_array_entry::name field and free this memory
      when an object_array_entry is deleted from the array.
      
      Many callers were passing the empty string as the name parameter, so
      as a performance optimization, treat the empty string specially.
      Instead of making a copy, store a pointer to a statically-allocated
      empty string to object_array_entry::name.  When deleting such an
      entry, skip the free().
      
      Change the callers that were already passing copies to
      add_object_array_with_mode() to either skip the copy, or (if the
      memory needed to be allocated anyway) freeing the memory itself.
      
      A part of this commit effectively reverts
      
          70d26c6e read_revisions_from_stdin: make copies for handle_revision_arg
      
      because the copying introduced by that commit (which is still
      necessary) is now done at a deeper level.
      Signed-off-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      31faeb20
  11. 29 5月, 2013 3 次提交
  12. 17 5月, 2013 8 次提交
    • K
      revision.c: make default history consider bottom commits · 141efdba
      Kevin Bracey 提交于
      Previously, the default history treated bottom commits the same as any
      other UNINTERESTING commit, which could force it down side branches.
      
      Consider the following history:
      
         *A--*B---D--*F         * marks !TREESAME parent paths
           \     /*
            `-C-'
      
      When requesting "B..F", B is UNINTERESTING but TREESAME to D. C is
      !UNINTERESTING.
      
      So default following would go from D into the irrelevant side branch C
      to A, rather than to B.  Note also that if there had been an extra
      !UNINTERESTING commit B1 between B and D, it wouldn't have gone down C.
      
      Change the default following to test relevant_commit() instead of
      !UNINTERESTING, so it can proceed straight from D to B, thus finishing
      the traversal of that path.
      Signed-off-by: NKevin Bracey <kevin@bracey.fi>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      141efdba
    • K
      revision.c: don't show all merges for --parents · bf3418b0
      Kevin Bracey 提交于
      When using --parents or --children, get_commit_action() previously showed
      all merges, even if TREESAME to both parents.
      
      This was intended to tie together the topology of the rewritten parents,
      but it was excessive - in fact we only need to show merges that have two
      or more relevant parents. Merges at the boundary do not necessarily need
      to be shown.
      Signed-off-by: NKevin Bracey <kevin@bracey.fi>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      bf3418b0
    • K
      revision.c: discount side branches when computing TREESAME · 4d826608
      Kevin Bracey 提交于
      Use the BOTTOM flag to define relevance for pruning. Relevant commits
      are those that are !UNINTERESTING or BOTTOM, and this allows us to
      identify irrelevant side branches (UNINTERESTING && !BOTTOM).
      
      If a merge has relevant parents, and it is TREESAME to them, then do not
      let irrelevant parents cause the merge to be treated as !TREESAME.
      
      When considering simplification, don't always include all merges -
      merges with exactly one relevant parent can be simplified, if TREESAME
      according to the above rule.
      
      These two changes greatly increase simplification in limited, pruned
      revision lists.
      Signed-off-by: NKevin Bracey <kevin@bracey.fi>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      4d826608
    • K
      revision.c: add BOTTOM flag for commits · 7f34a46f
      Kevin Bracey 提交于
      When performing edge-based operations on the revision graph, it can be
      useful to be able to identify the INTERESTING graph's connection(s) to
      the bottom commit(s) specified by the user.
      
      Conceptually when the user specifies "A..B" (== B ^A), they are asking
      for the history from A to B. The first connection from A onto the
      INTERESTING graph is part of that history, and should be considered. If
      we consider only INTERESTING nodes and their connections, then we're
      really only considering the history from A's immediate descendants to B.
      
      This patch does not change behaviour, but adds a new BOTTOM flag to
      indicate the bottom commits specified by the user, ready to be used by
      following patches.
      
      We immediately use the BOTTOM flag to return collect_bottom_commits() to
      its original approach of examining the pending commit list rather than
      the command line. This will ensure alignment of the definition of
      "bottom" with future patches.
      Signed-off-by: NKevin Bracey <kevin@bracey.fi>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      7f34a46f
    • K
      simplify-merges: drop merge from irrelevant side branch · 143f1eaf
      Kevin Bracey 提交于
      Reimplement commit 4b7f53da on top of the new simplify-merges
      infrastructure, tightening the condition to only consider root parents;
      the original version incorrectly dropped parents that were TREESAME to
      anything.
      
      Original log message follows.
      
      The merge simplification rule stated in 6546b593 (revision traversal:
      show full history with merge simplification, 2008-07-31) still
      treated merge commits too specially.  Namely, in a history with this
      shape:
      
      	---o---o---M
      	          /
               x---x---x
      
      where three 'x' were on a history completely unrelated to the main
      history 'o' and do not touch any of the paths we are following, we
      still said that after simplifying all of the parents of M, 'x'
      (which is the leftmost 'x' that rightmost 'x simplifies down to) and
      'o' (which would be the last commit on the main history that touches
      the paths we are following) are independent from each other, and
      both need to be kept.
      
      That is incorrect; when the side branch 'x' never touches the paths,
      it should be removed to allow M to simplify down to the last commit
      on the main history that touches the paths.
      Suggested-by: NJunio C Hamano <gitster@pobox.com>
      Signed-off-by: NKevin Bracey <kevin@bracey.fi>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      143f1eaf
    • K
      simplify-merges: never remove all TREESAME parents · 9c129eab
      Kevin Bracey 提交于
      When simplifying an odd merge, such as one that used "-s ours", we may
      find ourselves TREESAME to apparently redundant parents. Prevent
      simplify_merges() from removing every TREESAME parent; if this would
      happen reinstate the first TREESAME parent - the one that the default
      log would have followed.
      
      This avoids producing a totally disjoint history from the default log
      when the default log is a better explanation of the end result, and aids
      visualisation of odd merges.
      Signed-off-by: NKevin Bracey <kevin@bracey.fi>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9c129eab
    • K
      revision.c: Make --full-history consider more merges · d0af663e
      Kevin Bracey 提交于
      History simplification previously always treated merges as TREESAME
      if they were TREESAME to any parent.
      
      While this was consistent with the default behaviour, this could be
      extremely unhelpful when searching detailed history, and could not be
      overridden. For example, if a merge had ignored a change, as if by "-s
      ours", then:
      
        git log -m -p --full-history -Schange file
      
      would successfully locate "change"'s addition but would not locate the
      merge that resolved against it.
      
      Futher, simplify_merges could drop the actual parent that a commit
      was TREESAME to, leaving it as a normal commit marked TREESAME that
      isn't actually TREESAME to its remaining parent.
      
      Now redefine a commit's TREESAME flag to be true only if a commit is
      TREESAME to _all_ of its parents. This doesn't affect either the default
      simplify_history behaviour (because partially TREESAME merges are turned
      into normal commits), or full-history with parent rewriting (because all
      merges are output). But it does affect other modes. The clearest
      difference is that --full-history will show more merges - sufficient to
      ensure that -m -p --full-history log searches can really explain every
      change to the file, including those changes' ultimate fate in merges.
      
      Also modify simplify_merges to recalculate TREESAME after removing
      a parent. This is achieved by storing per-parent TREESAME flags on the
      initial scan, so the combined flag can be easily recomputed.
      
      This fixes some t6111 failures, but creates a couple of new ones -
      we are now showing some merges that don't need to be shown.
      Signed-off-by: NKevin Bracey <kevin@bracey.fi>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      d0af663e
    • K
      revision.c: treat A...B merge bases as if manually specified · a765499a
      Kevin Bracey 提交于
      The documentation assures users that "A...B" is defined as "A B --not
      $(git merge-base --all A B)". This wasn't in fact quite true, because
      the calculated merge bases were not sent to add_rev_cmdline().
      
      The main effect of this was that although
      
        git rev-list --ancestry-path A B --not $(git merge-base --all A B)
      
      worked, the simpler form
      
        git rev-list --ancestry-path A...B
      
      failed with a "no bottom commits" error.
      
      Other potential users of bottom commits could also be affected by this
      problem, if they examine revs->cmdline_info; I came across the issue in
      my proposed history traversal refinements series.
      
      So ensure that the calculated merge bases are sent to add_rev_cmdline(),
      flagged with new 'whence' enum value REV_CMD_MERGE_BASE.
      Signed-off-by: NKevin Bracey <kevin@bracey.fi>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      a765499a
  13. 19 4月, 2013 1 次提交
  14. 17 4月, 2013 1 次提交
    • T
      read_revisions_from_stdin: make copies for handle_revision_arg · 70d26c6e
      Thomas Rast 提交于
      read_revisions_from_stdin() has passed pointers to its read buffer
      down to handle_revision_arg() since its inception way back in 42cabc34
      (Teach rev-list an option to read revs from the standard input.,
      2006-09-05).  Even back then, this was a bug: through
      add_pending_object, the argument was recorded in the object_array's
      'name' field.
      
      Fix it by making a copy whenever read_revisions_from_stdin() passes an
      argument down the callchain.  The other caller runs handle_revision_arg()
      on argv[], where it would be redundant to make a copy.
      Signed-off-by: NThomas Rast <trast@inf.ethz.ch>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      70d26c6e
  15. 09 4月, 2013 1 次提交
  16. 29 3月, 2013 2 次提交
    • T
      Implement line-history search (git log -L) · 12da1d1f
      Thomas Rast 提交于
      This is a rewrite of much of Bo's work, mainly in an effort to split
      it into smaller, easier to understand routines.
      
      The algorithm is built around the struct range_set, which encodes a
      series of line ranges as intervals [a,b).  This is used in two
      contexts:
      
      * A set of lines we are tracking (which will change as we dig through
        history).
      * To encode diffs, as pairs of ranges.
      
      The main routine is range_set_map_across_diff().  It processes the
      diff between a commit C and some parent P.  It determines which diff
      hunks are relevant to the ranges tracked in C, and computes the new
      ranges for P.
      
      The algorithm is then simply to process history in topological order
      from newest to oldest, computing ranges and (partial) diffs.  At
      branch points, we need to merge the ranges we are watching.  We will
      find that many commits do not affect the chosen ranges, and mark them
      TREESAME (in addition to those already filtered by pathspec limiting).
      Another pass of history simplification then gets rid of such commits.
      
      This is wired as an extra filtering pass in the log machinery.  This
      currently only reduces code duplication, but should allow for other
      simplifications and options to be used.
      
      Finally, we hook a diff printer into the output chain.  Ideally we
      would wire directly into the diff logic, to optionally use features
      like word diff.  However, that will require some major reworking of
      the diff chain, so we completely replace the output with our own diff
      for now.
      
      As this was a GSoC project, and has quite some history by now, many
      people have helped.  In no particular order, thanks go to
      
        Jakub Narebski <jnareb@gmail.com>
        Jens Lehmann <Jens.Lehmann@web.de>
        Jonathan Nieder <jrnieder@gmail.com>
        Junio C Hamano <gitster@pobox.com>
        Ramsay Jones <ramsay@ramsay1.demon.co.uk>
        Will Palmer <wmpalmer@gmail.com>
      
      Apologies to everyone I forgot.
      Signed-off-by: NBo Yang <struggleyb.nku@gmail.com>
      Signed-off-by: NThomas Rast <trast@student.ethz.ch>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      12da1d1f
    • B
      Export rewrite_parents() for 'log -L' · c7edcae0
      Bo Yang 提交于
      The function rewrite_one is used to rewrite a single
      parent of the current commit, and is used by rewrite_parents
      to rewrite all the parents.
      
      Decouple the dependence between them by making rewrite_one
      a callback function that is passed to rewrite_parents. Then
      export rewrite_parents for reuse by the line history browser.
      
      We will use this function in line-log.c.
      Signed-off-by: NBo Yang <struggleyb.nku@gmail.com>
      Signed-off-by: NThomas Rast <trast@student.ethz.ch>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c7edcae0
  17. 23 3月, 2013 1 次提交
    • K
      Fix revision walk for commits with the same dates · c19d1b4e
      Kacper Kornet 提交于
      Logic in still_interesting function allows to stop the commits
      traversing if the oldest processed commit is not older then the
      youngest commit on the list to process and the list contains only
      commits marked as not interesting ones. It can be premature when dealing
      with a set of coequal commits. For example git rev-list A^! --not B
      provides wrong answer if all commits in the range A..B had the same
      commit time and there are more then 7 of them.
      
      To fix this problem the relevant part of the logic in still_interesting
      is changed to: the walk can be stopped if the oldest processed commit is
      younger then the youngest commit on the list to processed.
      Signed-off-by: NKacper Kornet <draenog@pld-linux.org>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c19d1b4e
  18. 12 2月, 2013 1 次提交
    • J
      log: re-encode commit messages before grepping · 04deccda
      Jeff King 提交于
      If you run "git log --grep=foo", we will run your regex on
      the literal bytes of the commit message. This can provide
      confusing results if the commit message is not in the same
      encoding as your grep expression (or worse, you have commits
      in multiple encodings, in which case your regex would need
      to be written to match either encoding). On top of this, we
      might also be grepping in the commit's notes, which are
      already re-encoded, potentially leading to grepping in a
      buffer with mixed encodings concatenated. This is insanity,
      but most people never noticed, because their terminal and
      their commit encodings all match.
      
      Instead, let's massage the to-be-grepped commit into a
      standardized encoding. There is not much point in adding a
      flag for "this is the encoding I expect my grep pattern to
      match"; the only sane choice is for it to use the log output
      encoding. That is presumably what the user's terminal is
      using, and it means that the patterns found by the grep will
      match the output produced by git.
      
      As a bonus, this fixes a potential segfault in commit_match
      when commit->buffer is NULL, as we now build on logmsg_reencode,
      which handles reading the commit buffer from disk if
      necessary. The segfault can be triggered with:
      
              git commit -m 'text1' --allow-empty
              git commit -m 'text2' --allow-empty
              git log --graph --no-walk --grep 'text2'
      
      which arguably does not make any sense (--graph inherently
      wants a connected history, and by --no-walk the command line
      is telling us to show discrete points in history without
      connectivity), and we probably should forbid the
      combination, but that is a separate issue.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      04deccda
  19. 18 1月, 2013 1 次提交
    • J
      simplify-merges: drop merge from irrelevant side branch · 4b7f53da
      Junio C Hamano 提交于
      The merge simplification rule stated in 6546b593 (revision traversal:
      show full history with merge simplification, 2008-07-31) still
      treated merge commits too specially.  Namely, in a history with this
      shape:
      
      	---o---o---M
      	          /
               x---x---x
      
      where three 'x' were on a history completely unrelated to the main
      history 'o' and do not touch any of the paths we are following, we
      still said that after simplifying all of the parents of M, 'x'
      (which is the leftmost 'x' that rightmost 'x simplifies down to) and
      'o' (which would be the last commit on the main history that touches
      the paths we are following) are independent from each other, and
      both need to be kept.
      
      That is incorrect; when the side branch 'x' never touches the paths,
      it should be removed to allow M to simplify down to the last commit
      on the main history that touches the paths.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      4b7f53da
  20. 11 1月, 2013 2 次提交
    • J
      log --use-mailmap: optimize for cases without --author/--committer search · df874fa8
      Junio C Hamano 提交于
      When we taught the commit_match() mechanism to pay attention to the
      new --use-mailmap option, we started to unconditionally copy the
      commit object to a temporary buffer, just in case we need the author
      and committer lines updated via the mailmap mechanism, and rewrite
      author and committer using the mailmap.
      
      It turns out that this has a rather unpleasant performance
      implications.  In the linux kernel repository, running
      
        $ git log --author='Junio C Hamano' --pretty=short >/dev/null
      
      under /usr/bin/time, with and without --use-mailmap (the .mailmap
      file is 118 entries long, the particular author does not appear in
      it), cost (with warm cache):
      
        [without --use-mailmap]
        5.42user 0.26system 0:05.70elapsed 99%CPU (0avgtext+0avgdata 2005936maxresident)k
        0inputs+0outputs (0major+137669minor)pagefaults 0swaps
      
        [with --use-mailmap]
        6.47user 0.30system 0:06.78elapsed 99%CPU (0avgtext+0avgdata 2006288maxresident)k
        0inputs+0outputs (0major+137692minor)pagefaults 0swaps
      
      which incurs about 20% overhead.  The command is doing extra work,
      so the extra cost may be justified.
      
      But it is inexcusable to pay the cost when we do not need
      author/committer match.  In the same repository,
      
        $ git log --grep='fix menuconfig on debian lenny' --pretty=short >/dev/null
      
      shows very similar numbers as the above:
      
        [without --use-mailmap]
        5.32user 0.30system 0:05.63elapsed 99%CPU (0avgtext+0avgdata 2005984maxresident)k
        0inputs+0outputs (0major+137672minor)pagefaults 0swaps
      
        [with --use-mailmap]
        6.64user 0.24system 0:06.89elapsed 99%CPU (0avgtext+0avgdata 2006320maxresident)k
        0inputs+0outputs (0major+137694minor)pagefaults 0swaps
      
      The latter case is an unnecessary performance regression.  We may
      want to _show_ the result with mailmap applied, but we do not have
      to copy and rewrite the author/committer of all commits we try to
      match if we do not query for these fields.
      
      Trivially optimize this performace regression by limiting the
      rewrites for only when we are matching with author/committer fields.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      df874fa8
    • A
      log: grep author/committer using mailmap · d72fbe81
      Antoine Pelisse 提交于
      Currently you can use mailmap to display log authors and committers
      but you can't use the mailmap to find commits with mapped values.
      
      This commit allows you to run:
      
          git log --use-mailmap --author mapped_name_or_email
          git log --use-mailmap --committer mapped_name_or_email
      
      Of course it only works if the --use-mailmap option is used.
      
      The new name and email are copied only when necessary.
      Signed-off-by: NAntoine Pelisse <apelisse@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      d72fbe81
  21. 18 10月, 2012 1 次提交
  22. 10 10月, 2012 3 次提交
  23. 30 9月, 2012 2 次提交