Staging Deleted files
Asked Answered
S

10

634

Say I have a file in my git repository called foo.

Suppose it has been deleted with rm (not git rm). Then git status will show:

Changes not staged for commit:

    deleted: foo

How do I stage this individual file deletion?

If I try:

git add foo

It says:

'foo' did not match any files.

Update (9 years later, lol):

This looks like it has been fixed in git 2.x:

$ git --version
git version 2.25.1

$ mkdir repo

$ cd repo

$ git init .
Initialized empty Git repository in repo/.git/

$ touch foo bar baz

$ git add foo bar baz

$ git commit -m "initial commit"
[master (root-commit) 79c736b] initial commit
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bar
create mode 100644 baz
create mode 100644 foo

$ rm foo

$ git status
On branch master
Changes not staged for commit:
    deleted: foo

$ git add foo

$ git status
On branch master
Changes to be committed:
    deleted:    foo
School answered 11/9, 2012 at 16:1 Comment(2)
Was this a problem in old Git versions? Nowadays it doesn't seem to be one, it works similar to modified files.Juglandaceous
@cst1992: Yes, it looks fixed now. git add foo now works. See Update.School
G
52

Since Git 2.0.0, git add will also stage file deletions.

Git 2.0.0 Docs - git-add

< pathspec >…

Files to add content from. Fileglobs (e.g. *.c) can be given to add all matching files. Also a leading directory name (e.g. dir to add dir/file1 and dir/file2) can be given to update the index to match the current state of the directory as a whole (e.g. specifying dir will record not just a file dir/file1 modified in the working tree, a file dir/file2 added to the working tree, but also a file dir/file3 removed from the working tree. Note that older versions of Git used to ignore removed files; use --no-all option if you want to add modified or new files but ignore removed ones.

Gabel answered 27/3, 2017 at 20:52 Comment(3)
The accepted answer doesn't solve the problem - and the other are more cumbersome since Git 2.0.0 - this is the best way! You have my upvoteMealie
There's an important caveat to this: something like git add foo/*/deleted.file won't work, because the * only expands to files that still exist. You can use other patterns that don't rely on files existing, though, such as git add foo/{bar,baz,quux}/deleted.fileDianthus
@Dianthus If files have been deleted from the file system at foo/*/deleted.file, you can also stage them for deletion by putting single quotes around the path, including the wildcard. That prevents the operating system from trying to expand the wildcard, and instead git expands it and stages the deleted files: git add 'foo/*/deleted.file'.Saturniid
B
600

Use git rm foo to stage the file for deletion. (This will also delete the file from the file system, if it hadn't been previously deleted. It can, of course, be restored from git, since it was previously checked in.)

To stage the file for deletion without deleting it from the file system, use git rm --cached foo

Bunn answered 11/9, 2012 at 16:2 Comment(13)
Also you can add --cache flag to remove file only from repository, and leaving untouch in filesystem.Rafferty
What would be the process to undo this operation, that is, un-stage the file for deletion? Is that possible?Galla
Just answered my own question... git reset HEAD <file> followed by a git checkout <file> seems to do the trick!Galla
If you want to delete files in a directory, you could use git rm -r directoryPolitesse
@Bunn This still gives me Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: sites/default/settings.php How do I add the file to be committed ?Butterball
@pal4life: you don't add the file to be committed, since you want its deletion to be committed, not its addition. git rm does just that. When you next git commit the deletion will be committed.Bunn
Actually OP asked how to stage already_deleted file and this can be done by git status | grep 'deleted:' | cut -d':' -f2 | xargs -t -I {} git add -u "{}" . Other answers seem to be showing how to stage file removal correctly (but not how to stage already deleted files). ps. the xargs based command works for me on Ubuntu 12.04, however when I manually do git add -u deleted_file.txt it doens't work. My git is 1.7.9.5Reynolds
@DimitryK: git rm will happily stage a file for deletion even if it's already been deleted from the filesystem. And as OP's comment on another answer points out, they wanted to stage one specific file that was already deleted.Bunn
this does not work for filenames with spaces, 'git add -u' does if needed.Pyrogenic
git rm doesn't stage already removed files. It throws this error: fatal: pathspec '~.SLDASM' did not match any files. Here are screens with proof: i.imgur.com/cKNKGGe.png i.imgur.com/1p9JdWF.png . First screenshot clearly shows that 2 files are deleted and not staged, second screenshot shows that when I type git rm "~$Box.SLDASM", it throws this error.Layer
@KulaGGin: read the error message. It's not trying to delete a file with "$Box" in the name because your shell got rid of that for you. Add more quotes if you're going to have files with horrible names.Bunn
@DimitryK how is it better from just git add -u?Mowery
@Mowery if you're asking why this long command is better than just manually typing git add -u <filename> - the long command adds all of the deleted files, not just one. Otherwise, I can't remember why it is better :) as I wrote this comment 8 years ago!Reynolds
C
484

Even though it's correct to use git rm [FILE], alternatively, you could do git add -u.

According to the git-add documentation:

-u --update

Update the index just where it already has an entry matching [FILE]. This removes as well as modifies index entries to match the working tree, but adds no new files.

If no [FILE] is given when -u option is used, all tracked files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories).

Upon which the index will be refreshed and files will be properly staged.

