Re: [PATCH v27 0/2] status: add status.compareBranches config for multiple branch comparisons
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Jan 22, 2026, 18:53 UTC
- Message-ID
- <xmqq1pjho4wn.fsf@gitster.g>
- In-Reply-To
- <pull.2138.v27.git.git.1769096240.gitgitgadget@gmail.com>
"Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com> writes:
Before these list of CC's (which does not seem to have any effect, by the way. The message is going only to the list with your personal address on CC: and to nobody else), ...
Show 6 quoted lines
> cc: Chris Torek chris.torek@gmail.com cc: Yee Cheng Chin > ychin.macvim@gmail.com cc: "brian m. carlson" sandals@crustytoothpaste.net > cc: Ben Knoble ben.knoble@gmail.com cc: "Kristoffer Haugsbakk" > kristofferhaugsbakk@fastmail.com cc: Phillip Wood phillip.wood123@gmail.com > cc: Nico Williams nico@cryptonector.com cc: Patrick Steinhardt ps@pks.im cc: > Jeff King peff@peff.net
... please summarize
(1) what this series of patches are about, to help those who
encounter these patches for the first time, and (2) what changed in this iteration (v27) relative to the previous
iteration (v26).I happen to have seen your other message so I can guess this is about deduping when more than one comparison target is listed and some happen to become the same branches, but others may not have seen that other message, and it is not helpful to just dump the range-diff and force them to read it to deduce what you did.
Thanks.
Show 140 quoted lines
> Harald Nordgren (2):
> refactor format_branch_comparison in preparation
> status: add status.compareBranches config for multiple branch
> comparisons
>
> Documentation/config/status.adoc | 20 ++
> remote.c | 192 ++++++++++++++----
> t/t6040-tracking-info.sh | 337 +++++++++++++++++++++++++++++++
> 3 files changed, 512 insertions(+), 37 deletions(-)
>
>
> base-commit: b5c409c40f1595e3e590760c6f14a16b6683e22c
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2138%2FHaraldNordgren%2Fahead_of_main_status-v27
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2138/HaraldNordgren/ahead_of_main_status-v27
> Pull-Request: https://github.com/git/git/pull/2138
>
> Range-diff vs v26:
>
> 1: 27a46f8d9c = 1: 27a46f8d9c refactor format_branch_comparison in preparation
> 2: caa761f615 ! 2: 0993420fc1 status: add status.compareBranches config for multiple branch comparisons
> @@ remote.c
> struct counted_string {
> size_t len;
> const char *s;
> -@@ remote.c: static void branch_release(struct branch *branch)
> - free((char *)branch->refname);
> - free(branch->remote_name);
> - free(branch->pushremote_name);
> -+ free((char *)branch->push_tracking_ref);
> - merge_clear(branch);
> - }
> -
> @@ remote.c: int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
> return stat_branch_pair(branch->refname, base, num_ours, num_theirs, abf);
> }
> @@ remote.c: int format_tracking_info(struct branch *branch, struct strbuf *sb,
> - const char *full_base;
> - char *base;
> - int upstream_is_gone = 0;
> --
> ++ char *compare_branches = NULL;
> ++ struct string_list branches = STRING_LIST_INIT_DUP;
> ++ struct string_list processed_refs = STRING_LIST_INIT_DUP;
> ++ int reported = 0;
> ++ size_t i;
> ++ const char *upstream_ref;
> ++ const char *push_ref;
> +
> - cmp_fetch = stat_tracking_info(branch, &ours, &theirs, &full_base, 0, abf);
> - if (cmp_fetch < 0) {
> - if (!full_base)
> - return 0;
> - upstream_is_gone = 1;
> -+ char *compare_branches_config = NULL;
> -+ struct string_list compare_branches = STRING_LIST_INIT_DUP;
> -+ struct string_list_item *item;
> -+ int reported = 0;
> -+ size_t i;
> -+ const char *upstream_ref;
> -+ const char *push_ref;
> -+
> + repo_config_get_string(the_repository, "status.comparebranches",
> -+ &compare_branches_config);
> ++ &compare_branches);
> +
> -+ if (compare_branches_config) {
> -+ string_list_split(&compare_branches, compare_branches_config,
> -+ " ", -1);
> -+ string_list_remove_empty_items(&compare_branches, 0);
> ++ if (compare_branches) {
> ++ string_list_split(&branches, compare_branches, " ", -1);
> ++ string_list_remove_empty_items(&branches, 0);
> + } else {
> -+ string_list_append(&compare_branches, "@{upstream}");
> ++ string_list_append(&branches, "@{upstream}");
> }
>
> - base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
> @@ remote.c: int format_tracking_info(struct branch *branch, struct strbuf *sb,
> - _(" (use \"git branch --unset-upstream\" to fixup)\n"));
> - } else {
> - format_branch_comparison(sb, !cmp_fetch, ours, theirs, base, abf, show_divergence_advice);
> -+ for (i = 0; i < compare_branches.nr; i++) {
> ++ for (i = 0; i < branches.nr; i++) {
> + char *full_ref;
> + char *short_ref;
> + int ours, theirs, cmp;
> + int is_upstream, is_push;
> + unsigned flags = 0;
> +
> -+ item = &compare_branches.items[i];
> -+ full_ref = resolve_compare_branch(branch, item->string);
> ++ full_ref = resolve_compare_branch(branch,
> ++ branches.items[i].string);
> + if (!full_ref)
> + continue;
> +
> ++ if (string_list_has_string(&processed_refs, full_ref)) {
> ++ free(full_ref);
> ++ continue;
> ++ }
> ++ string_list_insert(&processed_refs, full_ref);
> ++
> + short_ref = refs_shorten_unambiguous_ref(
> + get_main_ref_store(the_repository), full_ref, 0);
> +
> @@ remote.c: int format_tracking_info(struct branch *branch, struct strbuf *sb,
>
> - free(base);
> - return 1;
> -+ string_list_clear(&compare_branches, 0);
> -+ free(compare_branches_config);
> ++ string_list_clear(&branches, 0);
> ++ string_list_clear(&processed_refs, 0);
> ++ free(compare_branches);
> + return reported;
> }
>
> @@ t/t6040-tracking-info.sh: test_expect_success '--set-upstream-to @{-1}' '
> + )
> +'
> +
> ++test_expect_success 'status.compareBranches from upstream has no duplicates' '
> ++ (
> ++ cd test &&
> ++ git checkout main &&
> ++ git status >../actual
> ++ ) &&
> ++ cat >expect <<-EOF &&
> ++ On branch main
> ++ Your branch is up to date with ${SQ}origin/main${SQ}.
> ++
> ++ nothing to commit, working tree clean
> ++ EOF
> ++ test_cmp expect actual
> ++'
> ++
> +test_expect_success 'status.compareBranches shows ahead of both upstream and push branch' '
> + (
> + cd test &&