revision.c: don't show all merges for --parents

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>

Kevin Bracey committed May 16, 2013 at 18:32 UTC bf3418b08bac89902a5f6c70f8695f148df99828
2 files changed +17 -9
revision.c
+15 -7
@@ -2760,10 +2760,7 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
2760 if (revs->min_age != -1 && (commit->date > revs->min_age))
2761 return commit_ignore;
2762 if (revs->min_parents || (revs->max_parents >= 0)) {
2763 - int n = 0;
2764 - struct commit_list *p;
2765 - for (p = commit->parents; p; p = p->next)
2766 - n++;
2763 + int n = commit_list_count(commit->parents);
2764 if ((n < revs->min_parents) ||
2765 ((revs->max_parents >= 0) && (n > revs->max_parents)))
2766 return commit_ignore;
@@ -2773,12 +2770,23 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
2770 if (revs->prune && revs->dense) {
2771 /* Commit without changes? */
2772 if (commit->object.flags & TREESAME) {
2773 + int n;
2774 + struct commit_list *p;
2775 /* drop merges unless we want parenthood */
2776 if (!want_ancestry(revs))
2777 return commit_ignore;
2779 - /* non-merge - always ignore it */
2780 - if (!commit->parents || !commit->parents->next)
2781 - return commit_ignore;
2778 + /*
2779 + * If we want ancestry, then need to keep any merges
2780 + * between relevant commits to tie together topology.
2781 + * For consistency with TREESAME and simplification
2782 + * use "relevant" here rather than just INTERESTING,
2783 + * to treat bottom commit(s) as part of the topology.
2784 + */
2785 + for (n = 0, p = commit->parents; p; p = p->next)
2786 + if (relevant_commit(p->item))
2787 + if (++n >= 2)
2788 + return commit_show;
2789 + return commit_ignore;
2790 }
2791 }
2792 return commit_show;
t/t6111-rev-list-treesame.sh
+2 -2
@@ -139,7 +139,7 @@ check_result 'M L G' F..M --first-parent -- file
139 # If we want history since E, then we're quite happy to ignore G that took E.
140 check_result 'M L K J I H G' E..M --ancestry-path
141 check_result 'M L J I H' E..M --ancestry-path -- file
142 -check_outcome failure '(LH)M (K)L (EJ)K (I)J (E)I (E)H' E..M --ancestry-path --parents -- file # includes G
142 +check_result '(LH)M (K)L (EJ)K (I)J (E)I (E)H' E..M --ancestry-path --parents -- file
143 check_result '(LH)M (E)H (J)L (I)J (E)I' E..M --ancestry-path --simplify-merges -- file
144
145 # 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
168 check_result '(B)F' B..F --simplify-merges -- file
169 check_result 'F D' B..F --ancestry-path
170 check_result 'F' B..F --ancestry-path -- file
171 -check_outcome failure 'F' B..F --ancestry-path --parents -- file # includes D
171 +check_result 'F' B..F --ancestry-path --parents -- file
172 check_result 'F' B..F --ancestry-path --simplify-merges -- file
173 check_result 'F D' B..F --first-parent
174 check_result 'F' B..F --first-parent -- file