From 6546b5931e5608dfdcd3e4fbf9ebc90ee0982b56 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 31 Jul 2008 01:17:41 -0700 Subject: revision traversal: show full history with merge simplification The --full-history traversal keeps all merges in addition to non-merge commits that touch paths in the given pathspec. This is useful to view both sides of a merge in a topology like this: A---M---o / / ---O---B even when A and B makes identical change to the given paths. The revision traversal without --full-history aims to come up with the simplest history to explain the final state of the tree, and one of the side branches can be pruned away. The behaviour to keep all merges however is inconvenient if neither A nor B touches the paths we are interested in. --full-history reduces the topology to: ---O---M---o in such a case, without removing M. This adds a post processing phase on top of --full-history traversal to remove needless merges from the resulting history. The idea is to compute, for each commit in the "full history" result set, the commit that should replace it in the simplified history. The commit to replace it in the final history is determined as follows: * In any case, we first figure out the replacement commits of parents of the commit we are looking at. The commit we are looking at is rewritten as if the replacement commits of its original parents are its parents. While doing so, we reduce the redundant parents from the rewritten parent list by not just removing the identical ones, but also removing a parent that is an ancestor of another parent. * After the above parent simplification, if the commit is a root commit, an UNINTERESTING commit, a merge commit, or modifies the paths we are interested in, then the replacement commit of the commit is itself. In other words, such a commit is not dropped from the final result. The first point above essentially means that the history is rewritten in the bottom up direction. We can rewrite the parent list of a commit only after we know how all of its parents are rewritten. This means that the processing needs to happen on the full history (i.e. after limit_list()). Signed-off-by: Junio C Hamano --- Documentation/rev-list-options.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'Documentation/rev-list-options.txt') diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 3aa38097e6..ee6822a85d 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -193,12 +193,18 @@ endif::git-rev-list[] --full-history:: - Show also parts of history irrelevant to current state of a given - path. This turns off history simplification, which removed merges + 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. -- cgit v1.2.1 From d266a988456fcaab9918eae39f5faf8dcb20cb26 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Tue, 12 Aug 2008 01:55:37 +0200 Subject: Documentation: rev-list-options: move --simplify-merges documentation Fits --simplify-merges documentation into the 'History Simplification' section, including example. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- Documentation/rev-list-options.txt | 48 +++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'Documentation/rev-list-options.txt') diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 059ae69d84..15752b92a5 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -193,12 +193,6 @@ endif::git-rev-list[] Stop when a given path disappears from the tree. ---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. @@ -413,6 +407,48 @@ 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. +Finally, there is a fourth simplification mode available: + +--simplify-merges:: + + First, build a history graph in the same way that + '\--full-history' with parent rewriting does (see above). ++ +Then simplify each commit `C` to its replacement `C'` in the final +history according to the following rules: ++ +-- +* Set `C'` to `C`. ++ +* Replace each parent `P` of `C'` with its simplification `P'`. In + the process, drop parents that are ancestors of other parents, and + remove duplicates. ++ +* If after this parent rewriting, `C'` is a root or merge commit (has + zero or >1 parents), a boundary commit, or !TREESAME, it remains. + Otherwise, it is replaced with its only parent. +-- ++ +The effect of this is best shown by way of comparing to +'\--full-history' with parent rewriting. The example turns into: ++ +----------------------------------------------------------------------- + .-A---M---N---O + / / / + I B D + \ / / + `---------' +----------------------------------------------------------------------- ++ +Note the major differences in `N` and `P` over '\--full-history': ++ +-- +* `N`'s parent list had `I` removed, because it is an ancestor of the + other parent `M`. Still, `N` remained because it is !TREESAME. ++ +* `P`'s parent list similarly had `I` removed. `P` was then + removed completely, because it had one parent and is TREESAME. +-- ifdef::git-rev-list[] Bisection Helpers -- cgit v1.2.1