Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there a better solution for removing manually-removed files from the Git repository than my current error-prone command?

git status | grep deleted: | cut -d: -f2 | xargs git rm
share|improve this question
up vote 5 down vote accepted

I think you are asking to delete files from the index that were deleted from the working tree. The command git add -u will do that, in addition to adding any changes in the working tree (but not new files).

To do more exactly what you requested, the git-rm(1) manpage recommends the following, which is essentially the same as your solution but much less fragile.

If all you really want to do is to remove from the index the files that are no longer present in the working tree (perhaps because your working tree is dirty so that you cannot use git commit -a), use the following command:

git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
share|improve this answer
Sounds like a better way of doing it. Still a bit long for a command I do quite often. – Warren Seine Mar 1 '12 at 10:09
You could make it into a shell script — or a git alias. Also, git add -u is short, and if its behavior is a problem then you should maybe think about revising your workflow — why do you so frequently have changes to commit partially? – Kevin Reid Mar 1 '12 at 11:30
Typically, I embed headers from other libraries. When I update the library, I'd to take all changes from the directory (including removed files), but not mine. Or simply when I rename / move a bunch of files. – Warren Seine Mar 1 '12 at 21:06
If you want to apply all changes in a subdirectory, as in obtaining a new version of a library, then you can just use git add -A library/ and that will add all changes, including new and removed files, in that directory. – Kevin Reid Mar 1 '12 at 21:19

Hi i will point you to my script etckeeper-ng were i solved the same problem

I will describe shortly how you could do it better:

First create a helper file which can be parsed.

git status -s > $git_status_file

The git_status_file variable is in this case set to */tmp/git_status_file* The next i do is i use the $git_status_file as an input in a while loop:

while read line

  if [ $(echo $line |awk '{print $1}') == "D" 2> /dev/null ]
      # git uses "" to denote files with spaces in their names
      # and does not use "" when the name has no spaces
      # so we must distinguish these two cases
      del_file=$(echo $line |awk -F\" '{print $2}'|| echo "no")       
      del_file_S=$(echo $line | awk '{print $2}')

      # ensures that del_file is a full string

      # delete the file, ${del_file:0} expands to  the full file name
      # this is important for files with blanks in their names
      git rm "${del_file:0}" 2> /dev/null|| git rm $del_file_S 2> /dev/null

# this line does only work on non-possix shells
done < <($git_status_file)

This actually does work with my etckeeper-ng module where i solved the problem this way. hope that this helped.

share|improve this answer
You don't need that cat - Just use done < "$git_status_file" – l0b0 Mar 1 '12 at 9:32
Unfortunately, I can't accept something relying on a shell script. This is a command I do and I need to be able to do it with Git only. – Warren Seine Mar 1 '12 at 10:07
@I0b0 thank you. I've corrected this. – l1zard Mar 1 '12 at 13:27
@Warren Seine: no problem. but maybe the other solution is also more error prune for my script too. – l1zard Mar 1 '12 at 13:29

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.