Files
holocron/plugins/git/skills/git-remotes/SKILL.md
Defame1297 0239b00944 feat(git-plugin): add complete git workflow automation suite
## Why
The git plugin only covered a partial slice of common git workflows.
This adds the remaining skill set (branches, commits, history, remotes,
submodules, workflow, worktrees) plus a git-orchestrate agent so the
plugin can handle end-to-end git automation instead of a handful of
commands.

## Implementation Notes
Each new skill was validated against its research docs and org
conventions after initial authoring, which surfaced hallucinated
version pins, factual errors, and completeness gaps that were
corrected in the same pass rather than left for follow-up.

## Impact
Bumps the git plugin to 1.3.0.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 18:46:02 +00:00

9.2 KiB

name, description, metadata
name description metadata
git-remotes Manage git remote repositories — add/remove/configure remotes, push/pull with safety checks, handle fetch patterns and tracking branch updates, support multi-remote workflows. Use when automating remote operations, pushing with force-push safety, fetching with pruning, pulling with divergence resolution, or managing multi-remote tracking. Include indirect triggers: any git operation that touches a remote, even if the user doesn't explicitly name the remote. Do not use when working with local git history, commits, branches, or staging — use git-history or git-branches instead.
category source_keys
git-workflow
git-scm-remote-docs
git-scm-fetch-docs
git-scm-push-docs
git-scm-pull-docs
context7-git-htmldocs

Gotchas

  • Never force-push main or master, under any circumstances — this is a hard refusal, not a confirm: true gate. If a force-push targets one of these branches, decline and explain why, regardless of how the request is confirmed.
  • Force-push to any other branch requires explicit confirmation — never execute git push --force or git push -f without user/agent approval. Always ask or require confirm: true flag first.
  • --force-with-lease alone is not safe — background processes (IDE plugins, cron jobs) that run git fetch silently defeat the protection. Always combine with --force-if-includes or use explicit SHA form --force-with-lease=<ref>:<sha>.
  • Prune doesn't touch tags by default — git fetch --prune leaves orphaned tags. Use git fetch --prune --prune-tags or configure fetch.pruneTags true globally.
  • Pull with rebase rewrites history — only safe for unpublished work. Rebasing already-pushed commits breaks everyone downstream. Check what's been pushed before rebasing.
  • git remote show requires network access — use -n flag for cached data if working offline. git remote -v lists URLs without network queries.
  • Pull behavior defaults shift between Git versions — older versions default to merge, newer versions to --ff-only. Always set pull.ff only explicitly for deterministic behavior.

Operations

Remote Management

Use these to configure which remotes you push to and pull from:

  • Add a remote: git remote add <name> <url> or git remote add -f <name> <url> to fetch immediately
  • Remove a remote: git remote remove <name> (deletes remote + all tracking refs + config)
  • Rename a remote: git remote rename <old> <new>
  • Inspect remotes: git remote -v (show URLs) or git remote show <name> (live tracking status, requires network)
  • Set-url separately for fetch vs. push: git remote set-url --push <name> <url> changes only where pushes go — but fetch and push URLs must still reference the same repository. For genuine fetch-from-A / push-to-B workflows, use two separate named remotes instead; --push cannot do this. Full set-url variants (regex-targeted replace, --add, --delete): references/remotes.md.
  • Remove a stale URL: git remote set-url --delete <name> <regex>
  • Inspect effective URLs: git remote get-url <name> (shows URL after insteadOf rewrites) or git remote get-url --push --all <name> (all push URLs)
  • Track only one branch: git remote add -t <branch> <name> <url> (repeatable), or suppress tag import entirely with git remote add --no-tags <name> <url>
  • Mirror a remote: git remote add --mirror=fetch <name> <url> mirrors all refs locally (bare repos only); --mirror=push makes every push behave like --mirror
  • Prune stale tracking refs without fetching: git remote prune <name> (add --dry-run to preview first)
  • Set the remote's default branch pointer: git remote set-head <name> -a (auto-detect, requires a prior fetch), git remote set-head <name> <branch> (explicit), or git remote set-head <name> -d (delete refs/remotes/<name>/HEAD)

Fetch Operations

