Использование git для поиска первого введения токена в определенной строке файла. - PullRequest
13 голосов
/ 08 декабря 2009

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

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

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

Ответы [ 5 ]

28 голосов
/ 08 декабря 2009

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

  • 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).

13 голосов
/ 08 декабря 2009

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

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

4 голосов
/ 08 декабря 2009

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

1 голос
/ 08 декабря 2009

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

1 голос
/ 08 декабря 2009

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

с помощью:

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