From: "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, vdye@github.com, Derrick Stolee <stolee@gmail.com>
Subject: [PATCH v2 0/3] git for-each-ref: is-base atom and base branches
Date: Sun, 11 Aug 2024 17:34:44 +0000 [thread overview]
Message-ID: <pull.1768.v2.git.1723397687.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1768.git.1722550226.gitgitgadget@gmail.com>
This change introduces a new 'git for-each-ref' atom, 'is-base', in a very
similar way to the 'ahead-behind' atom. As detailed carefully in the first
change, this is motivated by the need to detect the concept of a "base
branch" in a repository with multiple long-lived branches.
This change is motivated by a third-party tool created to make this
detection with the same optimization mechanism, but using a much slower
technique due to the limitations of the Git CLI not presenting this
information. The existing algorithm involves using git rev-list
--first-parent -<N> in batches for the collection of considered references,
comparing those lists, and increasing <N> as needed until finding a
collision. This new use of 'git for-each-ref' will allow determining this
mechanism within a single process and walking a minimal number of commits.
There are benefits to users both on client-side and server-side. In an
internal monorepo, this base branch detection algorithm is used to determine
a long-lived branch based on the HEAD commit, mapping to a group within the
organizational structure of the repository, which determines a set of
projects that the user will likely need to build; this leads to
automatically selecting an initial sparse-checkout definition based on the
build dependencies required. An upcoming feature in Azure Repos will use
this algorithm to automatically create a pull request against the correct
target branch, reducing user pain from needing to select a different branch
after a large commit diff is rendered against the default branch. This atom
unlocks that ability for Git hosting services that use Git in their backend.
Thanks, -Stolee
Updates in v2
=============
* I had forgotten to include a documentation change in v1. My attempt to
create a succinct doc change in a follow-up hunk continued to be
confusing. This version includes a more expanded version of the
documentation blurb for the is-base token.
Derrick Stolee (3):
commit-reach: add get_branch_base_for_tip
for-each-ref: add 'is-base' token
p1500: add is-base performance tests
Documentation/git-for-each-ref.txt | 42 ++++++++++
commit-reach.c | 118 +++++++++++++++++++++++++++++
commit-reach.h | 17 +++++
ref-filter.c | 78 ++++++++++++++++++-
ref-filter.h | 15 ++++
t/helper/test-reach.c | 2 +
t/perf/p1500-graph-walks.sh | 31 ++++++++
t/t6600-test-reach.sh | 94 +++++++++++++++++++++++
8 files changed, 396 insertions(+), 1 deletion(-)
base-commit: bea9ecd24b0c3bf06cab4a851694fe09e7e51408
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1768%2Fderrickstolee%2Ftarget-ref-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1768/derrickstolee/target-ref-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/1768
Range-diff vs v1:
1: 580026f910d = 1: 580026f910d commit-reach: add get_branch_base_for_tip
2: a1fbdca374f ! 2: 13341e7e512 for-each-ref: add 'is-base' token
@@ Commit message
Signed-off-by: Derrick Stolee <stolee@gmail.com>
+ ## Documentation/git-for-each-ref.txt ##
+@@ Documentation/git-for-each-ref.txt: ahead-behind:<committish>::
+ commits ahead and behind, respectively, when comparing the output
+ ref to the `<committish>` specified in the format.
+
++is-base:<committish>::
++ In at most one row, `(<committish>)` will appear to indicate the ref
++ that is most likely the ref used as a starting point for the branch
++ that produced `<committish>`. This choice is made using a heuristic:
++ choose the ref that minimizes the number of commits in the
++ first-parent history of `<committish>` and not in the first-parent
++ history of the ref.
+++
++For example, consider the following figure of first-parent histories of
++several refs:
+++
++----
++*--*--*--*--*--* refs/heads/A
++\
++ \
++ *--*--*--* refs/heads/B
++ \ \
++ \ \
++ * * refs/heads/C
++ \
++ \
++ *--* refs/heads/D
++----
+++
++Here, if `A`, `B`, and `C` are the filtered references, and the format
++string is `%(refname):%(is-base:D)`, then the output would be
+++
++----
++refs/heads/A:
++refs/heads/B:(D)
++refs/heads/C:
++----
+++
++This is because the first-parent history of `D` has its earliest
++intersection with the first-parent histories of the filtered refs at a
++common first-parent ancestor of `B` and `C` and ties are broken by the
++earliest ref in the sorted order.
+++
++Note that this token will not appear if the first-parent history of
++`<committish>` does not intersect the first-parent histories of the
++filtered refs.
++
+ describe[:options]::
+ A human-readable name, like linkgit:git-describe[1];
+ empty string for undescribable commits. The `describe` string may
+
## ref-filter.c ##
@@ ref-filter.c: enum atom_type {
ATOM_ELSE,
3: db87434e146 = 3: 757c20090db p1500: add is-base performance tests
--
gitgitgadget
next prev parent reply other threads:[~2024-08-11 17:34 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-01 22:10 [PATCH 0/3] git for-each-ref: is-base atom and base branches Derrick Stolee via GitGitGadget
2024-08-01 22:10 ` [PATCH 1/3] commit-reach: add get_branch_base_for_tip Derrick Stolee via GitGitGadget
2024-08-01 22:10 ` [PATCH 2/3] for-each-ref: add 'is-base' token Derrick Stolee via GitGitGadget
2024-08-01 22:10 ` [PATCH 3/3] p1500: add is-base performance tests Derrick Stolee via GitGitGadget
2024-08-01 23:06 ` [PATCH 0/3] git for-each-ref: is-base atom and base branches Junio C Hamano
2024-08-02 14:32 ` Derrick Stolee
2024-08-02 16:55 ` Junio C Hamano
2024-08-02 17:30 ` Junio C Hamano
2024-08-11 17:34 ` Derrick Stolee via GitGitGadget [this message]
2024-08-11 17:34 ` [PATCH v2 1/3] commit-reach: add get_branch_base_for_tip Derrick Stolee via GitGitGadget
2024-08-12 20:30 ` Junio C Hamano
2024-08-13 13:39 ` Derrick Stolee
2024-08-11 17:34 ` [PATCH v2 2/3] for-each-ref: add 'is-base' token Derrick Stolee via GitGitGadget
2024-08-12 21:05 ` Junio C Hamano
2024-08-13 13:44 ` Derrick Stolee
2024-08-11 17:34 ` [PATCH v2 3/3] p1500: add is-base performance tests Derrick Stolee via GitGitGadget
2024-08-14 10:31 ` [PATCH v3 0/4] git for-each-ref: is-base atom and base branches Derrick Stolee via GitGitGadget
2024-08-14 10:31 ` [PATCH v3 1/4] commit-reach: add get_branch_base_for_tip Derrick Stolee via GitGitGadget
2024-08-14 10:31 ` [PATCH v3 2/4] commit: add gentle reference lookup method Derrick Stolee via GitGitGadget
2024-08-14 10:31 ` [PATCH v3 3/4] for-each-ref: add 'is-base' token Derrick Stolee via GitGitGadget
2024-08-14 10:31 ` [PATCH v3 4/4] p1500: add is-base performance tests Derrick Stolee via GitGitGadget
2024-08-19 19:52 ` [PATCH v3 0/4] git for-each-ref: is-base atom and base branches Junio C Hamano
2024-08-20 1:33 ` Derrick Stolee
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.1768.v2.git.1723397687.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=stolee@gmail.com \
--cc=vdye@github.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.