From 1115bffe4746846a4ad5eff337ec5784e7b73366 Mon Sep 17 00:00:00 2001 From: sterni Date: Sun, 16 Feb 2025 13:14:18 +0100 Subject: [PATCH] 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 Autosubmit: sterni --- users/sterni/git-only-push/git-only-push.sh | 32 +++++++++++---------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/users/sterni/git-only-push/git-only-push.sh b/users/sterni/git-only-push/git-only-push.sh index 9099fb5b3..71cddeb94 100755 --- a/users/sterni/git-only-push/git-only-push.sh +++ b/users/sterni/git-only-push/git-only-push.sh @@ -89,10 +89,7 @@ if [ "$#" -eq 0 ]; then die 100 "Missing commits" fi -# Resolve ranges, get them into chronological order repo="$(git rev-parse --show-toplevel)" -revs="$(git -C "$repo" rev-list --no-walk "$@" | tac)" - worktree= cleanup() { @@ -108,19 +105,24 @@ else git -C "$repo" worktree add "$worktree" "$base" fi -for rev in $revs; do - if $dry; then - printf 'Would cherry pick %s\n' "$rev" >&2 - else - no_cherry_pick=false - git -C "$worktree" cherry-pick ${cherry_pick_x:+-x} "$rev" || no_cherry_pick=true - 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" +for arg in "$@"; do + # Resolve ranges, get them into chronological order + revs="$(git -C "$repo" rev-list --no-walk "$arg" | tac)" + + for rev in $revs; do + if $dry; then + printf 'Would cherry pick %s\n' "$rev" >&2 + else + no_cherry_pick=false + git -C "$worktree" cherry-pick ${cherry_pick_x:+-x} "$rev" || no_cherry_pick=true + 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 + done done if $dry; then