Git development
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx@kernel.org>
To: Nico Williams <nico@cryptonector.com>
Cc: Junio C Hamano <gitster@pobox.com>,
	git@vger.kernel.org,  Ben Boeckel <mathstuf@gmail.com>,
	Viktor Dukhovni <viktor@openssl.org>
Subject: Re: [RFC] git-brebase
Date: Sat, 3 Oct 2026 23:38:29 +0200	[thread overview]
Message-ID: <asF0DkNtlnJ9-Sng@debian> (raw)
In-Reply-To: <asFv9QcpLgzPnnFb@ubby>

[-- Attachment #1: Type: text/plain, Size: 5987 bytes --]

Hi Nico,

> Date: 2026-10-03 16:13:25-0500
> From: Nico Williams <nico@cryptonector.com>
>
> On Sat, Oct 03, 2026 at 10:56:25PM +0200, Alejandro Colomar wrote:
> > > I also have a getopts_long-like function (see my gists) for bash if you
> > > like.
> > 
> > I think getopts(1) is not usable for git(1)-related scripts, because
> > getopts(1) interprets '--' as the end of the options, but git(1) uses it
> > for distinguishing commits from paths.  If anyone shows me how it can be
> > used, I'd be interested, because I've hit this issue in the past with
> > other script.
> 
> https://gist.github.com/nicowilliams/f3fe2b10b380aecdef403acb246dced2
> 
> Though there's many ways to do this.

That one still consumes the '--', but we don't want to consume it.  We
want it to remain there in $@ after the options have been parsed.

> > > > cat >"$callback" <<__EOF__
> > > > #!/bin/bash
> > > > ...
> > > > __EOF__
> > > > chmod +x "$callback";
> > > 
> > > Here what might be better is to have a command-line option to execute
> > > this callback without having to write it to a file,
> > 
> > How would you do it?
> 
> I'd have an option or sub-command of the main script that says "do the
> callback thing", then when you run `git bisect run ...` put in the name
> of this script as the command and the "do the callback thing" option
> next.

I'd need to see some code.  I'm not seeing it.  :)

> > > and use environment
> > > variables to pass arguments to it.
> > 
> > The callback doesn't really need any arguments, since 'git bisect run'
> > won't pass any arguments to it.
> 
> But you're embedding values into the temp executable script -- if you
> don't have that any more you'll have to pass those in.

But why would we want to not have it?
That would complicate the script, no?

> > > which means I can't use this in detached HEAD mode :(
> > 
> > Oh!  I wasn't aware that git-rebase(1) supported detached HEAD mode.
> 
> Sure does!
> 
> > > I work in detached HEAD mode almost exclusively.  I know, that's..
> > > weird.  But it works for me.
> > 
> > Ouch!  Indeed.  :)
> > Out of curiosity, are there any interesting reasons for such
> > self-implied pain?
> 
> I often do:
> 
> : ; git checkout origin/master
> : ; <do some work>
> : ; git add ...; git commit -m '...'
> : ; git push myfork HEAD:refs/heads/the-branch-name-here  # <-- I name it here
> 
> then open a PR.
> 
> Now I don't have a branch here, but who cares?  If I switch to other
> work and later want to come back to this work I'll either a) create a
> local branch then, and/or b) when I resume work on the first thing I'll
> `git checkout myfork/the-branch-name-here` and...  once more work in
> detached HEAD mode.
> 
> And if I need to see "what was I doing?" then I use `git log --oneline`
> and `git reflog` and I quickly see the remote branch of interest.
> 
> The remote branches are the symbolic names I need to preserve, and my
> clone will know them, so I only need local branch names for things I
> work on w/o a network or over a long time.
> 
> I do exaggerate a bit.  I do this a lot, but maybe not quite "almost
> exclusively".  Often I'm forced to have a local branch by opinionated
> tools other than git itself.

Hmmm, actually resembles what I do.  I use branches, then push to
a remote, and once it's in the remote, I remove the local branch.
I try to remove the local branches as soon as I can, because that way
I don't need to remember whether there was something I forgot to push,
or I wanted to explicitly discard it.  If there's no local branch,
there's no confusion.  Since I work with two local computers, having the
source of truth be the remote makes it less ambiguous.  But while
working locally, the branch helps a lot.

