Как выполнить Git коммитов diff или содержимого для определенного слова?

В репозитории Git-кода я хочу перечислить все коммиты, которые содержат определенное слово. Я пробовал это

git log -p | grep --context=4 "word"

но это не обязательно возвращает мне имя файла (если оно не менее 5 строк от слова, которое я искал. Я также пытался

git grep "word"

но это дает мне только настоящие файлы, а не историю.

Как мне искать всю историю, чтобы отслеживать изменения в определенном слове? Я имею в виду искать в моей кодовой базе вхождения слова, чтобы отследить изменения (поиск в истории файлов).

9 ответов

Решение

Если вы хотите найти все коммиты, где сообщение о коммите содержит данное слово, используйте

$ git log --grep=word

Если вы хотите найти все коммиты, где "слово" было добавлено или удалено в содержимом файла (а точнее: где изменилось число вхождений "слова"), то есть поиск по содержимому коммита, используйте так называемый поиск "кирки" с

$ git log -Sword

В современном git есть также

$ git log -Gword

искать различия, чья добавленная или удаленная строка соответствует "слову" (также фиксирует содержимое).

Обратите внимание, что -G по умолчанию принимает регулярное выражение, а -S принимает строку, но может быть изменена для принятия регулярных выражений, используя --pickaxe-regex,

Чтобы проиллюстрировать разницу между -S<regex> --pickaxe-regex а также -G<regex>рассмотрим коммит со следующим diff в том же файле:

+    return !regexec(regexp, two->ptr, 1, &regmatch, 0);
...
-    hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);

В то время как git log -G"regexec\(regexp" покажет этот коммит, git log -S"regexec\(regexp" --pickaxe-regex не будет (потому что количество вхождений этой строки не изменилось).

git logкирка найдет коммиты с изменениями, включая "слово" с git log -Sword

После долгих экспериментов я могу порекомендовать следующее, которое показывает коммиты, которые вводят или удаляют строки, содержащие заданное регулярное выражение, и отображает изменения текста в каждом, а цвета показывают слова, добавляемые и удаляемые.

git log --pickaxe-regex -p --color-words -S "<regexp to search for>"

Требуется время, чтобы бежать, хотя...;-)

Вы можете попробовать следующую команду:

git log --patch --color=always | less +/searching_string

или используя grep следующим образом:

git rev-list --all | GIT_PAGER=cat xargs git grep 'search_string'

Запустите эту команду в родительском каталоге, где вы хотите искать.

Еще один способ / синтаксис сделать это: git log -S "word"
Как это вы можете искать, например, git log -S "with whitespaces and stuff @/#ü !"

Чтобы использовать логический соединитель для регулярного выражения:

git log --grep '[0-9]*\|[a-z]*'

Это регулярное выражение для поиска регулярного выражения [0-9]* или [az]* в сообщениях фиксации.

Это полезно в сочетании с BGF / git-filter-repo, оно просто получает пути к файлам, чтобы вы могли передать их в один из двух инструментов, которые я только что упомянул.

A. Полные, уникальные, отсортированные пути:

      # Get all unique filepaths of files matching 'password'
# Source: https://stackoverflow.com/a/69714869/10830091
git rev-list --all | (
    while read revision; do
        git grep -F --files-with-matches 'password' $revision | cat | sed "s/[^:]*://"
    done
) | sort | uniq

Б. Уникальные отсортированные имена файлов (не пути):

      # Get all unique filenames matching 'password'
# Source: https://stackoverflow.com/a/69714869/10830091
git rev-list --all | (
    while read revision; do
        git grep -F --files-with-matches 'password' $revision | cat | sed "s/[^:]*://"
    done
) | xargs basename | sort | uniq

Эта вторая команда полезна для BFG, потому что она принимает только имена файлов, а не репо-относительные / системные пути.

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

Расслоение

Получить только имена / пути к файлам

Любой из следующих вариантов означает то же самое ( git-rep docs):

  • -l
  • --files-with-matches
  • --name-only

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

Ваш шаблон: A. Regex vs B. Fixed String?

Что касается -F, это просто означает использование фиксированной строки вместо регулярного выражения для интерпретации шаблона. Источник здесь .

Еще одно полезное примечание, которое принадлежит сюда, вы можете добавить -i или --ignore-caseбыть к нечувствительнымрегистру .

Избавьтесь от этого глупого ведущего хеша коммита

      sed "s/[^:]*://"

Источник .

Получите им уникальные пути!

      | sort | uniq

Кому нужны дублированные пути? не ты, не я! Ой, смотрите, они тоже отсортированы! Наслаждаться. Источник: я. Я использовал это столько, сколько себя помню.( man sort а также man uniq)

А как насчет имен файлов без путей?

      xargs basename

Вы могли бы подумать | basenameбудет работать, но нет. Он не принимает входной STDIN, но в качестве аргументов командной строки, вот объяснение этого. basename в основном возвращает основное имя файла без начального пути. man basename

Вдохновения

vim-fugitive универсален для такого рода исследований в Vim.

использование :Ggrep сделать это. Для получения дополнительной информации вы можете установить vim-fugitive и посмотреть турориал по :help Grep, И этот эпизод: исследование-хранилище-истории-git-репозитория поможет вам сделать все это.

Если вы хотите найти конфиденциальные данные для того, чтобы удалить их из своей истории мерзавцев (именно поэтому я попал сюда), для этого есть инструменты. Github в качестве специальной страницы справки по этому вопросу.

Вот суть статьи:

BFG Repo-Cleaner - более быстрая и простая альтернатива git filter-branch для удаления нежелательных данных. Например, чтобы удалить файл с конфиденциальными данными и оставить ваш последний коммит без изменений), выполните:

bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA

Чтобы заменить весь текст, указанный в файле passwords.txt, где бы он ни находился в истории вашего репозитория, запустите:

bfg --replace-text passwords.txt

См. Документацию BFG Repo-Cleaner для полного использования и инструкций по загрузке.

Другие вопросы по тегам