Для разработчика программного обеспечения умение обращаться с 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 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 предлагает разработчикам. Но мы надеемся, что они пригодятся вам, когда вы столкнетесь с проблемами, подобными тем, которые были затронуты здесь.

Спасибо за чтение!

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Juan Cruz Martinez: Five Advanced Git Concepts that Make You Look Like a Pro

Предыдущая статьяУправление средами Python на профессиональном уровне
Следующая статьяУстаревшие фреймворки JavaScript: как не потратить время на бесполезные технологии?