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.
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 againstorigin/<branch>, where a push goes, so a branch that tracksorigin/mainis 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.
- Open More Actions and tick Commit. The commit box appears under the header.
- Stage what you want in the commit.
- Type a message.
Entercommits,Shift+Enteradds a line. - Press
Enteror 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!andsquash!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 |