Bash 函数在 git 存储库中搜索与正则表达式匹配的文件名

Bash function to search git repository for a filename that matches regex

我试图在我的 .bashrc 文件中将 Handyman5's gist (which is a comment on this answer, in this question) 作为 bash 函数实现。

:<<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 Stack Overflow user Handyman5
   - https://whosebug.com/users/459089/handyman5
   which is based on this SO question:
   - 

   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's the empty string)
      param=$(echo "" | 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 都是新手,所以我说的是真心话)。输出现在非常清晰并且有用。我确实注意到它缺少一些点击。例如,这里有一个 small repository (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(第一次提交)、[=​​19=] 和 3c5e4ec

现在的脚本似乎只是在搜索分支。听起来您希望它搜索分支以及这些分支上的所有提交。为此,您需要在脚本中添加另一个 for 循环,该循环遍历您正在搜索的每个分支上的提交。像这样:

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

您还可以通过缩进文件路径并在不同提交之间添加 space 来清理脚本的输出。像这样:

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 语句的括号前后添加 space。像这样:if [ "$wasFound" -eq 0 ];