🧙 Садовник: уточнил шаги, добавил проверки и обоснования. Примите, если полезно.

#1
open+276proposed by devops · Aug 16, 2026 · based on v2
Result · becomes v3
Убедиться, что история вообще есть

Самая обидная преграда: репозиторий клонировали с обрезанной историей, и старых коммитов просто нет.

bash
1git rev-parse --is-shallow-repository # true = история обрезана
2git fetch --unshallow # дотянуть всю
3git log --oneline | wc -l # сколько коммитов теперь

Так бывает чаще, чем кажется: системы развёртывания клонируют с --depth 1 ради скорости.

Why: На обрезанной истории `git log` по файлу покажет один коммит и создаст впечатление, что файл сразу таким и родился. Можно потратить час на неверный вывод.
code
1git rev-parse --is-shallow-repository
  • Команда отвечает false
  • Число коммитов похоже на правду
Найти коммит, где появилась конкретная строка

Главный инструмент расследования — флаг -S, в документации он называется pickaxe, «кирка»:

bash
1# коммиты, где число вхождений строки изменилось
2git log -S'5432:5432' --oneline -- docker-compose.yml
3
4# то же, но сразу с датами и авторами
5git log -S'5432:5432' --format='%h %ad %an %s' --date=short
6
7# если нужна регулярка по тексту изменений
8git log -G'ports:\s*$' --oneline

Разница между ними важная. -S ищет коммиты, где строка появилась или исчезла. -G — все, где она просто встретилась в диффе, включая перемещения и переотступы. Для вопроса «когда это появилось» нужен -S.

Why: Поиск глазами по `git log -p` работает на десятке коммитов и проваливается на тысяче. `-S` даёт ответ за секунды на любом размере истории.
code
1git log -S'искомая строка' --format='%h %ad %an %s' --date=short
  • Найден коммит, в котором строка появилась
  • Ты понимаешь разницу между -S и -G
Посмотреть историю файла через переименованияRecommended
bash
1git log --oneline --follow -- путь/к/файлу

Флаг --follow продолжает историю через переименования и перемещения. Без него история обрывается в точке, где файл переехал в другую папку.

Работает только с одним путём — это ограничение самой команды.

Why: Файлы переезжают при любой перестройке структуры. Без --follow легко решить, что проблема свежая, хотя она ездит с проектом год.
code
1git log --oneline --follow -- путь/к/файлу
  • Видна вся история файла, включая жизнь под старым именем
Прочитать файл таким, каким он был в тот момент

Когда коммит найден, нужно увидеть контекст целиком, а не только строку:

bash
1# файл целиком на момент коммита
2git show <sha>:путь/к/файлу
3
4# только изменения по этому файлу
5git show <sha> -- путь/к/файлу
6
7# что ещё ехало в том же коммите
8git show --stat <sha>

Обрати внимание на двоеточие против двойного тире: <sha>:путь — содержимое файла, <sha> -- путь — дифф.

Why: Отдельная строка часто выглядит глупостью, а в контексте оказывается частью большого коммита на сотни строк — такого, который физически невозможно внимательно проревьюить. Это уже ответ на вопрос «как прошло мимо».
code
1git show --stat <sha>
  • Виден весь файл на момент коммита
  • Известен размер того коммита целиком
Посмотреть построчно, откуда взялась каждая строкаRecommended
bash
1# только нужный диапазон строк
2git blame -L 40,55 путь/к/файлу
3
4# игнорировать правки пробелов и отследить перенос строк из других файлов
5git blame -w -C -C -L 40,55 путь/к/файлу

Флаги важны: -w игнорирует изменения пробелов, -C -C ищет, откуда строку скопировали. Без них blame часто показывает того, кто прогнал форматтер — а не автора строки.

Why: Половина претензий к blame — из-за этих флагов. Люди видят чужую фамилию, махают рукой и решают, что инструмент врёт.
code
1git blame -w -C -C -L 40,55 путь/к/файлу
  • Ты понимаешь, зачем нужны -w и -C
Если опорной строки нет — бинарный поискRecommended

Когда известно только «раньше работало, теперь нет»:

bash
1git bisect start
2git bisect bad # текущий — сломанный
3git bisect good <старый-sha> # там было хорошо
4
5# git переключает на середину, ты проверяешь и говоришь:
6git bisect good # или
7git bisect bad
8
9git bisect reset # вернуться как было

Если проверку можно автоматизировать, git сделает всё сам:

bash
1git bisect run ./check.sh # код 0 = хорошо, не 0 = плохо

За 20 шагов просеивается миллион коммитов — это обычный двоичный поиск.

Why: Не всякая проблема выражается строкой, которую можно поискать. Падение производительности или плавающая ошибка ищется только так.
code
1git bisect start
  • Ты знаешь про git bisect run
  • Помнишь про git bisect reset в конце
Проверить актуальную версию Git

Убедитесь, что используете последнюю версию Git, так как некоторые флаги могут изменяться или устаревать.

Why: Актуальные версии содержат исправления и новые функции.
code
1git --version
  • Версия Git соответствует последним рекомендациям
Проверить наличие необходимых прав на репозиторий

Убедитесь, что у вас есть доступ для выполнения всех необходимых команд в репозитории.

Why: Без необходимых прав вы не сможете выполнить команды, что приведет к ошибкам.
A person is needed here: Есть ли у вас доступ к репозиторию?