If you just started with git, you probably have no concept of the stage (or as some people confusingly call it index). In other version control systems, the only thing you can select is which files you want to commit. However, git not only allows you to do that but also which parts of a file you want to select.
Unfortunately, the built-in command line tooling for that (provided via
git add -p
) is pretty hard to use and takes way too long.
Full a quick demo, check out my video on YouTube:
When you run git istage
inside your repo, it shows you the set of current
changes, i.e. the output of git diff
. But in contrast to git diff
, you can
select individual lines and add them to the stage by hitting S. You
can also permanently remove changes from your working copy by hitting
R (be careful: there is no undo for that operation).
At any point you can view the staged changes (i.e. the output of
git diff --cached
). If you decided that there are certain portions you don't
want to commit, you simply unstage the selected lines by hitting U.
All three shortcuts can be modified using Shift. In that case it will apply to all consecutive changes, called a block.
In order to quickly navigated you can use ← and →, which will jump between files, and [ and ], which will jump from block to block.
You can also customize the way the changes are presented. By using + and - to increase or decrease the number of contextual lines being displayed. Alternatively, you can use \ to toggle between viewing entire files or changes only.
When you are done, simply return to the command line by hitting Esc
or Q. Once there, I recommend you run git stash -u -k
, which will
stash all changes you didn't stage so you can test the code you're about to
commit. Or, you can stash right from inside of git istage by hitting
Alt S. Once satisfied, run git commit
and unstash via
git stash pop
.
More keyboard shortcuts listed below. A shortcut may be preceded by a number, N. Notes in parentheses indicate the behavior if N is given.
Shortcut | Name | Description |
---|---|---|
0 | AppendLineDigit0 | Append digit 0 to line. |
1 | AppendLineDigit1 | Append digit 1 to line. |
2 | AppendLineDigit2 | Append digit 2 to line. |
3 | AppendLineDigit3 | Append digit 3 to line. |
4 | AppendLineDigit4 | Append digit 4 to line. |
5 | AppendLineDigit5 | Append digit 5 to line. |
6 | AppendLineDigit6 | Append digit 6 to line. |
7 | AppendLineDigit7 | Append digit 7 to line. |
8 | AppendLineDigit8 | Append digit 8 to line. |
9 | AppendLineDigit9 | Append digit 9 to line. |
C | Commit | Author commit |
Alt C | CommitAmend | Amend commit |
- | DecreaseContext | Decreases the number of contextual lines. |
ESC | Exit | Return to command line. |
Q | Exit | Return to command line. |
End | GoEnd | Selects the last line. |
Shift G | GoEndOrInputLine | Selects the last line (or Line N). |
Home | GoHome | Selects the first line. |
G | GoHomeOrInputLine | Selects the first line (or Line N). |
→ | GoNextFile | Go to the next file. |
N | GoNextHit | Go to next search hit. |
] | GoNextHunk | Go to next change block. |
← | GoPreviousFile | Go to the previous file. |
P | GoPreviousHit | Go to the previous search hit. |
[ | GoPreviousHunk | Go to previous change block. |
+ | IncreaseContext | Increases the number of contextual lines. |
Backspace | RemoveLastLineDigit | Remove last line digit |
R | Reset | When viewing the working copy, removes the selected line from the working copy. |
Shift R | ResetHunk | When viewing the working copy, removes the selected block from the working copy. |
Ctrl + ↓ | ScrollDown | Scrolls down by one line. |
Ctrl + ← | ScrollLeft | Scrolls left by one character. |
PgDown | ScrollPageDown | Selects the line one screen below. |
Space | ScrollPageDown | Selects the line one screen below. |
PgUp | ScrollPageUp | Selects the line one screen above. |
Ctrl + → | ScrollRight | Scrolls right by one character. |
Ctrl + ↑ | ScrollUp | Scrolls up by one line. |
/ | Search | Searches for a pattern. |
↓ | SelectDown | Selects the next line. |
J | SelectDown | Selects the next line. |
↑ | SelectUp | Selects the previous line. |
K | SelectUp | Selects the previous line. |
F1 | ShowHelpPage | Show / hide help page. |
? | ShowHelpPage | Show / hide help page. |
S | Stage | When viewing the working copy, stages the selected line. |
Shift S | StageHunk | When viewing the working copy, stages the selected block. |
Alt S | Stash | Stashes changes from the working copy, but leaves the stage as-is. |
T | ToggleBetweenWorkingDirectoryAndStaging | Toggle between working copy changes and staged changes. |
F | ToggleFilesAndChanges | Toggle between seeing changes and changed files. |
' | ToggleFullDiff | Toggles between standard diff and full diff |
W | ToggleWhitespace | Toggles between showing and hiding whitespace. |
U | Unstage | When viewing the stage, unstages the selected line. |
Shift U | UnstageHunk | When viewing the stage, unstages the selected block. |
The default key bindings are set for a US QWERTY keyboard layout.
The key bindings can be modified by creating a JSON file at the following location:
- On Unix / macOS it's
$XDG_CONFIG_HOME/.git-istage/key-bindings.json
- If
$XDG_CONFIG_HOME
isn't set, it falls back to$HOME/.config
- This follows the XDG conventions
- If
- On Windows it's
%APPDATA%\.git-istage\key-bindings.json
If you want to get code-completion when editing the file, you should reference the schema:
{
"$schema": "https://raw.githubusercontent.com/terrajobst/git-istage/main/docs/keyBindings-schema.json",
// ...
}
For instance, to use the X key to exit the program instead of the default Esc or Q keys, use the following syntax:
{
"$schema": "https://raw.githubusercontent.com/terrajobst/git-istage/main/docs/keyBindings-schema.json",
"Exit": {
"keyBindings": ["X"]
}
}
This will override the default keyboard shorts. If you want to add them, you need to list the ones you want to keep as well. For example, in order to preserve the default Esc and Q key, you just include them in the list:
{
"$schema": "https://raw.githubusercontent.com/terrajobst/git-istage/main/docs/keyBindings-schema.json",
"Exit": {
"keyBindings": ["Escape", "Q", "X"]
}
}
Please note that key binding strings are case insensitive. In order to differ by case, you need to prefix them with a Shift
modifier, such as Shift+X
.