Skip to main content

6.3 Staging and Unstaging

Like Git, Magit can of course stage and unstage complete files. Unlike Git, it also allows users to gracefully un-/stage individual hunks and even just part of a hunk. To stage individual hunks and parts of hunks using Git directly, one has to use the very modal and rather clumsy interface of a git add --interactive session.

With Magit, on the other hand, one can un-/stage individual hunks by just moving point into the respective section inside a diff displayed in the status buffer or a separate diff buffer and typing s or u. To operate on just parts of a hunk, mark the changes that should be un-/staged using the region and then press the same key that would be used to un-/stage. To stage multiple files or hunks at once use a region that starts inside the heading of such a section and ends inside the heading of a sibling section of the same type.

Besides staging and unstaging, Magit also provides several other "apply variants" that can also operate on a file, multiple files at once, a hunk, multiple hunks at once, and on parts of a hunk. These apply variants are described in the next section.

You can also use Ediff to stage and unstage. See Ediffing.

s     (magit-stage)

Add the change at point to the staging area.

With a prefix argument and an untracked file (or files) at point, stage the file but not its content. This makes it possible to stage only a subset of the new file’s changes.

S     (magit-stage-modified)

Stage all changes to files modified in the worktree. Stage all new content of tracked files and remove tracked files that no longer exist in the working tree from the index also. With a prefix argument also stage previously untracked (but not ignored) files.

u     (magit-unstage)

Remove the change at point from the staging area.

Only staged changes can be unstaged. But by default this command performs an action that is somewhat similar to unstaging, when it is called on a committed change: it reverses the change in the index but not in the working tree.

U     (magit-unstage-all)

Remove all changes from the staging area.

user option magit-unstage-committed

This option controls whether magit-unstage "unstages" committed changes by reversing them in the index but not the working tree. The alternative is to raise an error.

M-x magit-reverse-in-index     (magit-reverse-in-index)

This command reverses the committed change at point in the index but not the working tree. By default no key is bound directly to this command, but it is indirectly called when u (magit-unstage) is pressed on a committed change.

This allows extracting a change from HEAD, while leaving it in the working tree, so that it can later be committed using a separate commit. A typical workflow would be:

  • Optionally make sure that there are no uncommitted changes.
  • Visit the HEAD commit and navigate to the change that should not have been included in that commit.
  • Type u (magit-unstage) to reverse it in the index. This assumes that magit-unstage-committed-changes is non-nil.
  • Type c e to extend HEAD with the staged changes, including those that were already staged before.
  • Optionally stage the remaining changes using s or S and then type c c to create a new commit.

M-x magit-reset-index     (magit-reset-index)

Reset the index to some commit. The commit is read from the user and defaults to the commit at point. If there is no commit at point, then it defaults to HEAD.

Staging from File-Visiting Buffers: