Changed files, staging, and committing
Development reference · View source
Space g g opens the changed-file list: files grouped by whether a commit
would take them, one per line. A selection over several rows is a selection of
files, and one key acts on all of them.
# main ↑1 · 2 staged · 1 not staged · 1 untracked · +105 -28
Staged
M +82 -12 src/app.rs
A +20 -0 src/git/stats.rs
Not staged
M +3 -16 README.md
Untracked
? · · logo.png
| Key | Action in the list |
|---|---|
Tab s / Tab u | Stage / unstage every file the selection covers |
Tab S | Stage every unstaged and untracked file in the list |
Enter | Show this row’s diff |
Tab d | Compare this row’s complete versions in a temporary split |
Tab o | Open the file on this line |
Tab D | Discard the selected files’ changes |
Tab c | Write a message and commit what is staged |
Tab i | Review everything staged for the next commit |
Tab p / Tab P | Pull / push the branch this working tree is on |
Space g r | Re-read everything from Git |
Reading the changed-file list
The first row names the branch, its drift from upstream, and how many
files are in each section. It counts sections rather than per-file states, so
it never calls a file “modified” above a heading that calls it staged. The
status line’s compact ~1 answers a different question: what changed, rather
than where it sits.
Line counts show what each change costs, added then removed, in one aligned column; the first row totals them.
- They use the theme’s
change_addedandchange_removed, the same colours as the gutter and diffs. Built-in themes use green and red; custom themes can change either. - They are Git’s own
--numstatcounts of the same two trees the row comes from. A file staged and then edited again is counted once on each of its rows, and the total is the sum of what is shown. - An untracked file counts every line as added.
- A change that cannot be counted — a binary file, an untracked symlink, a
file over a megabyte, or a whole untracked directory Git collapsed into one
row — shows
·in both columns and is left out of the total. A list with no countable rows omits the columns. - Counts are read only while the list is open.
A file in two sections (staged, then edited again) is not a duplicate:
those are two changes, staged separately. Enter on a staged row shows what a
commit would take; on an unstaged row, what it would not. A selection covering
both acts on the file once.
After staging, the caret follows the file into its new section, so Tab u
undoes what you just did.
Staging
Tab srecords each file as written on disk. When a buffer has unsaved changes, an INFO notification says so.- Staging moves the gutter’s base, so marks for staged lines disappear at once.
- For a rename, the displayed destination is what you open or diff, while staging and unstaging act on both paths, so a move is never split across the index.
- The changed-file list reads files on disk, not buffers — the one place the gutter and the diff views can disagree. The diff header says so when a buffer has unsaved changes.
Hunks. In a per-file diff, Tab s stages the exact hunk under the cursor
and Tab u unstages the exact staged hunk. The request carries the hunk bytes
plus repository, HEAD, index, file, and live-buffer preconditions; Git checks
the patch, and any stale precondition changes nothing.
Lines. :git-stage-lines stages a deliberately narrow slice from a saved,
clean source buffer: one contiguous selection containing every added or
modified new line in one hunk.
- Refused: dirty buffers, deletion-only choices, multiple or partial hunks, binary files, conflicts, renames, and untracked files.
- A refused partial action never becomes whole-file staging.
- Use Lazygit for finer patch surgery or advanced history work. Native merge review and conflict resolution are described below.
Committing
Tab c opens a commit message buffer with the template Git would give an
external editor: an empty first line, then commented instructions and the
files to be recorded.
| To | Do |
|---|---|
| Commit | Write the buffer: :w or :wq (:wq does not exit Runyte here) |
| Cancel an unchanged message | :c |
| Cancel an edited message | :c! |
- The index is refreshed first, so staging done outside the editor is included.
- A commit takes the index — exactly what the Staged section shows.
- Comment lines are not part of the message, so a message line cannot start
with
#. - Cancelling commits nothing and leaves the index as it was.
- A refused commit (an unset identity, a rejecting hook) keeps the message in the buffer to fix and retry.
- Afterwards the pane returns to where you started.
- Hooks run in the background commit, so a slow
pre-commitleaves the editor responsive. A signing key that wants a terminal prompt fails rather than asking.
Discarding
Tab D restores the selected files to HEAD, throwing away both staged and
unstaged changes.
- It is the only Git action here that cannot be undone: the content was never a commit, so no reflog brings it back. It asks first and names what it will take.
- A file with unwritten buffer edits is refused, so Git never overwrites text that exists only in the editor. Clean buffers reload afterwards.
- Discarding a staged addition removes its clean open buffer with the file. Discarding a rename restores the original path and removes the destination.
- Untracked files are refused. Discarding one could only mean deleting it,
which Git keeps behind
cleanand Runyte keeps in the explorer, where deletion is a confirmed plan that goes to the trash.