I was trying out some sample instructions of git and came across this peculiar case that when we do a git rm *
, it doesn't delete the .*
files in the first attempt.
Why is it so?
mkdir -p test_repo1/folder && cd test_repo1
touch .testfile1 .testfile2 testfile3 folder/testfile4 folder/.testfile5
git init && git add . && git commit -m "test commit"
If now I do a git rm
as follows, I have to do it a second time to remove all the files
$ git rm -r *
rm 'folder/.testfile5'
rm 'folder/testfile4'
rm 'testfile3'
$ git rm -r *
rm '.testfile1'
rm '.testfile2'
Why doesn't git remove all files in the first attempt itself? Also, why is this happening for files withing the repo root only?
Interestingly, if all I have are those .testfiles
, then git removes them in the first attempt itself.
I am using git version 1.7.9.5
The wildcard gets expanded by your shell, and the expansion does not include dot files, by default, in most shells.
So by the time git
executes, the first command has become
git rm -r folder testfile3
and the second probably a literal
git rm -r *
which git
then expands by itself.
As remarked by Keith, to remove everything in one go, prevent the shell from expanding the wildcard so that git
does the expansion the first time already. This can be done with double or single quotes, or with a backslash before the asterisk. I tend to prefer single quotes:
git rm -r '*'
When you run git rm *
you are actually using the shell's globbing rules to pass arguments to git-rm(1). Many shells don't include hidden files (e.g. files with leading dots) by default. In Bash, you can change the globbing rules with dotglob and GLOBIGNORE. For example:
Using the shopt builtin:
# set dotglob
shopt -s dotglob
git rm *
# unset dotglob
shopt -u dotglob
Using the GLOBIGNORE variable (which also sets dotglob):
# Run git within a modified environment that includes GLOBIGNORE.
GLOBIGNORE='.git' git rm *
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With