Cluny answered 11/9, 2012 at 16:36 Comment(7)
Yes git add -A . will add all changes, I specifically wanted to stage one deleted file.School
This will add all modified files; Not just deleted files.Politesse
That is correct. More specifically, it will stage all the changes in files that are already tracked, whether deleted or just modified. This helps when you delete multiple files and don't want to stage them individually.Cluny
Is there a way to only stage deleted files and not modified? Just curious.Mangonel
I am not aware of such option. In such cases, I individually stage deleted files with git rm file1 file2 command. If there are a lot of deleted files and less of modified, do git add -u followed by git reset file1 file2 command. On the whole, I think you can't avoid individual directories or files in these cases.Cluny
I did git add -u FolderWithDeletedFiles/ and it did what I want, thanksDisfrock
This works even when the directory (folder) containing the delete file has also been deleted.Terryn
O
206

To stage all manually deleted files you can use:

git rm $(git ls-files --deleted)

To add an alias to this command as git rm-deleted, run:

git config --global alias.rm-deleted '!git rm $(git ls-files --deleted)'
Octopus answered 24/12, 2015 at 16:26 Comment(8)
the $() notation aparently doesn't exist in windows bash console, leading to unknown option `deleted)Sperm
I don’t think this works if you have spaces in your path, either. At least, it doesn’t on my system (with zsh).Mainis
In windows do for /F %I in ('git ls-files --deleted') do git add -u %IInterposition
this does not work for filenames with spaces, 'git add -u' does if needed.Pyrogenic
Minor, but I would just replace git rm with git add since I the files are already deleted and I am only updating the index.Kep
In Windows Powershell Core I use git add (git ls-files --deleted) or more bravely git add (git ls-files --deleted) && git commit -m "deletions"Liquidity
"fatal: No pathspec was given. Which files should I remove?"Draft
How would that work if the filenames contain spaces?Fania
G
52

Since Git 2.0.0, git add will also stage file deletions.

Git 2.0.0 Docs - git-add

< pathspec >…

Files to add content from. Fileglobs (e.g. *.c) can be given to add all matching files. Also a leading directory name (e.g. dir to add dir/file1 and dir/file2) can be given to update the index to match the current state of the directory as a whole (e.g. specifying dir will record not just a file dir/file1 modified in the working tree, a file dir/file2 added to the working tree, but also a file dir/file3 removed from the working tree. Note that older versions of Git used to ignore removed files; use --no-all option if you want to add modified or new files but ignore removed ones.

Gabel answered 27/3, 2017 at 20:52 Comment(3)
The accepted answer doesn't solve the problem - and the other are more cumbersome since Git 2.0.0 - this is the best way! You have my upvoteMealie
There's an important caveat to this: something like git add foo/*/deleted.file won't work, because the * only expands to files that still exist. You can use other patterns that don't rely on files existing, though, such as git add foo/{bar,baz,quux}/deleted.fileDianthus
@Dianthus If files have been deleted from the file system at foo/*/deleted.file, you can also stage them for deletion by putting single quotes around the path, including the wildcard. That prevents the operating system from trying to expand the wildcard, and instead git expands it and stages the deleted files: git add 'foo/*/deleted.file'.Saturniid
H
47

You can use this command

git add `git ls-files --deleted`

Explanation:

git ls-files --deleted - This command will return the filenames of all deleted files.

Homiletic answered 13/11, 2019 at 13:14 Comment(1)
does not work if file names have spacesTrappings
S
39

to Add all ready deleted files

git status -s | grep -E '^ D' | cut -d ' ' -f3 | xargs git add --all

thank check to make sure

git status

you should be good to go

Sharpen answered 9/12, 2015 at 15:28 Comment(4)
Confirming that this works. I think the lesson here though is to not do rm <file>, but rather git rm <file>Dituri
FYI: cutting on spaces causes issues if any paths have spaces in themAdherent
this does not work for filenames with spaces, 'git add -u' does if needed.Pyrogenic
Works perfectly for me on git version 2.15.2 (Apple Git-101.1).Judsen
A
11

You can use

git rm -r --cached -- "path/to/directory"

to stage a deleted directory.

Alveraalverez answered 16/1, 2015 at 14:34 Comment(0)
S
7

If you want to simply add all the deleted files to stage then you can use git add .

This is the easiest way right now with git v2.27.0. Note that using * and . are different approaches. Using git add * would only add currently present files whereas git add . would also stage the files deleted with rm command.

It's obvious but worth mentioning that other files which have been modified would also be added to the staging area when you use git add ..

Sentence answered 9/2, 2021 at 19:55 Comment(0)
D
6

Ian Mackinnon found the answer, but it's better with xargs:

git ls-files --deleted -z | xargs -r0 git rm

As a git alias:

git config --global alias.rm-deleted '!git ls-files --deleted -z | xargs -r0 git rm'

This uses xargs with NUL termination (the only byte guarranteed not to appear in a path) and the option to not run git rm if the file list is empty.

This syntax is also fish compatible.

Dryasdust answered 20/8, 2020 at 18:45 Comment(0)
O
5

for those using git 2.x+ in powershell:

foreach ($filePath in (git ls-files --deleted)) { git add "$filePath" }
Ory answered 21/4, 2020 at 20:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.