#!/bin/bash # # git-blob-ids: List blobs (hash id and path) in a git repo # # Usage: git-blob-ids [-s] [-r REF] [-p PATH] # # -r REF an optional reference to a commit (hash or symbolic like HEAD), default: HEAD # -p PATH an option path to a subtree in repo, default is blank for root tree # -s shortens blob hash ids to 6 characters # function short { echo $@ | awk '{print substr($1,0,6);}'; } function nochange { echo $@; } ref=HEAD path= idfunc=nochange while getopts "sr:p:" options; do case "${options}" in s) idfunc=short ;; r) ref=${OPTARG} ;; p) path=${OPTARG} ;; esac done if [[ ${#path} > 0 ]]; then tree=$ref:$path else # start from root tree tree=(`git cat-file -p $ref | head -1 | awk '{print $2}'`) tree="${tree}|" fi # tokenize by line in git command output IFS=' ' # breadth-first iteration of sub-trees while [[ ${#tree} > 0 ]]; do el=`echo $tree | awk '{print $1}'` t=`echo $el | awk -F"|" '{print $1}'` path=`echo $el | awk -F"|" '{print $2}'` if [[ ${#path} > 0 ]]; then pfx=$path/ fi # pop tree=`echo $tree | sed 's/[^ ]* *//'` for l in `git cat-file -p $t`; do if [[ $l =~ "blob" ]]; then blob=`echo $l | sed 's/.* blob //;s/\t.*//'` blob=`$idfunc $blob` lpath=`echo $l | sed 's/.* blob //;s/.*\t//'` # output blob info echo $blob $pfx$lpath elif [[ $l =~ "tree" ]]; then id=`echo $l | sed 's/.* tree //;s/\t.*//'` lpath=`echo $l | sed 's/.* tree //;s/.*\t//'` # push if [[ ${#tree} > 0 ]]; then tree="${tree} $id|$pfx$lpath" else tree="$id|$pfx$lpath" fi fi done done