#!/bin/bash # Move tmuxrdr onto a newer herdr release: rebase the tmuxrdr commits from the # release they sit on onto the new one. # # tmuxrdr/scripts/sync-upstream newest stable release (vX.Y.Z) # tmuxrdr/scripts/sync-upstream v0.9.4 that release # # Releases, not upstream's master: a release is what Homebrew ships, so a # tmuxrdr build and the stock herdr beside it stay on the same version, and # their CLIs can talk to each other's servers. # The base is the newest release tag behind HEAD; the tmuxrdr commits are # everything after it. The branch as it was is kept as tmuxrdr-on-, # so a bad rebase costs nothing: `git switch -C tmuxrdr tmuxrdr-on-`. # rerere is on in this checkout, so a conflict resolved once is resolved again # by itself on the next release. set -euo pipefail cd "$(dirname "$0")/../.." branch="tmuxrdr" target="${1:-}" die() { >&2 echo "ERROR: $*"; exit 1; } [[ "$(git symbolic-ref --short -q HEAD)" == "$branch" ]] || die "check out $branch first" [[ -z "$(git status --porcelain)" ]] || die "uncommitted changes; commit or stash them first" git fetch --quiet --tags --prune upstream old="$(git describe --tags --abbrev=0 --match 'v[0-9]*' HEAD)" if [[ -z "$target" ]]; then target="$(git tag -l 'v[0-9]*' --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1)" fi git rev-parse -q --verify "refs/tags/$target^{commit}" >/dev/null || die "no release tag $target" if [[ "$target" == "$old" ]]; then echo "up to date: $branch is on $old" exit 0 fi [[ "$(printf '%s\n' "$old" "$target" | sort -V | tail -n 1)" == "$target" ]] \ || die "$target is older than $old, the release $branch is on" echo "$branch: $(git rev-list --count "$old..HEAD") commits on $old" git log --oneline --reverse "$old..HEAD" | sed 's/^/ /' echo "rebasing onto $target ($(git rev-list --count "$old..$target") upstream commits)" backup="$branch-on-$old" git branch -f "$backup" HEAD if ! git rebase --onto "$target" "$old" "$branch"; then cat <