Skip to content

Commit

Permalink
Make revision limiting more robust against occasional bad commit dates
Browse files Browse the repository at this point in the history
The revision limiter uses the commit date to decide when it has seen
enough commits to finalize the revision list, but that can get confused
if there are incorrect dates far in the past on some commits.

This makes the logic a bit more robust by

 - we always walk an extra SLOP commits from the source list even if we
   decide that the source list is probably all done (unless the source is
   entirely empty, of course, because then we really can't do anything at
   all)

 - we keep track of the date of the last commit we added to the
   destination list (this will *generally* be the oldest entry we've seen
   so far)

 - we compare that with the youngest entry (the first one) of the source
   list, and if the destination is older than the source, we know we want
   to look at the source.

which causes occasional date mishaps to be handled cleanly.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Linus Torvalds authored and Junio C Hamano committed Mar 19, 2008
1 parent 1d0a694 commit 7d00419
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
48 changes: 38 additions & 10 deletions revision.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,14 +564,39 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
free_patch_ids(&ids);
}

static void add_to_list(struct commit_list **p, struct commit *commit, struct commit_list *n)
/* How many extra uninteresting commits we want to see.. */
#define SLOP 5

static int still_interesting(struct commit_list *src, unsigned long date, int slop)
{
p = &commit_list_insert(commit, p)->next;
*p = n;
/*
* No source list at all? We're definitely done..
*/
if (!src)
return 0;

/*
* Does the destination list contain entries with a date
* before the source list? Definitely _not_ done.
*/
if (date < src->item->date)
return SLOP;

/*
* Does the source list still have interesting commits in
* it? Definitely not done..
*/
if (!everybody_uninteresting(src))
return SLOP;

/* Ok, we're closing in.. */
return slop-1;
}

static int limit_list(struct rev_info *revs)
{
int slop = SLOP;
unsigned long date = ~0ul;
struct commit_list *list = revs->commits;
struct commit_list *newlist = NULL;
struct commit_list **p = &newlist;
Expand All @@ -591,16 +616,19 @@ static int limit_list(struct rev_info *revs)
return -1;
if (obj->flags & UNINTERESTING) {
mark_parents_uninteresting(commit);
if (everybody_uninteresting(list)) {
if (revs->show_all)
add_to_list(p, commit, list);
break;
}
if (!revs->show_all)
continue;
if (revs->show_all)
p = &commit_list_insert(commit, p)->next;
slop = still_interesting(list, date, slop);
if (slop)
continue;
/* If showing all, add the whole pending list to the end */
if (revs->show_all)
*p = list;
break;
}
if (revs->min_age != -1 && (commit->date > revs->min_age))
continue;
date = commit->date;
p = &commit_list_insert(commit, p)->next;

show = show_early_output;
Expand Down
2 changes: 1 addition & 1 deletion t/t6009-rev-list-parent.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test_expect_success setup '
git log --pretty=oneline --abbrev-commit
'

test_expect_failure 'one is ancestor of others and should not be shown' '
test_expect_success 'one is ancestor of others and should not be shown' '
git rev-list one --not four >result &&
>expect &&
Expand Down

0 comments on commit 7d00419

Please sign in to comment.