From f0ff45f3ab6c6bbdedd69f39431eab132229a9c5 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Fri, 24 Apr 2026 11:27:36 +0200 Subject: [PATCH] sync-upstream: Simplify --- contrib/sync-upstream.sh | 149 +++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 76 deletions(-) diff --git a/contrib/sync-upstream.sh b/contrib/sync-upstream.sh index aaf8cb10..451456c9 100755 --- a/contrib/sync-upstream.sh +++ b/contrib/sync-upstream.sh @@ -3,112 +3,109 @@ set -eou pipefail help() { - echo "Sync merge commits from bitcoin-core/secp256k1 into secp256k1-zkp." - echo - echo "Usage:" - echo " $0 [-b ] " - echo " Find every merge commit present in upstream/master and missing in (default: master)." - echo - echo "This tool prepares the title and body for a sync PR" - echo "and generates a helper script contrib/gh-pr-create.sh." - echo - echo "Setup:" - echo " Requires a remote named 'upstream' pointing to bitcoin-core/secp256k1." - echo - echo "Listing upstream merge commits:" - echo " To list merge commits in upstream/master that are missing from (oldest first):" - echo " git log --oneline --topo-order --reverse --merges \$(git merge-base upstream/master )..upstream/master" - exit 1 +cat < + +This script creates a sync local branch pointing to . Moreover, it +generates a helper script for opening a pull request (PR) merging the created +local branch into . + +The synced upstream PRs are listed in the title and the description of the PR. +(This relies on upstream merging PRs using merge commits with titles of the form +"Merge #: ...".) + +Arguments: + : The branch to sync with upstream + : The upstream ref to merge into + +Usage examples: + $0 master upstream/master + $0 master abc1234 + $0 --switch origin/master upstream/master + +To find candidate merge commits from (oldest first), use: + git log --oneline --topo-order --reverse --merges \$(git merge-base ).. +EOT } -REMOTE=upstream -REMOTE_BRANCH="$REMOTE/master" -LOCAL_BRANCH="master" - -if ! git remote get-url "$REMOTE" &> /dev/null; then -echo "Error: Remote '$REMOTE' not found." -echo "Add it with: git remote add upstream git@github.com:bitcoin-core/secp256k1.git" -echo "Then run: git fetch upstream" -exit 1 -fi - -range() { - RANGESTART_COMMIT=$(git merge-base "$REMOTE_BRANCH" "$LOCAL_BRANCH") - RANGEEND_COMMIT=$(git rev-parse "$REMOTE_BRANCH") - COMMITS=$(git --no-pager log --pretty=format:%H --topo-order --reverse --merges "$RANGESTART_COMMIT".."$RANGEEND_COMMIT") -} - -# Process -b and -h arguments -while getopts "b:h" opt; do - case $opt in - b) - LOCAL_BRANCH=$OPTARG - ;; - h) - help - ;; - *) - echo - help - ;; - esac -done - -# Shift off the processed options -shift $((OPTIND -1)) -if [ "$#" -lt 1 ]; then - echo "Error: argument is required." >&2 - echo +### Parse arguments +if [ "$#" -ne 2 ]; then help exit 1 fi +BASE_BRANCH="$1" +UPSTREAM_REF="$2" -# Extract the PR branch argument -PR_BRANCH=$1 - -range - +### Create PR metadata TITLE="Upstream PRs" -BODY="${GITHUB_ACTIONS+This PR has been created by a GitHub Actions workflow without human involvement.}"$'\n' -for COMMIT in $COMMITS -do - PRNUM=$(git log -1 "$COMMIT" --pretty=format:%s | sed s/'Merge \(bitcoin-core\/secp256k1\)\?#\([0-9]*\).*'/'\2'/) +RANGESTART_COMMIT=$(git merge-base "$UPSTREAM_REF" "$BASE_BRANCH") +RANGEEND_COMMIT=$(git rev-parse "$UPSTREAM_REF") +COMMITS=$(git --no-pager log --pretty=format:%H --topo-order --reverse --merges "$RANGESTART_COMMIT".."$RANGEEND_COMMIT") +# If there are no commits, exit successfully +if [ -z "$COMMITS" ]; then + echo "No merge commits in range ${RANGESTART_COMMIT}..${RANGEEND_COMMIT}" >&2 + exit 0 +fi +BODY="${GITHUB_ACTIONS+*Note: This PR has been created by a GitHub Actions workflow without human involvement.* + +}" +BODY+="This PR syncs the following upstream PRs:" +for COMMIT in $COMMITS; do + PRNUM=$(git log -1 "$COMMIT" --pretty=format:%s | sed s/'Merge .*#\([0-9]*\):.*'/'\1'/) TITLE="$TITLE $PRNUM," - BODY=$(printf "%s\n%s" "$BODY" "$(git log -1 "$COMMIT" --pretty=format:%s | sed s/'Merge \(bitcoin-core\/secp256k1\)\?#\([0-9]*\)'/'[bitcoin-core\/secp256k1#\2]'/)") - LAST_COMMIT="$COMMIT" + BODY=$(printf "%s\n * %s" "$BODY" "$(git log -1 "$COMMIT" --pretty=format:%s | sed s/'Merge '//)") done # Remove trailing "," TITLE=${TITLE%?} -BODY+=$(cat <\` to show the conflict resolution in the merge commit. - * Use \`git read-tree --reset -u \` to replay these resolutions during the conflict resolution stage when recreating the PR branch locally. +Usage hints: + * If this PR has merge conflicts, resolve these by switching to the PR branch and merging the base branch into it using `git merge `. + * To show the conflict resolution diff from an existing merge commit, use `git show --remerge-diff `. + * In case you are recreating the PR branch locally, you can (during the conflict resolution state) replay this conflict resolution diff using `git read-tree --reset -u `. Be aware that this may discard your index as well as the uncommitted changes and untracked files in your worktree. EOF ) +### Create a sync branch locally. +SYNC_BRANCH="sync-$(git rev-parse --short "$UPSTREAM_REF")" +# This will error out if the branch already exists, which is what we want. +git branch --no-track "$SYNC_BRANCH" "$UPSTREAM_REF" + +### Print the PR metadata echo "-----------------------------------" echo "$TITLE" echo "-----------------------------------" echo "$BODY" echo "-----------------------------------" -# Escape single quote -# ' -> '\'' +### Generate the helper script for creating the PR +FNAME="gh-pr-create.sh" +# Escape single quote ' -> '\'' quote() { local quoted=${1//\'/\'\\\'\'} printf "%s" "$quoted" } TITLE=$(quote "$TITLE") BODY=$(quote "$BODY") - -BASEDIR=$(dirname "$0") -FNAME="$BASEDIR/gh-pr-create.sh" cat < "$FNAME" #!/bin/sh -gh pr create -t '$TITLE' -b '$BODY' --base '$LOCAL_BRANCH' --head '$PR_BRANCH' +TITLE='$TITLE' +BODY='$BODY' +SYNC_BRANCH='$SYNC_BRANCH' +BASE_BRANCH='$BASE_BRANCH' + +gh pr create --base "\$BASE_BRANCH" --head "\$SYNC_BRANCH" --title "\$TITLE" --body "\$BODY" "\$@" EOT chmod +x "$FNAME" -echo "Generated $FNAME for creating a pull request with the above title and body." \ No newline at end of file + +echo "Successfully created local sync branch $SYNC_BRANCH starting at $UPSTREAM_REF." +echo +echo "You can now:" +echo " 1. Optionally resolve merge conflicts by merging $BASE_BRANCH into $SYNC_BRANCH." +echo " 2. Push $SYNC_BRANCH to some GitHub remote." +echo " 3. Run ./$FNAME to create a pull request. (Tip: Pass --dry-run first.)"