Skip to content

Commit 633cde0

Browse files
authored
Merge pull request libgit2#6539 from cavaquinho/fix/revwalk-insert-by-date
Partial fix for libgit2#6532: insert-by-date order.
2 parents 15e42fb + 4edf6c1 commit 633cde0

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

src/libgit2/commit_list.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,18 @@ int git_commit_list_time_cmp(const void *a, const void *b)
4343
return 0;
4444
}
4545

46-
git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
47-
{
46+
git_commit_list *git_commit_list_create(git_commit_list_node *item, git_commit_list *next) {
4847
git_commit_list *new_list = git__malloc(sizeof(git_commit_list));
4948
if (new_list != NULL) {
5049
new_list->item = item;
51-
new_list->next = *list_p;
50+
new_list->next = next;
5251
}
52+
return new_list;
53+
}
54+
55+
git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
56+
{
57+
git_commit_list *new_list = git_commit_list_create(item, *list_p);
5358
*list_p = new_list;
5459
return new_list;
5560
}

src/libgit2/commit_list.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk);
4949
int git_commit_list_generation_cmp(const void *a, const void *b);
5050
int git_commit_list_time_cmp(const void *a, const void *b);
5151
void git_commit_list_free(git_commit_list **list_p);
52+
git_commit_list *git_commit_list_create(git_commit_list_node *item, git_commit_list *next);
5253
git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p);
5354
git_commit_list *git_commit_list_insert_by_date(git_commit_list_node *item, git_commit_list **list_p);
5455
int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit);

src/libgit2/revwalk.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,13 @@ int git_revwalk__push_commit(git_revwalk *walk, const git_oid *oid, const git_re
8383

8484
commit->uninteresting = opts->uninteresting;
8585
list = walk->user_input;
86-
if ((opts->insert_by_date &&
87-
git_commit_list_insert_by_date(commit, &list) == NULL) ||
86+
87+
/* To insert by date, we need to parse so we know the date. */
88+
if (opts->insert_by_date && ((error = git_commit_list_parse(walk, commit)) < 0))
89+
return error;
90+
91+
if ((opts->insert_by_date == 0 ||
92+
git_commit_list_insert_by_date(commit, &list) == NULL) &&
8893
git_commit_list_insert(commit, &list) == NULL) {
8994
git_error_set_oom();
9095
return -1;
@@ -609,7 +614,7 @@ static int sort_in_topological_order(git_commit_list **out, git_revwalk *walk, g
609614
static int prepare_walk(git_revwalk *walk)
610615
{
611616
int error = 0;
612-
git_commit_list *list, *commits = NULL;
617+
git_commit_list *list, *commits = NULL, *commits_last = NULL;
613618
git_commit_list_node *next;
614619

615620
/* If there were no pushes, we know that the walk is already over */
@@ -618,6 +623,12 @@ static int prepare_walk(git_revwalk *walk)
618623
return GIT_ITEROVER;
619624
}
620625

626+
/*
627+
* This is a bit convoluted, but necessary to maintain the order of
628+
* the commits. This is especially important in situations where
629+
* git_revwalk__push_glob is called with a git_revwalk__push_options
630+
* setting insert_by_date = 1, which is critical for fetch negotiation.
631+
*/
621632
for (list = walk->user_input; list; list = list->next) {
622633
git_commit_list_node *commit = list->item;
623634
if ((error = git_commit_list_parse(walk, commit)) < 0)
@@ -627,8 +638,19 @@ static int prepare_walk(git_revwalk *walk)
627638
mark_parents_uninteresting(commit);
628639

629640
if (!commit->seen) {
641+
git_commit_list *new_list = NULL;
642+
if ((new_list = git_commit_list_create(commit, NULL)) == NULL) {
643+
git_error_set_oom();
644+
return -1;
645+
}
646+
630647
commit->seen = 1;
631-
git_commit_list_insert(commit, &commits);
648+
if (commits_last == NULL)
649+
commits = new_list;
650+
else
651+
commits_last->next = new_list;
652+
653+
commits_last = new_list;
632654
}
633655
}
634656

0 commit comments

Comments
 (0)