From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 810A745041C for ; Thu, 8 Oct 2026 22:18:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791497935; cv=none; b=hYT3e4tGFeXmufyaEz5hyBws6/C9hmIc0CMTEtdwLneYOJOJgoHPqtu6g7R+RwJol6h/aW26c3DzQziM9HmsmoiBxnj6BYHHxsdvf1+/d6t2MjRfTuk4DRm6WVnbpnlaF70iFVK/wW2cyoYhoC7I4OaHDROnaxg93QITV36QmKQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791497935; c=relaxed/simple; bh=s9DGJeVupMR5rZDetKxugxA/bmoynQl91vb3R2cZxgI=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=thLROGeVaigQOWXZCjZLFbxgXV0S8WhwzMHmpMsqLTrzJ/b97/XMUMXp1zD9ueX7C3Vj5FfpT0bYr4AqmwMmDZZmPTwyuJSYmeAUFAthyMvSYL4SatB+c4YUgBj6CD5/lEI4oJc9wokLT1ik1Gmcv3BkxZ/YNaBxWS/A0s5tAYw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=R59QrNxC; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="R59QrNxC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12CCC1F000FF; Thu, 8 Oct 2026 22:18:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1791497934; bh=BNFi/RdmQLQS9BVPGmlv2NW4HIf6DHVpT7GyMCfItGo=; h=Date:From:To:Cc:Subject:References:In-Reply-To; b=R59QrNxCyj50yHo0a2nhStuwSTQxBtaovX3xwRIAn3yKIJUxuNPeQvyBPZ8PBOo8N 4kOHGrSoUb149Fe20RJyI1cGGi5T+MuUjohxf4HXJVnBCML5afdxqyr7qY1eww1PZr EGtJON4A0dO0+T9IMd6YZqEPRTPLjTUw3hAWbpQg28Cha+z42g/wLt2IcJA52+yevj r4KnQVH2PFBDlAaLrHl0oX04sMekkQhB7bDTSWGGDWsevIaoBNUN4OO3zfwDSmy6R9 d3HeBeVteVNKI7fBf/Vrd8chGabelP0UOEQaQs6vHLjXHHv4poIsLyAo14F18GFGna SY5taPm2aoPxA== Date: Fri, 9 Oct 2026 00:18:49 +0200 From: Alejandro Colomar To: Junio C Hamano , git@vger.kernel.org Cc: Ben Boeckel , Nico Williams , Viktor Dukhovni Subject: [RFC v3] git-bisect-rebase Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="gd67gmeek7vp2yaz" Content-Disposition: inline In-Reply-To: --gd67gmeek7vp2yaz Content-Type: multipart/mixed; protected-headers=v1; boundary="tnk4o2pmah4rn7p3" Content-Disposition: inline From: Alejandro Colomar To: Junio C Hamano , git@vger.kernel.org Cc: Ben Boeckel , Nico Williams , Viktor Dukhovni Subject: [RFC v3] git-bisect-rebase Message-ID: References: MIME-Version: 1.0 In-Reply-To: --tnk4o2pmah4rn7p3 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi! I've improved the usability of the script, thinking about two different use cases: - Moving a single branch. - Moving a tree of branches. For that, I've implemented --abort/--continue/--quit options, which are similar to the options in git-rebase(1), but different in that they act on the bisect-rebase operation, and not on a single rebase. The --continue flag is useful for the case of rebasing a single tree, not having to specify the target and flags each time. The --quit flag is useful to maintain the ability to terminate the bisect-rebase at the current point, having advanced the branch by some distance. This allows changing to other branches (descendants) that will be moved together with the parent, to minimize conflict resolution. I wrote in a different subthread the algorithms that would be used for each of these two cases, but I'll paste them again here: So, the usual algorithm for moving a tree would be (assuming A is a branch with two descendants, B and C): $ git bisect-rebase master A; $ git rebase --abort; $ git bisect-rebase --quit; $ git bisect-rebase A B; ## ... until success $ git bisect-rebase A C; ## ... until success $ git tag tmpA; $ git bisect-rebase master A; ## resolve conflicts here $ git rebase --continue; $ git bisect-rebase --quit; $ git rebase --onto A tmpA B; $ git rebase --onto A tmpA C; $ git tag -d tmpA; ## ... rinse and repeat (goto first command, until no conflicts) And the algorithm for moving a single branch would be simpler: $ git bisect-rebase master X; ## resolve conflicts here $ git rebase --continue; $ git bisect-rebase --continue; ## ... rinse and repeat (goto first command, until no conflicts) The script has been split into 3 smaller scripts. They are all attached, but can be also found in the Linux man-pages repository (alongside their history, which might clarify some design decisions): Of course, the entry point is git-bisect-rebase, with the other two being internal helpers. Have a lovely night! Alex --=20 --tnk4o2pmah4rn7p3 Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename=git-bisect-rebase #!/bin/bash # Copyright 2026, Alejandro Colomar # SPDX-License-Identifier: GPL-3.0-or-later set -Eeufo pipefail; shopt -s lastpipe; err() { >&2 printf '%s\n' "$(basename "$0"): error: $*"; exit 1; } git rev-parse --git-dir | read -r git_dir; git rev-parse --git-path bisect-rebase | read -r dir; while test $# -ge 1; do case "$1" in --abort) test -d "$dir/" || err 'Not in a bisect-rebase operation?'; set +e; git rebase --abort >/dev/null 2>/dev/null; git bisect reset >/dev/null 2>/dev/null; xargs git checkout <"$dir/head-name"; xargs git reset --hard <"$dir/orig-head"; rm -rf "$dir"; exit 0; ;; --continue) test -d "$dir/" || err 'Not in a bisect-rebase operation?'; if test -d "$git_dir/rebase-merge"; then err 'You must finish the current rebase operation.'; fi; git-bisect-rebase--continue; exit 0; ;; --quit) test -d "$dir/" || err 'Not in a bisect-rebase operation?'; if test -d "$git_dir/rebase-merge"; then err 'You must finish the current rebase operation.'; fi; rm -rf "$dir"; exit 0; ;; *) break; ;; esac; done; mkdir "$dir"; # shellcheck disable=SC2064 # we want expansion now trap "rm -rf '$dir'" EXIT; # shellcheck disable=SC2312 # False positive: cat <<-'__EOF__' | git bisect-rebase [