Use these to update your tracking branches without touching your local branches:

  • Fetch from one remote: git fetch <remote> — fetches all branches
  • Fetch one branch only: git fetch <remote> <branch> — stores the result in FETCH_HEAD, not a tracking ref
  • Fetch from all remotes: git fetch --all with optional --prune to clean up stale tracking refs
  • Prune properly: Use git fetch --all --prune --prune-tags to clean both branches and tags
  • Configure auto-prune: Set git config --global fetch.prune true to auto-prune on every fetch across all remotes (or remote.<name>.prune to scope it to one remote)
  • Shallow clones: --depth=<n> to deepen or create a shallow clone, --unshallow to convert to full history, --update-shallow to allow the shallow boundary to move. Details and the default fetch refspec: references/remotes.md.

Fetch never modifies your local branches — it only updates remote-tracking branches (refs/remotes/origin/*).

Push Operations

Use these to send your commits upstream. Default: safe push to same-named branch on the remote.

  • Basic push: git push <remote> <branch> — pushes to same-named remote branch
  • Set upstream: git push -u <remote> <branch> — push and configure this branch to track the remote
  • Multi-remote push: git push origin develop and git push staging develop sequentially, or use git remote set-url --add <name> <url> to push to multiple remotes with one command
  • Force-push safety: Always use git push --force-with-lease --force-if-includes <remote> <branch> over bare --force. Require explicit confirmation first — and never for main/master (see Gotchas). --force-if-includes is a no-op without --force-with-lease. If background tools (IDE, cron) auto-fetch and could poison the lease check, use a dedicated push-only remote instead — see references/remotes.md.
  • Server-side enforcement: receive.denyDeletes, receive.denyDeleteCurrent, and receive.denyNonFastForwards are enforced on the remote regardless of local flags — a hardened server rejects the push even with --force.
  • Delete remote branch: git push <remote> --delete <branch> (not :<branch> syntax; clearer and cleaner)
  • Push everything: git push --all (all local branches) or git push --tags (all tags)
  • Push a single tag: git push origin <tag>
  • Delete remote branches with no local counterpart: git push --prune origin 'refs/heads/*:refs/heads/*'
  • Force only part of a multi-ref push: prefix the one refspec that needs it with +, e.g. git push origin +main develop forces main while safe-pushing develop

Refspec syntax is [+]<src>[:<dst>]:

Pattern Meaning
<branch> Push to same-named remote branch
<src>:<dst> Push <src> local ref to <dst> remote ref
+<src>:<dst> Force this refspec (non-fast-forward allowed)
:<branch> Delete remote <branch>
refs/heads/*:refs/heads/* Glob: push all matching branches
^refs/heads/dev-* Negative: exclude matching refs
tag <name> Sugar for refs/tags/<name>:refs/tags/<name>

Pull Operations

Use these to fetch and integrate remote changes. Default strategy: --ff-only (fail if diverged, forcing a conscious choice).

  • Pull with fast-forward only: git pull --ff-only (recommended default — fails if you've diverged, forcing a rebase/merge decision)
  • Pull with rebase: git pull --rebase (replays your unpublished commits on top; linear history, but rewrites SHAs — only safe for unpublished work)
  • Pull with merge: git pull --no-rebase (three-way merge commit; preserves original commits, non-linear)
  • Pull with rebase, preserving merges: git pull --rebase=merges (like --rebase, but keeps intentional local merge commits during replay)
  • Pull without integrating: git pull --squash collapses incoming commits into staged changes without committing — you write the commit message
  • Set pull strategy globally: git config pull.ff only (or pull.rebase true; respects branch-specific overrides via branch.<name>.rebase). Full precedence order (CLI flag > pull.rebase > branch.<name>.rebase > branch.autoSetupRebase): references/remotes.md.
  • Check before rebasing: Always verify your commits haven't been pushed before using --rebase. Rebasing published commits breaks everyone downstream.
  • Merge strategy default: Git 2.34+ defaults to the ort merge strategy (recursive is now just an alias for it). Strategy options like -X ours, -X theirs, -X ignore-space-change still pass through unchanged.
  • Submodules on pull: --recurse-submodules only fetches submodules that are already checked out — newly added submodules are not initialized automatically. Use the git-submodules skill to initialize new ones.

If pull diverges and you haven't set a strategy, the operation fails — this is good, forces a conscious choice. Never auto-merge diverged branches without asking.

Return Format (for agents)

Return structured output:

{
  "success": true,
  "operation": "push",
  "remote": "origin",
  "branch": "main",
  "output": "...",
  "warnings": ["force-with-lease not confirmed"],
  "recommendations": ["set pull.ff=only globally"]
}

On failure, include error field with root cause and recovery suggestion.