On this pageOverview
Git and review

The Changes panel

Review what changed, stage files, hunks or lines, commit and push, discard, stash, rebase, and read the branch's history from the right panel.

The Changes panel is the right panel’s source control view for the branch or worktree you have selected. Open it from the branch icon in the right panel’s strip. Its tab shows how many files changed whenever another panel is in front.

Try it
Mserver.tssrcWORKING TREE
@@ -8,4 +8,4 @@
88const Query = z.object({
9- q: z.string().min(1),
9+ q: z.string().trim().min(1),
1010 limit: z.coerce.number().max(50),
1111});
@@ -13,5 +13,8 @@
1313app.get("/search", async (req) => {
1414 const { q, limit } = Query.parse(req.query);
1515 const hits = rank(index, q);
16- return { hits: hits.slice(0, limit) };
16+ return {
17+ total: hits.length,
18+ hits: hits.slice(0, limit),
19+ };
1720});
Richard's uncommitted work on hooli-search. Stage a file or a single hunk, write a message or let AI Draft write one, and commit.

The header

The first row names the branch, with Refresh (which also fetches) and More Actions (...). The second row says where the branch stands:

  • The size of your uncommitted work, across every changed file.
  • The sync pill: an up arrow with the commits to push and a down arrow with the commits to pull, such as up 2, down 1. Click it to push. It reads Unpushed before the first push (the first push sets the upstream), Pushing while it runs, and Deleted once the remote branch is gone. When the upstream was force-pushed over your commits it shows the count to pull and its click offers The upstream was force-pushed. Reset to it. It reads Diverged when both your branch and origin/<branch> have commits the other lacks. Its tooltip gives both counts and both likely causes: somebody else pushed, so use Pull (Rebase); or you rewrote history here (a rebase or an amend), so use Force Push. When the reflog shows the rewrite happened here, it adds This looks like a rewrite here. Clicking it opens More Actions instead of pushing. Diverged is measured against origin/<branch>, where a push goes, so a branch that tracks origin/main is not called diverged just because main moved.
  • Open a pull request, or Reopen the pull request for a closed one. See Pull requests and issues.
  • A plug to add an account for the repository’s host, or a person to pick which of your accounts the repository uses, when that is needed.

Inside a Topic, a strip of member chips above the header picks which repository the panel shows. Everything below follows it. Each chip carries the number of changed files in its repository, so you can see which members have work without clicking through them. A clean member shows no number.

A reference member of a Topic is read only: the panel shows its changes and can fetch and pull (fast-forward only), but never stages, commits, discards or pushes.

The file list

Changed files are grouped:

  • Conflicts, during a merge, rebase, cherry-pick or revert. See Merge conflicts.
  • Staged Changes: what the next commit will hold.
  • Changes: everything else, including new files git has never seen.

Each row shows the file’s icon, name, folder and a status letter: M modified, A added, D deleted, R renamed (with the old name), ? untracked. A new folder shows as the files inside it, not as one row.

  • Click a row to open its diff in a preview tab, which the next click replaces. Double-click to keep the tab. See Diffs.

  • Hover a row for its buttons:

    Button What it does
    Open the file itself Opens the file in the editor
    Copy diff Copies the file’s diff
    Discard (unstaged only) Throws away the unstaged changes to this file. For an untracked file it reads Delete, since the file was never committed
    Stage or Unstage Moves the whole file between the groups

To stage only part of a file, open its diff and stage a hunk or selected lines there.

With nothing changed the panel says No changes yet. Edit a file and it shows up here to stage, commit, and push.

The panel refreshes on its own when files change, and when HEAD, the index or a branch changes outside Tori, for example after a commit in a terminal.

Discard safely

Discarding asks first, and says what goes: Every unstaged change in this repo goes back to how it is staged. Anything already staged is kept.

Before discarding anything, Tori saves a snapshot of the whole folder, so a discard can be undone. Find it under Backstops in the Checkpoints tab and restore it.

Discarding, stashing and rebasing rewrite files across the worktree, so they check for agents first. If a session is in the middle of a turn in this worktree, the action is refused. If Tori cannot tell for sure, it asks Another session may be running here and lets you go ahead.

Commit

The commit box is hidden until you ask for it, so the panel stays a review surface by default.

  1. Open More Actions and tick Commit. The commit box appears under the header.
  2. Stage what you want in the commit.
  3. Type a message. Enter commits, Shift+Enter adds a line.
  4. Press Enter or click Commit.

The box shows how many files the commit will hold. Commit is never greyed out; clicking it with something missing says what: Write a commit message first., or Nothing staged to commit. The message is kept if the commit is refused, for example by a failing hook.

The arrow beside Commit offers:

  • Commit (Amend): amend the last commit instead. The message box fills with that commit’s message (what you had typed comes back if you stop amending), and the button reads Amend. If the commit looks like it is already pushed, Tori asks Amend a pushed commit? first; that check is only as fresh as your last fetch.
  • Commit & Push, or Amend & Push. The push goes through the same checks as Push (see Before a push). In a Topic each repository is pushed in turn, so each question comes on its own.
  • Stop amending.

AI Draft

AI Draft asks the session selected in the sidebar to write a commit message for the staged files. It puts Draft a commit message for the staged changes: and the file names into that session’s composer, for you to send. The agent’s reply is a suggestion in its chat; copy what you like into the message box.

Commit across a Topic

Inside a Topic, the box shows a chip for each repository with staged changes, and the button reads Commit in 3 repos. Click a chip to leave that repository out, or put it back. One message goes into each. They are committed one at a time, and if one fails the rest are left untouched.

More Actions

The ... menu acts on the repository on screen:

Item What it does
Stage All Changes, Unstage All Changes Everything at once
Discard All Changes… Discards every unstaged change, after a snapshot
Fetch Fetches from the remote
Pull Fetches and merges. Always merges, even if your git config says pull.rebase
Pull (Rebase) Fetches and rebases on top
Push Pushes, setting the upstream on the first push
Force Push Only on a diverged branch. Replaces origin/<branch> with your branch, after a confirm
Rebase A submenu, below
Stash All Changes Puts every change aside
Commit Shows or hides the commit box
Graph, Stashes, Checkpoints Shows or hides each history tab
Open Graph in Editor The full commit graph in a tab

Under Pull, Pull (Rebase) and Push, a line says what each will do to this branch right now, with the counts:

  • Pull: Fast-forward to origin/feat, 3 commits, or Merge origin/feat into this branch, 1 commit, adds a merge commit when both sides have moved. On a reference member, where pull only fast-forwards, it says the pull will refuse.
  • Pull (Rebase): Replay your 2 commits on top of origin/feat, after its 1 commit.
  • Push: 2 commits to origin/feat, or Publish feat to origin before the first push.

When the upstream was force-pushed over your commits, Pull reads Reset to Upstream instead.

Before a push

Push on a diverged branch does nothing. Its line reads Diverged: pull with rebase, or force push, because git would reject it anyway. Commit & Push still commits, and Push to origin and Git: Sync in the palette stop with the same message. Sync stops before it pulls, since a pull would merge the old history back in.

Any push of two or more commits is checked against origin/main (your base branch) first. If more than half of the commits are already there under other hashes, usually because a pull replayed main onto your branch, Push copies of base commits? asks first, for example 23 of 23 commits are already on main under other hashes, a pull replayed main onto this branch. You can choose Rebase onto origin/main, which drops the copies, Push anyway, or Cancel. Only the commits not already on origin/<branch> count.

The pull request form’s Push and open a pull request and Push only skip both checks for now: they push as they are, and a diverged branch is rejected by git instead.

Force Push asks Force push feat? and says how many commits on origin/<branch> it replaces and how many of yours go up. It is a force-with-lease on the exact commit that dialog was showing: if somebody pushed in the meantime, the push is rejected and nothing of theirs is lost. It goes through the same copy check.

A push or fetch that needs a password or passphrase asks in a Tori dialog, and the answer goes straight to git; Tori does not store it.

Rebase

  • Onto origin/main (your base branch): rebases onto the remote’s copy of the base.
  • Onto Branch…: pick any branch to rebase onto.
  • Interactive…: see below.
  • Autosquash Fixups: folds fixup! and squash! commits into the commits they name.

Interactive rebase

Interactive… opens Rebase N commits: every commit of the branch since its base, oldest first. For each, pick an action:

Action Does
Pick Keeps the commit
Reword Keeps it with a new message you type in the row
Squash Folds it into the commit above, keeping both messages
Fixup Folds it into the commit above, keeping only the one above
Drop Leaves it out

Reorder commits with Move up and Move down. Commits already pushed are tagged pushed, since rewriting them means a force push. The Rebase button explains when the plan cannot run: every commit dropped, a squash with nothing above it, or a reworded commit with no message.

A branch with merge commits cannot be rebased interactively, because the merges would be flattened; Tori says so instead of opening the dialog.

When an operation stops

A merge, rebase, cherry-pick or revert that stops shows a bar under the header: Rebase in progress (2 conflicts), with:

  • Continue: carries on. Greyed out until every conflict is resolved.
  • Skip: leaves out the commit it stopped on (rebase and cherry-pick).
  • Abort: goes back to before the operation.

See Merge conflicts.

Graph, Stashes and Checkpoints

Under the file list is a section with three tabs. Drag its top edge to resize it, and use the chevron to fold it down to its tab strip. Drag the tabs to reorder them, and hide any you do not use from More Actions. The size and state are remembered.

Graph

The branch’s commits as a lane, newest first, with the sync count above. A commit opens to the files it changed, and a file opens that commit’s diff in a tab. all branches shows every branch instead of this one, and the graph button opens the full graph in a tab.

Stashes

Every stash in the repository, with its branch and age on hover. The bar has an untracked checkbox, to also stash files git has never seen, and Stash all, which uses the first line of your commit message as the stash’s name when you have typed one.

Click a stash to see its files. Its buttons:

  • Open this stash as a commit: its full diff in a tab.
  • Apply: lays it back down and keeps it in the list.
  • Pop: lays it back down and removes it.
  • Drop: deletes it. This one cannot be undone from the timeline, because a stash is not part of the working tree and no snapshot holds it.

Nothing can be stashed while a merge has unresolved conflicts.

Checkpoints

Tori’s own snapshot of the tree at every prompt, so you can see and undo what each agent turn did. See Checkpoints.

Git commands in the palette

Everything here, and more, is in the command palette (Cmd+K) under Git:. A command that cannot run right now is shown greyed with the reason. In a Topic, each command names the repository it will act on.

Command What it does
Git: Fetch, Pull, Pull (Rebase) As in the menu
Git: Sync (pull, then push) Both, in that order. Stops on a diverged branch
Git: Stage All Changes, Unstage All Changes Everything at once
Git: Discard All Changes After a snapshot
Git: Commit (Signed Off) Commits with a Signed-off-by line
Git: Undo Last Commit Takes the last commit back, keeping its changes
Git: Stash Staged Stashes only what is staged
Git: Merge Branch… Merges a branch you pick into this one
Git: Rebase Branch…, Autosquash Fixups As in the Rebase menu
Git: Continue Merge or Rebase, Skip Commit (Rebase), Abort Merge or Rebase For an operation that stopped
Git: Create Branch…, Rename Branch…, Delete Branch… Branch housekeeping
Stage this file, Unstage this file, Commit staged changes, Push to origin For the file and branch in front of you