What are staging areas?#
When you run git status after modifying some files, you’ll see something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: file1.txt
modified: file8.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file2.txt
modified: file4.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
file5.txt
sacred-texts.txt
|
Notice there are three categories of files here:
to be committed (also called staged), not staged for commit, and untracked files.
These are the different staging areas.
- To be committed/staged means that these files will be included in the next commit made.
- Not staged for commit means that git noticed changes in those files, but they will not be included by default next time
git commit
is run. - Untracked means that git is not watching those files.
Moving files between staging areas#
There are two git subcommands we need to understand for this: git add
and git resore
.
git add#
We introduced git add
in the last tutorial.
It moves a file to the staged area so that it will be included in the next commit.
Here’s an example (the lines starting with $
are the commands run:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| $ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: file1.txt
modified: file8.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file2.txt
modified: file4.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
file5.txt
sacred-texts.txt
$ git add file2.txt file5.txt
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: file1.txt
modified: file2.txt
modified: file5.txt
modified: file8.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file4.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
sacred-texts.txt
|
As you can see, running git add file{2,5}.txt
moved them to the staged area.
This is also referred to as “staging” a file.
A file can also be partially staged, where some part(s) of it are included in the next commit, but not the whole thing.
This usually happens when you stage a file and then edit it.
Running git add <partially staged file>
will stage the entire thing.
git restore#
This command is slightly more complicated than the other ones we’ve used so far.
git restore
overwrites a file, using either the latest commit or the staged version as reference.
That might be quite confusing at first, and that’s okay.
You can always come back to a tutorial, man page, or documentation later.
git restore
can be very dangerous since it won’t warn you before overwriting files. Be careful!
There are some options that control how the file is overwritten.
default (–worktree, -W)#
By default if no options are specified, or with the --worktree, -W
option, git restore
will discard any unstaged changes.
This means that if you have a partially staged file, the staged changes will be kept, while the unstaged ones will be discarded.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| $ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: file2.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file2.txt
$ git restore file2.txt
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: file2.txt
|
Running git restore file2.txt
discarded the unstaged changes in file2.txt
while keeping the staged ones.
–staged, -S#
Running git restore
with the --staged, -S
option will essentially unstage any currently staged changes, but does not discard them.
Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| $ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: file1.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file2.txt
$ git restore --staged file1.txt
$ git status
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file1.txt
modified: file2.txt
|
Note that this command is also listed in the output of git status
, so it’s easy to remember.
–worktree, -W and –staged, -S#
Using both the --worktree, -W
and --staged, -S
options will completely overwrite the file to its last committed state.
It discards both staged and unstaged changes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| $ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: file1.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file1.txt
modified: file2.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
file5.txt
$ git restore --worktree --staged file1.txt
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file2.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
file5.txt
|
Running git restore --worktree --staged file1.txt
discarded all changes in file1.txt
.
Tip: using short options can make the commands much simpler. git restore -WS <file>
is equivalent to the above command.
Tip: almost all git commands can handle directories, too.
Since git doesn’t track directories, it just applies the command recursively to all files in the directory.
So git add .
will stage all files in the current directory, and git restore --staged .
will unstage them all.