Skip to content

Git and Files

The Git view shows the session’s repository: its branches, its history as a graph, and its working changes. The Files view lets you read and edit the session’s files while its agent keeps working. The Git and Files buttons at the window’s right edge open each one over the board and the transcript for the open session. The view’s header names the session. The same button closes it, and the other one switches to it. The view’s X button closes it too, and so does Escape, except in the editor. Files refreshes when the session’s turn ends.

The session’s repository at its folder, or its worktree where it has one, in three columns. /diff opens it too. It follows the repository as it changes, so an agent’s commit shows as it lands, and it reads it all again when the window comes back to the front. Where it can’t follow it, as past Linux’s limit of watched folders, it says so.

  • The left column lists the local branches, in folders by their prefix (feature/login under feature), each with how far it’s ahead of its upstream (↑) and behind it (↓), or “gone” where its upstream was deleted. Then come the remote branches, the worktrees, the stashes and the tags, each section with its count. Folders start closed, and a click on a section’s name closes or opens it. Filter narrows every section at once. The session’s own branch says “this session”. The worktree the view opened on, the session’s own where it has one, shows its name in bold, and each worktree names the sessions working in it.
  • Fold the list to icons shrinks the left column to an icon for each section, with its count in the icon’s tooltip. An icon opens the column again at its section.
  • A click on a branch, a remote branch, a tag, a stash or a worktree shows its commit.
  • Beside each branch and remote branch, while the pointer or the focus is on it: hide it in the graph, pin it to the left, or show it alone. Above the graph, a branch shown alone or pinned is named, and a click there shows every branch again or unpins it. If that branch is deleted, every branch shows again, and the view says so.
  • The middle column is the history as a graph, its branches as lanes, each lane in its own colour, with each commit’s branch, remote-branch and tag labels (the branch checked out first), its message, its author, its date and its short SHA. Columns, above it, shows or hides each of those four. The top row is the working changes, with how many files they touch. The history reads more as you scroll, so a large repository opens at once.
  • The find box above the graph finds commits by their message, their author or their SHA, as Find by picks. Enter finds them and chooses the first; the arrows beside it go through the rest. It finds at most 100 commits, newest first, on the branches the graph shows. A message or an author is found as written, ignoring case, and a SHA needs at least 4 of its characters.
  • The right column shows the commit chosen: its summary and description, its author with the date, its committer where the name, email or time isn’t the author’s, its co-authors, its SHA, its parents (a click shows a parent), whether it’s signed and what git made of the signature (good, by a key git doesn’t trust, bad, by an expired or a revoked key, or not checked here), and its files, by path or As a tree. All files lists every file in the commit, not just those it changed.
  • Each person shows as a coloured circle with their initials, made on your computer. Nothing about them is sent anywhere.
  • With the working changes’ row chosen, the right column lists the files in conflict, then those unstaged and those staged. The + and − beside a file stage and unstage it, and Stage all and Unstage all do every file. The commit box below takes a summary and a description, with Amend the last commit to change the last commit instead, which fills an empty box with the last commit’s message. Commit needs a summary and something staged; with Amend the last commit on, the button is Amend and needs only a summary. A merge, rebase, cherry-pick or revert that stopped partway says so; finish or abort it in the session’s terminal.
  • Each session keeps its Git view as it was left, across a switch to another session, while the window is open: the column folded or not, the filter, the folders opened, the columns, the find, the branches hidden, pinned or shown alone, the row chosen, and the commit box’s draft.
  • It needs git, and the session’s folder must be a git repository; otherwise it says why.
  • If a read fails once the view is open, it says why above the graph, with Read again.

The button left of the find box does one of Fetch all, Pull, fast-forward if possible, Pull, fast-forward only, Pull, rebase or Push, and the arrow beside it, What the button does, picks which one and does it. A choice that can’t run now, such as a pull with no branch checked out, says why.

  • Fetch all fetches every remote; if one can’t be fetched, the others still are, and the view says what went wrong.
  • Pull takes the branch’s upstream: fast-forward if possible merges where the branches have gone different ways, fast-forward only refuses then, and rebase replays your commits on top.
  • Push sends the branch to its upstream. A branch without one goes to the repository’s only remote, or, with two or more, asks which in Push to a remote; that remote becomes its upstream. With no remote, the item can’t run and says so.
  • A push the remote rejects says why: the remote has commits the branch doesn’t, or the branch is behind its remote (pull first, then push), or the remote declined it.
  • A force push, from a branch’s menu, replaces the remote branch only while it’s still at the commit the view showed, so a teammate’s push in the meantime is refused rather than lost.
  • While the view is open, it fetches every 3 minutes.

Git never asks for a password or a key’s passphrase here; it uses the sign-ins already set up on this computer: your credential helper or keychain, Git Credential Manager, or your SSH agent. When one is missing or refused, or a host isn’t trusted yet, the view says so. Set it up in the session’s terminal, for example by running git fetch there once, then try again. When a host’s key has changed since this computer trusted it, which can mean someone is in the way, nothing is sent, and the view says so. After such a failure, the timed fetches stop until the view is opened again. A pull that stops at a conflict is finished or aborted in the session’s terminal.

A right-click on a branch, a remote branch, a tag, a commit, the working changes, a stash, a worktree or a file opens its menu, as does the keyboard’s menu key on whichever has the focus. A commit’s branch, remote-branch and tag labels in the graph open their own. An item that can’t run now says why beneath it.

  • A branch: Check out; Merge into, Rebase onto and Fast-forward to, for the branch checked out; Fast-forward to its upstream where it’s behind; the three pulls, on the branch checked out; Push and Force push over its upstream; Create a branch here… and Create a tag here…; Make a worktree from it; Rename…, Set the upstream… and Delete; Copy the name and Copy a link.
  • A remote branch: Fetch all, as the button over the graph does; Check out as a local branch of the same name; merge, rebase or fast-forward the branch checked out; create a branch or a tag there; Delete from its remote; copy its name or a link.
  • A tag: Check out this commit; create a branch there; Delete the tag, or Delete the tag here and on a remote; copy its name.
  • A commit: Check out this commit; create a branch or a tag; Make a worktree here…; Cherry-pick and Revert; Fast-forward to this commit; reset the branch checked out here: Reset here, keeping the changes staged, Reset here, keeping the changes unstaged or Reset here, discarding the changes; on the commit checked out, Edit the message…; Compare with the working changes; Copy the SHA, Copy a link and Copy the patch.
  • The working changes: Stash the changes…, Apply a patch…, Stage all and Unstage all. The first two are also buttons under the working changes’ files.
  • A stash: Apply it, Apply it and drop it, or Drop it.
  • A worktree: Open each session working in it, Start a session here…, Remove the worktree or Remove the worktree and its branch, and Copy the path.
  • A file, among a commit’s files, the working changes or a comparison, or from the button beside its name over the graph: Open in Files, where it’s inside the session’s folders; Open in the text editor, never in the app for its kind, so nothing an agent wrote runs; Show in the file manager; Show its history and Show its blame; staging, unstaging, discarding or restoring it, as its side allows; for an untracked file, Ignore the file, every file with its extension, or its folder; Delete the file; Copy the path and Copy the patch. Moontors checks each path is inside the view’s worktree before opening or showing it.

Some items ask first, in a dialog of their own: Create a branch (its name, and Check it out or not), Rename the branch, Set the upstream (as remote/branch, with the remote branches offered), Create a tag (a message makes it annotated), Make a worktree (a new branch, or none for the commit on its own), Edit the last commit’s message (what’s staged stays out of it), Stash the changes (with a message) and Apply a patch (pasted, and Stage it too or not).

Discarding, deleting a file, resetting, force pushing, deleting a remote branch, rebasing and dropping a stash always ask in Before it runs, with what they lose: the commits no other branch or tag holds, and the working changes to how many files. Deleting a branch or removing a worktree asks when it would lose either, and restoring a file asks where it has changes of its own. So does any action that would change the files of a folder where a turn is running. Deleting a tag, here or on a remote too, asks where it alone holds commits, and so does a checkout, of a branch, a remote branch or a commit, that leaves behind a detached HEAD whose commits no branch or tag holds. A copy says it’s done, and a link is built only for github.com, gitlab.com and bitbucket.org.

Compare with the working changes lists, at the right, the files that differ between the commit and the working tree, under Compared with the working changes; a click opens a file’s changes from the commit to the working tree. Back to the commit ends it, as choosing another row does.

A worktree in the left column with one session working in it names that session, and a click opens it; one with several says how many, and a click lists them in its menu to open. The + beside a worktree, or Start a session here… in its menu, opens Create session in its folder. Its menu also offers Remove the worktree, or Remove the worktree and its branch, though never the main worktree or the one the view is open on; a worktree a session still works in is refused, and the view says to archive or delete that session first.

A click on a file, among a commit’s files or in the working changes, opens its changes over the graph. Back to the history shows the graph again. The buttons above it show:

  • Hunks: git’s own patch, hunk by hunk, each line numbered on the side it’s on.
  • Inline and Split: the file before and after in the editor’s comparison, in one column or side by side, with the stretches that didn’t change folded away.
  • File: the whole file as it stands.
  • Blame: each line with the commit that last changed it. A click on a commit chooses it in the history. Lines not yet committed say Not committed yet. Staged changes have no blame, as blame reads the working tree or a commit, not what’s staged.
  • History: the commits that changed the file, newest first, across renames. A click opens the file’s changes in that commit.

Beside the hunks and the comparison, where they act:

  • Ignore whitespace: in Hunks, changes in whitespace are left out; in Inline and Split, only whitespace at the start and end of lines is, as the editor compares them.
  • Wrap lines wraps long lines, and Previous change and Next change go from one change to the next.

What the file can do:

  • Each hunk acts on git’s own: unstaged, Stage hunk or Discard hunk; staged, Unstage hunk; in a commit, Revert into the working changes. A hunk’s buttons wait while whitespace is ignored, as git takes a hunk whole, and a hunk that changed since it was shown is refused rather than guessed at.
  • The file itself: unstaged, Stage file or Discard changes; staged, Unstage file; in a commit, Restore from this commit, which puts it back as it was there, asking first where the file has changes of its own.
  • Discarding asks first, in Before it runs, with what it loses, and so does an action that would change the files of a folder where a turn is running: Go ahead or Cancel.
  • A file in conflict shows no hunks or actions: finish the merge or rebase, or abort it, in the session’s terminal, and its changes show here once it’s done.
  • A binary file says so in place of its lines, and a very large change shows only its first lines, and says so.
  • Inline, Split, File and Blame read the file’s whole text, which opens only as UTF-8 and at most 10 MB. History lists the newest 1,000 commits that changed the file.
  • Each session keeps the file it had open and how it showed it, across a switch to another session.
  • Each action is your own git, run as you’d run it, so your hooks and commit signing run too. When git refuses, its own message shows as it wrote it, in your language.
  • A merge, rebase, cherry-pick or revert is refused while tracked files have changes: “Working changes would be overwritten. Commit or stash them first.”
  • A stash that moved since it was shown, as when another stash was made, is refused: “This changed since it was shown. Check it again, then try again.”
  • What an action loses is counted as it runs, after any action or fetch before it in the same repository, so the question is never about a state that has since changed.
  • If another git is writing in the repository at that moment, as an agent’s commit, the action tries once more, then says so. Moontors never deletes git’s lock files.
  • A stash takes the untracked files too, never the ignored ones. Dropping one counts the files it holds, its untracked ones included.
  • Ignoring a file adds a line to the folder’s .gitignore. A file git already tracks stays tracked until it’s removed from the index. A .gitignore that’s a link, or anything but a file, is left as it is, and Ignore says so.
  • A worktree made here goes in Moontors’ own folder, as a worktree session’s does.
  • A merge, rebase, cherry-pick or revert that stops partway, as on a conflict, is left for you or the agent to finish in the session’s terminal. So are a stash’s conflicts, where popping or applying it meets them; the stash is kept.

A file tree on the left, and an editor on the right with a tab per open file.

  • The tree leaves out .git and the files git ignores; outside a git repository, hidden folders and node_modules. A folder lists at most 5,000 entries, then says “More files than are listed”.
  • The editor colours code like the transcript does.
  • Files open from the session’s folder (or its worktree) and any folder added with /add-dir, never from anywhere else.
  • A tab shows when it has unsaved changes. Cmd+S (Ctrl+S on Windows and Linux) saves, writing the file in place and keeping its permissions. Cmd+W (Ctrl+W) closes the tab.
  • Closing a tab with unsaved changes asks “Discard unsaved changes?”: Discard or Keep editing.
  • Files opens text in UTF-8 only. A binary file, a file larger than 10 MB, or text in another encoding opens as a note in its tab saying why, never as text that saving would damage.
  • If the editor doesn’t load, Files says “The editor didn’t load.” with Try again.

The editor is the one Visual Studio Code is built on, with its own keys and its right-click menu: cut, copy and paste, find and replace (Cmd+F, or Ctrl+F on Windows and Linux), folding, several cursors at once, and moving and copying lines. Besides the Git view’s eight (see Menus), it’s the only right-click menu in Moontors.

  • A line longer than 10,000 characters is cut off on screen, and one longer than 50,000 isn’t coloured. The file itself is kept whole.
  • Each session keeps its open tabs, the active one and unsaved edits while the window is open, across a switch to another session. They aren’t kept across a restart: closing the window with unsaved edits asks first.
  • When the agent changes a file you have open with no unsaved changes, the tab reloads. Undo takes you back.
  • When you have unsaved changes and the agent changes the file, your changes are kept, and the tab says the file changed on disk.
  • Saving a file that changed on disk since you opened it asks first: Reload, Overwrite, or Keep editing.
  • If the file is deleted while you have unsaved changes, the tab keeps them, and saving writes the file again.
  • A file that mixes line endings says so: saving makes every line end the same way.
  • Your hand edits aren’t part of Claude Code’s checkpoints, so a /rewind that restores files can overwrite them; its confirmation says so.
  • Archiving a session with unsaved changes asks first. So does Restart to update, naming the unsaved files: Restart and discard, or Keep working.
  • Closing the window or quitting with unsaved changes asks Close with unsaved changes?: Save all saves each file, then closes or quits; Discard drops the changes; Cancel keeps you editing. If a file can’t be saved, it’s named, and nothing closes. A message you’ve started typing to the agent holds a close too: the question names “the unsent message in” its session. Save all saves only the files and lets the message go; with no files to save, the question offers Discard and Cancel.