Re: Leveraging --rebase-merges --update-refs mechanism to rebase several branches in one run
- From
- Yann Dirson <ydirson@free.fr>
- Date
- Jan 7, 2024, 11:37 UTC
- Message-ID
- <1930018756.1822864601.1704627466836.JavaMail.root@zimbra39-e7>
- In-Reply-To
- <ed9f9fc5-c398-4424-9b5b-dbe618cca2ed@kdbg.org>
Johannes Sixt wrote:
Show 28 quoted lines
> Am 06.01.24 um 20:05 schrieb Yann Dirson: > > The "core + 1 variant" case pretty much works out of the box, with > > --rebase-merges > > and --update-refs generating a perfect instructions sheet. > > > > But if I was to rebase just one variant while rewriting the core > > branch, obviously > > all other variants would still fork off the pre-rewrite core > > branch, and we'd loose > > all chances of automating the same work on the other variants. > > > > OTOH, if I get `git-rebase` to generate the instruction sheets for > > those other > > variants first, strip them (manually) from the common part, and > > insert them in the > > instruction sheet of my "core + 1 variant" case ... I do get the > > whole of my branches > > rebased together, and sharing the updated core. > > Not a complete automation, but... You can merge all variant branches > into a temporary branch (or detached HEAD), even if that are merely > -s > ours merges, and then rebase the temporary branch with > --rebase-merges > --update-refs. This will generate the instruction sheet that you > want. > You can remove the final merge instructions (the temporary ones) from > the instruction sheet if you do not want them to be executed.
Nice idea, and this is indeed automatable for the most part, Q&D PoC below.
There are a few things I can see missing in this PoC:
- removal of the final merge from instruction sheet
Could be done by wrapping $EDITOR - I'm not particularly fond doing things behind the user's back, but I lack better ideas.
- restoration of HEAD
In the general case it cannot be done from the script, so we would naturally want to do that from the instruction sheet?
While I was at manually removing the final merge, I experimented with changing the "reset onto" to "reset <a branch name>", but that resulted in moving HEAD to the pre-rebase version of the requested branch.
- When aborting the rebase HEAD still points to the extra merge
This is indeed a special case of the above, where instruction sheet cannot be used, and where the script could help since we won't be in the middle of a rebase when git-rebase stops.
There does not seem to be any documented exit-code protocol to tell the git-rebase caller the user aborted. I guess "HEAD pointing to this commit" could be used to identify the abort.
---- 8< ---- git-rebase-batch #!/bin/bash set -e
die() {
echo >&2 "ERROR: $0: $*"
exit 1
}REBASE_OPTS=(--interactive --rebase-merges --update-refs)
# all args before "--" are passed to git-rebase
while [ $# -ge 1 ]; do
case "$1" in
--) shift; break;;
*) REBASE_OPTS+=("$1"); shift;;
esac
done[ $# -ge 3 ] || die "need cutting-point and at least 2 refs to rebase" CUT="$1" shift
git checkout --detach "$CUT" git merge -s ours "$@" -m "temporary handle for all rebased branches" git rebase "${REBASE_OPTS[@]}" "$CUT" HEAD
# here we can be in the middle of interactive rebase, cannot perform # any kind of cleanup (which would include restoring HEAD ref to its # original destination) ---- 8< ----