fix(sterni/git-only-push): resolve args to revs individually

git-rev-list(1) orders the printed revisions before printing. This is
quite complicated and I noticed that it behaves in unexpected ways
w.r.t. commits given individually: sometimes they are reordered,
sometimes not. This is problematic when interdependent commits are given
via the command line individually: If they aren't re-ordered by
git-rev-list(1), we'd be cherry picking them in reverse order.

To solve this, just call git-rev-list(1) on all arguments individually,
allowing ranges to be resolved, but always picking individual arguments
in the correct order.

Notably, this means that excluding commits via individual REV^ arguments
won't ever work, but I believe this wasn't possible previously
anyways (maybe due to --no-walk?).

Change-Id: If8e83e0b47a74baf37d77b6c4f68a55af944b366
Reviewed-on: https://cl.tvl.fyi/c/depot/+/13149
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Autosubmit: sterni <sternenseemann@systemli.org>
This commit is contained in:
sterni 2025-02-16 13:14:18 +01:00 committed by clbot
parent eddb4c783a
commit 1115bffe47

View file

@ -89,10 +89,7 @@ if [ "$#" -eq 0 ]; then
die 100 "Missing commits" die 100 "Missing commits"
fi fi
# Resolve ranges, get them into chronological order
repo="$(git rev-parse --show-toplevel)" repo="$(git rev-parse --show-toplevel)"
revs="$(git -C "$repo" rev-list --no-walk "$@" | tac)"
worktree= worktree=
cleanup() { cleanup() {
@ -108,19 +105,24 @@ else
git -C "$repo" worktree add "$worktree" "$base" git -C "$repo" worktree add "$worktree" "$base"
fi fi
for rev in $revs; do for arg in "$@"; do
if $dry; then # Resolve ranges, get them into chronological order
printf 'Would cherry pick %s\n' "$rev" >&2 revs="$(git -C "$repo" rev-list --no-walk "$arg" | tac)"
else
no_cherry_pick=false for rev in $revs; do
git -C "$worktree" cherry-pick ${cherry_pick_x:+-x} "$rev" || no_cherry_pick=true if $dry; then
if $no_cherry_pick; then printf 'Would cherry pick %s\n' "$rev" >&2
tmp="$worktree" else
# Prevent cleanup from removing the worktree no_cherry_pick=false
worktree="" git -C "$worktree" cherry-pick ${cherry_pick_x:+-x} "$rev" || no_cherry_pick=true
die 101 "Could not cherry pick $rev. Please manually fixup worktree at $tmp" if $no_cherry_pick; then
tmp="$worktree"
# Prevent cleanup from removing the worktree
worktree=""
die 101 "Could not cherry pick $rev. Please manually fixup worktree at $tmp"
fi
fi fi
fi done
done done
if $dry; then if $dry; then