bashgitshellplasticscm

Parsing gitignore in bash/coreutils without git


My goal is to copy all files from a directory except those that are specified in an ignore file to another directory. However, imagine git is not installed (it's using Plastic SCM, but the ignore format is identical to gitignore for all intents and purposes). How would you go about doing this in bash?


Solution

  • This strips out comments and empty lines from the ignore file:

    grep -v '^#' ~/.config/git/ignore | grep '[^[:blank:]]'
    

    Join those lines with a pipe character and capture in a variable

    ignores=$(grep -v '^#' ~/.config/git/ignore | grep '[^[:blank:]]' | paste -sd '|')
    

    Enagle extended globbing

    shopt -s extglob nullglob
    

    and now this will show the non-ignored files in the current directory

    echo !($ignores)
    

    to find non-ignored files descending into directories, this might work (I don't know the git internals, this is a guess)

    # read the ignores into an array
    readarray -t ign < <(grep -v '^#' ~/.config/git/ignore | grep '[^[:blank:]]')
    
    # construct find options
    find_opts=()
    for i in "${ign[@]}"; do find_opts+=( -o -name "$i" ); done
    
    # do it
    find . -type f \
           -not '(' "${find_opts[@]:1}" ')' \
           -exec printf 'do something with: %s\n' {} +