Skip to content

ff pull

Update the current branch from its base branch and its remote copy. Pull fetches first, incorporates remote work, and replays local commits when needed. It also updates the selected branch's local base branches, down to trunk. ff sync is an alias.

Usage

Usage: ff pull [OPTIONS] [branch]...

Examples

ff pull                         # Update this branch and its local bases
ff pull side                    # Select side instead
ff pull a b                     # Select two branches, with one fetch
ff pull --all                   # Select every local branch
ff pull -n                      # Preview local updates; still fetches
ff pull -n --no-fetch           # Preview using existing tracking refs
ff push                         # Send this branch after reviewing it

Options

Arguments:
  [branch]...
          Branches to update with their local bases; defaults to this branch

Options:
      --all
          Every local branch

  -n, --dry-run
          Preview local updates without applying them; still fetches

      --json
          Emit machine-readable JSON

      --fetch
          Fetch now on commands that support fetching, regardless of cadence

      --no-fetch
          Skip the fetch: read the tracking refs as they stand

      --session <name>
          Session name for this invocation

  -C, --cwd <dir>
          Run as if fufu had been started in <dir>

  -h, --help
          Print help (see a summary with '-h')

Which branches

With no names, pull selects the current branch. Names select one or more branches instead; --all selects every local branch. Unique local branch prefixes are accepted. Unknown or ambiguous names are refused before fetching.

Each selected branch brings its local base branches into the run, down to trunk. Their remote copies are incorporated first, so a teammate's change on main can reach your branch through local main, even when trunk is configured as origin/main.

Dependent branches above a selected branch are not themselves selected. They follow a replay beneath them, but their own remote copies are not incorporated unless you name them or use --all. A non-current branch that only fast-forwards moves its ref without cascading to dependents.

Remote and base updates

If a local branch has not changed since fufu last recorded seeing its remote copy, it follows that copy, including a force-push. Otherwise new remote work is incorporated and local commits replay above it. Remote commits recognized as old versions of local work are left for ff push to replace. An ahead branch is reported without sending anything.

Only branches tracking the fetched remote receive this remote update. With --no-fetch, or for a branch tracking another remote, only the current branch's remote copy is considered. The base update still runs without a remote: if the base moved, local commits replay onto it and dependent branches follow parent before child.

A deleted remote copy is reported while its local branch remains. With fufu.pruneGone enabled, eligible branches are pruned first using ff branch --prune's rules, including protection for unpublished commits and reassignment of dependents. Pruning is part of the same undoable operation. The setting defaults to false.

Conflicts and recovery

A conflicting replay holds that branch without landing its new tip or files. The run continues with other branches; dependents of the held branch stay put. Captures and hold metadata may still be written. Switch to the named branch and run ff resolve to continue. The exit is 3 if any branch holds.

Branches checked out in another worktree, already holding a rewrite, containing merges, or sharing no history with their base are skipped and named.

Local branch and working-copy changes form one operation, including cascades and pruning. One ff undo reverses them. Only the current branch has files written in this worktree; other selected branches move as refs and objects. Fetched objects, tracking refs, and tags are separate from these undoable changes. No remote branch update is sent.

Dry runs and network effects

--dry-run (-n) plans every selected branch and reports what would fast-forward, replay, hold, or be skipped. It moves no local branch, writes no worktree files, takes no pull capture, and records no hold or replay operation. The exit is 3 if a branch would hold.

Fetching still writes objects, remote-tracking refs, and tags, and prunes tracking refs for deleted remote branches. Add --no-fetch to use existing refs. Successful invocations can still run automatic trimming and update maintenance in either form.

Report and JSON

The current branch is reported first when selected, then other branches that changed, held, or were skipped. An idle run prints nothing to pull.

With --json, the other selected branches appear in branches, tagged Pulled, Elsewhere, or Held. A Pulled row has remote and base results. The top-level remote and base describe the current branch and read NotNamed when it was not selected. files and still_open describe the one working-copy write. In a dry run, undo is null and files is the projected count; dry_run describes the replay preview, not the absence of all writes.