From faf0156b278d1a760362cda1d294a88be7608de4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 14 Aug 2008 10:59:44 -0700 Subject: [PATCH 1/3] revision --simplify-merges: use decoration instead of commit->util field The users of revision walking machinery may want to use the util pointer for their own use. Use decoration to hold the data needed during merge simplification instead. Signed-off-by: Junio C Hamano --- revision.c | 49 +++++++++++++++++++++++++++++++++++++------------ revision.h | 1 + 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/revision.c b/revision.c index 0aaa4c10b..33cb207f2 100644 --- a/revision.c +++ b/revision.c @@ -1408,16 +1408,34 @@ static int remove_duplicate_parents(struct commit *commit) return surviving_parents; } -static struct commit_list **simplify_one(struct commit *commit, struct commit_list **tail) +struct merge_simplify_state { + struct commit *simplified; +}; + +static struct merge_simplify_state *locate_simplify_state(struct rev_info *revs, struct commit *commit) +{ + struct merge_simplify_state *st; + + st = lookup_decoration(&revs->merge_simplification, &commit->object); + if (!st) { + st = xcalloc(1, sizeof(*st)); + add_decoration(&revs->merge_simplification, &commit->object, st); + } + return st; +} + +static struct commit_list **simplify_one(struct rev_info *revs, struct commit *commit, struct commit_list **tail) { struct commit_list *p; + struct merge_simplify_state *st, *pst; int cnt; + st = locate_simplify_state(revs, commit); + /* - * We store which commit each one simplifies to in its util field. * Have we handled this one? */ - if (commit->util) + if (st->simplified) return tail; /* @@ -1426,7 +1444,7 @@ static struct commit_list **simplify_one(struct commit *commit, struct commit_li * anyway. */ if ((commit->object.flags & UNINTERESTING) || !commit->parents) { - commit->util = commit; + st->simplified = commit; return tail; } @@ -1435,7 +1453,8 @@ static struct commit_list **simplify_one(struct commit *commit, struct commit_li * Otherwise we are not ready to rewrite this one yet. */ for (cnt = 0, p = commit->parents; p; p = p->next) { - if (!p->item->util) { + pst = locate_simplify_state(revs, p->item); + if (!pst->simplified) { tail = &commit_list_insert(p->item, tail)->next; cnt++; } @@ -1446,8 +1465,10 @@ static struct commit_list **simplify_one(struct commit *commit, struct commit_li /* * Rewrite our list of parents. */ - for (p = commit->parents; p; p = p->next) - p->item = p->item->util; + for (p = commit->parents; p; p = p->next) { + pst = locate_simplify_state(revs, p->item); + p->item = pst->simplified; + } cnt = remove_duplicate_parents(commit); /* @@ -1482,9 +1503,11 @@ static struct commit_list **simplify_one(struct commit *commit, struct commit_li (commit->object.flags & UNINTERESTING) || !(commit->object.flags & TREESAME) || (1 < cnt)) - commit->util = commit; - else - commit->util = commit->parents->item->util; + st->simplified = commit; + else { + pst = locate_simplify_state(revs, commit->parents->item); + st->simplified = pst->simplified; + } return tail; } @@ -1508,7 +1531,7 @@ static void simplify_merges(struct rev_info *revs) struct commit_list *next = list->next; free(list); list = next; - tail = simplify_one(commit, tail); + tail = simplify_one(revs, commit, tail); } } @@ -1519,9 +1542,11 @@ static void simplify_merges(struct rev_info *revs) while (list) { struct commit *commit = list->item; struct commit_list *next = list->next; + struct merge_simplify_state *st; free(list); list = next; - if (commit->util == commit) + st = locate_simplify_state(revs, commit); + if (st->simplified == commit) tail = &commit_list_insert(commit, tail)->next; } } diff --git a/revision.h b/revision.h index dfa06b521..765ef6c5e 100644 --- a/revision.h +++ b/revision.h @@ -110,6 +110,7 @@ struct rev_info { struct reflog_walk_info *reflog_info; struct decoration children; + struct decoration merge_simplification; }; #define REV_TREE_SAME 0 From 53030f8d1199ef9da86e7ddc2b8a659a355e5f69 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 18 Aug 2008 00:37:34 -0700 Subject: [PATCH 2/3] revision --simplify-merges: do not leave commits unprocessed When we still do not know how parents of a commit simplify to, we should defer processing of the commit, not discard it. Signed-off-by: Junio C Hamano --- revision.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/revision.c b/revision.c index 33cb207f2..8cd39da2e 100644 --- a/revision.c +++ b/revision.c @@ -1459,8 +1459,10 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c cnt++; } } - if (cnt) + if (cnt) { + tail = &commit_list_insert(commit, tail)->next; return tail; + } /* * Rewrite our list of parents. From 5eac739e05620e491555850d5b513ef60595c016 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 14 Aug 2008 13:52:36 -0700 Subject: [PATCH 3/3] revision --simplify-merges: make it a no-op without pathspec When we are not pruning there is no reason to run the merge simplification. Also avoid running topo-order sort twice. Signed-off-by: Junio C Hamano --- revision.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/revision.c b/revision.c index 8cd39da2e..db2ab2b11 100644 --- a/revision.c +++ b/revision.c @@ -1518,7 +1518,10 @@ static void simplify_merges(struct rev_info *revs) struct commit_list *list; struct commit_list *yet_to_do, **tail; - sort_in_topological_order(&revs->commits, revs->lifo); + if (!revs->topo_order) + sort_in_topological_order(&revs->commits, revs->lifo); + if (!revs->prune) + return; /* feed the list reversed */ yet_to_do = NULL;