Всем привет! В прошлой части мы разобрали основные инструменты приведения истории GIT в порядок, в этот раз мы постараемся ответить на ряд вопросов, которые позволят нам чуть глубже понимать механизмы работы с историей коммитов и даже попытаемся провести настоящее детективное расследование и выйти на авторов, которые внесли те или иные изменения в код!

Содержание

git push -f — наш союзник или враг?

Часто приходилось слышать мнение, что git push -f — это наш враг номер 1 и что никогда нельзя использовать эту команду, так ли это? Попробуем выяснить. 

git push -f — это force push, команда, которая позволяет переписать историю коммитов в remote ветке. Звучит страшно? На самом деле, не очень, но необходимо понимать и оценивать риски:

  • принудительно отправляет изменения в remote

  • игнорирует расхождения истории

  • перезаписывает удалённую ветку

💡«ломает правила ради результата»

Рассмотрим, в каких сценариях можно использовать git push -f:

  • после rebase,

  • после commit --amend,

  • после rebase -i.

В общем, в тех ситуациях, когда локальный commit hash не совпадает с тем, что в удалённой ветке.

Когда точно можно использовать: 

  • работаешь один в ветке,

  • feature-ветка,

  • чистишь историю перед PR/MR.

Как и с любым другим инструментом, использование этого несёт в себе определенные риски, важно понимать, что в этих сценариях использование git push -f оправдано и польза превышает риск.

Когда точно нельзя использовать:

  • общая ветка,

  • несколько разработчиков,

  • кто-то уже подтянул изменения.

В этих сценариях риск не оправдан совсем. Что же может пойти не так?

  • исчезнут чужие коммиты,

  • сломается история,

  • люди не смогут сделать pull.

Начнётся полнейший хаос, и коллеги тебе за такое «спасибо» не скажут.

Как используем:

  • только в своей ветке,

  • убедиться, что никто не работает с ней,

  • предупредить команду (если нужно),

  • когда ты действительно понимаешь, что делаешь.

Можем себя обезопасить: у этой команды есть «старший брат» - git push --force-with-lease. 

git push --force-with-lease — перед отправкой данных в remote и переписыванием истории проверяет «а не закинул ли кто-то чего-то своего в эту ветку?». Можно назвать это умным git push -f, и данная команда — твой верный союзник.

Подведём итоги: 

  • мощный инструмент,

  • дает контроль над историей,

  • безопасен при правильном использовании.

Важно

  • если не уверен — не используй push -f,

  • если ветка твоя личная — push -f твой союзник для чистой истории.

git commit --amend — не делаем много однотипных коммитов

Если вы частенько задавались вопросами: «можно ли как-то исправить последний коммит?» или «можно ли не делать кучу однотипных коммитов на ревью?», то у меня для вас замечательная новость! У нас есть команда git commit --amend. Попробуем разобраться, как это работает.

Что это вообще такое?

Команда git commit --amend позволяет создать новый коммит на базе последнего коммита. После введения команды можно отредактировать содержимое коммита и сообщение. Так как меняется и содержимое, и метаданные, то GIT пересчитывает hash, поэтому после внесения изменений требует git push -f для отправки данных в remote.

В каких сценариях может быть полезен?

  • забыл добавить файл,

  • опечатка в сообщении,

  • мелкая правка сразу после commit,

  • must have для мелких изменений в процессе проведения код-ревью, на каждое изменение можно не создавать отдельный коммит, достаточно добавить изменения в последний.

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

Когда точно нельзя использовать:

  • commit уже у других,

  • общая ветка,

  • main / develop.

💡можно сломать историю

Плюсы использования инструмента:

  • чистая история,

  • нет “fix fix fix”,

  • аккуратный PR/MR.

Разберём на графическом примере для понимания, как это работает:

Есть некоторая история коммитов во feature-ветке, наблюдаем, что в последнем коммите ужасное сообщение и мечтаем поправить его:

  1. выполняем команду git commit --amend

  2. открывается редактор сообщения

  3. вводим необходимое сообщение, сохраняем и закрываем

  4. создается новый коммит на базе последнего, но уже с новым сообщением

