Используя git, чтобы найти первое введение токена в определенной строке файла

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

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

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

Ответы

Ответ 1

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

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

Ответ 2

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

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

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

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

Ответ 3

Возможно, изменение не всегда было в строке 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, чтобы узнать автора.

Ответ 4

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

Ответ 5

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

с помощью:

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