The staging area in Git is a state that files can be in before being committed to a repository. This tutorial will explain how to add and remove files from the staging area.
git stage
#Git’s staging area allows you to be selective in the changes you want to include in a commit. Sometimes, you may want to commit every change in your working directory to the repository. In other cases, you may want to include some changes in your commit and exclude others. It can be useful to exclude changes if they’re still a work in progress or if they’re unrelated to your current work.
Adding files to the staging area is also referred to as “staging changes” (as in: “I will stage my changes”). Removing files from the staging area is also referred to as “unstaging changes” (as in: “I unstaged these changes”).
The staging area is sometimes called the “staging index” or just “index.” Some Git commands use the term “index” in their output, and it’s also sometimes used in Git documentation. In this usage, “index” is synonymous with “staging area.”
This guide will explore a few different ways that you can stage and unstage files. It will discuss several Git commands that operate on the staging area:
git add
git restore
git rm
git mv
git reset
With these above commands, you’ll be able to stage and unstage changes by file, directory, or pattern.
To stage a modified file, use the git add
command followed by a filename as the argument.
For example, to add a modified file named license.txt
, run git add
with the name of the file.
git
add
license.txt
While the command is called git add
, note that this use of the word “add” doesn’t only refer to adding new files to the repository. It refers to adding any changed files to the staging area. The staging area can contain created, deleted, or modified files. You can use git add
on a deleted file, for example.
You can list multiple filenames as arguments to git add
to stage them all in one step. For example, to stage a set of files named first.txt
, second.txt
, and third.txt
, you can run the following git add
command.
git
add
first.txt second.txt third.txt
The above is equivalent to running git add
on each one individually, as follows.
gitaddfirst.txtgitaddsecond.txtgitaddthird.txt
You can stage a file that is deep in the directory structure by providing its entire path. For example, to stage a file located at static/pages/docs/index.html
, you can provide that full path to git add
.
git
add
static/pages/docs/index.html
The argument to git add
is always interpreted as relative to the current directory. This means that as an alternative to the above deeply nested path, you can switch to the file’s directory first and then use git add
on the file name directly. Here’s how you can do this by changing the current directory with cd
and then staging index.html
from there:
cdstatic/pages/docsgitaddindex.html
By using relative file paths in this way, you can stage changes from any directory in the repository tree.
Similarly to staging a file, you can stage a directory by providing its path to the git add
command. When staging a directory, all changed files within all subdirectories will be added. In other words, changes are added recursively. This is useful when you have many files that you intend to commit, all located within a particular directory of the project.
For example, to add all changes in the docs
directory, provide the directory name to the git add
command.
git
add
docs
Similar to staging files, you can specify multiple directories in the same command by listing them. The following example shows how to stage two directories: docs
and assets
.
git
add
docs assets
After running the above command, all changes contained within these two directories will be staged.
When you don’t need to select specific files or directories for a commit, you can stage all changes at once. To do that, run git add
with the -A
flag (or its synonym, -all
). No other arguments are necessary when using this flag.
git
add
-A
This will stage all changes in the repository directory and all subdirectories. It will include all files that are modified, created, or deleted.
git add -A
is not affected by the current directory. You can run it from within any subdirectory of your project, and it will apply to the entire repository.
Git repositories cannot contain empty directories. This means that if you create an empty directory in your project and attempt to stage it, it won’t be added to the staging area. This is because Git is only capable of tracking files and is unable to track a directory if there are no files inside. It’s a limitation of how Git represents files internally.
Empty directories can often be useful as temporary storage areas, for example, or as locations for build output. A common workaround to include an empty directory in a Git repository is to put a placeholder file inside so that it’s not truly empty. By convention, this placeholder is usually named .gitkeep
.
You can get a sense of how common this convention is by performing a Sourcegraph Cloud search to find the presence of files named .gitkeep
in many popular open source repositories, as demonstrated by the following search query.
If you would like to leverage this method for adding directories to your staging area like the repos that were revealed in the above query, you can also initialize a directory with .gitkeep
.
Suppose you have an empty directory named output
that you want to add to a repository. You can first create a placeholder file named .gitkeep
within that directory by using the touch
command in the terminal, which creates a blank file. Then, you can use the git add
command to stage the directory.
touchoutput/.gitkeepgitaddoutput
This will stage the output
directory, which is empty except for the placeholder file, to be committed to the repository.
If you want to stage all files that match a pattern, like all files that end in the .py
extension, you can use git add
with a glob pattern.
Glob patterns use the star symbol (*
) as a wildcard to match file names. For example, to stage all files with a .py
extension in the current directory, you can provide the following pattern to git add
:
git
add
*.py
The double star pattern (**
) is a wildcard that matches any subdirectories in a file’s path. For example, to recursively stage all files named index.js
in all subdirectories of the project, you can run git add
with the following pattern.
git
add
**/index.js
This will find all files named index.js
, regardless of their subdirectory, and stage them.
The above two patterns can be combined. For example, you can run the following command to stage all files ending in the .py
extension in all subdirectories.
git
add
**/*.py
The double star (**
) pattern will search across all subdirectories recursively and the single star (*
) pattern will match all filenames with a .py
extension in the project.
The git rm
command deletes a file and then stages it. You can think of git rm
as a replacement for two steps that can otherwise be done independently:
rm
terminal command on the file.git add
with the path of the deleted file.Like the git add
command, git rm
can be used with files, directories, or patterns as arguments.
For example, to remove and stage a file named license.txt
, you can run git rm
as follows.
git
rm
license.txt
The license.txt
file will now be in the staging area as a deleted file.
If you’ve already deleted a file by some other means and want to stage it as a deleted file, you don’t need to use git rm
. You can use git add
to stage it since you only need to perform the second step of the process.
It’s a common occurrence to rename or move a file to a different directory in the repository. In Git, renaming a file is analogous to moving it to a new file name. In either case, Git will initially interpret the change as two distinct changes:
To stage a moved or renamed file, you have to stage both of these changes. You could do this manually by running git add
on both file names, or you can use the git mv
command.
The git mv
command renames or moves files and also stages the change in one step. It takes two arguments: a source and a destination.
For example, to rename a file named todo.txt
to done.txt
, you can run git mv
with the original name and new name as arguments.
git
mv
todo.txt done.txt
This will perform three tasks in one command:
todo.txt
to done.txt
in the current directory.todo.txt
as a deleted file.done.txt
as a newly created file.After both changes related to a moved or renamed file are staged, Git will identify that it’s the same file under a different path. From that point, it will appear with the label renamed
in the output of git status
.
We’ve explored a variety of ways to add changes to the staging area. Removing changes from the staging area can occasionally be useful, as well.
Unstaging changes can help when you’ve changed your mind about what you want to commit, or you’ve staged some changes unintentionally.
The git restore --staged
command allows you to unstage changes and remove them from the staging area. You can think of it as the opposite of the git add
command.
It’s necessary to include the --staged
flag to indicate that you want to remove staged changes. If you run git restore
without that flag, it will instead discard changes in your working directory.
Like git add
, git restore --staged
takes a file name as an argument. For example, suppose you previously staged a file named README.md
using git add
.
git
add
README.md
To unstage this file, use git restore --staged
with the same file name.
git
restore --staged README.md
The file’s changes will remain in the working directory, but the file will no longer be present in the staging area.
You can also provide a directory name to git restore --staged
. This will remove all files within that directory and its subdirectories from the staging area.
To start the staging process over from the beginning, you can unstage all changes in one command.
The git reset
command removes all changes from the staging area.
git
reset
After running the above command, all changes will be unstaged but will remain in the working directory. The output gives you a summary of those changes, as in the example below.
Unstaged changes after reset: M index.html D script.js D style.css
From here, you can start staging changes again.
In this guide, we took a deep dive into different ways to stage changes in Git and to unstage them.
To learn more about using Git to create commits, read How to commit code with the Git command-line-interface.
Check out our other Git tutorials or visit the Sourcegraph Learn home page for more educational resources.