Для разработчика программного обеспечения умение обращаться с Git — по сути, одна из рабочих обязанностей. Работа с локальными и удаленными репозиториями, внесение изменений и управление локальными копиями: вот основы Git, которые необходимо знать как свои пять пальцев.
Но помимо этих основ у Git есть более продвинутые команды, способные облегчить жизнь. Они могут повысить вашу производительность и разрешить некоторые не столь уж редкие трудности, с которыми вы сталкиваетесь при работе над проектом совместно с десятками и сотнями других разработчиков. Если вы хотите стать профессионалом в работе с Git, эти команды должны быть у вас под рукой.
git bisect
Предположим, в репозитории, куда вы вносите вклад, несколько тестов завершились неудачно из-за ошибки. Никто до сих пор не смог определить причину, и найти плохой коммит особенно сложно, потому что после последнего рабочего коммита в репозиторий были сделаны сотни новых.
git bisect
позволяет быстро найти точно тот коммит, который в ответе за ошибку. Когда вы предоставляете известный “хороший” коммит и “плохой”, используется двоичный поиск, чтобы достичь первого проблемного коммита за наименьшее количество времени.
Выполнение операции деления пополам начинается с команды:
git bisect start
Вы можете определить ссылку на хороший коммит, при котором все еще работало как надо, и плохой коммит, при котором происходит сбой, просмотрев историю в журнале git log
. Необходимо предоставить эти два коммита с помощью следующих двух команд:
git bisect good <good-commit-ref>
git bisect bad <bad-commit-ref>
Как только вы запускаете git bisect bad
, команда проверяет коммит в средней точке между хорошим и плохим и дает вам возможность просмотреть его. Если тесты по-прежнему не проходят в извлеченном коммите, вы можете сообщить об этом, запустив git bisect bad
. С другой стороны, если это хороший коммит, запустите git bisect good
.
После этого шага git bisect
снова проверяет промежуточный коммит между обновленными вариантами хорошего и плохого, чтобы вы могли снова просмотреть код и запустить тесты для выяснения, хороший попался коммит или плохой. Этот процесс продолжается до тех пор, пока не достигнет первого плохого коммита.
Вы можете остановить операцию деления пополам и перейти к последнему коммиту с помощью
git bisect reset
git cherry-pick
Хоть и нечасто, но мы все же сталкиваемся со сценариями, когда хотим выбрать конкретный коммит из другой ветки репозитория и отправить его в ту ветку, над которой сейчас работаем.
Например, вы намерены выбрать изменения, которые ошибочно внесли в другую ветку, и внедрить их в нужную. Или хотите добавить решение, предоставленное кем-то другим, в ветку, над которой работаете, без написания кода с нуля. Если в подобных ситуациях вы пользуетесь git merge
, в вашей текущей ветке могут оказаться изменения, которые не имеют к ней никакого отношения. Поэтому в таких случаях удобнее воспользоваться командой git cherry-pick
.
При выполнении этой команды вам нужно сначала получить ссылку на коммит, который вы хотите выбрать, используя git log
. Затем переключитесь на ветку, в которой хотите применить выбранный коммит.
git checkout feature-1
Теперь можно применить коммит с помощью команды:
git cherry-pick <commit-ref>
Если вы хотите просто внести изменения в эту ветку, но не коммитить их, то воспользуйтесь:
git cherry-pick <commit-ref> --no-commit
Важно отметить, что в некоторых случаях эта команда может оказаться не лучшим решением. В зависимости от того, как вы пользуетесь git cherry-pick
, в вашей ветке могут появиться повторяющиеся коммиты. Выбранный вами коммит также может привести к появлению новых ошибок в целевой ветке. Поэтому, выбирая коммиты с помощью git cherry-pick
, сначала убедитесь, что это последнее средство, к которому вы прибегаете после того, как опробовали все остальные варианты.
git rebase
Обычно для объединения изменений, внесенных в две разные ветки, репозитория, мы пользуемся командой git merge
. Если обратиться к истории коммитов репозитория после операции слияния, будет сложно следить за чередованием коммитов из двух веток.
Что, если мы хотим упростить отслеживание истории нашего проекта, выровняв историю объединяющейся ветки в одну линию с другой? Вот тут-то и вступает в дело git rebase
.
Простыми словами, ответственность команды rebase
заключается в изменении базового коммита ветки. Обсудим, что именно это означает, на примере.
Допустим, у вас в репозитории есть две ветки: main
и feature
. После создания feature
ваша команда добавила коммиты в обе эти ветки. Но теперь вы хотите объединить ветку feature
с основной веткой перед выпуском релиза. На этом этапе можно запустить git rebase
в своей ветке feature
, прежде чем объединять ее с помощью git merge
. Эта команда изменяет базу ветки feature
на последний коммит в вашей основной ветке main
, как показано на следующем рисунке:
Команда git rebase
предоставляет ветке feature
линейно совместимую историю с основной веткой, чего не было раньше. Теперь, если вы запустите git merge
, история коммитов главной ветки будет менее запутанной и более понятной.
Использовать эту команду довольно просто. Сначала проверьте ветку, которую вы хотите перебазировать. Затем запустите следующее:
git rebase <base-branch-name>
Однако git rebase
— команда, которую следует применять с осторожностью, поскольку она переписывает историю ветки. Во время этого процесса возможна потеря полезной информации, которая хранится в истории веток. Негативные последствия также возможны в случае, если вы работаете с веткой, куда пишут одновременно много участников. Поэтому лучше ограничить использование git rebase
личными ветками, если только вы не находитесь стопроцентно на одной волне со всеми членами вашей команды.
git add -p
git add
— один из необходимых шагов в рабочем процессе Git. Эта команда размещает в каталоге проекта файлы, которые необходимо добавить в следующий коммит. В зависимости от конкретного случая нам подходят разные версии этой команды:
git add <file-path>
— для размещения файлов по определенному пути.git add .
— для размещения всех измененных и новых файлов.
Но если вам хочется просмотреть изменения в каждом файле по частям (в виде исправлений), прежде чем решать, вносить их или нет, вы можете задействовать команду git add -p
. Она отображает изменения, внесенные в файл, в виде нескольких фрагментов и предлагает выбрать, следует ли добавлять каждый из них или нет.
Вот варианты выбора, которые Git предоставляет для каждого такого фрагмента. Когда вам будет предложено подтвердить решение, нужно ввести соответствующую букву.
y
: разместить этот фрагмент;n
: не размещать этот фрагмент;q
: выйти; не размещать этот фрагмент или любой из оставшихся;a
: разместить этот фрагмент и все последующие фрагменты в файле;d
: не размещать этот фрагмент и все последующие фрагменты в файле;e
: вручную отредактировать текущий фрагмент.
git commit –amend
Сколько раз вы обнаруживали, что хотите изменить свой последний коммит, потому что допустили ошибку или забыли добавить что-то важное? git commit –amend
позволяет сделать именно это.
С помощью этой команды можно изменить свой последний комментарий к коммиту или объединить текущие промежуточные изменения с предыдущим коммитом без создания нового. Этот шаг не просто изменяет предыдущий коммит; он заменяет его на совершенно новый.
Посмотрим, как вносить изменения в коммиты при помощи этой команды.
Если вы хотите изменить комментарий:
git commit --amend -m <commit message>
Если вы хотите объединить поэтапные изменения, сначала добавьте измененные файлы с помощью git add
. Затем измените последний коммит следующим образом:
git commit --amend --no-edit
Если вы уже отправили последний коммит в удаленный репозиторий, вам придется использовать команду git push — force-with-lease
для отправки измененного коммита.
Опять же, поскольку эта операция изменяет историю коммитов, вам следует проявить осторожность в том, когда и где вы ей пользуетесь.
Заключение
В этой статье мы показали пять продвинутых концепций и команд Git, которыми вы можете воспользоваться для эффективного управления версиями. Однако то, что мы здесь обсуждали, — это лишь несколько впечатляющих инструментов, которые Git предлагает разработчикам. Но мы надеемся, что они пригодятся вам, когда вы столкнетесь с проблемами, подобными тем, которые были затронуты здесь.
Спасибо за чтение!
Читайте также:
- 3 верных способа оптимизировать ревью на GitHub
- Как написать красивый и информативный README.md
- Как рационально использовать GIT
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Juan Cruz Martinez: Five Advanced Git Concepts that Make You Look Like a Pro