Kevin Bracey <[email protected]> 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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html