Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git rm * doesn't remove all files in one go

Tags:

git

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

like image 528
Anshul Goyal Avatar asked Oct 14 '13 15:10

Anshul Goyal


2 Answers

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 '*'
like image 181
tripleee Avatar answered Nov 11 '22 21:11

tripleee


Shell Globbing

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 *
    
like image 33
Todd A. Jacobs Avatar answered Nov 11 '22 21:11

Todd A. Jacobs