27

How do I easily remove several files without manually typing the full paths of all of them to git rm? I have plenty of modified files I'd like to keep so removing all modified is not possible either.

And also it is possible to revert the changes of several files without manually typing git checkout -- /path/to/file?

Nick Volynkin
  • 11,882
  • 6
  • 39
  • 62
Tower
  • 87,855
  • 117
  • 329
  • 496

11 Answers11

41

You can give wildcards to git rm.

e.g.

git rm *.c

Or you can just write down the names of all the files in another file, say filesToRemove.txt:

path/to/file.c
path/to/another/file2.c
path/to/some/other/file3.c

You can automate this:

find . -name '*.c' > filesToRemove.txt

Open the file and review the names (to make sure it's alright).

Then:

cat filesToRemove.txt | xargs git rm

Or:

for i in `cat filesToRemove.txt`; do git rm $i; done

Check the manpage for xargs for more options (esp. if it's too many files).

Manish
  • 3,342
  • 1
  • 15
  • 16
11

Just delete them using any other method (Explorer, whatever), then run git add -A. As to reverting several files, you can also checkout a directory.

Ana Betts
  • 71,086
  • 16
  • 135
  • 201
  • 1
    Easiest method on this page. – Jon Jan 24 '13 at 19:12
  • i came here looking for an easier way than explorer. if I can find all files i want to remove using recursive search in bash i'd prefer not having to do this in explorer and go back to git bash to complete it. something like this _almost_ works find . -name "*debug*" -exec bash -c 'file={}; git rm $file' \; it's just using relative paths – Sonic Soul Nov 30 '15 at 18:16
  • beware of using the -A argument. "If no is given when -A option is used, all files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories)" With the `-A` argument you might stage changes that you were not ready to stage – Kay Jan 14 '21 at 21:53
4

I found git rm's handling of wild cards annoying. Find can do the trick in one line: find . -name '*.c' -exec git rm {} \; the {} is where the file name will be substituted. The great thing about find is it can filter on a huge variety of file attributes not just name.

CpILL
  • 4,495
  • 3
  • 32
  • 31
1

For removing multiple files at once, you might want to checkout the answer here

You can delete the files that you don't want and run this command: git rm $(git ls-files --deleted)

Community
  • 1
  • 1
krngrvr09
  • 113
  • 2
  • 9
1

You can simply use:

git add -u

From the official documentation

-u --update

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

If no 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).

In other words from this answer,

It will update or remove previously tracked files from the entire working tree. It will not add new files.

Kay
  • 562
  • 6
  • 23
Balman Rawat
  • 3,762
  • 1
  • 13
  • 9
1

On Windows 10, using Git Bash, from the .gitignore location in your file structure.

git rm -r --cached some_directory/

I just used this to ignore a whole directory, recursively. This is what is in my .gitignore file for this:

# Use .gitignore to ignore a directory and its contents #
/some_directory/ 
Kirk Powell
  • 881
  • 8
  • 14
1

On POSIX systems, you can create a shell glob that will match all desired files, you can simply pass that to git rm and git checkout --. On Windows, cmd.exe and PowerShell do not include globbing and farm that out to the applications (git doesn't do it for files, from what I've read). You would need to use a Windows command or script to prepare a file list and pipe it to your git commands appropriately to get a similar effect.

Any strategy that you would use to pass a list of files to a shell command will work for git commands that accept file paths.

jmlane
  • 1,961
  • 1
  • 15
  • 24
  • Oh, Windows' cmd.exe and PowerShell doesn't do globbing and git for Windows doesn't include this functionality as far as I know because it would break tree/branch/commit globbing (or so I've read). You would have to explore Windows' shell methods for file path matching. – jmlane Mar 02 '12 at 07:24
0

You could also check out Cygwin, as it provides much of the Unix/Linux/*BSD functionality on Windows. Cygwin includes a Bash shell and find(1), among other tools mentioned above. (I usually have 2-4 Cygwin mintty terminals up at one time on Windows 7 because I find Cygwin that handy.)

Mark Leighton Fisher
  • 5,431
  • 2
  • 14
  • 26
0

You simply use

find . -name '*.DS_Store' | xargs git rm

to remove many files match the wildcards.

Thengocphan
  • 18
  • 1
  • 5
0

Or you can just write down the names of all the files in another file, say filesToRemove.txt

That is a good approach with Git 2.26 (Q2 2020), since "git rm" and "git stash" learns the new "--pathspec-from-file" option.

So no more for i incat filesToRemove.txt; do git rm $i; done

A simple git rm --pathspec-from-file=filesToRemove.txt is enough.

See commit 8a98758, commit 8c3713c, commit 3f3d806, commit b229091, commit 0093abc, commit 2b7460d, commit 5f393dc (17 Feb 2020), and commit 6a7aca6 (16 Jan 2020) by Alexandr Miloslavskiy (SyntevoAlex).
(Merged by Junio C Hamano -- gitster -- in commit 9b7f726, 09 Mar 2020)

rm: support the --pathspec-from-file option

Signed-off-by: Alexandr Miloslavskiy

Decisions taken for simplicity:

It is not allowed to pass pathspec in both args and file.

Adjustments were needed for if (!argc) block:

This code actually means "pathspec is not present".
Previously, pathspec could only come from commandline arguments, so testing for argc was a valid way of testing for the presence of pathspec. But this is no longer true with --pathspec-from-file.

During the entire --pathspec-from-file story, I tried to keep its behavior very close to giving pathspec on commandline, so that switching from one to another doesn't involve any surprises.

However, throwing usage at user in the case of empty --pathspec-from-file would puzzle because there's nothing wrong with "usage" (that is, argc/argv array).

On the other hand, throwing usage in the old case also feels bad to me. While it's less of a puzzle, I (as user) never liked the experience of comparing my commandline to "usage", trying to spot a difference. Since it's already known what the error is, it feels a lot better to give that specific error to user.

Judging from commit 7612a1ef ("git-rm: honor -n flag" 2006-06-09, git v1.4.0), it doesn't seem that showing usage in this case was important (the patch was to avoid segfault), and it doesn't fit into how other commands react to empty pathspec (see for example git add with a custom message).

Therefore, I decided to show new error text in both cases.
In order to continue testing for error early, I moved parse_pathspec() higher. Now it happens before read_cache() / hold_locked_index() / setup_work_tree(), which shouldn't cause any issues.

VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
0

Easy way:

  • Delete files in your file explorer
  • use git ls-files --deleted | xargs git add to stage them. They will be removed in the remote once you push.

Git way: Referencing what @CpILL said (https://stackoverflow.com/a/34889424/6538751) use

  • find . -name 'DeleteMe*.cs' -exec git rm {} \;

you can utilize wildcards.

Andre
  • 1,587
  • 2
  • 6
  • 10