3

I noticed my git repository has a lot of .keep files. They were once useful when their parent directories were otherwise empty, but since then a lot of the directories now have real children that keep them alive in git.

Is there a nice way to remove all unneeded .keep files? Particularly, those that:

  1. Have 0 size (no real content)
  2. Have precisely the name .keep
  3. Have neighbors in their folders (i.e. their deletion wouldn't lead to their parent folders becoming empty)

I looked at the docs of git gc, git clean, etc. but I didn't find such a feature.

Alexander
  • 59,041
  • 12
  • 98
  • 151

3 Answers3

2

Git does not have any mention on what a keep file is, so its name is just a convention (.gitkeep, .keep, etc). This is why git-clean is does not support anything like that. I can't think of an extremely easy of doing that, so I ended up with a small script like this:

#!/bin/bash

# read all directories without escaping
while IFS= read -r DIR; do
    # enter to each directory to simplify parsing
    pushd "$DIR" 1> /dev/null
    # ask git to list all tracked files in the current directory
    #   filtering out the .keep file (the inVerted -v grep switch)
    #   and checking if it is giving more than 1 line
    if [[ $(git ls-files | grep -Pv '^.keep$' | head -1) ]]; then
        # if true, just print out the directory along with its "keep" file
        echo "$DIR/.keep"
    fi
    popd 1> /dev/null
    # the -mindepth would enable the depth-first traversing
    #   (empty files only named .keep and never walk into .git directories -- print out directories only)
done < <(find -mindepth 1 -not -path '*/\.git/*' -type f -name '.keep' -empty -printf '%h\n')

This script would print out all redundant .keep files in dry run. If the generated like looks fine, pipe it with xargs: above_script_path | xargs git rm

2

Late to the party but you could run something like this which doesn't use git for tracked files but goes through all the directories:

find . -type d -exec sh -c '[[ $(ls -1A {} | wc -l) -gt 1 ]] && [ ! -s {}/.keep ] && rm -f {}/.keep' \;

find . -type d -exec sh -c '...' \;: Find all directories (recursive operation by default) and run the following shell command for that directory.

[[ $(ls -1A {} | wc -l) -gt 1 ]] && [ ! -s {}/.keep ] && rm {}/.keep': Run through each of the dirs and see if there are more than one files+directories located in them. If that is the case AND the file is empty, then delete .keep.

amtux
  • 41
  • 5
1

As you can read from Random 'concerns' folders and '.keep' files .keep files are just useful files to allow folders to be "committed" to a repository.

Here's a command to remove all .keep files. Then just commit that as you want afterwards.

zrrbite@ZRRBITE MINGW64 /d/dev/git/keeptest (master) 
$ git ls-files *.keep | xargs git rm                          
rm '.keep' 
rm 'test/.keep'
                                                         
zrrbite@ZRRBITE MINGW64 /d/dev/git/keeptest (master) 
$ git st                                                     
## master                                                    
D  .keep
D  test/.keep                                                 
zrrbite
  • 1,180
  • 10
  • 22
  • I wasn't trying to delete them all, I wanted to delete only those that would not cause the deletion (roughly speaking, because git doesn't track folders) of their parent folder – Alexander Oct 07 '20 at 20:55
  • Ah. I thought you only had `.keep` files in folders that were empty, otherwise. This way, you could remove them all and be safe. The other `.keep` files are redundant (since the folders are not empty) and could be added when needed. I think this is a cleaner approach (to not have `.keep` files in non-empty-folders). It sounds like you might just want to remove all .keep files because you don't want to "keep" empty folders. – zrrbite Oct 07 '20 at 21:16
  • 1
    It's a big repo, with *lots* of contributors. I don't know their motivation behind wanting to keep certain folders for future use, and I don't want to take that away from them. However, I can be sure that `.keep` files in otherwise non-empty files are certainly useless, and feel comfortable removing them. – Alexander Oct 07 '20 at 22:26