#!/usr/bin/env bash
# Desc: Grep search filenames of all git committed work trees
# Usage: git-bk-find-file [string grep pattern]
# Example git-bk-find-file '.txt$'
# Ref/Attrib: albfan "How can I search Git branches for a file or directory?" https://stackoverflow.com/a/16868704/10850071
# Version: 0.2.0
# Depends: GNU bash v5.1.16, GNU parallel 20210822

yell() { echo "$0: $*" >&2; } # print script path and all args to stderr
die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status
must() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails
check_depends() {
    # Desc: Check dependencies
    # Usage: check_depends
    # Depends: GNU parallel 20210822
    if ! command -v parallel 1>/dev/random 2>&1; then die "FATAL:Missing:parallel"; fi;
    if ! command -v git 1>/dev/random 2>&1; then die "FATAL:Missing:git"; fi;
};
check_args() {
    if [[ $# -le 0 ]]; then die "FATAL:Incorrect number of args:$#"; fi;
}; # check arguments
display_commit() {
    # Show commit if filename in committed tree matches grep pattern
    # Input: arg1: commit id
    #        args2+: passed to grep
    # Output: stdout
    # Depends: git 2.34.1
    local commit results;
    
    commit="$1"; shift;

    # Decide if need to show commit at all
    if results="$(git ls-tree -r --name-only "$commit" | grep "$1")"; then
        # Get commit timestamp
        time="$(git -c log.showSignature=false show -s --format=%cI "$commit")";

        # Get first 8 chars of commit
        short_commit="${commit:0:8}";

        # Output results
        while read -r line; do
            if [[ -z "$line" ]]; then continue; fi; # skip blank lines
            printf "%s %s %s\n" "$time" "$short_commit" "$line";
        done < <(printf "%s\n" "$results");
    fi;
    
    return 0;
}; # display commit
main() {
    check_depends;
    check_args "$@";
    export -f yell die must display_commit;
    git rev-list --all | parallel --jobs=75% display_commit "{}" "$@";
};

main "$@";

# Author: Steven Baltakatei Sandoval
# License: GPLv3+