Поиск текста в диапазоне git commit

Мне нужно найти текст "ТЕКСТ" в прошлые 20 git совершает (или диапазон)
Мне нужно увидеть имя файла и номер строки, где у меня есть совпадение.

Примечание:
Я хочу искать контент коммитов, но не проект на этом деле, как git grep.
По коммит-контенту я имею в виду то, что вижу, используя git diff HEAD^^^..HEAD

Ближе всего я использую git log --raw -GTEXT, он показывает мне commit, который содержит "ТЕКСТ" в сообщении о контенте и именах файлов. Тем не менее, номера строк отсутствуют.

И с некоторыми трубопроводами
git diff $(git log -n 20 --pretty=format:%h -GTEXT) | grep -E 'TEXT|\+\+\+|@@\s'
Это еще несколько словесный и с большим количеством шума, если у вас есть лучшее решение, ответьте.

Ответ 1

Получите последние 20 коммитов:

git log -n 20

Получить каждый из ассоциативных массивов:

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)

Затем итерация:

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

Это дает аналогичную информацию ниже:

key  : 1
value:  commit 778f88ec8ad4f454aa5085cd0c8d51441668207c Author: Nick <[email protected]> Date:   Sun Aug 7 11:43:24 2016 +0100  Second commit 
key  : 2
value:  commit a38cd7b2310038af180a548c03b086717d205a61 Author: Nick <[email protected]> Date:   Sun Aug 7 11:25:31 2016 +0100  Some commit

Теперь вы можете искать каждый в цикле с помощью 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

Итого:

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
}

ИЗМЕНИТЬ:

Использование:

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

Пример:

search_last_commits "Aug" 20

Ответ 2

Самый простой способ: GIT_SEQUENCE_EDITOR=: git rebase --exec "git rev-parse HEAD; git --no-pager grep -n 'TEXT_TO_FIND'; echo " -i HEAD~20

Подробнее:

git rev-parse HEAD - показать текущий sha1

git --no-pager grep -n 'TEXT_TO_FIND' - команда grep для поиска вашего текста, вы можете использовать здесь любую другую команду (например, обычный grep и т.д.)

echo - команда для печати пустой строки между каждой фиксацией и убедитесь, что возвращаемое значение всегда ОК

HEAD~20 - сколько верните назад, вы хотите выполнить поиск (здесь я сделал 20)

Некоторые полезные ответы: link1 link2

Ответ 3

Попробуйте следующее:

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}')

Это работает для меня для одной версии фиксации. Может быть, вы можете занять несколько раз для достижения своей цели.