简体   繁体   English

在 git commit 范围内搜索文本

[英]Search for text in git commit range

I need to search for text "TEXT" in past 20 git commits (or range)我需要在过去 20 次 git 提交(或范围)中搜索文本“TEXT”
I need to see filename and line number where I have a match.我需要查看匹配的文件名和行号。

Note:注意:
I want to search commits content, but not project on that commit as git grep does.我想搜索提交内容,但不像git grep那样在该提交上进行项目。
By commits content I mean what I can see using git diff HEAD^^^..HEAD通过提交内容我的意思是我可以看到使用git diff HEAD^^^..HEAD

Closest I got is using git log --raw -GTEXT , it shows me commit which contains "TEXT" in commit content and show file names.我得到的最接近的是使用git log --raw -GTEXT ,它向我显示提交内容中包含“TEXT”并显示文件名的提交。 Still no line numbers however.然而仍然没有行号。

And with some piping还有一些管道
git diff $(git log -n 20 --pretty=format:%h -GTEXT) | grep -E 'TEXT|\\+\\+\\+|@@\\s'
It is still somewhat wordy and with a lot of noise, if you have better solution, please answer.还是有点罗嗦,噪音很大,如果有更好的解决方法,请回答。

Get the last 20 commits:获取最后 20 次提交:

git log -n 20

Get each to an associative array:获取每个关联数组:

declare -A COMMITS # Declare associative array
COMMITNUMBER=0

while read -r line; do # For each line, do
    # Add 1 to COMMITNUMBER, if the current line contains "commit [0-9a-f]* (e.g., new associative array index for each commit)
    # As this'll happen straight way, our array is technically 1-indexed (starts from "${COMMITS[1]}", not "${COMMITS[0]}")
    REGEX="commit\s[0-9a-f]*"
    [[ "$line" =~ $REGEX ]] && COMMITNUMBER=$(( COMMITNUMBER+1 ))

    # Append the commit line to the index
    COMMITS[$COMMITNUMBER]="${COMMITS[$COMMITNUMBER]} $line"
done < <(git log -n 20)

Then iterate:然后迭代:

for i in "${!COMMITS[@]}"
do
  echo "key  : $i"
  echo "value: ${COMMITS[$i]}"
done

This gives similar output to below:这给出了与以下类似的输出:

key  : 1
value:  commit 778f88ec8ad4f454aa5085cd0c8d51441668207c Author: Nick <nick.bull@jgregan.co.uk> Date:   Sun Aug 7 11:43:24 2016 +0100  Second commit 
key  : 2
value:  commit a38cd7b2310038af180a548c03b086717d205a61 Author: Nick <nick.bull@jgregan.co.uk> Date:   Sun Aug 7 11:25:31 2016 +0100  Some commit

Now you can search each in the loop using grep or anything, and match what you need:现在您可以使用grep或任何东西搜索循环中的每个,并匹配您需要的内容:

for i in "${!COMMITS[@]}"
do
    REGEX="Date:[\s]*Sun\sAug\7"
    if [[ "${COMMITS[$i]}" =~ $REGEX ]]; then
        echo "The following commit matched '$REGEX':"
        echo "${COMMITS[$i]}"
    fi
done

Altogether:总而言之:

search_last_commits() {
    [[ -z "$1" ]] && echo "Arg #1: No search pattern specified" && return 1
    [[ -z "$2" ]] && echo "Arg #2: Number required for number of commits to return" && return 1

declare -A COMMITS # Declare associative array
COMMITNUMBER=0

    while read -r line; do # For each line, do
        # Add 1 to COMMITNUMBER, if the current line contains "commit [0-9a-f]* (e.g., new associative array index for each commit)
        # As this'll happen straight way, our array is technically 1-indexed (starts from "${COMMITS[1]}", not "${COMMITS[0]}")
        REGEX="commit\s[0-9a-f]*"
        [[ "$line" =~ $REGEX ]] && COMMITNUMBER=$(( COMMITNUMBER+1 ))

        # Append the commit line to the index
        COMMITS[$COMMITNUMBER]="${COMMITS[$COMMITNUMBER]} $line"
    done < <(git log -n $2)

    for i in "${!COMMITS[@]}"
    do
        REGEX="$1"
        if [[ "${COMMITS[$i]}" =~ $REGEX ]]; then
            echo "The following commit matched '$REGEX':"
            echo "${COMMITS[$i]}"
        fi
    done
}

EDIT :编辑

Usage:用法:

search_last_commits <search-term> <last-commits-quantity>

Example:示例:

search_last_commits "Aug" 20

如果你想在范围内搜索修改过的文件(并且不关心那些提交中没有实际修改的文件的匹配行),你可以运行:

git grep TEXT -- $(git diff --name-only RANGE)

The easiest way: GIT_SEQUENCE_EDITOR=: git rebase --exec "git rev-parse HEAD; git --no-pager grep -n 'TEXT_TO_FIND'; echo " -i HEAD~20最简单的方法: GIT_SEQUENCE_EDITOR=: git rebase --exec "git rev-parse HEAD; git --no-pager grep -n 'TEXT_TO_FIND'; echo " -i HEAD~20

Details:详情:

git rev-parse HEAD - show the current sha1 git rev-parse HEAD - 显示当前的 sha1

git --no-pager grep -n 'TEXT_TO_FIND' - the grep command to find your text, you can use here any other command (like regular grep etc.) git --no-pager grep -n 'TEXT_TO_FIND' - 用于查找文本的 grep 命令,您可以在此处使用任何其他命令(如常规grep等)

echo - a command to print empty line between each commit, and make sure that the return value is always OK echo - 在每次提交之间打印空行的命令,并确保返回值始终正常

HEAD~20 - how many commit back do you want to search (here I did 20) HEAD~20 - 你想搜索多少回提交(这里我做了 20 个)

Some helpful answers: link1 link2一些有用的答案: link1 link2

Try this out :试试这个:

echo `git log --raw --pretty=format:%h -GTEXT | xargs | awk '{print $NF}'` ;grep -ni 'MAX_STR_LEN' $(git log --raw --pretty=format:%h -GMAX_STR_LEN | xargs | awk '{print $NF}')

This works for me for single commit version.这适用于我的单一提交版本。 May be you can loop for n number of times to achieve your goal.可能你可以循环 n 次来实现你的目标。

git grep SEARCH `git rev-list HEAD~20..HEAD`

Specify whatever range you need.指定您需要的任何范围。

The result will be a grep for each revision.结果将是每个修订版的 grep。 That is, you see all occurrences in each revision.也就是说,您会看到每个修订版中的所有事件。 You do not see what changed relative to the previous revision.您看不到相对于先前修订版的更改。 (other by comparing yourself to the lines listed for the previous revision) (其他通过将自己与上一修订版中列出的行进行比较)

Also it is quite slow.它也很慢。 Since it does a full grep on each revision in the range.因为它对范围内的每个修订版都进行了完整的 grep。


Alternatively you can limit it to revisions (within the range) in which there was a change related to the search term.或者,您可以将其限制为与搜索词相关的更改(在范围内)。

git grep SEARCH  `git log -G SEARCH  --format=%H HEAD~20..HEAD`

While limited to revisions with related search, again in each such revision you get all lines.虽然仅限于具有相关搜索的修订,但在每个此类修订中,您都会获得所有行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM