Editora 0.20.0 docs. You are reading an archived version, kept so links from that release keep working. Read the 0.21.0 docs →
Git
Editora’s Git support shells out to your installed git, with no bundled
library. It’s on by default; turn it off in Settings → Version Control →
Git or with view.toggleGit. If git isn’t installed, the integration stays
inert.
Git integration
- The status bar shows the current branch with ahead/behind counts. Click it
for a dropdown to switch or create branches, pull, fetch, and push. Outside a
repo it reads “No VCS” and offers to clone or create one. While a merge,
rebase, cherry-pick, or revert is in progress it names it (
main · MERGING). A repository Git refuses to work in (for example “dubious ownership”) is reported with Git’s reason in the status bar and the Commit window. - Gutter change bars mark added and modified lines against HEAD; deleted lines show as a corner flag at the top of the line that follows them. Hover a bar for that hunk’s diff, or click it for a card with actions (see Changes in the editor). Editor tabs are tinted by their file’s Git status, and the minimap marks changed lines.
- The Project tree marks files by Git status, IntelliJ-style: a single-letter prefix (M / A / D / R / U) and a color, added (green), modified (blue), deleted (gray), renamed (violet), untracked (olive), with changed folders tinted. The Commit window’s rows use the same letters and colors, so the two read identically. It updates as you edit, stage, commit, or switch branches.
- The Commit tool window (
M-4) groups staged, changed, and untracked files with stage, unstage, discard, and a commit box (Ctrl/Cmd+Enter to commit). See The Commit window. - A Git Log tool window (
C-x v S-l), the active file’s history (git.fileHistory,C-x v l), blame annotations in a gutter column (toggle withgit.toggleBlame), and stashes (git.stashes).
In a file’s history, double-click a revision or press Enter to compare it with the editable working file. The full diff viewer opens, including line, hunk, whole-file, Result, Undo, and Save controls. The repository-wide Git Log keeps its parent-to-commit view; use Compare with Working Tree on a changed file when you want the editable comparison instead.
| Action | Command | Default key |
|---|---|---|
| Commit (open the Commit window) | git.commit | C-x v v |
| Switch branch (dropdown) | git.switchBranch | C-x v b s |
| New branch | git.newBranch | C-x v b c |
| Pull | git.pull | C-x v S-= |
| Push | git.push | C-x v S-p |
| Fetch | git.fetch | (palette) |
| Next / previous change in the file | git.nextChange / git.previousChange | C-x v ] / C-x v [ |
| Git Log | tool.gitLog | C-x v S-l |
| File history | git.fileHistory | C-x v l |
| Toggle blame annotations | git.toggleBlame | C-x v g |
| Clone a repository | git.clone | (palette) |
| Create a repository in a folder | git.init | (palette) |
| Refresh | git.refresh | (palette) |
The VCS menu keeps the daily actions at the top level (Commit, Commit and Push, Push, Pull, Fetch, Switch Branch, Git Log, and Continue / Skip / Abort) and groups the rest into submenus: Changes, Branches, Remotes & Worktrees, Tags, Stash, Patches, History & Blame, and Compare.
Cloning asks for a URL and a destination, then opens a file from the clone (its
README if present) so Git activates without creating a project. The clone form
also takes a branch (blank is the remote’s default), a shallow depth (blank is
all history), and an option to clone submodules. The destination can start with
~ or be relative; missing parent folders are created, and an existing empty
folder is accepted.
Branch switch, pull, and push reload unmodified open buffers whose files changed on disk. Branch switches, discard, and stash never silently replace a dirty open copy; deleted and edited buffers remain available for recovery. Git paths are passed literally, including names that look like options or contain unusual characters, and conflicted entries remain visible while a merge is unresolved. History mutations and refreshes also revalidate the active file and working-tree state before applying their result.
Editora uses the git on your PATH; Git: Set Git Command
(git.setCommand) points it somewhere else, and a blank value goes back to the
PATH one. Editora never asks for a password, a key passphrase, or a host-key
confirmation, and Git commands never start an external editor. When a remote
refuses to sign you in, the error says what to set up (a credential helper, an
SSH agent, or a first connection from a terminal).
The Commit window
The Commit window (tool.commit, M-4) lists Staged, Changes, and
Untracked files, each row with its added and removed line counts. Its header
shows how many commits are waiting to be pushed or pulled, or that the branch
has not been published yet.
- Space stages or unstages the selected rows; on a group header it acts on
the whole group. Group menus offer Stage All in Group, Unstage All
(
git.unstageAll), and Discard All Changes… (git.discardAll), which returns tracked files to the last commit and deletes untracked files after a confirmation. - Amend (
git.commitAmend) makes the next commit replace the last one. Nothing needs to be staged to change only its message. If the commit is already on the remote, the window says that amending it will need a force push. - Commit and Push (
git.commitAndPush) commits and then pushes the branch. A failed commit does not push. - Sign off adds a
Signed-off-byline (git commit -s). The choice is remembered for the repository until Editora closes. - A length guide under the message shows the subject length and counts long body lines, following the 50/72 convention. It is advice only and never blocks a commit.
- Recent Commit Messages… (
git.commitMessageHistory) puts a message you committed earlier in this session back in the box. When the repository has acommit.template, the box starts from it and its comment lines are left out of the commit. - Undo Last Commit… (
git.undoLastCommit) takes the last commit off the branch, keeps its changes staged, and puts its message back in the commit box (git reset --soft HEAD~1). It asks first, and warns when the commit is already on the remote. A merge commit or a branch’s first commit is not undone this way.
Ctrl/Cmd+Enter does nothing when nothing is staged or while a commit is running. The list keeps its selection, collapsed groups, and scroll position as the status updates.
Operations in progress and conflicts
A merge, rebase, cherry-pick, or revert that stops part-way is shown in the status bar and as a banner at the top of the Commit window, with Continue, Skip, and Abort.
| Action | Command | Default key |
|---|---|---|
| Continue once the conflicts are resolved | git.continueOperation | (palette) |
| Skip the commit a rebase, cherry-pick, or revert stopped at | git.skipOperation | (palette) |
| Abort and go back to the state before it | git.abortOperation | (palette) |
| Open the resolver for the active file | merge.resolve | (palette) |
Any Git command that stops on conflicts (pull, merge, rebase, revert, cherry-pick, stash pop, or a 3-way patch) opens the Commit window with the conflicted files in their own Conflicts group. Each has:
- Resolve Conflicts…, which opens the three-way resolver. Applying a complete resolution saves the file and stages it, which clears it from the group.
- Actions that keep one side whole. They are named for what the sides mean in the current operation: Accept Ours / Accept Theirs in a merge, Keep the Upstream Version / Keep My Commit’s Version in a rebase, and Accept the Commit’s Version in a cherry-pick or revert.
- Mark Resolved, for a file you fixed by hand.
Committing is blocked while conflicts are unresolved. When a merge is ready to conclude, the commit box is prefilled with the message Git prepared.
Pulling and pushing
Pull mode (Settings → Version Control → Git, or git.setPullMode) decides
how git.pull brings in the remote commits:
- Fast-forward only (the default) never rewrites or merges anything. When the branch and its upstream have diverged, the pull offers Rebase or Merge for that one pull.
- Rebase replays your local commits on top of the remote ones.
- Merge joins the two histories with a merge commit.
git.pullRebase and git.pullMerge pull one way regardless of the setting.
Rebase and merge pulls carry uncommitted changes across with --autostash and
report what happened to them; if applying them back conflicts, they stay in the
stash and the conflicts appear in the Commit window.
| Action | Command | Default key |
|---|---|---|
| Push the current branch | git.push | C-x v S-p |
| Push to another remote or under another branch name | git.pushTo | (palette) |
| Force push | git.pushForce | (palette) |
| Push every local tag the remote lacks | git.pushTags | (palette) |
The first push of a branch publishes it to the push remote configured in Git
(the branch’s pushRemote, then the repository’s pushDefault) or to the
repository’s only remote. Force Push always uses --force-with-lease and asks first: it
is refused if the remote branch has moved since your last fetch. A push rejected
because the remote has commits you do not offers Pull, then Push, Force
with Lease, or Cancel.
Automatic fetch
Fetch automatically (Settings → Version Control → Git, or
git.toggleAutoFetch) fetches the active repository in the background so
incoming commits show without asking. It is off by default; the interval is 10
minutes unless you change it (git.setAutoFetchInterval). The background fetch
never prompts, and runs only in a trusted folder or in a repository you have
fetched, pulled, or pushed in during the session.
Branches
The branch dropdown lists local and remote branches, with remote branches
grouped by remote when there are several. Clicking a row checks the branch out.
A row’s ⋯ button, a right-click, or the Menu key opens its actions; the same
actions are in the palette and under VCS ▸ Branches.
| Action | Command |
|---|---|
| New branch from any branch or tag, with or without switching to it | git.newBranchFrom |
| Check out a tag, branch, or commit by name | git.checkoutRevision |
| Rename a local branch | git.renameBranch |
| Merge a branch into the current one | git.mergeBranch |
| Rebase the current branch onto another | git.rebaseOnto |
| Review the files that differ from the current branch | git.compareBranch |
| Set or unset the upstream | git.setUpstream / git.unsetUpstream |
| Delete a local branch | git.deleteBranch |
| Delete a branch on its remote | git.deleteRemoteBranch |
Deleting a branch with commits that are not merged into the current branch asks first and states how many there are. Deleting on the remote always asks. A local branch whose upstream was deleted is marked “(gone)”. Checking out a tag or a commit reports the detached HEAD.
Remotes and worktrees
Manage Remotes… (git.remotes) lists the repository’s remotes with their
fetch and push URLs and can add, rename, re-point (Set URL), fetch, prune, and
remove them. Fetch Remote… (git.fetchRemote) fetches one remote and prunes
its deleted branches.
Manage Worktrees… (git.worktrees) lists the repository’s worktrees and can
add one (for an existing branch or a new one; a relative folder is created
beside the repository), open one in a new window, remove one, and prune entries
whose folder is missing. Removing a worktree deletes its folder and keeps its
branch and commits; one that holds modified or untracked files asks again
before deleting them.
Tags
| Action | Command |
|---|---|
| New tag at the commit selected in the Git Log, or at HEAD | git.tag.create |
| Check out a tag | git.tag.checkout |
| Push one tag | git.tag.push |
| Delete a tag | git.tag.delete |
The same actions are on a commit row’s context menu in the Git Log. A new tag with a message is annotated; leaving the message empty makes a lightweight tag. Deleting a tag removes it locally only.
Changes in the editor
The gutter marks are also the way to work on one change at a time, compared with HEAD.
| Action | Command | Default key |
|---|---|---|
| Go to the next / previous change | git.nextChange / git.previousChange | C-x v ] / C-x v [ |
| Peek the change at the caret | git.peekChange | (palette) |
| Revert the change at the caret | git.revertHunk | (palette) |
| Stage the change at the caret | git.stageHunk | (palette) |
| Stage / unstage the whole file | git.stageFile / git.unstageFile | (palette) |
| Discard the file’s changes | git.discardFile | (palette) |
Next and previous wrap around at the ends of the file and report the position (“Change 2 of 5”). Clicking a change bar, or Peek Change at Caret, opens a card showing the old and new lines with Revert Hunk, Stage Hunk, Copy Old Text, Open Diff, and Previous / Next.
Revert Hunk puts the HEAD lines back into the buffer as an ordinary undoable edit; nothing is written to disk. Stage Hunk saves the file first and then stages only that change. Change bars and blame annotations follow unsaved insertions and deletions as you type.
Git Log
The Git Log (tool.gitLog, C-x v S-l) lists the current branch’s commits and
loads more as you scroll, a page at a time, so it reaches the whole history
(git.log.loadMore does the same from the keyboard).
- All branches (
git.log.toggleAllBranches) lists the commits of every branch, remote, and tag. - A commit graph is drawn beside the rows when the list is a plain walk of the history. It is hidden for a file history, a search result, and a filtered list.
- The details area shows the selected commit’s full message, author, date, hash, parents, and refs, above the files it changed.
- Enter on a commit (
git.log.reviewCommit) opens everything it changed as one multi-file review. With two commits selected, Compare Selected Commits (git.log.compareSelected) reviews the difference between them. - A commit’s context menu has Copy Hash, Checkout, New Branch from Here…, New
Tag…, Revert Commit, Cherry-Pick, Reset Current Branch to Here, and Create
Patch…. The matching
Git Log: …palette commands act on the commit selected in the visible log; when the log is hidden they open it and ask for a commit. - File history follows the file across renames.
Typing in the filter box narrows the commits already loaded. Pressing Enter
there (or git.log.search) searches the whole history:
| Term | Meaning |
|---|---|
| any other word | message text; every word must match |
author:name | author name or e-mail contains name |
content:text | commits that add or remove text |
since:date, until:date | anything Git reads as a date |
path:glob | commits touching a matching path, from the repository root |
Terms are separated by blanks, double quotes keep blanks inside one term, and matching ignores case. A running search is cancelled when you replace or clear it.
Reset (Soft, Mixed, or Hard) states how many commits leave the branch and how many of them are not on the upstream, and asks before stranding any. Reverting a merge commit asks which parent is the mainline.
Blame
git.toggleBlame (C-x v g) shows each line’s last commit, author and date,
in a gutter column. git.blameShowCommit opens the diff of the commit that last
changed the caret line.
- Annotate Previous Revision (
git.blamePreviousRevision) opens the file as it was before the commit the caret line is blamed on, annotated in turn, so you can walk a line back through history. - Ignore Whitespace Changes (
git.blame.ignoreWhitespace) looks through commits that only changed whitespace (git blame -w). - Detect Moved and Copied Lines (
git.blame.detectMoves) follows lines moved or copied within and between files (git blame -M -C). - A
.git-blame-ignore-revsfile at the repository root is used automatically.
The two toggles apply to the window they are set in.
Stashes
Stash Changes… (git.stash) takes an optional message and three options:
include untracked files, stash the staged changes only (Git 2.35 or later), and
keep the staged changes in the index.
Stashes… (git.stashes) lists every stash with the files it holds. Enter
shows a stash’s changes as a review, and each stash can be applied, popped,
dropped, turned into a branch, or have its name copied. git.stashPop applies
and removes the latest stash, git.unstash applies one you pick, and
git.stashDrop deletes one.
A stash that applies with conflicts is kept, and the conflicted files appear in the Commit window. A stash that would overwrite local changes is not applied.
Patches
Create Patch… (git.createPatch) writes the staged changes, the unstaged
changes, or a commit you pick as a patch, to a file or to a new untitled buffer.
Create Patch… on a Git Log row (git.log.createPatch) does the same for
that commit.
Apply Patch… (git.applyPatch) applies a .patch/.diff file, or the
active buffer if it is a patch, to the working tree or to the index. The patch
is checked first: one that does not fit changes nothing, shows Git’s message,
and offers Try 3-Way Merge, which applies what fits and leaves conflict
markers where it does not. Those conflicts appear in the Commit window like any
others.
To read a patch before applying it, see Diff & merge.
What runs automatically
Some Git commands run without you asking: status, the gutter diff, log, blame
and file-content lookups happen as you open files and switch tabs. Editora runs
those background reads so that a repository’s own configuration cannot start a
program through them. core.fsmonitor and hooks are overridden, external diff
and textconv drivers are switched off, and Git never waits on a terminal prompt.
A partial clone is also told not to fetch missing objects on demand; that needs
Git 2.45 or newer (or a 2.39.4–2.44.1 maintenance release), and older versions
ignore it.
One thing is not covered: filter drivers selected through .gitattributes
(Git LFS, for example) still run when Git has to re-hash a modified file.
Commands you start yourself (commit, checkout, pull, push and the rest) are
not restricted, so your hooks run as they do in a terminal. A revision name
that starts with - is refused rather than passed to Git, where it would be
read as an option.
None of the automatic reads contact a remote. The only network command Editora starts on its own is the optional automatic fetch, which is off by default.
Seeing what it ran
The Output console (tool.buildOutput) has a Git tab holding a
transcript of what Editora ran on your behalf: the command line, its output, and
its exit code and duration.
It logs the commands you asked for: commit, push, pull, fetch, checkout,
stash and clone. It leaves out the status and diff reads it re-runs on every
tab switch, focus change and save, which would bury them.
Clone, fetch, pull, and push open the Git tab as soon as they start and show the
command running: the git command line, then Git’s own progress (counting,
receiving, resolving, writing) updating in place, then the exit line. While one
runs, the tab’s Stop button or git.cancel cancels it. A command that fails
also brings the tab forward. A local command that succeeds does not, so a Git
Log action leaves the log in view and the transcript is there when you open the
window.
After a pull, the transcript lists the files it changed. Clicking a file’s
change graph (4 ++--) opens a diff of that file between the commit you were on
and the one the pull brought; clicking the file name opens the file.
For comparing files and resolving merge conflicts, see Diff & merge. For pull requests, reviews, and CI runs, see GitHub.