Merge branch 'jc/post-simplify' into tr/rev-list-docs
authorJunio C Hamano <gitster@pobox.com>
Wed, 13 Aug 2008 04:40:05 +0000 (21:40 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 13 Aug 2008 04:40:05 +0000 (21:40 -0700)
* jc/post-simplify:
Topo-sort before --simplify-merges
revision traversal: show full history with merge simplification
revision.c: whitespace fix

Conflicts:
Documentation/rev-list-options.txt

1  2 
Documentation/rev-list-options.txt
index 0ce3f7fbd93db297291f08305c1a2b2bf603dcaa,ee6822a85df9965901403e99d353fc3c0e1a9eed..059ae69d8471b4a864056f3f359ba64687a3c688
@@@ -43,13 -43,11 +43,13 @@@ endif::git-rev-list[
  
  --parents::
  
 -      Print the parents of the commit.
 +      Print the parents of the commit.  Also enables parent
 +      rewriting, see 'History Simplification' below.
  
  --children::
  
 -      Print the children of the commit.
 +      Print the children of the commit.  Also enables parent
 +      rewriting, see 'History Simplification' below.
  
  ifdef::git-rev-list[]
  --timestamp::
@@@ -73,7 -71,7 +73,7 @@@ For example, if you have this topology
           o---x---a---a  branch A
  -----------------------------------------------------------------------
  +
 -you would get an output line this:
 +you would get an output like this:
  +
  -----------------------------------------------------------------------
        $ git rev-list --left-right --boundary --pretty=oneline A...B
@@@ -193,6 -191,20 +193,12 @@@ endif::git-rev-list[
  
        Stop when a given path disappears from the tree.
  
 ---full-history::
 -
 -      Show also parts of history irrelevant to current state of given
 -      paths. This turns off history simplification, which removed merges
 -      which didn't change anything at all at some child. It will still actually
 -      simplify away merges that didn't change anything at all into either
 -      child.
 -
+ --simplify-merges::
+       Simplify away commits that did not change the given paths, similar
+       to `--full-history`, and further remove merges none of whose
+       parent history changes the given paths.
  --no-merges::
  
        Do not print commits with more than one parent.
@@@ -258,10 -270,11 +264,10 @@@ With '\--pretty' format other than onel
  this causes the output to have two extra lines of information
  taken from the reflog.  By default, 'commit@\{Nth}' notation is
  used in the output.  When the starting commit is specified as
 -'commit@{now}', output also uses 'commit@\{timestamp}' notation
 +'commit@\{now}', output also uses 'commit@\{timestamp}' notation
  instead.  Under '\--pretty=oneline', the commit message is
  prefixed with this information on the same line.
 -
 -Cannot be combined with '\--reverse'.
 +This option cannot be combined with '\--reverse'.
  See also linkgit:git-reflog[1].
  
  --merge::
        Output uninteresting commits at the boundary, which are usually
        not shown.
  
 +--
 +
 +History Simplification
 +~~~~~~~~~~~~~~~~~~~~~~
 +
 +When optional paths are given, 'git-rev-list' simplifies commits with
 +various strategies, according to the options you have selected.
 +
 +Suppose you specified `foo` as the <paths>.  We shall call commits
 +that modify `foo` !TREESAME, and the rest TREESAME.  (In a diff
 +filtered for `foo`, they look different and equal, respectively.)
 +
 +In the following, we will always refer to the same example history to
 +illustrate the differences between simplification settings.  We assume
 +that you are filtering for a file `foo` in this commit graph:
 +-----------------------------------------------------------------------
 +        .-A---M---N---O---P
 +       /     /   /   /   /
 +      I     B   C   D   E
 +       \   /   /   /   /
 +        `-------------'
 +-----------------------------------------------------------------------
 +The horizontal line of history A--P is taken to be the first parent of
 +each merge.  The commits are:
 +
 +* `I` is the initial commit, in which `foo` exists with contents
 +  "asdf", and a file `quux` exists with contents "quux".  Initial
 +  commits are compared to an empty tree, so `I` is !TREESAME.
 +
 +* In `A`, `foo` contains just "foo".
 +
 +* `B` contains the same change as `A`.  Its merge `M` is trivial and
 +  hence TREESAME to all parents.
 +
 +* `C` does not change `foo`, but its merge `N` changes it to "foobar",
 +  so it is not TREESAME to any parent.
 +
 +* `D` sets `foo` to "baz".  Its merge `O` combines the strings from
 +  `N` and `D` to "foobarbaz"; i.e., it is not TREESAME to any parent.
 +
 +* `E` changes `quux` to "xyzzy", and its merge `P` combines the
 +  strings to "quux xyzzy".  Despite appearing interesting, `P` is
 +  TREESAME to all parents.
 +
 +'rev-list' walks backwards through history, including or excluding
 +commits based on whether '\--full-history' and/or parent rewriting
 +(via '\--parents' or '\--children') are used.  The following settings
 +are available.
 +
 +Default mode::
 +
 +      Commits are included if they are not TREESAME to any parent
 +      (though this can be changed, see '\--sparse' below).  If the
 +      commit was a merge, and it was TREESAME to one parent, follow
 +      only that parent.  (Even if there are several TREESAME
 +      parents, follow only one of them.)  Otherwise, follow all
 +      parents.
 ++
 +This results in:
 ++
 +-----------------------------------------------------------------------
 +        .-A---N---O
 +       /         /
 +      I---------D
 +-----------------------------------------------------------------------
 ++
 +Note how the rule to only follow the TREESAME parent, if one is
 +available, removed `B` from consideration entirely.  `C` was
 +considered via `N`, but is TREESAME.  Root commits are compared to an
 +empty tree, so `I` is !TREESAME.
 ++
 +Parent/child relations are only visible with --parents, but that does
 +not affect the commits selected in default mode, so we have shown the
 +parent lines.
 +
 +--full-history without parent rewriting::
 +
 +      This mode differs from the default in one point: always follow
 +      all parents of a merge, even if it is TREESAME to one of them.
 +      Even if more than one side of the merge has commits that are
 +      included, this does not imply that the merge itself is!  In
 +      the example, we get
 ++
 +-----------------------------------------------------------------------
 +      I  A  B  N  D  O
 +-----------------------------------------------------------------------
 ++
 +`P` and `M` were excluded because they are TREESAME to a parent.  `E`,
 +`C` and `B` were all walked, but only `B` was !TREESAME, so the others
 +do not appear.
 ++
 +Note that without parent rewriting, it is not really possible to talk
 +about the parent/child relationships between the commits, so we show
 +them disconnected.
 +
 +--full-history with parent rewriting::
 +
 +      Ordinary commits are only included if they are !TREESAME
 +      (though this can be changed, see '\--sparse' below).
 ++
 +Merges are always included.  However, their parent list is rewritten:
 +Along each parent, prune away commits that are not included
 +themselves.  This results in
 ++
 +-----------------------------------------------------------------------
 +        .-A---M---N---O---P
 +       /     /   /   /   /
 +      I     B   /   D   /
 +       \   /   /   /   /
 +        `-------------'
 +-----------------------------------------------------------------------
 ++
 +Compare to '\--full-history' without rewriting above.  Note that `E`
 +was pruned away because it is TREESAME, but the parent list of P was
 +rewritten to contain `E`'s parent `I`.  The same happened for `C` and
 +`N`.  Note also that `P` was included despite being TREESAME.
 +
 +In addition to the above settings, you can change whether TREESAME
 +affects inclusion:
 +
  --dense::
 +
 +      Commits that are walked are included if they are not TREESAME
 +      to any parent.
 +
  --sparse::
  
 -When optional paths are given, the default behaviour ('--dense') is to
 -only output commits that changes at least one of them, and also ignore
 -merges that do not touch the given paths.
 +      All commits that are walked are included.
 ++
 +Note that without '\--full-history', this still simplifies merges: if
 +one of the parents is TREESAME, we follow only that one, so the other
 +sides of the merge are never walked.
  
 -Use the '--sparse' flag to makes the command output all eligible commits
 -(still subject to count and age limitation), but apply merge
 -simplification nevertheless.
  
  ifdef::git-rev-list[]
 +Bisection Helpers
 +~~~~~~~~~~~~~~~~~
 +
  --bisect::
  
  Limit output to the one commit object which is roughly halfway between
@@@ -461,6 -348,7 +467,6 @@@ after all the sorted commit objects, th
  `--bisect-vars` had been used alone.
  endif::git-rev-list[]
  
 ---
  
  Commit Ordering
  ~~~~~~~~~~~~~~~