On Fri, Mar 10 2023, Derrick Stolee via GitGitGadget wrote: > At $DAYJOB, we have used a custom 'ahead-behind' builtin in our fork of Git > for lots of reasons. The main goal of the builtin is to compare multiple > references against a common base reference. The comparison is number of > commits that are in each side of the symmtric difference of their reachable > sets. A commit C is "ahead" of a commit B by the number of commits in B..C > (reachable from C but not reachable from B). Similarly, the commit C is > "behind" the commit B by the number of commits in C..B (reachable from B but > not reachable from C). I have a local change to get rid of the various "the_repository" macros, which a merge of this in "seen" conflicted with (semantically). The below patch on top of "seen" will fix it, could you please squash it in in the appropriate places? Aside from a desire to get rid of "the_repository" macros this also makes your own code consistent, i.e. you use repo_clear_commit_marks(), but then use parse_commit() instead of the repo_parse_commit() in the same function. It also makes the new API more future-proof, I don't think we should be adding new code that implicitly uses "the_repository" to our libraries if we can help it, much better to pass it down, even if all the current users are built-in that end up using "the_repository". diff --git a/builtin/branch.c b/builtin/branch.c index 21526d9883a..7c7dba839cf 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -448,7 +448,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin if (verify_ref_format(format)) die(_("unable to parse format string")); - filter_ahead_behind(format, &array); + filter_ahead_behind(the_repository, format, &array); ref_array_sort(sorting, &array); for (i = 0; i < array.nr; i++) { diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 1cdf8eb5a6b..e097f44e226 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -102,7 +102,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) filter.match_as_path = 1; filter_refs(&array, &filter, FILTER_REFS_ALL); - filter_ahead_behind(&format, &array); + filter_ahead_behind(the_repository, &format, &array); ref_array_sort(sorting, &array); diff --git a/builtin/tag.c b/builtin/tag.c index 8652d5edd47..7e2f686600a 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -67,7 +67,7 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, die(_("unable to parse format string")); filter->with_commit_tag_algo = 1; filter_refs(&array, filter, FILTER_REFS_TAGS); - filter_ahead_behind(format, &array); + filter_ahead_behind(the_repository, format, &array); ref_array_sort(sorting, &array); for (i = 0; i < array.nr; i++) { diff --git a/commit-reach.c b/commit-reach.c index 0abd43801fc..4a2216b8ae0 100644 --- a/commit-reach.c +++ b/commit-reach.c @@ -977,8 +977,9 @@ static void free_bit_array(struct commit *c) *bitmap = NULL; } -void ahead_behind(struct commit **commits, size_t commits_nr, - struct ahead_behind_count *counts, size_t counts_nr) +void ahead_behind(struct repository *r, struct commit **commits, + size_t commits_nr, struct ahead_behind_count *counts, + size_t counts_nr) { struct prio_queue queue = { compare_commits_by_gen_then_commit_date }; size_t width = (commits_nr + BITS_IN_EWORD - 1) / BITS_IN_EWORD; @@ -1024,7 +1025,7 @@ void ahead_behind(struct commit **commits, size_t commits_nr, for (p = c->parents; p; p = p->next) { struct bitmap *bitmap_p; - parse_commit(p->item); + repo_parse_commit(r, p->item); bitmap_p = init_bit_array(p->item, width); bitmap_or(bitmap_p, bitmap_c); @@ -1039,7 +1040,7 @@ void ahead_behind(struct commit **commits, size_t commits_nr, } /* STALE is used here, PARENT2 is used by insert_no_dup(). */ - repo_clear_commit_marks(the_repository, PARENT2 | STALE); + repo_clear_commit_marks(r, PARENT2 | STALE); clear_bit_arrays(&bit_arrays); clear_prio_queue(&queue); } diff --git a/commit-reach.h b/commit-reach.h index f871b5dcce9..2269fab8261 100644 --- a/commit-reach.h +++ b/commit-reach.h @@ -131,7 +131,8 @@ struct ahead_behind_count { * Given an array of commits and an array of ahead_behind_count pairs, * compute the ahead/behind counts for each pair. */ -void ahead_behind(struct commit **commits, size_t commits_nr, - struct ahead_behind_count *counts, size_t counts_nr); +void ahead_behind(struct repository *r, struct commit **commits, + size_t commits_nr, struct ahead_behind_count *counts, + size_t counts_nr); #endif diff --git a/ref-filter.c b/ref-filter.c index 4125ec3fd3a..cdc054beede 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2462,7 +2462,7 @@ static void reach_filter(struct ref_array *array, free(to_clear); } -void filter_ahead_behind(struct ref_format *format, +void filter_ahead_behind(struct repository *r, struct ref_format *format, struct ref_array *array) { struct commit **commits; @@ -2502,7 +2502,7 @@ void filter_ahead_behind(struct ref_format *format, commits_nr++; } - ahead_behind(commits, commits_nr, array->counts, array->counts_nr); + ahead_behind(r, commits, commits_nr, array->counts, array->counts_nr); free(commits); } diff --git a/ref-filter.h b/ref-filter.h index 7e8bff3864e..1a757b49233 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -163,7 +163,7 @@ struct ref_array_item *ref_array_push(struct ref_array *array, * * If this is not called, then any ahead-behind atoms will be blank. */ -void filter_ahead_behind(struct ref_format *format, +void filter_ahead_behind(struct repository *r, struct ref_format *format, struct ref_array *array); #endif /* REF_FILTER_H */