Полезные команды Git: безопасная отмена коммитов, добавление файла из другой ветки и другие
57К открытий61К показов
Рассказывает автор блога AlgoTech
Git — это мощный, хотя и незамысловато выглядящий, инструмент, который при неосторожном использовании может устроить большой беспорядок. Поэтому, прежде чем пробовать выполнять различные фокусы с Git, я рекомендую ознакомиться с его основными командами (init, clone, push, pull, status, log и т.д.) и концептами (репозиторий, ветвь, коммит, и т.д.).
Итак, если вы уверенно чувствуете себя при работе с Git, вот несколько полезных трюков, о которых я знаю.
Reflog. Отмена операций
Я помню, что в начале знакомства с Git я боялся запускать команды. Я думал, что всё испорчу. Например, первое использование git rebase
вызвало у меня несколько восклицаний наподобие «Вот *****! Что я только что сделал?!» из-за дублировавшихся или вообще исчезнувших коммитов. Вскоре после этого я понял, что нужно идти дальше.
Лично я не люблю использовать инструмент, не зная, что именно он делает для достижения результата. Это как вождение машины без руля: всё прекрасно до тех пор, пока не доедешь до поворота. А что потом? Ну, вы меня поняли.
Итак, в нашем деле очень важно понимать концепты. Я много читал про Git, прошёл несколько обучающих курсов, и моё видение мира Git кардинально изменилось. Используя его, я стал чувствовать себя гораздо спокойнее, а что более важно, я познал его истинную мощь. И одной из самых мощных команд является git reflog
.
Используя reflog
, вы можете вернуться в прошлое, отменяя почти любые действия, сделанные в Git. Даже если это были rebase
или reset
. Кроме того, её легко использовать. Чтобы доказать это, приведу маленький пример.
Чтобы изменить нужное состояние, нужно запустить checkout
, используя абсолютную ссылку:
или относительную ссылку:
и вы окажетесь в независимом (detached) состоянии HEAD, из которого можно создать новую ветвь.
Вот и всё. Все операции после вышеуказанного состояния отменены.
Revert. Отмена изменений коммита
Вы, должно быть, сталкивались с ситуацией, когда вам нужно было отменить некоторые изменения. На помощь придёт команда revert
:
Что она делает? Она просто отменяет действия прошлых коммитов, создавая новый, содержащий все отменённые изменения. Зачем использовать её вместо других решений? Это — единственный безопасный способ, так как он не изменяет историю коммитов. Он обычно используется в публичных ветвях, где изменение истории нежелательно.
Давайте взглянем на другие команды, способные отменять действия.
Rebase
Вы можете выполнить эту команду и просто убрать строки, относящиеся к ненужным коммитам. Это самое очевидное и простое решение, но у него есть недостаток, из-за которого его нельзя использовать в публичных ветвях: он изменяет историю коммитов. Поэтому после rebase’а у вас может возникнуть проблема с push’ем.
Reset
Эта команда удаляет все коммиты выше указанного. Она лучше предыдущей тем, что не добавляет новую информацию в историю, но тем не менее тоже ее меняет.
Checkout
Эта команда откатывает выбранный файл к состоянию в более ранней версии указанного коммита. Отменённые изменения будут в рабочей директории, и их можно будет закоммитить как угодно.
Вывод таков, что git revert
— самая безопасная операция для отмены действий. Кроме того, нужно заметить, что эти команды не взаимозаменяемы в 100% случаев.
Log. Более приятное форматирование
С git log
всё просто. Вы вводите команду и видите историю коммитов в хронологическом порядке, и каждый пункт включает в себя хэш коммита, автора, дату и прикреплённое сообщение.
Давайте взглянем на вид лога по умолчанию:
Я думаю, что могло бы быть и лучше.
Я предпочитаю простые вещи. Поэтому я использую две опции:
--oneline
– показывает каждый коммит в одной строке. Кроме того, она показывает лишь префикс ID коммита.--decorate
– печатает все относительные имена показанных коммитов.
Вот как это выглядит:
Опция --oneline
сокращает количество занятых строк, а опция --decorate
добавляет относительные имена (локальные/удалённые ветви + HEAD). Используя эти две опции, мы получаем более компактный и осмысленный git log
. Да, мы теряем некоторые вещи, но они не особо важны. Так гораздо лучше, да?
Тем не менее, иногда нам нужно знать дату и автора коммита. В таких случаях я использую следующее:
Ничего себе! Давайте посмотрим, как это выглядит:
Весьма неплохо.
И всё-таки вводить эти команды каждый раз достаточно неудобно, так? Давайте создадим алиасы. Я считаю, что использование алиасов очень сильно повышает продуктивность. Чтобы зарегистрировать их, добавим следующие строки в «~/.bash_profile» (конечно, если вы используете *nix OS):
Таким образом, мы получили не только хорошо выглядящую историю коммитов, но и упрощённый способ доступа к ней, используя команды gl
и gh
.
Еще один вариант украшения вывода лога приведен в этой статье.
Diff. Разница между коммитами
Простая команда, показывающая изменения между объектами в проекте — git diff
. Один из основных сценариев её использования — сравнение двух коммитов:
Другой — вывод всех изменений, не внесённых в индекс. Для этого нужно выполнить следующее:
Branch. Проверка ветвей на слияние
Я думаю, вы уже знаете, что делает базовая команда git branch
(без опций выводит список локальных веток — прим. перев.), поэтому перейдём к делу. Время от времени вам понадобится удалять старые или ненужные ветви из вашего «дерева» git.
Используя следующее:
вы получите список всех веток, соединённых с текущей.
Можно и наоборот:
Так вы получите список всех не соединённых с текущей веток.
Таким образом, вы всегда узнаете, безопасно ли удаление той или иной ветви.
Checkout. Получение файла из другой ветви
Вам наверняка приходилось искать конкретную версию файла, которая была в другой, ещё не присоединённой ветви. Помните команду checkout
, приведённую выше? Она выглядит так:
Указанный файл будет приведен к версии, указанной в заданном коммите. Раньше мы использовали это для отмены изменений файла. Удобно то, что этот коммит необязательно должен находиться в той же ветви, что и наш файл. Поэтому мы можем задать любому файлу любую версию из любого коммита или ветви.
Надеюсь, вы нашли здесь для себя что-то полезное. Прошу заметить, что все вышеуказанные моменты субъективны, поскольку я подгонял их под свои нужды.
57К открытий61К показов