|
1 | | -#! /bin/bash |
| 1 | +#!/bin/bash |
| 2 | +set -euo pipefail |
| 3 | + |
| 4 | +TEMPLATE_REPO="${TEMPLATE_REPO:-https://github.com/blooop/python_template.git}" |
| 5 | +BRANCH="feature/update_from_template" |
| 6 | + |
| 7 | +# Ensure clean working tree |
| 8 | +if ! git diff --quiet || ! git diff --cached --quiet; then |
| 9 | + echo "Error: working tree is dirty. Commit or stash changes first." |
| 10 | + exit 1 |
| 11 | +fi |
2 | 12 |
|
3 | 13 | git config --global pull.rebase false |
4 | | -git remote add template https://github.com/blooop/python_template.git |
5 | | -git fetch --all |
6 | | -git checkout main && git pull origin main |
7 | | -git checkout -B feature/update_from_template; git pull |
8 | | -git merge template/main --allow-unrelated-histories -m 'feat: pull changes from remote template' |
9 | | -git checkout --ours pixi.lock |
10 | | - |
11 | | -# regenerate lockfile to match merged pyproject.toml |
| 14 | + |
| 15 | +# Setup merge driver for pixi.lock (idempotent) |
| 16 | +git config merge.ourslock.driver true |
| 17 | + |
| 18 | +# Add template remote (remove first if leftover from a failed run) |
| 19 | +git remote remove template 2>/dev/null || true |
| 20 | +git remote add template "$TEMPLATE_REPO" |
| 21 | + |
| 22 | +cleanup() { |
| 23 | + git remote remove template 2>/dev/null || true |
| 24 | +} |
| 25 | +trap cleanup EXIT |
| 26 | + |
| 27 | +git fetch template main |
| 28 | + |
| 29 | +# Check if there are any changes to merge |
| 30 | +if git diff HEAD...template/main --quiet 2>/dev/null; then |
| 31 | + echo "No changes from template. Already up to date." |
| 32 | + exit 0 |
| 33 | +fi |
| 34 | + |
| 35 | +# Get to a clean main/master |
| 36 | +DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main") |
| 37 | +git checkout "$DEFAULT_BRANCH" && git pull origin "$DEFAULT_BRANCH" |
| 38 | + |
| 39 | +# Create or reset the update branch |
| 40 | +git checkout -B "$BRANCH" |
| 41 | + |
| 42 | +# Merge template changes — this is a real git merge so: |
| 43 | +# - 3-way merge at line level across ALL files |
| 44 | +# - git remembers the merge base, so conflicts only appear once |
| 45 | +# - --allow-unrelated-histories is needed for the first merge, harmless after |
| 46 | +if ! git merge template/main --allow-unrelated-histories -m 'feat: pull changes from remote template'; then |
| 47 | + echo "" |
| 48 | + echo "=============================================" |
| 49 | + echo " Merge conflicts detected — resolve them," |
| 50 | + echo " then run: pixi update && git add pixi.lock" |
| 51 | + echo " and commit to finish the merge." |
| 52 | + echo "=============================================" |
| 53 | + exit 1 |
| 54 | +fi |
| 55 | + |
| 56 | +# Resolve pixi.lock: keep ours, then regenerate from merged pyproject.toml |
| 57 | +git checkout --ours pixi.lock 2>/dev/null || true |
12 | 58 | pixi update |
13 | 59 | git add pixi.lock |
14 | 60 | git diff --cached --quiet || git commit -m 'chore: update pixi.lock after template merge' |
15 | 61 |
|
16 | | -git remote remove template |
17 | | -git push --set-upstream origin feature/update_from_template |
18 | | -git checkout main |
| 62 | +git push --set-upstream origin "$BRANCH" |
| 63 | + |
| 64 | +# Create a PR if gh is available and no open PR exists |
| 65 | +if command -v gh &>/dev/null; then |
| 66 | + EXISTING=$(gh pr list --head "$BRANCH" --state open --json number -q '.[0].number' 2>/dev/null || true) |
| 67 | + if [ -z "$EXISTING" ]; then |
| 68 | + gh pr create \ |
| 69 | + --title "feat: sync updates from template repo" \ |
| 70 | + --body "Automated pull of changes from [$TEMPLATE_REPO]($TEMPLATE_REPO) using \`git merge\`." \ |
| 71 | + --fill 2>/dev/null || echo "PR creation skipped (gh not authenticated or not a GitHub repo)." |
| 72 | + else |
| 73 | + echo "PR #$EXISTING already open for $BRANCH." |
| 74 | + fi |
| 75 | +fi |
| 76 | + |
| 77 | +git checkout "$DEFAULT_BRANCH" |
| 78 | +echo "Done. Review the PR for branch $BRANCH." |
0 commit comments