65 lines
3.0 KiB
Markdown
65 lines
3.0 KiB
Markdown
---
|
|
name: deploy-target-dirty-blob-audit
|
|
description: "When scripts/deploy.sh on serverAppConfigs aborts with \"Your local changes to the following files would be overwritten by merge\", prove whether the target's dirty file is already-merged content before restoring it, then deploy from the main checkout."
|
|
---
|
|
|
|
# Deploy target dirty-file audit
|
|
|
|
`deploy.sh <host>` pushes the local branch, then ssh-pulls on the target. The pull is
|
|
`git pull --ff-only origin main` on the TARGET checkout, so any uncommitted edit there
|
|
aborts the whole deploy with:
|
|
|
|
```
|
|
error: Your local changes to the following files would be overwritten by merge:
|
|
scripts/run-qwen38-bf16.sh
|
|
Aborting
|
|
```
|
|
|
|
Nothing is dispatched, so the service is untouched (no wasted outage) — but the deploy
|
|
cannot proceed until that path is reconciled. This happens when an agent edited the file
|
|
directly on the host (the repo's "never edit on the remote" law) and committed the same
|
|
bytes later from a worktree, leaving the host's HEAD behind its own working tree.
|
|
|
|
## 1. Classify before touching anything
|
|
|
|
```bash
|
|
ssh <host> 'cd <checkout> && git status --porcelain' # every dirty path
|
|
ssh <host> 'cd <checkout> && git hash-object <file>
|
|
&& git rev-parse <target_sha>:<file>' # compare blobs
|
|
```
|
|
|
|
- Hash equal to the blob the pull wants (`origin/main:<file>`, or a commit main contains)
|
|
→ the edit is already merged; restoring is lossless, no trash copy needed.
|
|
- Hash matches neither HEAD nor the incoming blob → real unmerged content: `cp` it to
|
|
`.AGENTTRASH/YYYYMMDD-topic/` first, then decide.
|
|
- `D` entries under `.AGENTTRASH/` (deletions, not modifications) do not block the pull
|
|
unless those paths changed between HEAD and main. Leave them — only Frank purges trash.
|
|
|
|
## 2. Restore, then deploy from the MAIN checkout
|
|
|
|
```bash
|
|
ssh <host> 'cd <checkout> && git checkout -- <file>'
|
|
cd ~/Projects/serverAppConfig && ./scripts/deploy.sh <host> --service <svc>
|
|
```
|
|
|
|
`deploy.sh` refuses with `FAIL: deploy.sh must run from the main branch.` when run from a
|
|
feature worktree — use the host's `~/Projects/serverAppConfig` main checkout, and pull it
|
|
`--ff-only` first so `[1/2] Pushing main to origin` reports `Everything up-to-date`.
|
|
A missing server-side path (`/home/dank/models`) plus an `rm -f` in the chain means the
|
|
`.rad` was already retired; confirm before relaunching anything that needs it.
|
|
|
|
## 3. Long deploys never fit an async bash slot
|
|
|
|
An LLM-service deploy waits up to 20 min for model load plus the Playwright gate, but an
|
|
async `bash` call is killed at 600 s. Launch it as a named service instead, then watch the
|
|
pid with a deadline-free watcher:
|
|
|
|
```bash
|
|
bash command="cd ~/Projects/serverAppConfig && ./scripts/deploy.sh <host> --service <svc>" \
|
|
name=deploy-<host> ready.log="Deployment plan"
|
|
# then: while kill -0 <pid> 2>/dev/null; do sleep 20; done (timeout 0, async)
|
|
```
|
|
|
|
`ready.log="Deployment plan"` matches the plan banner, so readiness reports the deploy
|
|
started rather than finished; the real result arrives when the watcher completes.
|