Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

fold

Fold source(s) into a target — a polymorphic command that amends files into commits, fixups commits together, moves commits between branches, or uncommits changes.

Usage

git loom fold <target>
git loom fold <source>... <target>
git loom fold -p [<files>...] <target>
git loom fold -p <commit1> <commit2>
git loom fold -p <commit> zz
git loom fold --create <commit>... <new-branch>

When only a target is given, currently staged files are folded into the target commit. When two or more arguments are provided, the last argument is the target and all preceding arguments are sources.

Options

OptionDescription
-p, --patchInteractively select hunks before folding. Three forms depending on argument types (see below).
-c, --createCreate a new branch and move the source commit(s) into it.

Type Dispatch

The action depends on the types of the arguments, detected automatically:

SourceTargetAction
(staged)CommitAmend staged: fold currently staged files into the commit
File(s)CommitAmend: stage files into the commit
zzCommitAmend all: stage all changed files into the commit
CommitCommitFixup: absorb source commit into target
CommitBranchMove: relocate commit(s) to the branch
CommitzzUncommit: remove commit, put changes in working directory
CommitFilezzUncommit file: remove one file from a commit to working directory
CommitFileCommitMove file: move one file’s changes between commits
CommitNew branch (-c)Create: make a new branch and move the commit(s) into it

CommitFile sources use the commit_sid:index format shown by git loom status -f (e.g. fa:0 for the first file in commit fa).

Actions

Fold staged files into a commit

When only a target is given, staged files are folded into the commit:

git add src/auth.rs
git loom fold ab
# Folds staged changes into commit ab

Only files in the git index are folded — unstaged changes to the same files are preserved. Errors with "Nothing to commit" if nothing is staged.

Amend files into a commit

git loom fold src/auth.rs ab
# Stages src/auth.rs and amends it into commit ab

Multiple files can be folded at once:

git loom fold src/main.rs src/lib.rs HEAD
# Amends both files into the HEAD commit

Use zz to fold all working tree changes at once (staged and unstaged):

git loom fold zz ab
# Stages all changed files and amends them into commit ab

If zz is mixed with individual file arguments, zz takes precedence and all changed files are folded.

Interactive hunk selection (-p)

With -p, an interactive TUI opens for hunk-level selection. There are three forms depending on the argument types.

Form 1 — pick working-tree hunks → fold into commit:

git loom fold -p ab
# Opens hunk picker for all working-tree changes
# Selected hunks are staged and folded into commit ab

Provide file arguments before the target to narrow the picker:

git loom fold -p src/auth.rs ab
# Opens hunk picker filtered to src/auth.rs

Form 2 — pick hunks from a commit → move into another commit:

git loom fold -p c2 c1
# Opens commit-diff picker for c2
# Selected hunks are removed from c2 and added to c1

The source (c2) must be newer than the target (c1). Binary and deleted files are not supported.

Form 3 — pick hunks from a commit → uncommit to working tree:

git loom fold -p ab zz
# Opens commit-diff picker for ab
# Selected hunks are removed from ab and appear as unstaged modifications

All -p forms error with "No hunks selected" if nothing is selected.

Fixup a commit into another

Absorbs the source commit’s changes into the target. The source disappears from history; the target keeps its message.

git loom fold c2 c1
# c2's changes are absorbed into c1, c2 disappears

The source commit must be newer than the target.

Move a commit to another branch

Removes the commit from its current branch and appends it to the target branch’s tip.

git loom fold d0 feature-b
# Commit d0 moves to feature-b, removed from its original branch

Several commits can go in one move. They are ordered oldest-first whatever order you list them in — ancestors before their descendants, and commits from unrelated branches by commit date — so they travel in a single rebase and land in history order.

git loom fold d0 d1 d2 feature-b
# d0, d1 and d2 all move to feature-b

A single commit can be resumed with git loom continue if it conflicts. A move of several rolls back instead, leaving history as it was.

