Files
holocron/plugins/git/skills/git-remotes/references/pull.md
Defame1297 20e5627fd7 fix(git): correct three command claims the plugin got wrong, and give rebase an owner
Three statements were false against the git in use (2.39.5), each verified by
running it.

`git rebase --autosquash HEAD~N` without `-i` is a silent no-op: git prints
"Successfully rebased", the `fixup!` commit survives with the same SHA, and
rewrite-history.md presented that as the preferred flow with `-i` as an optional
review step. The agent reports the squash as done and the `fixup!` subject then
trips this repo's own commit-msg gate. `-i` is now the command, not the alternative.

"Fetch never modifies a local branch, so it is always safe to run" — new text on
this branch — is false: `git fetch origin main:probe` fast-forwarded the local
branch, and a `+` prefix force-updates it, losing commits. The claim is scoped to
the no-refspec form.

`git worktree add --orphan` does not exist before Git 2.42; on 2.39.5 it is
`error: unknown option 'orphan'`, exit 129. The same file gives a version floor for
`--recurse-submodules` three sections earlier. Floor added, with a fallback that
was tested before being documented.

git-workflow claimed "every request resolves to exactly one of these six" while
rebase, reset and stash were owned by no skill — `git reset` appeared nowhere in
the plugin, old tree or new — so "undo my last commit" routed nowhere. The claim is
gone, the router gains rows for all three, and the procedures now exist: plain
rebase with `--onto` and conflict handling, a reset mode table gated on `--hard`,
and stash save/pop/list/drop. `--hard` gets an always-loaded Gotcha, matching the
register the force-push refusal already sets.

Cherry-pick had three claimants pointing at git-history while git-commits owned the
flow, and the two copies were not equivalent — git-history's lacked the destination
check, the rtk prefix and `--abort`. Resolved to git-commits per #112; the weaker
duplicate is replaced by a hand-off.

git-commits' metadata.version was deleted rather than bumped in 14af50b, leaving two
house-contract documents citing a worked v0.1.2 to v0.1.3 transition against a file
declaring no version. Restored to 0.1.3.

Also: the divergent-pull explanation stated a `--ff-only` default that does not
exist (it is a hard error); `--remote` "requires" a configured branch where it uses
one; `git push origin --delete` moved to git-remotes, which owns the remote-side
gates; seven retired `git:<name>` source slugs; git-orchestrate quoted a
git-workflow sentence that no longer exists; git-submodules regains the indirect
trigger that made "add a dependency repo" routable; and commit atomicity is a common
gate rather than reachable only from the create flow.

Refs: #112, #113
2026-09-01 12:38:38 +00:00

2.4 KiB

topic, source_keys
topic source_keys
pull
git-scm-pull-docs
context7-git-htmldocs

Pulling

Default strategy: --ff-only. It fails on divergence, which forces a conscious choice instead of an accidental merge commit.

  • Fast-forward only: git pull --ff-only — the recommended default
  • Rebase: git pull --rebase replays your commits on top for linear history, but rewrites SHAs. Verify nothing being replayed has been pushed: rebasing published commits breaks everyone downstream.
  • Merge: git pull --no-rebase — three-way merge commit, preserves original commits, non-linear
  • Rebase preserving merges: git pull --rebase=merges keeps intentional local merge commits during the replay
  • Stage without committing: git pull --squash collapses incoming commits into staged changes; you write the message
  • Merge strategy: Git 2.34+ defaults to ort (recursive is now an alias for it). Strategy options such as -X ours, -X theirs, -X ignore-space-change pass through unchanged.
  • Submodules: --recurse-submodules only fetches submodules already checked out. Newly added ones are not initialized — use the git-submodules skill for those.

On divergence

A pull that diverges with no strategy configured fails, and that failure is the useful outcome. Report the divergence and the three ways out — --ff-only, --rebase, --no-rebase — and let the caller choose. Auto-merging a diverged branch buries a decision that belongs to the human.

Config precedence

--ff-only is not Git's default on an unset config, and never has been. Older versions silently merged on divergence; current ones refuse outright — verified on Git 2.39.5, a divergent pull with nothing configured prints the reconciliation hint and exits 128 with fatal: Need to specify how to reconcile divergent branches. The behaviour therefore still varies by installed version, and neither variant is the one you want. Set it explicitly.

Highest wins:

  1. Command-line flag (--ff-only / --rebase / --no-rebase)
  2. pull.rebase config (global or local)
  3. branch.<name>.rebase (branch-specific override)
  4. branch.autoSetupRebase (set automatically when the tracking branch was created)
git config pull.ff only                  # deterministic default across Git versions
git config --global pull.rebase true
git config branch.develop.rebase false   # develop always merges, regardless of the global default