4.7 KiB
name, version, description
| name | version | description |
|---|---|---|
| pulling-before-work | 1.0.0 | Pulls the current branch from origin once at session start and on explicit re-sync requests. Use when CLAUDE.md contains the trigger line "pull remote before work", or when the user says "sync", "resync", "pull", "обнови репо", "git pull please", or close variants asking to refresh from the remote. Runs `git pull --ff-only` — never auto-merges or rebases. Stays silent in non-git folders. Prints one informational line and exits when there is no origin remote, no upstream tracking, the working tree is dirty, or HEAD is detached. Does not stash, commit, or push. Activated by `project-bootstrap` v1.4.0+ via the canonical CLAUDE.md template. |
pulling-before-work
Pull from
originonce when work starts. Don't auto-merge. Don't trample dirty work-trees. Don't ask twice in the same session unless asked.
When this runs
At session start — once, when the skill is activated by the pull remote before work line in CLAUDE.md. The cycle below runs immediately.
On explicit re-sync — when the user says any of: sync, resync, pull, обнови репо, pull please, git pull, подтяни, pull from origin. Re-runs the full cycle. There is no per-session counter; the user is always allowed to ask.
Never before each commit, before each tool call, on every message, or in any other implicit cadence. Mode-3 ("start + on-demand") was the explicit design choice — see .wiki/concepts/pulling-before-work-design.md.
The pull cycle
Run these checks in order. Print at most one line of chat output per run.
1. Inside a git work-tree?
git rev-parse --is-inside-work-tree 2>/dev/null
If the command fails or prints anything other than true → exit silently, no chat output. This is the not-a-git-repo case; the skill must not be noisy in random folders.
2. Has an origin remote?
git remote get-url origin 2>/dev/null
If the command fails (no such remote) → print one line and exit:
no origin remote — skip pull
3. Is the working tree clean?
git status --porcelain
If the output is non-empty → print one line and exit:
working tree dirty — skipping pull. commit/stash, потом скажи "sync"
Never stash automatically. Stash-pop conflicts are exactly the friction this skill exists to remove.
4. Is HEAD attached?
git symbolic-ref -q HEAD
If the command fails (empty output, exit 1) → detached HEAD. Print:
detached HEAD — skip pull
5. Does the current branch have an upstream?
git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null
Capture the upstream name (e.g. origin/master). If the command fails → no upstream tracking. Print:
no upstream tracking for <branch> — skip pull
(Where <branch> is git rev-parse --abbrev-ref HEAD.)
6. Pull, fast-forward only
git pull --ff-only
(No args — uses the configured upstream captured above.)
Classify by exit code and stdout:
| Result | |
|---|---|
| Already up to date | ✅ already up to date with <upstream> |
| Fast-forward, N commits | ✅ pulled N commits from <upstream> |
| Non-fast-forward / diverged (exit non-zero with "diverged" or "non-fast-forward" in output) | ⚠️ diverged from <upstream> — resolve manually (git pull --rebase or merge); skill never auto-merges/rebases |
Out of scope
The skill never:
- commits, stashes, or pushes
- recurses into submodules
- pulls from non-
originremotes - pulls on detached HEAD
- runs auto-merge or auto-rebase
- runs more than once per session unless the user asks
Recovery hints
If the skill skipped because of a dirty tree:
# Windows / PowerShell
git status # see what's dirty
git add . ; git commit -m "wip"
# then ask the agent: "sync"
# Linux / macOS
git status
git add . && git commit -m "wip"
# then say "sync"
If the skill reported diverged:
# Option A: rebase your local commits on top of origin
git pull --rebase
# Option B: explicit merge (creates a merge commit)
git pull --no-ff
The skill stays out of these decisions on purpose — both options have valid use cases and the user owns the choice.
Why this exists
Stale local branches are a silent footgun: edits land on top of yesterday's origin, the divergence shows up at push time, and by then there's a chunk of work to rebase or merge on the wrong base. One pull at start covers the common case; an explicit re-sync trigger handles long sessions where someone pushed mid-flight.
Full design rationale (mode choice, dirty-tree skip vs stash, --ff-only vs auto-merge, the upstream-check) lives in .wiki/concepts/pulling-before-work-design.md.