A branch that ended at d0 (a stacked branch) stays behind: it ends at the commit before, or at the base if d0 was its only commit. It never follows the commit into feature-b. A branch left empty this way is named in the result:

git loom fold d0 feature-b
# ✓ Moved d0 to branch feature-b (now e1f2a3b)
#   › branch feature-x now empty, at the base

The target can be a branch stacked inside another one: the commit lands right after that branch’s tip, and the branch stacked on top is replayed over it.

git loom fold d0 feature-a
# feature-c is stacked on feature-a: d0 becomes feature-a's tip,
# feature-c's commits now build on d0

Create a new branch and move a commit into it

Use --create (-c) to create a new branch and move the commit in one step. Works whether the commit is a loose commit on the integration line or already on an existing branch.

git loom fold -c d0 new-feature
# Creates new-feature and moves commit d0 into it

You can list several commits to move them all into the new branch. They are ordered oldest-first so the new branch preserves their history order.

git loom fold -c d0 d1 d2 new-feature
# Creates new-feature and moves d0, d1, d2 into it

Like any move of several commits, -c is not resumable: a conflict rolls it back rather than pausing for git loom continue.

-c creates, so a name that is already taken is refused. Moving onto a branch that exists is a plain fold, and accepting the name here would let a typo drop your commits into another branch.

git loom fold -c d0 existing-branch
# ✗ Branch `existing-branch` already exists
#   Use `loom fold <commit>... existing-branch` to move commits onto it

Uncommit to the working directory

Removes a commit from history and places its changes as unstaged modifications.

git loom fold ab zz
# Removes commit ab, its changes appear as unstaged modifications

The changes are merged back into the working tree three-way, so a later commit that edited nearby lines does not break the apply (-p hunk selections are the exception — they carry no blob ids to merge through). It still fails when they overlap for real, or when you have uncommitted changes in one of the same files. Either way nothing is left half-done: history and your uncommitted changes both go back to where they were.

If ab was the only commit of a branch, the branch survives, empty, at the base it built on — ready for git loom commit -b <branch> once the change is reworked:

git loom fold ab zz
# ✓ Uncommitted ab to working directory
#   › branch feature-x now empty, at the base

Uncommit a single file

Removes one file’s changes from a commit, preserving the rest of the commit.

git loom fold ab:1 zz
# Removes the second file from commit ab to the working directory

Move a file between commits

Moves one file’s changes from one commit to another.

git loom fold c2:1 c1
# Moves the second file from c2 to c1

Arguments

Arguments can be:

  • File paths — files with changes in the working tree
  • Commit hashes — full or partial git hashes
  • Branch names — local branch names
  • Short IDs — compact IDs from git loom status
  • Git referencesHEAD, HEAD~2, etc.
  • zz — reserved token for the unstaged working directory

Conflicts

The following fold operations support conflict recovery (pause/resume):

  • Amend files into a non-HEAD commit
  • Fixup a commit into another
  • Move a commit to a branch
  • Uncommit a commit to the working directory (non-HEAD)

If a supported fold hits a conflict, the operation is paused:

git loom fold d0 feature-b
# ! Conflicts detected — resolve them with git, then run:
#   loom continue   to complete the fold
#   loom abort      to cancel and restore original state
git add <resolved-files> && git loom continue
# ✓ Moved `d0` to branch `feature-b` (now `e1f2a3b`)

The following fold operations do not support pause/resume and abort immediately on conflict:

  • All -p (patch mode) forms — any conflict causes an automatic abort and restores the original state
  • Uncommit a single file (CommitFile → zz)
  • Move a file between commits (CommitFile → Commit)
  • Create a new branch and move a commit (--create)

See continue and abort for details.

Prerequisites

  • Must be in a git repository with a working tree
  • For short ID arguments: must have upstream tracking configured
  • All operations are atomic and automatically preserve uncommitted changes