-
Notifications
You must be signed in to change notification settings - Fork 46
feat(dx): add worktree:sync mise task to rebase clean worktrees on origin/main #218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a398cf0
b5a16b8
eef91e3
fe30fb7
86809bf
04fba1e
6677e4d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -164,6 +164,55 @@ run = [ | |
| "mise run hooks:pre-push:tests", | ||
| ] | ||
|
|
||
| ################## | ||
| #### WORKTREE #### | ||
| ################## | ||
|
|
||
| # Issue #197: worktrees branched from origin/main drift silently as other PRs | ||
| # merge. This task fetches origin/main and rebases every clean linked worktree | ||
| # onto it. Worktrees on already-merged branches are reported and skipped (no | ||
| # rebase needed); dirty worktrees are skipped (no rebase on uncommitted | ||
| # changes); main itself (the primary worktree) is also skipped. Branches that | ||
| # fail to rebase are aborted and reported so the next push surfaces the | ||
| # conflict explicitly rather than silently leaving a half-rebased state. | ||
| [tasks."worktree:sync"] | ||
| description = "Fetch origin/main and rebase every clean linked worktree onto it" | ||
| run = """ | ||
| #!/usr/bin/env bash | ||
| set -eu -o pipefail | ||
| git fetch origin main | ||
| status=0 | ||
| # tab-delimited "worktree<TAB>branch" pairs, one per linked worktree | ||
| pairs="$(git worktree list --porcelain | awk ' | ||
| /^worktree / { wt = substr($0, 10) } | ||
| /^branch / { print wt "\\t" substr($0, 8); wt = "" } | ||
| ')" | ||
| while IFS=$'\\t' read -r wt branch; do | ||
| [ -z "${wt:-}" ] && continue | ||
| short_branch="${branch#refs/heads/}" | ||
| # Skip the main branch — `git pull` is the right tool for it, not rebase. | ||
| case "$short_branch" in main|master) continue ;; esac | ||
| # If the branch tip is already in origin/main, the work has merged and a | ||
| # rebase would either no-op or replay merged commits depending on history. | ||
| # Report and skip so the operator can prune the worktree at their leisure. | ||
| if git -C "$wt" merge-base --is-ancestor HEAD origin/main 2>/dev/null; then | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-blocking: |
||
| echo "MERGED $short_branch ($wt) — already in origin/main, no rebase needed" | ||
| continue | ||
| fi | ||
| if [ -n "$(git -C "$wt" status --porcelain)" ]; then | ||
| echo "SKIP $short_branch ($wt) — dirty working tree" | ||
| continue | ||
| fi | ||
| echo "Rebasing $short_branch ($wt) onto origin/main..." | ||
| if ! git -C "$wt" rebase origin/main; then | ||
| echo "FAIL $short_branch — rebase aborted (resolve conflicts manually)" | ||
| git -C "$wt" rebase --abort || true | ||
| status=1 | ||
| fi | ||
| done <<< "$pairs" | ||
| exit $status | ||
| """ | ||
|
|
||
| ################## | ||
| ##### BUILD ##### | ||
| ################## | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking style: this is the repo's first
"""(escape-processed) multilinerun, which forced the\\tdouble-escaping below. A'''literal multiline string would carry the script verbatim (\t,$'\t') with no escaping and less risk of a future edit mis-escaping.