Итог

  • быстрый способ поправить commit,

  • идеально для последних изменений,

  • делает историю аккуратной.

git blame — учимся анализировать статистику, смотреть историю конкретных участков кода

Вам когда-нибудь хотелось узнать историю конкретного участка кода? Узнать, кто, когда и зачем написал определённую строку, удаление которой приводит к краху всего проекта? Если для вас эти вопросы актуальны, то добро пожаловать в мир построчной аналитики файлов с помощью инструментов GIT. 

Разберём команду git blame и посмотрим, с какими ещё командами её можно использовать, чуть-чуть залезем в bash и посмотрим на реальную магию.

Что это вообще такое?

  • показывает, кто изменил каждую строку,

  • показывает commit и дату,

  • даёт быстрый доступ к истории.

💡история на уровне строки

Пример вывода команды:

git blame file.ts

a1b2c3d4 (alex 2024-01-10 12:30:00) const user = getUser()
e5f6g7h8 (ivan 2024-01-11 09:15:00) if (!user) return null

В выводе можно увидеть следующую информацию:

  • hash коммита

  • автор

  • дата

  • строка

Для чего это может быть полезно:

  • понять, кто писал код,

  • понять, когда добавили баг,

  • быстро найти commit,

  • выйти на автора.

Важно понимать:

Эта команда не для обвинения вашего коллеги, а способ нахождения контекста проблемы. Удобно использовать в паре с командой git show.

git show позволяет просмотреть подробную информацию по изменениям в файлах по хэшу коммита.

Сценарий использования:

  • в файле был обнаружен какой-то странный код

  • if (isEnabled && !isEnabled) 🤡

  • делаем git blame file.ts

  • git show <hash>

Profit! Находим контекст определённой строки и понимаем, какая логика была добавлена вместе с ней.

У команды есть несколько флагов, чтобы облегчить нам жизнь:

  • git blame -L 10,20 file.ts — позволяет задать диапазон строк (если нет смысла просматривать весь файл);

  • git blame -w file.ts — позволяет игнорировать пробелы, улучшает вывод, так как не учитывает изменения beautify code.

Так как вывод команды — это фактически полноценная таблица с данными, то для анализа мы можем использовать awk, и тут начинается магия! Чтобы разобрать, как работает awk, нужна отдельная статья, поэтому просто посмотрим несколько кейсов.

Анализируем, кто чаще вносил изменения в файл, делаем красивый вывод в таблице, где отобразим количество написанных строк и автора изменений:

git blame file.ts | awk '{print $2}' | sort | uniq -c | sort -nr

120 Alex
45 Ivan
10 Sergey

Сделаем задачу ещё интереснее — выяснить, какое количество строк в файле являются самыми древними. Мы можем это сделать с помощью тех же самых инструментов:

git blame file.ts | awk '{print $3}' | sort | uniq -c

12 2021-03-10
44 2022-07-15
87 2025-01-12

 Можем наблюдать здесь следующие данные:

  • количество строк

  • дата

Статистика может помочь определить, насколько часто вносят изменения в файл.

На самом деле, комбинируя различные bash команды и git blame, можно вытаскивать из файлов полезную информацию и проводить настоящие расследования. 

Ну и, конечно же, рассмотрим плюсы этой команды:

  • быстрый анализ кода,

  • помогает в дебаге,

  • находит владельца логики.

Минусы (куда же без них):

  • может вводить в заблуждение,

  • форматирование ломает blame,

  • не показывает всю историю.

Итог:

  • инструмент анализа, а не обвинения,

  • показывает «кто и когда»,

  • всегда проверяй commit.

Общий итог

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

Я хотел показать, что терминальный GIT не так страшен, в сложных сценариях, таких как rebase, recovery после неудачного merge, аналитика кода зачастую дает больше контроля и понимания происходящего.

Иногда UI помогает быстро наломать дров, а исправлять последствия всё равно приходится через терминал.

Делитесь своим опытом и задавайте вопросы в комментариях!