Bash функция для поиска репозитория git для имени файла, которое соответствует регулярному выражению

Я пытаюсь реализовать Handyman5 gist (который является комментарием этого ответа, в этот вопрос) как функция bash в моем файле .bashrc.

:<<COMMENT
   Searches all commits in the current git repository for a file that matches a regular expression.

   Usage: gitf <regex>

   Parameter is required, and must be at least one non-whitespace character.

   Based on the GitHub gist
   - https://gist.github.com/anonymous/62d981890eccb48a99dc
   written by Qaru user Handyman5
   - https://stackoverflow.com/users/459089/handyman5
   which is based on this SO question:
   - /info/22799/how-can-i-search-git-branches-for-a-file-or-directory372654#372654

   Short description: Stored in GITF_DESC
COMMENT
#GITF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
GITF_DESC="gitf [searchterm]: Searches the current git repository for the file name that matches a regular expression.\n"

Тело функции:

gitf()  {
   set +x
   #Exit if no parameter is provided (if it the empty string)
      param=$(echo "$1" | trim)
      echo "$param"
      if [ -z "$param" ]  #http://tldp.org/LDP/abs/html/comparison-ops.html
      then
        echo "Required parameter missing. Cancelled"; return
      fi

   wasFound="0";
   LOC=refs/remotes/origin # to search local branches only: 'refs/heads'
   ref="%(refname)"
   for branch in `git for-each-ref --format="$ref" $LOC`; do
      found=$(git ls-tree -r --name-only $branch | grep "$param")
      if [ $? -eq 0 ]; then
         echo "${branch#$LOC/}: $ref:"; echo " $found"
         wasFound="1";
      fi
   done

   if ["$wasFound" -eq 0]; then
      echo "No files in this repository match '$param'."
   fi
   set -x
}

Я пытаюсь заставить его распечатать его, поэтому я могу быстро это проверить. Но это только печатает путь к файлу, несмотря на эхо. Любое руководство к тому, что мне не хватает?

Токовый выход для gitf "05":

$ gitf "05"
+ gitf 05
+ set +x
05
master:
non_django_files/wordpress_posts/build_java/BuildPart05.java
non_django_files/wordpress_posts/templates/05_login_remember_me.html
[1: command not found
++ history -a

Я уверен, что последние две строки являются несвязанной проблемой .bashrc или .inputrc, но я включаю их в случае, если они релевантны.


@SwankSwashbucklers: Спасибо, что в основном выполняю свою работу для меня (я новичок как в bash, так и в Git, поэтому я говорю это искренне). Результат теперь очень ясный и полезный. Я замечаю, что у него отсутствуют некоторые хиты. Вот, например, небольшой репозиторий (например, 2mb zip). Поиск "05" отвечает

$ gitf 05
05
master: 14e5cdd:
  non_django_files/wordpress_posts/build_java/BuildPart05.java
  non_django_files/wordpress_posts/templates/05_login_remember_me.html
master: 2efdeb1:
  non_django_files/wordpress_posts/build_java/BuildPart05.java
  non_django_files/wordpress_posts/templates/05_login_remember_me.html

Эти две фиксации являются последними двумя, если это что-то значит. 05_login_remember_me.html также существует, по крайней мере, f87540e (самое первое коммит), 3a7dac9 и 3c5e4ec.

Ответ 1

script, поскольку он прямо сейчас, похоже, просматривает ветки. Похоже, вы хотите, чтобы он просматривал ветки и все коммиты на этих ветвях. Для этого вам нужно добавить еще один цикл для вашего script, который выполняет итерацию через фиксации на каждой из ветвей, которые вы ищете. Что-то вроде этого:

for branch in `git for-each-ref --format="$ref" $LOC`; 
do
    for commit in `git rev-list $branch | grep -oP ^.\{7\}`; 
    do
        found=$(git ls-tree -r --name-only $commit | grep "$param")
        if [ $? -eq 0 ]; 
        then
            echo "${branch#$LOC/}: $commit:"; echo " $found"
            wasFound="1";
        fi
    done
done

Вы также можете очистить вывод своего script, вставив в него пути к файлам и добавив пространство между различными коммитами. Вот так:

for branch in `git for-each-ref --format="$ref" $LOC`; 
do
    for commit in `git rev-list $branch | grep -oP ^.\{7\}`; 
    do
        found=$(git ls-tree -r --name-only $commit | grep "$param")
        if [ $? -eq 0 ]; 
        then
            echo "${branch#$LOC/}: $commit:"
            while read line;
            do
                echo "  $line"
            done < <(echo "$found")
            wasFound="1";
        fi
    done
done

И, как упоминалось в комментариях, вам нужно добавить пробел после и перед скобками вашего оператора if. Например: if [ "$wasFound" -eq 0 ];