Project Git client
A full git GUI for a project's main checkout: commit graph with branches, tags, stashes and worktrees, pull, push, line staging, compare, blame, history rewrites, undo and conflict resolution.
The project view's Git tab is a full git GUI for your repository's main checkout — a commit graph with branches, tags, stashes and your sessions' work in progress, plus pull, push, staging down to single lines, compare, file history and blame, editing and reordering commits, undo, context-menu branch surgery, and in-app conflict resolution.
This is the project-level counterpart to the session's Git tab: that one manages a single session's worktree branch, while this one manages the repository itself. Throughout this page ⌘ is Cmd on macOS and Ctrl on Windows and Linux.
Open the project view
Click a project row in the left sidebar. This opens the project view and expands the project's sessions — it never collapses them. To collapse or expand a project without opening it, click the small chevron on the row instead; the two are separate targets, so the chevron never opens the view.
The header shows the project's name and repository path, a New session button, and an × to close the view. Below it sit three tabs:
| ⌘1 | Switch to the Dashboard tab |
| ⌘2 | Switch to the Git tab |
| ⌘3 | Switch to the Terminal tab |
These share their default combos with the session tab shortcuts — a session and a project are never in view at the same time, so they don't conflict, and each is rebindable on its own. Plexus remembers which tab you left open per project.
The Dashboard tab
The Dashboard tab is the global dashboard's session table scoped to this one project: every unarchived session with its live activity dot, branch, and PR badge, per-project summary counts in the header, the same sort modes, and a New session button. Click a row to jump to that session. See Dashboard.
The Git tab
The commit graph takes the whole tab. A toolbar with the branch switcher, sync actions and Undo / Redo runs across the top, and a narrow rail down the left edge counts your Local branches, Remote branches, Worktrees, Stashes and Tags — plus Pull requests when the repository is on GitHub or Bitbucket — click any of them to open the References panel at that section. Everything else slides in over the graph and back out again: click a commit and its details open as a layer on the right, click one of its files and the diff takes the graph's place beside it — see Commits and diffs open as layers. The graph stays where it was underneath, so closing a layer puts you back exactly where you were in the history.
Everything operates on the project's primary checkout — the folder you registered as the project — never on a session's worktree. Plexus keeps the tab current on its own: after its own operations, whenever you return to the window, and — while the tab is open — by checking every few seconds for git activity from your sessions or an outside terminal. New commits from your remotes arrive on their own too, through automatic fetching. The toolbar's refresh button forces a fetch and reload any time.
The commit graph
The graph draws the repository's full history as a lane graph, GitKraken-style: colored lanes trace each branch line — running unbroken through the merges that join them — and a line that joins or leaves another runs straight down its own lane and turns once, with a small rounded corner, in the row of the commit it meets. Each commit is the author's avatar ringed in its lane's color; a merge commit is a small hollow ring with a dot in the middle. The lane colors are all equally bright and deliberately avoid green and amber, so a lane never reads as a session's Working or Needs you color. The commit's subject fills the row, followed by the first lines of its description in a muted color, with a compact relative age (2h, 3d) on the right edge. Commits are listed newest first by date, so a branch you worked on this week sits near the top even when it forked from a much older line, and a long-lived branch that keeps merging another one stays a couple of lanes wide instead of spreading across the screen. The graph is virtualized and extends itself as you scroll — deep histories load in pages automatically, with no Load more button to press.
Hovering a row tints it in its lane's color from the commit outward, and a row that carries a branch or tag keeps a faint wash of its lane color. A thin line with a small label — Today, Yesterday, This week, A week ago, and so on up to 6+ years ago — marks where each stretch of history begins. The selected row is marked by one highlight that glides to the row you click, and jumps straight there when you move it from the keyboard.
Branch and tag labels sit in a fixed column on the graph's left edge, each tinted in its branch's lane color and tied to its commit by a connector line in the same color, so you can tell at a glance which line a name belongs to. A branch gets one label wherever it lives, with presence icons telling you where: a computer icon when the branch exists locally, a cloud icon when it exists on a remote, and both together when local and remote point at the same commit — hover the label for the full remote-qualified names. A branch that exists only on a remote shows the bare branch name with just the cloud icon, so a glance still tells you whether a tip is only on your machine, only on the remote, or both. The checked-out branch's label is filled solid in its lane color with a check mark, and tags keep a plain outline and their tag icon. Right-click a label and you get that branch's or tag's own context menu — the same actions as its row in the References panel; right-clicking anywhere else on the row still gives you the commit menu. A row with several refs shows the first label and folds the rest into a +N badge — hover it, click it, or focus it and press Enter for a small panel listing the folded refs, each with the same right-click menu. Click a folded branch to check it out; clicking a folded tag jumps the graph to its commit instead, because checking a tag out detaches HEAD and that stays a deliberate menu action. Double-click a branch label to check the branch out — a remote label with no local branch yet creates a local tracking branch first; a remote label whose local branch already exists switches to that local branch and fast-forwards it to the remote. If your local branch has commits the remote doesn't, Plexus asks what you want instead of guessing — see Checking out a remote branch. Either way it matches checking the branch out from the References panel. Double-click a commit row to open its details — it never checks the commit out.
Branch labels can also be dragged onto one another: drop one branch's label on another's and a menu offers the actions that fit that pair. A tag label can be dragged onto a local branch, which offers Reset <branch> to <tag>… or Create branch from <tag>…; nothing can be dropped onto a tag, and a drop with nothing to offer simply does nothing.
- Fast-forward the dragged branch to the target — offered when the dragged branch is local; it refuses cleanly if the two have diverged.
- Push the dragged branch to the target's remote branch — offered when the dragged branch is local and the target exists on a remote; it pushes your commits onto that remote branch even though the names differ. The push is never forced — it refuses if the remote branch has commits the dragged branch doesn't.
- Merge the dragged branch into the target, or rebase the dragged branch onto the target — offered for any two different branches, and always in the direction you dragged (dropping
developonacceptoffers Merge develop into accept). Because git can only merge or rebase the checked-out branch, Plexus first checks out the receiving branch (for a merge) or the moving branch (for a rebase) when it isn't already current — so after Merge develop into accept you end up onaccept. Both use the same confirm dialogs as the context menus: merge offers--no-ff, and conflicts flip the tab into conflict resolution as usual. - Reset the current branch to the target's tip (Soft / Mixed / Hard) — offered only when you drag the checked-out branch itself; a hard reset keeps its typed confirmation.
- Start a pull request from the dragged branch's remote counterpart to the target's — offered when both branches exist on the same remote. A small dialog asks for a title (required) and an optional description, then Plexus creates the pull request on your provider — GitHub today — using the same authentication as the session-level Pull requests flow, and the success toast links to the new PR. Unlike the session flow, there's no AI-drafted description here.
Operations that change the working tree ride the usual busy-checkout guard.
Whenever you have uncommitted work, an Uncommitted changes row sits at the top of the graph with a live count of changed files. Its node is a dotted ring on the checked-out branch's lane, joined to that branch's commit by a dotted line — it is the commit you are about to make. Click it to open the staging pane. An empty repository shows No commits yet; the row for uncommitted work still works, so you can stage and make the first commit from here.
Columns and jumping to HEAD
A header runs along the top of the graph: Branch / Tag, Graph and Commit message. Drag the edge of any column to resize it — double-click the Graph column's edge to fit every lane. The gear at the right end of the header adds Author, Date and SHA columns, resets the column widths, and holds the switches for what the graph shows (see Show or hide branches). Plexus remembers your columns.
The header's target button — or ⌘⇧H — scrolls the graph to the commit you have checked out and selects it, loading more history first if it is further down than you have scrolled.
Stashes on the graph
Each stash appears in the graph as its own row, directly above the commit it was taken on, with a dotted circle and a stash icon instead of an author picture. Click it to open the stash: when it was taken, the commit it was taken on (click that to jump to it), the files it holds — new files included — and Apply, Pop and Drop…. Click a file to see what the stash changed in it. Right-click the row for the full stash menu, including Rename….
Your sessions' uncommitted work
When one of your sessions' worktrees has changes nobody has committed yet, a // WIP row appears in the graph directly above the commit that worktree is on, naming the session and counting the changed files — hover it for staged, unstaged, new and conflicted counts. It's the commit an agent is about to make, visible before it makes it. Click it to open the session, or to select the commit it is on. Plexus checks these every few seconds while the tab is open, and straight away when a session reports activity, without ever locking the files an agent is working on.
Show or hide branches
A busy repository can have more branch lines than you want to look at. To narrow the graph:
- click the eye next to a branch in the References panel to hide it from the graph, and again to bring it back;
- right-click a branch and choose Show only this branch to see just that line of history, Hide this branch, or Hide with its remote (Hide with its local branch on a remote branch) to drop both copies at once;
- turn off Show remote branches, Show tags or Show stashes in the header's gear menu.
While the graph is narrowed, a strip above it says what is left out — "Showing only develop", "3 branches hidden · tags hidden" — with a Show all button to put everything back. The branch you have checked out is always shown. Plexus remembers these choices per project. Search always covers the whole repository.
Moving through the graph with the keyboard
Click the graph (or Tab to it) and the keyboard takes over the selection:
| ↑↓ | Select the previous or next row |
| kj | The same, without leaving the home row |
| Enter | Open the selected row's commit layer |
| Esc | Close the top layer — the diff first, then the commit layer, then the References panel |
Moving the selection never opens a layer by itself, so you can run down the history without anything sliding in on every step. If the commit layer is already open, it follows the selection and shows each commit as you land on it. These keys are fixed rather than rebindable, and they stand aside while you are typing in the search box.
Three more work anywhere in the Git tab, and can be rebound like any other shortcut:
| ⌘⇧H | Jump to the checked-out commit (HEAD) |
| ⌘Z | Undo the last git operation |
| ⌘⇧Z | Redo the operation you last undid |
Undo and redo stand aside while you are typing in a text field, the editor or a terminal, so ⌘Z there still undoes your typing. See Undo and redo.
Sessions on the graph
When a branch is checked out in one of your sessions' worktrees, a chip beside its label in the graph shows what that session is doing, in the same words and colors as the sidebar — Working in green, Needs you in amber — and hovering the chip names the session. The commit at the tip of that branch gets a ring in the same color, so you can see from the history alone which lines an agent is busy on and which one is waiting for you. A session that is idle shows just its name, with no ring.
New commits as they arrive
Commits that land while you are looking — an agent committing in a session, a fetch bringing in someone else's work — slide in at the top of the graph instead of appearing in one jump, and the rows already on screen move down to make room. A new commit stays highlighted until you hover over it or select it, so a commit that arrived while you were reading something else is still easy to spot.
If you have scrolled down into the history, Plexus keeps what you are reading where it is and shows a new commits button at the top of the graph instead, with how many arrived. Click it to scroll back up to them. Commits that were already there when you opened the tab are never highlighted, and switching to another project clears the highlights.
The marker strip
A narrow strip along the graph's right edge is the graph's scrollbar, and a map of the history Plexus has loaded. Small marks show where the checked-out commit is, where each session's branch tip is (in that session's state color), where new commits are, and where your selection is, with a shaded box — the scrollbar's thumb — for the part of the graph you are looking at. Drag the box to scroll, click a mark to jump to it, or click elsewhere on the strip to page up or down; with the strip focused, Page Up, Page Down, Home and End work too. When a layer is open, the strip moves with the layer's left edge, so it is never hidden behind it; while a diff has taken the graph's place, the strip steps aside with the graph and comes back when the diff closes.
Author avatars
Avatars come from Gravatar, matched by a one-way SHA-256 hash of each commit author's email — the address itself is never sent, results are cached on disk, and authors without a Gravatar get locally-drawn initials on a stable color.
Commits and diffs open as layers
Click a commit and its details slide in from the right as a layer over the graph: a header — the author's avatar, the sha, the commit's parents (click one to jump to it), and a changed-file count — above the list of changed files, switchable between a flat List and a folder Tree. Selecting a commit never opens a diff by itself. Click another commit while the layer is open and its contents change in place, without sliding out and back in. The graph stays visible to the layer's left, and the selected row stays in view.
Click a file and its diff opens where the graph was, to the left of the commit layer. The commit layer stays where it is and you can keep using it: click another file and the diff switches to that one. The diff's header reads as a path — the commit's short sha (or Uncommitted), then the file. Click the first part, the ✕ or press Escape to close the diff and bring the graph back. The diff follows the Unified / Split toggle above it — one app-wide preference shared with the Review tab.
In a narrow window — roughly under 1,400 pixels wide with the References panel pinned — there isn't room for a readable diff beside the commit layer, so the diff opens over it instead. The commit layer then steps back, leaving a strip of it showing on the left; click that strip to close the diff and get back to the file list.
Close the commit layer with its ✕ and the commit stays selected in the graph, so the arrow keys carry on from it and Enter opens it again — at the file list, not at the diff you last had open.
Escape closes one layer at a time: the diff first, then the commit layer, then the References panel if it is open and not pinned. It leaves alone the places where Escape already means something — the search box and other text fields, the conflict editor, menus and dialogs.
Selecting Uncommitted changes works the same way: the commit layer holds the staging lists and commit composer, and a clicked file's diff — or a conflicted file's resolve pane — opens beside them, so you can stage, unstage or pick the next file without closing it. So do a stash, a comparison and a file's history: each opens in the first layer, and a file you click in it opens its diff — or its blame — in the second.
The References panel
The rail on the left of the tab shows how many Local branches, Remote branches, Worktrees, Stashes and Tags the repository has. Click one and the References panel slides out over the graph, scrolled to that section; click the same button again, or press Escape, to put it away. While an agent is busy in one of your sessions' worktrees, the Worktrees button carries a small dot: amber when an agent needs you, otherwise green while one is working. Clicking in the graph leaves it open, so you can keep it beside you while you pick commits. To keep it there for good, click its pin: a pinned panel docks beside the graph, which narrows to make room, stays open, and is still pinned the next time you open the tab. The panel's ✕ unpins it and closes it.
The panel lists every ref in collapsible sections, each with a count: Local branches, one section per remote (e.g. origin — those sections are also where remotes are added, edited and removed), Worktrees, Stashes, and Tags. Names containing / nest into folders, so feature/login and feature/search group under feature. The Filter refs… box at the top narrows every section at once.
Clicking a branch or tag jumps the graph to its commit; right-clicking opens its context menu — the same menu the matching label carries in the graph; double-clicking a branch checks it out (a remote branch with no local copy gets a local tracking branch first; one that already has a local branch switches to it and fast-forwards it to the remote, or asks first if your local branch has commits the remote doesn't — see Checking out a remote branch). The eye beside a branch hides it from the graph or shows it again — see Show or hide branches. Branch rows also drag onto one another for the same drop menu as the graph — handy when the branch you want to merge into, rebase onto, or push is scrolled out of view in the graph. Local branch rows also carry the sync state against their upstream: ↑/↓ ahead/behind counts, plus a cloud icon when the branch is fully on its remote or a computer icon when its latest commits exist only locally. The Worktrees section lists the repository's linked worktrees and their branches — with Plexus, that's typically one per session. Each row names the session that owns it, or reads project checkout for the repository itself. A row owned by an archived session says so — archiving never removed the worktree, so that folder is what restoring the session would resume into. A worktree whose folder git can no longer find is struck through and badged missing; one that has been locked carries a locked badge with the reason. Right-clicking any row opens its context menu, which is where you clean both of those up — see When a branch is locked to a worktree.
Hovering a stash row reveals Apply, Pop, and Drop actions. Drop asks for a second click (the button flips to Drop? for a moment) instead of a dialog. Stash rows also have a right-click menu with those same two actions plus Create branch from stash…, Rename…, and a Drop… that confirms in a dialog naming the stash — see Context menus. Click a stash to open it, exactly as from its row in the graph.
Checking out a remote branch
Checking out a remote branch — double-clicking origin/develop, or Checkout as local branch from its menu — puts you on your local develop:
- If there is no local
developyet, Plexus creates one that tracksorigin/develop. - If your local
developis behind the remote, Plexus switches to it and fast-forwards it, and the toast says how many commits it moved ("Checked out develop — fast-forwarded 4 commits"). - If your local
develophas commits the remote doesn't — you committed on it, or the remote was rewritten — Plexus stops before anything moves and asks what you want. The dialog says how far apart the two are ("Local develop has 3 commits that are not on origin/develop, and is 5 behind it") and offers:- Reset develop to origin/develop — make your local branch match the remote. The dialog says how many of your local commits will no longer be on any branch. If you have uncommitted changes, Stash my uncommitted changes first (on by default) saves them as a stash before the reset; turn it off and the reset is refused rather than throwing them away.
- Check out develop as it is — switch to your local branch and leave it where it is.
- Cancel — do nothing.
The same dialog fronts Reset to <upstream>… on a local branch's menu and Reset local <branch> to this… on a remote branch's menu, for when you want to make a local branch match its remote on purpose. On a branch you don't have checked out, that reset only moves the branch — your files aren't touched.
Remotes
Each remote the repository is configured with — origin, an upstream you added, a mirror on a network share — gets its own section in the References panel, holding the branches Plexus last fetched from it. The section header is the remote itself: hover it to see the URL it points at, and the separate push URL underneath when it has one.
Right-click that header to manage it:
- Edit remote… — rename it, point it at a different URL, or give it a separate push URL so fetches and pushes go to different places. Clear the push URL again by emptying the field.
- Add remote… — add another one, by name and URL. An HTTPS or SSH URL, or a path to a local repository, all work.
- Remove remote… — drop it from this repository.
- Copy URL / Copy remote name — for pasting into a terminal or a message.
Adding a remote doesn't contact it. The dialog's Fetch after adding switch (on by default) runs an ordinary fetch straight afterwards, so its branches show up right away — but the two are separate steps, and a URL typo or a credential problem is reported as a failed fetch against a remote that was still added successfully, rather than as an add that half-worked.
If the repository has no remotes at all, the References panel says so and offers Add remote… there; the same item sits in the Pull button's menu, since with nothing to pull from there is no section header to right-click.
Renaming is the safe rewrite: git moves the remote's branches to the new name (upstream/main becomes fork/main) and repoints every local branch that was tracking them, so nothing is lost and nothing needs re-setting afterwards.
Removing a remote deletes the copies of its branches on your machine and clears the upstream of every local branch that was tracking one. The confirmation spells that out first — it lists the branch copies that go, counts the locals that lose their upstream, and says how many running sessions share the configuration you are about to change. Your own branches and their commits stay exactly where they are, and nothing changes on the server — the remote repository, and everyone else's copy of it, is untouched.
Bitbucket's SSH host move
Bitbucket is moving git over SSH from bitbucket.org to a new address, ssh.bitbucket.org. bitbucket.org itself stays: the website, the API and git over HTTPS keep using it. So a remote that looks like git@bitbucket.org:<workspace>/<repo>.git or ssh://git@bitbucket.org/<workspace>/<repo>.git needs the new address, and a remote that starts with https:// needs nothing.
Plexus recognises ssh.bitbucket.org as Bitbucket. Pull requests, CI status, Open on Bitbucket and cross-device sync work the same before and after you switch, and a project you have switched still matches the same project on a machine that hasn't switched yet. SSH remotes on altssh.bitbucket.org (Bitbucket's SSH on port 443) and GitHub's ssh.github.com are recognised the same way.
The notice
A little while after Plexus starts, and again whenever you add or clone a project, Plexus looks through your projects' remotes. It reads your git and SSH configuration on your machine and sends nothing anywhere. If a project still has an SSH remote on bitbucket.org, a notice says Bitbucket is moving SSH to ssh.bitbucket.org:
- Review opens the dialog described below.
- Not now puts the notice away. It comes back the next time you open Plexus, for as long as anything still points at the old address. It also comes back straight away if a project you add or clone needs the same change.
Reviewing the change
The dialog lists each affected project and every remote address that would change, with the current address and the new one:
git@bitbucket.org:acme/app.git → git@ssh.bitbucket.org:acme/app.git
Only the host changes. The user, workspace, repository and any port stay as they are. A remote with a separate push URL has that address listed too.
Under the list is a checkbox, ticked by default: Add Bitbucket's published SSH host keys for ssh.bitbucket.org to your known_hosts file, with the file's path. The first time ssh connects to a host it hasn't seen, it stops and asks whether you trust it. Git running inside Plexus can't answer that question: background fetches and the commands an agent runs in a session have nowhere to show it, so the connection fails with Host key verification failed. Adding the keys up front means there is no question to answer.
The keys Plexus adds are built into the app. They are the keys Atlassian publishes for Bitbucket, and Plexus doesn't fetch them from the network when you click. They are added at the end of the file under a comment that says Plexus added them. Nothing already in the file is changed. The checkbox only appears when your known_hosts has no entry for ssh.bitbucket.org yet. If it already has one with a different key, Plexus leaves it alone and the dialog says so, so you can check it against Bitbucket's published keys. If a project sets its own SSH command, trusting the new host is up to that SSH client.
Click Update to make the changes. The button names how many projects it covers, for example Update 2 projects. Nothing is written to a repository or to known_hosts until you click it, and a message afterwards says what changed. Remotes belong to the repository, so every session of the project uses the new address straight away.
What Plexus leaves to you
Sometimes the address isn't in the remote itself. Plexus never edits ~/.ssh/config and never rewrites your git URL rules. For these cases the dialog shows the exact change to make, with a copy button:
- A
Hostalias. A remote such asgit@bb-work:acme/app.git, where~/.ssh/confighasHost bb-workwithHostName bitbucket.org, gets its address from that file. The remote is fine as it is. Change the line underHost bb-worktoHostName ssh.bitbucket.org. - A git URL rule. If a
url.<base>.insteadOforpushInsteadOfrule in your git config turns the remote into abitbucket.orgaddress, the rule is what needs the new host. - A
Host bitbucket.orgblock. If~/.ssh/configchooses a key, user or proxy forHost bitbucket.org, that block won't apply tossh.bitbucket.org. After the switch ssh would use a different key and fail withPermission denied (publickey). The dialog names the settings that differ and shows the fix, which is to list both hosts on theHostline:Host bitbucket.org ssh.bitbucket.org
Update stays disabled until both hosts get the same settings. Edit the file, then click Check again. If Plexus can't runsshto compare the two, Update stays available and the dialog says what to check yourself.
After changing an alias's HostName, trust the new host once: connect from a terminal (see Switching by hand) or add the published keys yourself.
If you've already pointed the old address at the new one, Plexus sees that and doesn't list the remote. That covers an insteadOf rule of your own, and a ~/.ssh/config that sends bitbucket.org itself to the new host:
Host bitbucket.org
HostName ssh.bitbucket.org
If a fetch or push to the old address fails from 12 November 2026, the error says that Bitbucket is blocking SSH on bitbucket.org in scheduled windows until it switches it off on 10 December, and how to fix the remote. From 10 December it says that Bitbucket stopped accepting SSH there. If a remote on ssh.bitbucket.org fails with Host key verification failed, the error says that ssh doesn't know the new host yet.
Switching by hand
You can make the same change in a terminal. In the project's folder, list the remotes and change each one that uses bitbucket.org over SSH:
git remote -v
git remote set-url origin git@ssh.bitbucket.org:<workspace>/<repo>.git
If a remote has a separate push URL, change it with git remote set-url --push origin git@ssh.bitbucket.org:<workspace>/<repo>.git. You can also use Edit remote… on the remote's header in the References panel (see Remotes).
To trust the new host up front, add these three lines to ~/.ssh/known_hosts:
ssh.bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE=
ssh.bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO
ssh.bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
Their fingerprints are:
- ED25519
SHA256:ybgmFkzwOSotHTHLJgHO0QN8L0xErw6vd0VhFA9m3SM - ECDSA
SHA256:FC73VB6C4OQLSCrjEayhMp9UMxS97caD/Yyi2bhW/J0 - RSA
SHA256:46OSHA1Rmj8E8ERTC6xkNcmGOw9oFxYr0WF6zWW8l1E
Don't take our word for them. Compare them with Atlassian's own list at bitbucket.org/site/ssh, which gives the same keys under the name bitbucket.org. Atlassian says the new address uses the same host keys as before. Or connect once from a terminal with ssh -T git@ssh.bitbucket.org, check the fingerprint ssh shows against the ones above, and answer yes.
Switching back
Until Bitbucket switches SSH off on bitbucket.org, you can go back to the old address the same way: git remote set-url origin git@bitbucket.org:<workspace>/<repo>.git, or Edit remote…. The lines added to known_hosts only ever apply to ssh.bitbucket.org, so they can stay. If you'd rather remove them, delete the Plexus comment and the three lines under it.
The toolbar
- Branch switcher — shows the checked-out branch (or a short commit id with a
detachedbadge). Open it to filter and check out another local branch, or pick Create branch… to branch from the current head, optionally checking it out immediately. - Pull — a split button. The main click runs your default action; the arrow opens the full menu with the same four actions as the Default Pull action setting: Fetch all (download only) (all remotes, pruning deleted branches), Fast-forward if possible (ff), Fast-forward only (ff-only), and Rebase. The same menu's Prune when fetching switch (on by default, remembered per project) decides whether Fetch all also removes your copies of branches that were deleted on the remote. The Default action picker in the same menu saves your choice for this project — it's the Default Pull action setting (Settings → Git), which defaults to Fast-forward if possible and can also be set globally in Settings. Pull disables with an explanatory tooltip when there's nothing it could do — no remotes, a detached HEAD, or a branch with no upstream.
- Push — pushes the current branch to its upstream, with
↑/↓ahead/behind counts alongside. If the branch has no upstream yet, a Publish branch? prompt offers to push it tooriginand set the upstream in one go. If the remote has diverged — you amended, rebased, or reset a branch that was already pushed — git rejects the push and Plexus asks first: a Force push? prompt offers to overwrite the remote with--force-with-lease, pinned to the exact remote state that rejection saw — if anyone else pushes in the meantime, the force push fails instead of overwriting their work. Cancel to leave the remote untouched. If the remote holds work you haven't fetched at all, Plexus doesn't offer the force — fetch first, then decide. - Stash / Pop — stash all changes including untracked files, or pop the newest stash. Individual stashes are managed from the graph and the References panel.
- Undo / Redo — step back through the last git operations you ran here, or forward again. Hover either button to see which operation it would undo or redo — see Undo and redo.
- Refresh — fetch from your remotes, then reload the graph, refs, and status. Use it when you want to be certain you're looking at the latest, rather than waiting for the next automatic fetch. Because you asked for it, this fetch authenticates exactly like Fetch all does — it can use your credential helper or ask for an SSH key passphrase, where a background fetch never will. If the fetch couldn't run — another git operation is already using the repository, it has no remotes, or a leftover lock file is blocking it — Plexus says so rather than quietly showing you the same local state again.
Every one of these talks to your remotes with your own git credentials. If your machine has none for an https remote, a connected provider is tried as a fallback — and if that doesn't work either, the error names the host that refused and what to do next, rather than reporting a password prompt you never saw.
Next to Refresh, a small note tells you how fresh what you're looking at actually is — "Fetched 3m ago", or "Never fetched" for a repository nothing has fetched into yet. This matters more than it sounds: the ↑/↓ counts are worked out against the copy of the remote on your machine, so "↓0" only means "nothing to pull as of the last fetch". The note tells you when that was. It spins while a fetch is running and turns amber, with the reason in its tooltip, when something is wrong: "Fetch failed" after a few failures in a row — a broken remote URL, an expired token, or simply being offline — or "Fetch blocked" when a leftover .lock file in the repository is stopping fetches from running at all (close any other git process using the repository; if none is running, delete the leftover lock file the tooltip describes). Both warnings are about automatic fetching, so they go away if you turn it off — the note then just keeps telling you how long ago the repository was last fetched, by anything.
When you are behind, the ↓N count is clickable: one click runs your default Pull action for those commits.
Automatic fetching
Plexus fetches from your remotes in the background so the commit graph and the ahead/behind counts stay current without you asking. It only downloads — nothing is merged, checked out, reset, or deleted, and no branch is ever removed, so a fetch can never change your files or lose work.
Two speeds, because they answer different questions:
- the project whose Git tab you have open is fetched about once a minute — that's where a stale count is on screen in front of you;
- your other projects are fetched about every ten minutes, so their graphs are already right when you switch to them.
Fetching pauses while the Plexus window is hidden, slows down while the window is in the background, and stands aside whenever a git operation of your own is running — it will never make one of your actions wait or fail. It also leaves your SSH setup alone: if you've configured your own ssh command for git, background fetches use it exactly as your own commands do. A background fetch will never prompt you for anything — no password box, no key passphrase — so a remote that needs one is simply left for Refresh or Fetch all, where you're there to answer. A connected provider is the exception that needs no answer from you: an https remote on GitHub or Bitbucket authenticates with that connection in the background, exactly as it would on Refresh. If a fetch fails, Plexus says nothing: it backs off, keeps trying more slowly, and shows it on the freshness note rather than interrupting you.
Because a fetch only downloads, it never moves your own branches: after one, origin/main is current but your local main is exactly where you left it. That's the gap the New session dialog's pull toggle closes — Pull base branch first when the session cuts a new branch, Pull the branch first when it starts on an existing one — see Pull before you start.
Search the history
The box above the commit graph finds commits by message, author name or email, or commit id — a short prefix is enough. Results replace the graph with a plain list, newest first, and searching covers the whole repository rather than only the part of the history you've scrolled to.
The lane graph can't be drawn for a filtered set of commits — the lines between commits only mean something when their neighbours are present — so search deliberately shows a list instead. Clear the box (or press Escape in it) to return to the graph exactly where you were. With the box already empty, Escape does whatever it would normally do — closing the diff layer, for instance — rather than being swallowed by the search field.
Stage and commit
Select Uncommitted changes (the top row of the graph) to open the staging pane in the commit layer. Files group into Staged, Unstaged, and Conflicted sections with per-file and per-section stage/unstage buttons; clicking a file opens its working-tree diff in the diff layer.
Inside a diff, every hunk carries its own Stage hunk / Unstage hunk button, so you can split one file across several commits. Untracked files are the exception — they have no hunks yet and stage as a whole.
Select several files
Selection in the staging lists works like a file manager: click a file to select it, Ctrl/Cmd-click to add or remove a file, and Shift-click to select a range. A diff is shown while exactly one file is selected: a plain click opens that file's diff, and selecting a second file closes it again and brings the graph back, keeping your selection. Ctrl/Cmd-click files away until one is left and its diff comes back. Conflicted files can't join a selection, so Ctrl/Cmd-clicking one simply opens its resolve pane. Right-clicking a file selects it without opening its diff.
With files selected, the header shows two compact buttons next to Discard (N) — a stage icon and an unstage icon, each with the number of files it will move. Stage moves the selected unstaged files into the staged section and Unstage does the reverse; each appears only when the selection has files on its side, and hovering one says what it will do ("Stage the 3 selected files"). The same actions are in the right-click menu of any file inside the selection.
Stage single lines
When a hunk is more than you want to commit, pick the lines themselves. In the diff of an uncommitted file, click an added or removed line to select it, Shift-click to select a range, and Ctrl/Cmd-click (or Space on a focused line) to add or remove one; the arrow keys move between lines and Escape clears the selection. A bar appears on the hunk with Stage N lines (or Unstage N lines on the staged side) and, on the unstaged side, Discard N lines. Everything you didn't select stays exactly as it was.
If the file changed after you made your selection — an agent edited it, say — Plexus refuses rather than stage different lines than the ones you picked; the diff refreshes and you select again.
Discard changes
There are three ways to throw work away, and all of them confirm first.
One or more files. Right-click a changed file and choose Discard changes…, or select files and use the header button. Selection works like a file manager — see Select several files; once something is selected the header's Stash button is joined by Discard (N). Right-clicking a file that's already part of your selection acts on the whole selection — the menu entry says so, reading Discard 3 files… — while right-clicking outside it selects just that file first. Discard reverts modified and deleted files to the last commit and deletes new or untracked files from disk (there's no committed version to restore); the confirmation lists every affected path.
Everything at once. With nothing selected, the header offers Discard all instead. It returns every tracked file to the last commit and, unless you turn the switch off in the dialog, deletes every new file from disk — including new files you've already staged, which have never been committed either. Empty folders left behind by those files go too.
A single hunk, or single lines. In the diff layer, each hunk on the unstaged side carries a Discard hunk button next to Stage hunk. It reverts just those lines and leaves the rest of the file — and anything you've already staged in it — untouched. To throw away only part of a hunk, select the lines and use Discard N lines.
Discard is blocked while an agent session is running on the main checkout unless you confirm the override — the same guard as checkout and reset. Discard all additionally refuses while a merge, rebase, cherry-pick or revert is in progress: finish or abort it from the conflict banner first. To discard a staged hunk or line, unstage it first and then discard it from the unstaged side, where you can see the combined result before confirming.
The composer below takes a summary and an optional description. The AI button drafts both from the staged diff (tune it with the AI commit message instructions setting under Settings → Git), and Commit lands the staged files.
Amend
The composer's Amend switch rewrites the head commit instead of creating a new one: toggling it on prefills the message from the current head (unless you've already typed), and an amend may be message-only — no staged files required.
Compare two commits
Select one commit, then Ctrl/Cmd-click a second one: the first layer shows Comparing the two, with a button to swap which side is which. Or right-click a branch or tag and choose Compare with current branch.
Two ways of comparing sit side by side:
- Direct — everything that differs between the two.
- From merge base — only what the second side changed since the two went their separate ways, the way a pull request shows it. If the two share no history at all there is no merge base, so Plexus shows the direct comparison and says so.
Below that are the commits each side has that the other doesn't — click one to select it in the graph — and the changed files; click a file for its diff.
File history and blame
Right-click a file in a commit, a stash, a comparison or your uncommitted changes and choose:
- File history — every commit that touched the file, newest first, following it through renames (the commit that renamed it says what it was called before). Click an entry to see what that commit changed in the file, or its short sha to select the commit in the graph. A folder gets a Folder history of every commit that touched anything inside it.
- Blame — the file line by line, with the commit that last changed each block of lines in a gutter on the left: who wrote it and how long ago, shaded so older lines fade. Hover a block for the commit's message, click it to select that commit in the graph, or use Blame previous revision to see who wrote the lines before that. Ignore whitespace skips commits that only re-indented a line. Blame a file from your uncommitted changes and the lines you haven't committed yet read Not committed yet. From a file's history, Blame at this commit shows the file as it was then.
Edit, squash and reorder commits
Right-click a commit for three ways to rewrite history. Each is greyed out, with the reason on hover, when it can't apply to that commit.
- Edit message… — change the message of any commit on a local branch, not just the last one. Every commit after it is rewritten with its new parent, but nothing in your files changes, so it works even while you have uncommitted changes — and on the branch you have checked out.
- Squash into parent… — fold a commit into the one before it. The dialog shows both messages combined for you to edit; the result keeps the earlier commit's author. Like editing a message, it never touches your files.
- Interactive rebase from here… — rework your current branch from that commit up. The dialog lists the commits oldest first — the order git replays them in, the opposite of the graph. Drag a row by its handle (or focus it and press Alt+↑ / ↓) to reorder, and pick an action for each: Pick keeps it, Reword keeps it with a new message, Squash folds it into the commit above and combines the messages, Fixup folds it in and drops its message, Drop removes it. On a focused row, p, r, s, f and d set the action. Rebase N commits starts it.
An interactive rebase needs a clean working tree and a branch checked out, and isn't offered across merge commits — it would flatten them. If a step conflicts, the conflict banner takes over as for any rebase, and the messages you wrote are applied once you continue. Abort puts the branch back as it was.
On Windows, interactive rebase relies on the sh shell that comes with Git for Windows. If git can't start it, Plexus cancels the rebase before anything is replayed and says why.
Undo and redo
Undo in the toolbar — or ⌘Z while the Git tab is in front and you're not typing — reverses the last git operation you ran in this tab; Redo (⌘⇧Z) runs it again. Hover a button to see what it would do ("Undo Merge develop into accept"), and the toast confirms what happened. Plexus remembers the last 20 operations per project for as long as the app is open.
You can undo commits and amends (the changes go back to being staged), creating, deleting and renaming branches and tags, checkouts, fast-forwards, resets, merges, rebases (interactive ones too), edited messages and squashes, cherry-picks, reverts, pulls, saving a stash and dropping one.
Undo only ever reverses what it did. Before it changes anything, Plexus checks that every branch the operation moved is still exactly where the operation left it. If something else has moved one since — an agent committed, you ran git in a terminal, a pull came in — undo refuses ("the repository changed since …") and clears its history, rather than rewind work you didn't mean to touch. It also refuses to overwrite uncommitted changes in your files.
Pull requests
When the repository's origin is on GitHub or Bitbucket and you have connected that provider, the rail gets a Pull requests button with the number of open pull requests. Its section lists each one with its number and title, a Draft, Merged or Closed badge where it applies, its checks and review state, its author's initials, and which branch it merges into which. Tick Show closed to include closed and merged ones, or press the refresh button to ask the provider again right away. A branch in the graph that heads an open pull request carries a #number chip in the colour of its checks — click it to open the pull request in your browser.
Click a pull request to jump to its latest commit in the graph, and double-click it to check it out. Right-click for Check out, Open on GitHub (or Bitbucket), Copy link, Copy branch name and Compare with current branch. Checking out a pull request from the same repository fetches its branch and checks it out like any remote branch — including the question if your local copy has commits of its own. A pull request from a fork lands on a local branch named pr/<number>.
The list refreshes every couple of minutes while the section is open and the window is in front, straight from your device to the provider. Authors are shown as initials only — Plexus doesn't load their profile pictures. For how Plexus tracks a session's pull request, see Pull requests.
Submodules
If the repository has submodules, the References panel gets a Submodules section listing each one with its path and state: uninitialized, up to date, out of sync (checked out at a different commit than the repository records — both commits are shown), or conflicted. Press Update on a submodule — Initialize if it was never downloaded — or Update all in the section header to check out the commits the repository records. Updating downloads from each submodule's own remote, so it authenticates like a fetch, and it can take a while for a large submodule. Right-click a submodule to Open as project — it is added next to this project in the same workspace — or to copy its path or URL.
Git LFS
If the repository stores files with Git LFS, the References panel gets a Git LFS section that shows which file patterns LFS tracks and how many tracked files are still placeholders in your checkout rather than their real content — press Pull LFS files to download them. If your LFS server supports locking, the section lists file locks with their owner; Unlock releases one of yours, and Force unlock… releases someone else's after asking. To lock a file so others know you're editing it, right-click it among your uncommitted changes and choose Lock file; locked files show a lock icon there. Plexus only reads the repository's own settings to show this — opening the section never changes your LFS setup. If Git LFS isn't installed on your machine, the section says so instead.
Context menus
Right-click gives each surface its own menu. There are nine: branches, remotes, tags, stashes, and worktrees in the References panel, commits in the graph, changed files in the staging pane, and the file lists of a commit, a stash or a comparison — and the branch and tag menus follow their labels into the graph, folded refs in the +N panel included, so a right-click on a ref offers the same actions wherever you find it. On a commit row, the ref labels take the right-click and the rest of the row opens the commit menu.
Entries spell out what they will act on — "Merge into main…", "Delete from origin…" — so the labels below stand in <placeholders> for the part that varies. Anything that acts on the checked-out branch is greyed out when there isn't one, on a detached HEAD, and destructive entries always confirm before running.
Local branches — "Checkout <branch>" · "Create branch here…" · "Pull" (only on the branch you're on, and only with an upstream) · "Fast-forward to <upstream>" · "Reset to <upstream>…" (when the branch has commits its upstream doesn't — see Checking out a remote branch) · "Push" · "Merge into <current>…" · "Rebase <current> onto this…" · "Compare with current branch" · "Set upstream…" · "Rename…" · Delete → "Delete local…", "Delete remote only…", "Delete local and remote…" · "Copy branch name" / "Copy sha" · "Open on GitHub" (or Bitbucket) · "Create tag here…" · "Show only this branch" / "Hide this branch" / "Hide with its remote" — or "Show in the graph" once hidden (see Show or hide branches).
- "Fast-forward to
<upstream>" catches a branch up to its remote without checking it out and without touching your working tree — so you can bringmainup to date while you keep working on your feature branch. It appears when the branch has an upstream and is behind it, and it only fast-forwards: a branch that has diverged is left alone. - "Delete remote only…" deletes the branch on the remote and keeps yours — the usual tidy-up after a merged pull request. It's available on the branch you're currently on, too; only local deletion needs you to be somewhere else first.
- Deleting or renaming a branch that belongs to a session warns you first, naming the session.
Remote branches — "Checkout as local branch" (creating the local tracking branch, or switching to an existing one and fast-forwarding it to the remote — or asking first if yours has commits of its own) · "Create branch here…" · "Pull into <current>" and "Fast-forward <current> to this" (offered when it's the current branch's upstream) · "Reset local <branch> to this…" · "Merge into <current>…" · "Rebase <current> onto this…" · "Compare with current branch" · "Delete from <remote>…" · "Copy branch name" (the full origin/… name — what you'd paste into a git command) / "Copy sha" · "Open on GitHub" (or Bitbucket) · "Create tag here…" · "Show only this branch" / "Hide this branch" / "Hide with its local branch" — or "Show in the graph".
Remotes — on a remote's section header, not on the branches under it: "Edit remote…" · "Add remote…" · "Remove remote…" · "Copy URL" (what the header shows — a credential stored in the URL is never copied along) / "Copy remote name". See Remotes.
Commit rows — "Checkout commit" (detaches HEAD) · "Create branch here…" · "Create tag here…" · "Cherry-pick commit" · "Revert commit" · "Reset <current> to this commit" (Soft / Mixed / Hard — a hard reset discards work, so it demands a typed confirmation) · "Edit message…" · "Squash into parent…" · "Interactive rebase from here…" (see Edit, squash and reorder commits) · "Copy sha" / "Copy short sha" / "Copy subject" / "Copy message" (subject and body, the way git writes it) · "Open on GitHub" (or Bitbucket).
Tags — "Create branch here…" · "Checkout tag" (detaches HEAD) · "Compare with current branch" · "Push to <remote>", one entry per remote · "Copy tag name" / "Copy sha" · "Open on GitHub" (or Bitbucket) · "Delete tag locally…" · "Delete from <remote>…", again one per remote. The two deletions are deliberately separate: the local one only affects this checkout, while deleting from a remote removes the tag for everyone who fetches it.
Stashes — "Create branch from stash…" · "Apply" · "Pop" · "Rename…" · "Copy message" · "Drop…".
- "Create branch from stash…" asks for a name, then creates that branch where the stash was made, checks it out, applies the stash into it, and drops the entry — the clean way out of a stash that no longer fits the branch you're on.
- Apply and Pop are the same actions as the row's hover buttons. "Drop…" is not: the menu entry opens a confirmation dialog naming the stash, while the hover button keeps its quicker two-step click.
- "Rename…" changes the stash's message. git can only do that by storing the stash again, so a renamed stash moves to the top of the list.
- If the stash list changed since you looked — a stash was popped in a terminal, say — Plexus refreshes it rather than act on whichever stash now sits in that position.
Changed files — "Stage file" or "Unstage file", whichever side the file is on (or "Stage N files" / "Unstage N files" inside a selection of several) · "File history" · "Blame" · "Copy path" / "Copy file name" · "Discard changes…". On a conflicted file the staging entries give way to "Take ours (whole file)" / "Take theirs (whole file)", and discard is greyed out — resolve it first, or discard the whole file from the header.
- The menu acts on your whole selection when you right-click inside one of several files, and the labels spell out how many: with three unstaged files selected it reads "Stage 3 files" and "Discard 3 files…". A selection with files on both sides offers both "Stage N files" and "Unstage N files", each moving only the files on its own side. Right-click a file outside the selection and every entry acts on that one file.
File lists — in a commit, a stash or a comparison: "File history" · "Blame" · "Copy path". See File history and blame.
Worktrees — "Copy path" · "Remove worktree…" · "Prune stale worktree entries…".
- "Remove worktree…" deletes the worktree's folder from disk and clears git's record of it, which releases the branch it was holding. The dialog offers to delete that branch too (off by default). That branch delete is the safe kind: if the branch still carries commits that aren't merged anywhere, git keeps it and Plexus tells you — the worktree is gone by then, so the follow-up dialog offers to delete just the branch, spelling out that its commits go with it. The repository's main checkout can't be removed here, and neither can a worktree with a running session in it — stop that session first, even if that session belongs to another project on the same repository. A session that is in the middle of starting or stopping is refused the same way; try again once it settles. Removing one that belongs to a stopped session asks you to confirm, naming the session. An archived session's worktree removes without that extra confirmation — reclaiming those leftovers is what this section is for — but the dialog says whose it is and warns that restoring that session will no longer be able to resume it. Either way the session stops pointing at the folder you just removed, so it offers a fresh Start rather than a Resume that could only fail.
Two things can stand in the way of a removal, and each gets its own confirmation: a folder that belongs to a stopped session, and a folder with uncommitted or untracked work in it. Confirming one never waives the other — if both apply, you'll be asked twice, once in each set of words. - "Prune stale worktree entries…" is repo-wide and touches nothing on disk. It only clears git's records for worktree folders that are already gone, and it tells you how many it cleared. The confirmation lists every record it will clear. Locked entries are left out of that list: a lock is how git marks a worktree that lives on removable or network storage and is only temporarily missing, so clearing one is a separate switch in the dialog — and the toast says how many locked entries it kept. Like Remove, it also stops any session that still pointed at a pruned folder from offering a Resume into it.
When a branch is locked to a worktree
git refuses to delete or check out a branch that is checked out in any worktree — including one whose folder has been deleted behind git's back. That second case is the confusing one: git names a path that no longer exists, so there's nothing to go and look at.
Plexus clears its own leftovers automatically: on startup it drops the records for any worktree it created that has since disappeared. It deliberately leaves worktrees you made yourself alone, even when their folder is missing — a worktree on an unplugged drive looks exactly the same, and cleaning it up is your call, not the app's.
Detached HEAD
"Checkout commit" and "Checkout tag" leave you on a detached HEAD — you're looking at that exact snapshot, with no branch to record new commits on (a commit isn't a branch, and neither is a tag, so there's nothing for further commits to advance). The branch switcher shows the short commit id with a detached badge, and everything that acts on the current branch — Pull, Push, merge, rebase, reset, cherry-pick, revert — greys out until you check a branch out again.
Conflict resolution
A merge, rebase, cherry-pick, revert, pull, or stash pop that hits conflicts doesn't fail — the tab switches into conflict mode and lets you resolve everything in place.
An amber banner appears under the toolbar naming the operation and counting the conflicted files remaining. While it's up, the toolbar and branch switcher are disabled and the commit layer opens on your uncommitted changes and stays there, with conflicted files listed in their own section.
Each conflicted file offers three ways out:
- Ours / Theirs on the file row — take one side whole, no questions asked. (Binary or very large files resolve this way only.)
- Hunk picker — click the file and its resolve pane opens in the diff layer, each conflict shown as side-by-side ours and theirs cards, labeled with where each side came from. Pick Take ours, Take theirs, or Take both per conflict; once every conflict has a choice, Apply resolution writes the file, and the default-on Mark resolved after applying switch stages it in the same step.
- Edit file — switch the picker to a full editor to resolve the markers by hand, then Save & mark resolved.
When no conflicted files remain, the banner's action button finishes the operation — Commit merge, Continue rebase, Continue cherry-pick, Continue revert, or Done for a stash pop (which then drops the now-applied stash). A rebase that spans several commits may stop again on the next conflict; the banner simply stays up with the new file list. Abort (with a confirmation) backs the whole operation out and restores your working tree — a popped stash survives an abort.
The busy-checkout guard
Sessions started on the root tree run their agent directly in the same checkout this tab operates on. If such a session's agent is running, any operation that would change the working tree — checkout, pull, merge, rebase (interactive too), reset, revert, cherry-pick, stash apply/pop, an undo or redo that changes files, checking out a pull request, updating submodules, pulling LFS files, and continuing or aborting a conflict — is stopped first with an "An agent session is running on this checkout" dialog naming the session.
That's a guard, not a wall: Cancel leaves everything untouched, while Continue anyway runs the operation regardless — do that only when you're sure the agent won't trip over files changing underneath it. Operations that never touch the working tree — fetch, push, staging, committing, tag work, editing a commit message and squashing into a parent — are never blocked.
The Terminal tab
The Terminal tab opens plain shell terminals rooted in the project's root directory — the same primary checkout the Git tab operates on, never a session worktree. The shells are kept warm in the background, so a dev server or watcher you start here keeps running as you move around the app; add, close, and rename tabs the same way as the session's bottom terminal. See Project Terminal.
Related
- Project Terminal — root-level shells on the project's main checkout.
- Session Git — the per-session git tab for a worktree branch.
- Pull requests — how Plexus tracks a session's PR, and what changing
originresets. - Connections — connecting GitHub or Bitbucket, which the Pull requests section uses.
- Dashboard — the global session table; the project view scopes it down.
- Settings — Default Pull action, Show commit author avatars from Gravatar, and the AI commit prompt.
- Keyboard shortcuts — the project tab bindings, the commit graph's keys, and Jump to HEAD, Undo and Redo.