ivalexander2 часа назад
GIT: как ломать и чинить историю правильно (2 часть)
Время на прочтение5 минОхват и читатели2.8KБлог компании Wildberries & RussGit*ТуториалВсем привет! Впрошлой части мы разобрали основные инструменты приведения истории GIT в порядок, в этот раз мы постараемся ответить на ряд вопросов, которые позволят нам чуть глубже понимать механизмы работы с историей коммитов и даже попытаемся провести настоящее детективное расследование и выйти на авторов, которые внесли те или иные изменения в код!
Содержание
• git push -f — наш союзник или враг?
• git commit --amend — не делаем много однотипных коммитов
• git blame — учимся анализировать статистику, смотреть историю конкретных участков кода
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-ветке, наблюдаем, что в последнем коммите ужасное сообщение и мечтаем поправить его:
• выполняем команду git commit --amend
• открывается редактор сообщения
• вводим необходимое сообщение, сохраняем и закрываем
• создается новый коммит на базе последнего, но уже с новым сообщениемИтог
• быстрый способ поправить 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 помогает быстро наломать дров, а исправлять последствия всё равно приходится через терминал.
Делитесь своим опытом и задавайте вопросы в комментариях!Теги:• GIT
• rebase
• commit
• merge
• git pushХабы:• Блог компании Wildberries & Russ
• Git
Получайте больше инсайтов о систематизации бизнеса
Подписывайтесь на Telegram-канал Business Operations — ежедневные материалы о бизнес-процессах, операционном управлении и повышении эффективности
💬 Подписаться на канал→ Оригинальная статья