Remove all "deleted" files in Git

5

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

Warren Seine

Posted 2012-02-29T23:23:13.887

Reputation: 219

Answers

5

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

Kevin Reid

Posted 2012-02-29T23:23:13.887

Reputation: 2 854

Sounds like a better way of doing it. Still a bit long for a command I do quite often. – Warren Seine – 2012-03-01T10:09:44.397

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 – 2012-03-01T11:30:09.080

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 – 2012-03-01T21:06:47.383

2If 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 – 2012-03-01T21:19:40.753

0

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

https://github.com/tuxlover/etckeeper-ng/blob/master/modules/backup_git.sh

I will describe shortly how you could do it better:

First create a helper file which can be parsed.

git_status_file=/tmp/git_status_file
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
do

  if [ $(echo $line |awk '{print $1}') == "D" 2> /dev/null ]
    then
      # 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
      del_file="${del_file[*]}"


      # 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.

l1zard

Posted 2012-02-29T23:23:13.887

Reputation: 933

You don't need that cat - Just use done < "$git_status_file" – l0b0 – 2012-03-01T09:32:08.267

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 – 2012-03-01T10:07:49.237

@I0b0 thank you. I've corrected this. – l1zard – 2012-03-01T13:27:25.687

@Warren Seine: no problem. but maybe the other solution is also more error prune for my script too. – l1zard – 2012-03-01T13:29:35.637