git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [RFC PATCH] hooks--pre-push.sample: identify branch point
@ 2023-03-09 22:04 Antoine Beaupré
  2023-03-09 23:22 ` Felipe Contreras
  0 siblings, 1 reply; 6+ messages in thread
From: Antoine Beaupré @ 2023-03-09 22:04 UTC (permalink / raw)
  To: git; +Cc: Antoine Beaupré

The pre-push hook introduced in 87c86dd14a (Add sample pre-push hook
script, 2013-01-13) has a pretty naive implementation that inspects
the entirety of that branch history, regardless of previous merges.

In other words, if you create a topic branch from a current history,
the entire history will be inspected by the pre-push hook. In my case,
there was an old "WIP" commit log that broke the hook, even though
that commit wasn't specific to the branch in question, nor was it
introduced by the push.

This patch aims at fixing that problem by restricting the revisions inspected when a new branch is pushed to something that is more specific to that branch.

This implementation will first attempt to find an ancestor that the
current branch is related to (`--merged=`). This is where this
implementation is the most questionable; normally you would put
`master` or `main` as a base branch, but who knows what people
actually use for this nowadays. And besides, it's fair to assume you
could be pushing something based on a branch that already exists
upstream that is *not* master or main... But still, that's a tricky
bit I'm not sure of.

Then we find the "branch point" which is the latest commit on the
ancestor branch that's shared with the inspected ref. This,
interestingly, seems to be a really tricky problem as well. I base my
implementation off this answer on Stack Overflow (I know! at least
it's not ChatGPT!):

https://stackoverflow.com/a/71193866/1174784

There are currently a whopping twenty-five answers to that question in
that thread, and I'm hoping the community here will have a more
definitive answer to this question. I have picked the answer that uses
the least possible external commands, but it still uses a `tail -1`
which I'm somewhat unhappy about. I have thought of using
`--max-count` for this instead, but I understand that probably does
the equivalent of a `head -n` *and* it's applied before `--reverse`,
so there's not other way to do this.

The final question to answer here is whether this is a good idea in
the first place, and whether this is the right place to answer this
kind of question. I happen to really like using pre-push (instead of
pre-commit) for inspecting my work before submitting it upstream, so
it was a natural fit for me, but this might be everyone's taste.

As the subject indicates, I would very much welcome comments on
this. I would be happy to submit a more elaborate version of
this (e.g. with unit tests) if it's interesting for the community, or
receive guidance on where best this could be implemented or improved.

Signed-off-by: Antoine Beaupré <anarcat@debian.org>
---
 templates/hooks--pre-push.sample | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/templates/hooks--pre-push.sample b/templates/hooks--pre-push.sample
index 4ce688d32b..f871b65195 100755
--- a/templates/hooks--pre-push.sample
+++ b/templates/hooks--pre-push.sample
@@ -33,8 +33,24 @@ do
 	else
 		if test "$remote_oid" = "$zero"
 		then
-			# New branch, examine all commits
-			range="$local_oid"
+			# new branch
+			#
+			# search for a base branch that's part of this branch, latest modified
+			#
+			# it's a better heuristic than hardcoding "master" or "main"
+			base_branch=$(git for-each-ref \
+					  --merged="$local_ref" \
+					  --no-contains="$local_ref" \
+					  --format="%(refname:strip=-1)" \
+					  --sort='-*authordate' \
+					  refs/heads )
+			# find the place where we branched off the base branch
+			branch_point=$(git rev-parse \
+					   $(git rev-list --exclude-first-parent-only \
+						 ^"$base_branch" "$local_ref"| tail -1)^ \
+                                    )
+			# examine all commits up to the branch point
+		        range="$branch_point..$local_oid"
 		else
 			# Update to existing branch, examine new commits
 			range="$remote_oid..$local_oid"
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-03-16 17:33 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-09 22:04 [RFC PATCH] hooks--pre-push.sample: identify branch point Antoine Beaupré
2023-03-09 23:22 ` Felipe Contreras
2023-03-10 16:28   ` Antoine Beaupré
2023-03-10 22:09     ` Felipe Contreras
2023-03-12 18:14       ` Antoine Beaupré
2023-03-16 17:32         ` Felipe Contreras

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).