Использование git для поиска первого введения токена в определенной строке файла.

Допустим, у меня есть файл A.cpp, и я заметил ошибку в строке 15 файла. Допустим, ошибка представляет собой "const" в функции, которая возвращает указатель на переменную-член, то есть использование const в функции технически правильно, но семантически неправильно. Я хотел бы обсудить семантику с автором, который внес изменения.

Используя git, есть ли способ узнать, какая ревизия ввела токен "const"? Более конкретно, я хотел бы знать, кто представил токен.

"git blame" показывает, кто сделал последнее изменение в строке, но мне бы хотелось найти первый коммит, содержащий токен.

5 ответов

Решение

git bisect - это то, что вы ищете. С помощью этой команды вы можете быстро найти, какой коммит ввел const.

Вы начинаете процесс с git bisect start, а затем пометить старую версию без const как хорошо с git bisect good и и текущий как bisect bad, Затем система отправит вам версию посередине. Вы можете проверить наличие злого конста и пометить эту версию как хорошую или плохую в зависимости от нее. Затем процесс повторяется до тех пор, пока вы не найдете плохой коммит.

Есть несколько возможных способов сделать это.

  • git blameили лучший графический инструмент обвинения (например, git gui blame или взгляд на вину в git instaweb / gitweb) просматривать историю строки, возвращаясь к истории, пока не найдете подходящий коммит.

  • так называемый "поиск кирки", т.е. git log -S с соответствующим токеном / регулярным выражением, чтобы найти (перечислить) все коммиты, где изменилось количество данных токенов (что обычно означает, где данный токен был добавлен или удален), например:

    git log --reverse -p -S'const int foobar' -- A.cpp
    
  • git bisect где "плохой" коммит будет означать тот, у которого "const" там, где его не должно быть (тестирование с использованием, например, grep).

Изменение, возможно, не всегда было в строке 15 A.cppтак что используйте окружающий контекст. Скажи, что это было определение const int foobar:

git grep 'const *int *foobar' \
  $(git log --reverse --pretty=format:%H -- A.cpp) -- \
  A.cpp | head -1

Это ищет во времени все коммиты в текущей ветви, которые касаются A.cpp и находит первый, который содержит оскорбительный образец. Результатом будет SHA-1 коммита и соответствующая строка в его ревизии A.cpp,

Как только вы знаете коммит, используйте git show узнать автора.

Если линия существовала без const в некотором коммите, который вы знаете, вы можете начать там и использовать --reverse пометить git-blame, чтобы найти последнюю ревизию, в которой в строке не было const маркер. Тогда просто посмотрите на следующую ревизию в файле после этого.

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

с помощью:

  • откройте QGit в репозитории
  • открыть дерево
  • найти файл
  • найти линию
  • выберите интересующую линию
  • нажмите кнопку "Фильтровать ревизию выбранных линий", выглядит как воронка.
Другие вопросы по тегам