Anyway, I've patched it to work with detached HEAD.  (I need to remember
to add two traps, now.)

	diff --git i/src/bin/git-brebase w/src/bin/git-brebase
	index d652c37ef08d..a57acc350d7e 100755
	--- i/src/bin/git-brebase
	+++ w/src/bin/git-brebase
	@@ -50,8 +50,16 @@ if test $# -gt 1; then
	 fi;
	 git rev-list -1 "$1" \
	 | read -r tgt;
	-git rev-parse --abbrev-ref HEAD \
	+
	+mktemp \
	 | read -r branch;
	+{
	+       git rev-parse --abbrev-ref HEAD;
	+       git rev-list -1 HEAD;
	+} \
	+| sed '/^HEAD$/d' \
	+| sed '1!d' \
	+>"$branch";
	 
	 # Set up the callback script for 'git rebase run'.
	 mktemp \
	@@ -91,7 +99,8 @@ cat >"$callback" <<__EOF__
			fi;
		fi;
	 
	-       git switch '$branch' >/dev/null 2>/dev/null;
	+       cat '$branch' \
	+       | xargs -I{} git checkout {} >/dev/null 2>/dev/null;
		git rev-list -1 HEAD \
		| read -r old_head;
		printf '%s' 'Rebase: ';
	@@ -103,6 +112,13 @@ cat >"$callback" <<__EOF__
			git checkout --detach "\$bisect_head" 2>/dev/null;
			exit 1;
		fi;
	+       {
	+               git rev-parse --abbrev-ref HEAD;
	+               git rev-list -1 HEAD;
	+       } \
	+       | sed '/^HEAD$/d' \
	+       | sed '1!d' \
	+       >"$branch";
	 
		if test -n '$post'; then
			printf '%s' 'Post-rebase exec: ';
	@@ -146,7 +162,8 @@ fi;
	 # shellcheck disable=SC2248  # gbopts may hold multiple options
	 git bisect start $gbopts >/dev/null;
	 git bisect bad "$tgt" >/dev/null;
	-git merge-base "$branch" "$tgt" \
	+cat "$branch" \
	+| xargs -I{} git merge-base {} "$tgt" \
	 | xargs -I{} git bisect good {};
	 git bisect run "$callback";
	 git rev-list -1 bisect/bad \
	@@ -154,7 +171,8 @@ git rev-list -1 bisect/bad \
	 git bisect reset >/dev/null 2>/dev/null;
	 
	 # Perform the conflicting rebase
	-git switch "$branch";
	+cat "$branch" \
	+| xargs -I{} git checkout {};
	 # shellcheck disable=SC2086  # gropts may hold multiple options
	 git rebase $gropts "$bad";
	 if test -v post; then

I've tested it, and it works fine with a detached HEAD.


Cheers,
Alex

> 
> Nico
> -- 

-- 
<https://www.alejandro-colomar.es>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2026-10-03 21:38 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-03 20:11 [RFC] git-brebase Alejandro Colomar
2026-10-03 20:13 ` Alejandro Colomar
2026-10-03 20:39 ` Nico Williams
2026-10-03 20:48   ` Nico Williams
2026-10-03 21:07     ` Alejandro Colomar
2026-10-03 21:17       ` Nico Williams
2026-10-03 21:29         ` Alejandro Colomar
2026-10-03 21:50           ` Nico Williams
2026-10-03 20:56   ` Alejandro Colomar
2026-10-03 21:13     ` Nico Williams
2026-10-03 21:38       ` Alejandro Colomar [this message]
2026-10-03 22:19         ` Nico Williams
2026-10-03 21:17     ` Alejandro Colomar
2026-10-08 22:18 ` [RFC v3] git-bisect-rebase Alejandro Colomar

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=asF0DkNtlnJ9-Sng@debian \
    --to=alx@kernel.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=mathstuf@gmail.com \
    --cc=nico@cryptonector.com \
    --cc=viktor@openssl.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox