Skip to content

land (merge) & prune

git city land finishes a feature: it fast-forwards the parent to the feature's tip, re-homes the feature's children onto that parent, and pushes the parent. Because the parent fast-forwards, your history stays perfectly linear — there is no merge commit and no rebase to redo. By default it keeps the feature branch (flagged landed) so you can keep working on it; prune sweeps landed branches away later, or land --delete removes it on the spot.

git city merge is an exact alias; use whichever verb reads better to you.

git city land [branch] [--delete] [--yes] [--dry-run]

With no branch, git-city lands the current branch. Land moves commits, so it refuses to run on a dirty working tree — commit or stash first. Plain land keeps the branch and is fully reversible, so it does not prompt; land --delete deletes the feature locally and on the remote, so it prints the plan and asks for confirmation (pass --yes / -y to skip it, required to run non-interactively).


Why it keeps the branch

Deleting the branch the instant you land is a footgun: think you're done, land, then spot a bug — and the branch you wanted to fix is gone. So land keeps it. If you find a problem afterwards, switch back, commit the fix, and land again. When you're genuinely finished, prune removes every branch you've landed in one go.

A kept branch sits at its parent's tip (ahead 0) carrying a landed flag, shown as a landed tag in info and tree. Commit to it again and it is ahead of the parent once more — no longer "merged" — so prune leaves it alone until you re-land.


What it does

For a feature whose parent is up to date, land performs these steps in order:

  1. Fast-forward the parent to the feature's tip. The feature's commits become part of the parent with no merge commit (linear history).
  2. Re-home the children. Any branches stacked on the feature are reparented onto the parent, so the rest of the stack stays intact. The commits do not move now — the next sync restacks each child onto the updated parent.
  3. Push the parent to its remote.
  4. Flag the feature landed and keep it — or, with --delete, delete it both locally and on the remote.
Argument / option Meaning
branch The feature to land. Defaults to the current branch.
--delete / -d Delete the feature (local + remote) instead of keeping it, as land did before.
--yes / -y Skip the confirmation prompt for --delete (and allow non-interactive use).
--dry-run Print the exact ordered git commands and execute nothing.

Note

The alias git city merge exists for muscle memory, but land never creates a merge commit. The parent simply fast-forwards over the feature's commits.


Must be synced first

Land refuses if the feature is behind its parent — that is, the parent has commits the feature does not. A fast-forward is only possible when the feature's tip already contains the parent's tip, so you must rebase first:

git city sync
git city land

After a clean sync the feature sits directly on top of its parent, the fast-forward is trivially possible, and land proceeds.

Tip

Run git city (the dashboard) or git city tree before landing. If the feature shows (behind) against its parent, sync before you land.

sync


Example

You have a feature add-login on main, fully synced:

main  (trunk)
└─ ● add-login  ↑2 ↓0

Preview exactly what will run:

git city land --dry-run

Then land it:

git city land

add-login's two commits are now on main, main is pushed, and add-login is kept — sitting at main's tip with a landed tag, ready for you to keep working on if you need to. If add-login had children, each one is now parented on main and will restack onto it on its next sync. When you're done, remove it (and any other landed branches) with:

git city prune

Or land and delete in one step with git city land --delete.


prune

git city prune [--yes] [--dry-run]

prune is the cleanup half of the keep-by-default land. It deletes every branch you have landed — locally and on the remote — and nothing else:

  • The branch must be flagged landed (only land sets it).
  • It must have no commits of its own ahead of its parent — its work is wholly merged. Commit to a landed branch again and it is ahead once more, so prune skips it until you re-land.
  • It must have no children, so pruning can never orphan a stacked branch.

Because it deletes branches, prune prints its plan and asks for confirmation (--yes / -y to skip, required non-interactively), refuses on a dirty working tree, and — like everything else — is reversible with git city undo. With nothing to remove it just prints no landed branches to prune.

git city prune --dry-run     # see exactly which branches would go
git city prune               # confirm, then delete the landed branches

Errors

All errors print as a clean git-city: <message> on stderr with exit code 1 — never a raw traceback.

Situation What happens
Working tree is dirty Refused. Commit or stash first.
Feature is behind its parent Refused. Run git city sync, then land again.
Target is a trunk, not a feature Refused. Only features can be landed.

Undo

Landed by mistake? With the default keep behavior the branch is still there — just git city undo to rewind the parent (and clear the landed flag), or simply keep working on the branch. undo reverses the last git-city command: it restores moved refs and, for land --delete, recreates the deleted feature branch and can even bring back a force-pushed or deleted remote branch git-city itself created. Undo is single-level (only the most recent command), refuses on a dirty working tree, and refuses to destroy commits that exist on no other branch.

undo and recovery


  • sync — rebase a feature onto its parent; required before landing.
  • prune — delete the branches you've landed once their work is in the parent.
  • delete — remove a branch without merging its commits into the parent.
  • undo and recovery — reverse a land (or any other command).
  • the mental model — trunks, features, parents, and stacks.