git-pull
Skill3 starsChanged 21 days agoMITView on GitHub
Fast-forward a local branch from origin, defaulting to the current HEAD; an off-HEAD target updates the branch ref only, never its working tree. Use for "pull", "pull main", "pull feature/foo", or updating a branch with new origin commits. Refuses non-fast-forward and suggests git-merge on divergence; never rebases, stashes, or forces.
- Reads credentials
2 other projects use a version of this.
Adopted by
Most recently taken up by
- aktsmm/Agent-Skillstheir own version, first seen Nov 1, 2026
- cognis-digital/skillsmiththeir own version, first seen Oct 11, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- aktsmm/Agent-Skills★ 26same name
- cognis-digital/skillsmith★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository15 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- git-branch-createSkill
- git-branch-deleteSkill
- git-commitSkill
- git-fetchSkill
- git-mergeSkill
- git-pushSkill
- git-tagSkill
- hf-downloadSkill
- hf-setupSkill
- hf-uploadSkill
- py-env-setupSkill
- repo-docsSkill
- repo-initSkill
The file
We split this skill into the rules it gives an agent
12 rules. About 0 are common, 5 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 21
Run every command in this skill in a POSIX shell.
- Distinctive: line 26
If no name was given AND HEAD is detached, STOP and ask with a choice question which local branch to pull.
- Very specific: line 40
Unborn current branch: every commit on origin/<branch> is incoming and nothing is local-only.
- Very specific: line 98
NEVER use --force, --rebase, a + refspec that writes a local branch (+<branch>:<branch>), or any flag that rewrites history.
- Very specific: line 99
NEVER auto-resolve a non-fast-forward by rebasing, merging another branch in, or stashing.
- Distinctive: line 100
NEVER act on a branch name, user-supplied or current, whose case variant the step-1 exact name check found, and NEVER put a name that fails …
- Very specific: line 101
NEVER drop --no-overwrite-ignore from the step-5 fast-forward or skip the step-4 unborn-branch check, and never delete or move a file that …
- Very specific: line 102
NEVER touch the working tree of a branch that is not the current HEAD.
- Distinctive: line 103
NEVER skip the step 5 confirmation.
- Very specific: line 104
NEVER draft a commit message here, and NEVER write one to a file (no tmp/commit_msg.txt, no .git/COMMIT_EDITMSG pre-population, no scratch …
- Very specific: line 105
NEVER allow an AI tool, model, agent, or vendor co-author trailer into any merge commit produced by the git-merge run this skill suggests.
- Distinctive: line 106
If the pull fails for any reason, report the failure verbatim.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Goal
Bring a local branch up to date with origin/<branch> via fast-forward only. When the requested branch is the current HEAD the pull updates the working tree; otherwise the skill updates the local branch ref without checking it out.
When NOT to use
- Local and remote have diverged: this skill STOPS and suggests
git-mergewithorigin/<branch>as the source. - The user wants local commits published:
git-push. - The user wants remote state inspected without integrating anything:
git-fetch.
Procedure
Terms such as choice question, independent reads, invoke, and suggest follow AGENTS.md (Skill authoring); in a non-interactive session every gate ends this skill.
Run every command in this skill in a POSIX shell; the redirections used across this skill family are POSIX syntax and break under PowerShell.
- Resolve target branch.
- A branch named by the user in the current turn wins ("pull main", "pull feature/foo").
- Else default to the current branch:
git branch --show-current. Empty output means detached; an unborn zero-commit branch prints its name normally. Unlikegit symbolic-ref --short HEAD, it never prints a disambiguatedheads/<branch>when a tag shares the branch name. - If no name was given AND HEAD is detached, STOP and ask with a choice question which local branch to pull. Do not guess.
- Name format check, first, for a user-supplied
<branch>: require[ "$(git check-ref-format --branch "<branch>" 2>/dev/null)" = "<branch>" ](equality also rejects@{-1}, which the command expands) and that the name contains none of*,?,[. On failure, STOP:<branch>is not a valid branch name. Step 2 puts the name into a fetch refspec, wherefeature/*becomes a glob that force-updates every matchingorigin/*tracking ref. - Exact name check, before any other step, for
<branch>, including the current branch (skip only when<branch>is the current branch andgit rev-parse --verify --quiet HEADprints nothing, as on an unborn branch): require[ "$(git for-each-ref --format='%(refname)' "refs/heads/<branch>")" = "refs/heads/<branch>" ]. On failure, list the names that match ignoring case: local branches (git for-each-ref --format='%(refname:lstrip=2)' refs/heads/ | grep -ixF -- '<branch>') and the current branch, which may be unborn. Any match: STOP, name the matches, and ask for the exact name (for the current branch, suggestgit switch <exact-name>); a case variant resolves to another branch's ref on a case-insensitive filesystem (Windows, default macOS). No match:<branch>does not exist locally in any case; continue to step 2, whose missing-branch route applies.
Gather state for the target branch. Local reads name the branch as
refs/heads/<branch>: a tag sharing the short name would otherwise win, andgit logthen silently lists the tag's history. First batch. Run these independent reads:git status --short(working-tree state).git rev-parse --verify --quiet refs/heads/<branch>(local branch exists). No output means either an unborn branch (<branch>is the step-1 current branch and has zero commits) or a branch that does not exist locally.git fetch --no-tags origin +refs/heads/<branch>:refs/remotes/origin/<branch>(refresh the remote ref). The explicit refspec writesorigin/<branch>even in a--single-branchor shallow clone whose configured fetch refspec does not cover<branch>; its+force-updates only that remote-tracking ref, as the default refspec does, and--no-tagsstops the tag auto-follow an explicit refspec would otherwise trigger. Route a non-zero exit before proceeding:couldn't find remote ref(exit 128):<branch>is absent on origin, so there is nothing to pull. When the local probe found it, it was never pushed: say so, suggestgit-pushto publish it, and STOP. When the probe also missed, the name exists on neither side: say so and STOP.'origin' does not appear to be a git repository: the repo has no origin remote. Suggestgit remote add origin <url>(user-run) and STOP; both transports work, so recommend whichever the machine is set up for (a configured credential helper favors HTTPS, a working ssh auth favors SSH; dual probe pergit-pushstep 2).- Anything else (network, auth, proxy): surface stderr verbatim and STOP.
Route the local-branch probe before any range read, since a range read against a missing ref exits 128 with empty output that would look like "up to date":
- Missing locally, not the current branch (only reached when the step-1 exact name check found no case variant): say
<branch>has no local branch, rendergit branch --track <branch> origin/<branch>for the user to run themselves, and STOP.git-branch-createdoes not fit: it only creates new<type>/...names and refusesmain,develop, andsupport/*. The created branch already sits atorigin/<branch>with tracking set, so a re-run of this skill reports it up to date. - Unborn current branch: every commit on
origin/<branch>is incoming and nothing is local-only. Read the incoming list withgit log origin/<branch> --oneline, capped at 20 lines with an overflow count, and go to step 4 (step 3 does not apply).
Otherwise, after the fetch completes, run these independent reads:
git log refs/heads/<branch>..origin/<branch> --oneline(incoming commits).git log origin/<branch>..refs/heads/<branch> --oneline(local-only commits).
A non-zero exit from either read is an error, never an empty list: surface it verbatim and stop.
- Classify and refuse on no-op or non-fast-forward.
- Both lists empty: already up to date with
origin/<branch>. STOP and say so. - Only local-only non-empty: local is ahead, remote has nothing new. STOP; suggest
git-pushif they want to publish. - Both lists non-empty (divergence): integration would need a non-fast-forward merge. STOP, show both lists, and suggest
git-mergewith source=origin/<branch>, target=<branch>; its step 2 owns any checkout behind its own gate. This skill runs no checkout and never produces the merge commit itself. - Only incoming non-empty: fast-forward is possible; proceed.
- Both lists empty: already up to date with
- Handle dirty tree.
- Current HEAD equals the target AND
git status --shortnon-empty: warn that local edits to files touched by the incoming commits will block the fast-forward, and suggestgit-commitfirst or abort. Do NOT stash. - Current HEAD differs from the target: the working tree is untouched; mention this in the plan output and proceed.
- Unborn current branch:
--no-overwrite-ignoredoes not protect a merge into an unborn branch, so list the incoming paths that already exist on disk, plus any parent directory of one that exists as a file or symlink (see Rationale). Any output: STOP, list them, and ask the user to move or back them up; never delete them.top=$(git rev-parse --show-toplevel) && git ls-tree -r -z --full-tree --name-only refs/remotes/origin/<branch> | tr '\0' '\n' | while IFS= read -r p; do q=$p while :; do if [ -L "$top/$q" ] || { [ -e "$top/$q" ] && { [ "$q" = "$p" ] || [ ! -d "$top/$q" ]; }; }; then echo "file in the way: $q"; break fi case $q in */*) q=${q%/*} ;; *) break ;; esac done done | sort -u
- Current HEAD equals the target AND
- Show the plan and confirm. Display the commits about to land (the step-2 incoming list) and the exact command, then ask with a choice question (pull / abort). A "pull" / "yes pull" / "go ahead" typed in the current turn counts as confirmation; ambiguous replies do not.
- Current HEAD == target:
git merge --ff-only --no-overwrite-ignore refs/remotes/origin/<branch>(step 2 already fetched). This also covers the unborn current branch, where it creates the branch atorigin/<branch>.--no-overwrite-ignoremakes the merge fail instead of silently replacing an ignored local file (such as.env) that the incoming commits track;git status --shortnever shows ignored files. - Current HEAD != target:
git fetch . origin/<branch>:refs/heads/<branch>(local-only refspec; step 2 already refreshedorigin/<branch>, so no second network round-trip, the full destination ref cannot be mistaken for a same-name tag, and without a leading+the refspec stays fast-forward-only).
- Current HEAD == target:
- Run the pull. Execute the command exactly as displayed. Capture output verbatim.
- Handle failures. Do NOT retry blindly.
- Non-fast-forward rejection (a race between step 2 and step 6): re-fetch, surface the new divergence per step 3, stop, and suggest
git-merge. - "Your local changes would be overwritten": surface verbatim, suggest
git-commitfirst, stop. Do NOT auto-stash. - "untracked working tree files would be overwritten": surface verbatim and stop. The listed files, often ignored ones such as
.env, would be replaced by tracked versions; the user moves or backs them up first. Never delete them or drop--no-overwrite-ignore. - Network or auth: surface verbatim and stop.
- Non-fast-forward rejection (a race between step 2 and step 6): re-fetch, surface the new divergence per step 3, stop, and suggest
- Report success. Show:
- The pulled range (
<old-sha>..<new-sha>), or the new tip alone for an unborn branch. - The target branch name, and whether the working tree was updated (current-HEAD case) or only the branch ref (off-HEAD case).
git log --oneline -5 refs/heads/<branch>so the user can confirm the new tip.
- The pulled range (
Rationale
- Fast-forward only, so the skill can never invent history. Any merge commit the user needs is produced by
git-merge, which carries the.gitmessagedrafting flow and its own confirmation gate. - Exact branch names. On a case-insensitive filesystem,
refs/heads/Mainresolves to the loose ref file ofmain, sopull Mainwould read and write another branch under a name the user did not mean.for-each-refreports only real ref names; the equality test is needed because it also matches every branch under arefs/heads/<branch>/hierarchy. The current branch is checked too: aftergit checkout Mainwith onlymainpresent, HEAD isrefs/heads/Mainandgit branch --show-currentprintsMain, so the fast-forward would movemainunder the wrong name. - Parent paths in the unborn check. An ignored local file
dd, where origin addsdd/inner, sits at no incoming path itself, yet the fast-forward silently replaces it with a directory. The step-4 loop therefore walks up each incoming path and reports the first ancestor that exists as a non-directory or symlink. - Off-HEAD targets use
git fetch . origin/<branch>:refs/heads/<branch>instead of a checkout, so a branch the user is not standing on can be advanced without disturbing the working tree they are actually using.
Hard rules
- NEVER use
--force,--rebase, a+refspec that writes a local branch (+<branch>:<branch>), or any flag that rewrites history. The skill is fast-forward only; the step-2+refs/heads/<branch>:refs/remotes/origin/<branch>updates only the remote-tracking ref. - NEVER auto-resolve a non-fast-forward by rebasing, merging another branch in, or stashing. Divergence means STOP and suggest
git-merge. - NEVER act on a branch name, user-supplied or current, whose case variant the step-1 exact name check found, and NEVER put a name that fails the step-1 format check into a refspec.
- NEVER drop
--no-overwrite-ignorefrom the step-5 fast-forward or skip the step-4 unborn-branch check, and never delete or move a file that blocks either; ignored files are user data. - NEVER touch the working tree of a branch that is not the current HEAD. Use
git fetch . origin/<branch>:refs/heads/<branch>for off-HEAD targets; nevergit checkoutto switch first. - NEVER skip the step 5 confirmation. Confirming the incoming commits is the safety net.
- NEVER draft a commit message here, and NEVER write one to a file (no
tmp/commit_msg.txt, no.git/COMMIT_EDITMSGpre-population, no scratch file). When a merge commit is required, suggestgit-merge, which keeps its draft inline in chat only. - NEVER allow an AI tool, model, agent, or vendor co-author trailer into any merge commit produced by the
git-mergerun this skill suggests. That message MUST follow.gitmessage, stay in concise bullet form, and stay human-authored. - If the pull fails for any reason, report the failure verbatim. Let the user diagnose.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

