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.
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:
- Fast-forward the parent to the feature's tip. The feature's commits become part of the parent with no merge commit (linear history).
- 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.
- Push the parent to its remote.
- Flag the feature
landedand 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:
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:
Preview exactly what will run:
Then land it:
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:
Or land and delete in one step with git city land --delete.
prune¶
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(onlylandsets 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.
Related¶
- 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.