[PATCH] three --merge-order bug fixes

This patch fixes three bugs in --merge-order support
    * mark_ancestors_uninteresting was unnecessarily exponential which
      caused a problem when a commit with no parents was merged near the
      head of something like the linux kernel
    * removed a spurious statement from find_base which wasn't
      apparently causing problems now, but wasn't correct either.
    * removed an unnecessarily strict check from find_base_for_list
      that causes a problem if git-rev-list commit ^parent-of-commit
      is specified.
    * added some unit tests which were accidentally omitted from
      original merge-order patch

The fix to mark_ancestors_uninteresting isn't an optimal fix - a full
graph scan will still be performed in this case even though it is
not strictly required. However, a full graph scan is linear
and still no worse than git-rev-list HEAD which runs in less than 2
seconds on a warm cache.

Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Jon Seymour
2005-06-09 00:37:41 +10:00
committed by Linus Torvalds
parent 32798c707e
commit 4e7346735a
2 changed files with 177 additions and 3 deletions

View File

@ -229,7 +229,7 @@ static int find_base_for_list(struct commit_list *list, struct commit **boundary
struct commit *item = list->item;
if (item->object.util || (item->object.flags & UNINTERESTING)) {
if (item->object.util) {
die("%s:%d:%s: logic error: this should not have happened - commit %s\n",
__FILE__, __LINE__, __FUNCTION__, sha1_to_hex(item->object.sha1));
}
@ -323,7 +323,6 @@ static int find_base(struct commit *head, struct commit **boundary)
struct commit_list *pending = NULL;
struct commit_list *next;
commit_list_insert(head, &pending);
for (next = head->parents; next; next = next->next) {
commit_list_insert(next->item, &pending);
}
@ -418,8 +417,8 @@ static void mark_ancestors_uninteresting(struct commit *commit)
int boundary = flags & BOUNDARY;
int uninteresting = flags & UNINTERESTING;
commit->object.flags |= UNINTERESTING;
if (uninteresting || boundary || !visited) {
commit->object.flags |= UNINTERESTING;
return;
// we only need to recurse if