#!/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+