Upstream is a periodic one-way export of xAI's monorepo (linear "Synced from monorepo" commits, SOURCE_REV pinning the internal SHA) and explicitly refuses external contributions. So local changes can never be upstreamed, and upstream re-drops the whole tree on every sync -- structurally the same problem CraftBukkit has with Mojang. Adopt the Spigot/BuildTools model: patches/ is the source of truth, work/ is a disposable build artifact regenerated from upstream.rev plus patches/. scripts/apply-patches.sh ~ applyPatches.sh scripts/rebuild-patches.sh ~ rebuildPatches.sh scripts/update-upstream.sh forward-ports patches onto a new sync scripts/setup.sh toolchain: rust 1.94.0, dotslash/protoc upstream.rev ~ BuildTools versions/*.json pin format-patch uses --zero-commit so rebases do not rewrite the From line of every patch, and apply's git clean preserves work/target so replaying patches does not cost a cold Rust rebuild. Ships two [EXAMPLE PATCH] commits demonstrating a source edit and a new-file addition; both are safe to delete. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
86 lines
2.7 KiB
Bash
Executable File
86 lines
2.7 KiB
Bash
Executable File
#!/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 <rev>]
|
|
|
|
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 <<EOF
|
|
|
|
${C_YELLOW}${C_BOLD}==> 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 <<EOF
|
|
|
|
${C_GREEN}${C_BOLD}==> 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
|