Kevin Bracey <kevin@xxxxxxxxx> writes: > @@ -342,13 +342,13 @@ 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---Q > + / / / / / / > + I B C D E Y > + \ / / / / / > + `-------------' X > ----------------------------------------------------------------------- > -The horizontal line of history A---P is taken to be the first parent of > +The horizontal line of history A---Q is taken to be the first parent of > each merge. The commits are: > > * `I` is the initial commit, in which `foo` exists with contents > @@ -369,6 +369,10 @@ each merge. The commits are: > * `E` changes `quux` to "xyzzy", and its merge `P` combines the > strings to "quux xyzzy". `P` is TREESAME to `O`, but not to `E`. > > +* `X` is an indpendent root commit that added a new file `side`, and `Y` > + modified it. `Y` is TREESAME to `X`. Its merge `Q` added `side` to `P`, and > + `Q` is TREESAME to `P`, but not to `Y`. > + OK, we say "filtering for a file `foo`" in the very beginning, so there is an implied "with respect to `foo`" in all of these "A is TREESAME to B", and the description in the new bullet point looks correct. > diff --git a/revision.c b/revision.c > index 7535757..20c7058 100644 > --- a/revision.c > +++ b/revision.c > @@ -2119,6 +2119,22 @@ static int mark_redundant_parents(struct rev_info *revs, struct commit *commit) > return marked; > } > > +static int mark_treesame_root_parents(struct rev_info *revs, struct commit *commit) > +{ > + struct commit_list *p; > + int marked = 0; > + > + for (p = commit->parents; p; p = p->next) { > + struct commit *parent = p->item; > + if (!parent->parents && (parent->object.flags & TREESAME)) { > + parent->object.flags |= TMP_MARK; > + marked++; > + } > + } > + > + return marked; > +} > + > /* > * Awkward naming - this means one parent we are TREESAME to. > * cf mark_treesame_root_parents: root parents that are TREESAME (to an > @@ -2284,10 +2300,18 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c > * / / o: a commit that touches the paths; > * ---o----' > * > - * Detect and simplify this case. > + * Further, a merge of an independent branch that doesn't > + * touch the path will reduce to a treesame root parent: > + * > + * ----o----X X: the commit we are looking at; > + * / o: a commit that touches the paths; > + * r r: a root commit not touching the paths > + * > + * Detect and simplify both cases. > */ > if (1 < cnt) { > int marked = mark_redundant_parents(revs, commit); > + marked += mark_treesame_root_parents(revs, commit); > if (marked) > marked -= leave_one_treesame_to_parent(revs, commit); > if (marked) The solution looks surprisingly simple ;-) Thanks. > diff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh > index 4e55872..57ce239 100755 > --- a/t/t6012-rev-list-simplify.sh > +++ b/t/t6012-rev-list-simplify.sh > @@ -110,7 +110,7 @@ check_result 'L K J I H G F E D C B A' --full-history > check_result 'K I H E C B A' --full-history -- file > check_result 'K I H E C B A' --full-history --topo-order -- file > check_result 'K I H E C B A' --full-history --date-order -- file > -check_outcome failure 'I E C B A' --simplify-merges -- file > +check_result 'I E C B A' --simplify-merges -- file > check_result 'I B A' -- file > check_result 'I B A' --topo-order -- file > check_result 'H' --first-parent -- another-file -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html