Skip to content

Partial fix for #6532: insert-by-date order. #6539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/libgit2/commit_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,18 @@ int git_commit_list_time_cmp(const void *a, const void *b)
return 0;
}

git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
{
git_commit_list *git_commit_list_create(git_commit_list_node *item, git_commit_list *next) {
git_commit_list *new_list = git__malloc(sizeof(git_commit_list));
if (new_list != NULL) {
new_list->item = item;
new_list->next = *list_p;
new_list->next = next;
}
return new_list;
}

git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
{
git_commit_list *new_list = git_commit_list_create(item, *list_p);
*list_p = new_list;
return new_list;
}
Expand Down
1 change: 1 addition & 0 deletions src/libgit2/commit_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk);
int git_commit_list_generation_cmp(const void *a, const void *b);
int git_commit_list_time_cmp(const void *a, const void *b);
void git_commit_list_free(git_commit_list **list_p);
git_commit_list *git_commit_list_create(git_commit_list_node *item, git_commit_list *next);
git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p);
git_commit_list *git_commit_list_insert_by_date(git_commit_list_node *item, git_commit_list **list_p);
int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit);
Expand Down
30 changes: 26 additions & 4 deletions src/libgit2/revwalk.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,13 @@ int git_revwalk__push_commit(git_revwalk *walk, const git_oid *oid, const git_re

commit->uninteresting = opts->uninteresting;
list = walk->user_input;
if ((opts->insert_by_date &&
git_commit_list_insert_by_date(commit, &list) == NULL) ||

/* To insert by date, we need to parse so we know the date. */
if (opts->insert_by_date && ((error = git_commit_list_parse(walk, commit)) < 0))
return error;

if ((opts->insert_by_date == 0 ||
git_commit_list_insert_by_date(commit, &list) == NULL) &&
git_commit_list_insert(commit, &list) == NULL) {
git_error_set_oom();
return -1;
Expand Down Expand Up @@ -609,7 +614,7 @@ static int sort_in_topological_order(git_commit_list **out, git_revwalk *walk, g
static int prepare_walk(git_revwalk *walk)
{
int error = 0;
git_commit_list *list, *commits = NULL;
git_commit_list *list, *commits = NULL, *commits_last = NULL;
git_commit_list_node *next;

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

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

if (!commit->seen) {
git_commit_list *new_list = NULL;
if ((new_list = git_commit_list_create(commit, NULL)) == NULL) {
git_error_set_oom();
return -1;
}

commit->seen = 1;
git_commit_list_insert(commit, &commits);
if (commits_last == NULL)
commits = new_list;
else
commits_last->next = new_list;

commits_last = new_list;
}
}

Expand Down