Git Sync
Bring the local branch current with origin. Fast-forward when the branch is only behind; merge to integrate when local and remote have both moved. Never rebase, never force-push, never resolve conflicts automatically.
When to run
- The router (
blake-os:git-ops) sends a "get the latest" request - As the integrate step of a full backup, after
git-commit— a clean working tree is required (Step 3), which is why the router commits first - Directly, only on the exact request "git pull" or "git sync"
Workflow
Step 1: Verify repo and remote
git rev-parse --is-inside-work-tree >/dev/null 2>&1 && echo "in_repo: yes"
git remote get-url origin
git branch --show-current
If not a git repo, stop: "This directory is not a git repository."
If no origin remote, stop: "No remote configured." Do not invent one.
Step 2: Fetch and measure state
git fetch origin
git rev-list --left-right --count @{u}...HEAD # output: "<behind> <ahead>"
git status --porcelain # any output = dirty working tree
If git fetch fails (network, auth), report the error verbatim and stop. Do not pull.
The rev-list line prints two numbers: behind (commits the remote has that the local branch doesn't) and ahead (local commits the remote doesn't have). These two numbers drive the decision in Step 3 — not error-message text. (If @{u} errors because no upstream is set, the branch has never been pushed; there is nothing to sync — tell the user to git-push to publish it.)
Step 3: Act on the measured state
behind = 0 — already current. If ahead > 0, note there are unpushed commits (run git-push). Done.
behind > 0 and ahead = 0 — simple fast-forward:
git pull --ff-only
On success, report how many commits were pulled. If it fails because the working tree is dirty (local changes would be overwritten), stop — list the blocking files and tell the user to commit them with git-commit or set them aside, then sync again. Do not stash.
behind > 0 and ahead > 0 — diverged; both sides committed. Integrate with a merge:
The working tree must be clean first. If
git status --porcelainprinted anything, stop: "You have uncommitted changes — commit them withgit-commit, then sync to integrate." Do not stash, do not merge over a dirty tree.With a clean tree, merge:
git pull --no-rebase --no-edit--no-editaccepts the default merge-commit message so the command never stalls waiting on an editor.Clean merge: report the merge commit and how many remote commits were integrated. Local is now
ahead N / behind 0— tell the user to rungit-push.Conflict (the command exits non-zero, or
git statusshows unmergedUUpaths): abort immediately and hand off —git merge --abortThen stop: list the conflicted files and report "Automatic merge hit conflicts; reverted to the pre-merge state. These need to be resolved by hand." Never edit files to resolve a conflict.
Step 4: Confirm
git rev-list --left-right --count @{u}...HEAD
git status --short --branch
Report: branch, behind/ahead after sync, whether a merge commit was created, clean or dirty tree.
Guardrails
- Merge is the only integration method. Never
git rebase, nevergit reset --hard, never force-push. - Never auto-resolve conflicts —
git merge --abortand hand off to a human. - Never stash unless the user explicitly asks.
- Never create feature branches.
Order
Ordering across operations is owned by blake-os:git-ops.