#!/usr/bin/env bash # Follow a new upstream sync: re-pin upstream.rev, replay patches/ on top of it, # and write the forward-ported result back out. # # usage: update-upstream.sh [--dry-run] [--to ] source "$(dirname "${BASH_SOURCE[0]}")/lib.sh" DRY_RUN=0 TARGET="" while [[ $# -gt 0 ]]; do case "$1" in -n|--dry-run) DRY_RUN=1; shift ;; --to) TARGET="${2:?--to needs a revision}"; shift 2 ;; *) die "unknown argument: $1" ;; esac done ensure_upstream OLD="$(read_rev)" if [[ -n "$TARGET" ]]; then NEW="$(git -C "$UPSTREAM_DIR" rev-parse --verify "${TARGET}^{commit}")" \ || die "revision '$TARGET' not found in upstream" else NEW="$(git -C "$UPSTREAM_DIR" rev-parse --verify "origin/$UPSTREAM_BRANCH")" fi if [[ "$OLD" == "$NEW" ]]; then info "Already pinned to the newest upstream commit ($(git -C "$UPSTREAM_DIR" rev-parse --short "$NEW")). Nothing to do." exit 0 fi count="$(git -C "$UPSTREAM_DIR" rev-list --count "$OLD..$NEW" 2>/dev/null || echo '?')" info "Upstream moved: $(git -C "$UPSTREAM_DIR" rev-parse --short "$OLD") -> $(git -C "$UPSTREAM_DIR" rev-parse --short "$NEW") ($count new commit(s))" git -C "$UPSTREAM_DIR" log --oneline --no-decorate "$OLD..$NEW" | sed 's/^/ /' # Each upstream commit is a squashed monorepo drop; SOURCE_REV names the # internal commit it came from, which is the only human-meaningful version here. old_src="$(git -C "$UPSTREAM_DIR" show "$OLD:SOURCE_REV" 2>/dev/null | tr -d '[:space:]' || true)" new_src="$(git -C "$UPSTREAM_DIR" show "$NEW:SOURCE_REV" 2>/dev/null | tr -d '[:space:]' || true)" [[ -n "$old_src$new_src" ]] && info "SOURCE_REV: ${old_src:-?} -> ${new_src:-?}" changed="$(git -C "$UPSTREAM_DIR" diff --name-only "$OLD" "$NEW" | wc -l | tr -d ' ')" info "$changed file(s) changed upstream" if [[ "$DRY_RUN" == "1" ]]; then info "--dry-run: upstream.rev left at $OLD" exit 0 fi info "Pinning upstream.rev -> $NEW" write_rev "$NEW" info "Replaying patches on the new base" if ! "$ROOT/scripts/apply-patches.sh" --force; then cat >&2 < upstream.rev has been bumped, but patches did not apply cleanly.${C_RESET} Finish the 'git am' in work/ (instructions above), then run: make rebuild To abandon this update entirely and go back: cd work && git am --abort printf '%s\\n' "$OLD" > upstream.rev # or: git checkout upstream.rev make apply EOF exit 1 fi info "Patches replayed cleanly -- regenerating patches/ against the new base" "$ROOT/scripts/rebuild-patches.sh" cat < Update complete.${C_RESET} Review and commit the result: git diff --stat upstream.rev patches/ make build git add upstream.rev patches/ && git commit -m 'Update upstream to $(git -C "$UPSTREAM_DIR" rev-parse --short "$NEW")' EOF