revision.c: don't show all merges for --parents
authorKevin Bracey <kevin@bracey.fi>
Thu, 16 May 2013 15:32:40 +0000 (18:32 +0300)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 May 2013 18:51:10 +0000 (11:51 -0700)
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: Kevin Bracey <kevin@bracey.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
revision.c
t/t6111-rev-list-treesame.sh
index 1c750705d833b2597042b4bc872ac4d7e68523dd..edb7e1c4d1712456bc26537695e95600547c167a 100644 (file)
@@ -2760,10 +2760,7 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
        if (revs->min_age != -1 && (commit->date > revs->min_age))
                return commit_ignore;
        if (revs->min_parents || (revs->max_parents >= 0)) {
-               int n = 0;
-               struct commit_list *p;
-               for (p = commit->parents; p; p = p->next)
-                       n++;
+               int n = commit_list_count(commit->parents);
                if ((n < revs->min_parents) ||
                    ((revs->max_parents >= 0) && (n > revs->max_parents)))
                        return commit_ignore;
@@ -2773,12 +2770,23 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
        if (revs->prune && revs->dense) {
                /* Commit without changes? */
                if (commit->object.flags & TREESAME) {
+                       int n;
+                       struct commit_list *p;
                        /* drop merges unless we want parenthood */
                        if (!want_ancestry(revs))
                                return commit_ignore;
-                       /* non-merge - always ignore it */
-                       if (!commit->parents || !commit->parents->next)
-                               return commit_ignore;
+                       /*
+                        * If we want ancestry, then need to keep any merges
+                        * between relevant commits to tie together topology.
+                        * For consistency with TREESAME and simplification
+                        * use "relevant" here rather than just INTERESTING,
+                        * to treat bottom commit(s) as part of the topology.
+                        */
+                       for (n = 0, p = commit->parents; p; p = p->next)
+                               if (relevant_commit(p->item))
+                                       if (++n >= 2)
+                                               return commit_show;
+                       return commit_ignore;
                }
        }
        return commit_show;
index e32b37306f9bacdcaee476227f2433a843129697..25cc8ad0e8f17e8c423d31197e2f3efb48190425 100755 (executable)
@@ -139,7 +139,7 @@ check_result 'M L G' F..M --first-parent -- file
 # If we want history since E, then we're quite happy to ignore G that took E.
 check_result 'M L K J I H G' E..M --ancestry-path
 check_result 'M L J I H' E..M --ancestry-path -- file
-check_outcome failure '(LH)M (K)L (EJ)K (I)J (E)I (E)H' E..M --ancestry-path --parents -- file # includes G
+check_result '(LH)M (K)L (EJ)K (I)J (E)I (E)H' E..M --ancestry-path --parents -- file
 check_result '(LH)M (E)H (J)L (I)J (E)I' E..M --ancestry-path --simplify-merges -- file
 
 # Should still be able to ignore I-J branch in simple log, despite limiting
@@ -168,7 +168,7 @@ check_result '(D)F (BA)D' B..F --full-history --parents -- file
 check_result '(B)F' B..F --simplify-merges -- file
 check_result 'F D' B..F --ancestry-path
 check_result 'F' B..F --ancestry-path -- file
-check_outcome failure 'F' B..F --ancestry-path --parents -- file # includes D
+check_result 'F' B..F --ancestry-path --parents -- file
 check_result 'F' B..F --ancestry-path --simplify-merges -- file
 check_result 'F D' B..F --first-parent
 check_result 'F' B..F --first-parent -- file