Advanced Git концепты, которые нужно знать

Эта статья познакомит вас с advanced концепциями git и покажет как использовать их в реальных сценариях
Stash
Команда git stash
сохраняет неподтвержденные изменения (индексированные и неиндексированные) в отдельном хранилище, чтобы вы могли вернуться к ним позже. Затем происходит откат до исходной рабочей копии.
Чтобы использовать stash
, необходимо добавить файлы в staging area:
git add .
и пушнуть это в stash:
git stash push
OR
git stash push -m "<stash message>"
Чтобы вернуть сделанные изменения, используйте:
git stash apply
OR
git stash pop
Разница между apply
и pop
заключается в том, что pop
применяет изменения в Stash и также удаляет их из Stash, а apply
сохраняет изменения в stash даже после применения.
Для просмотра айтемов которые мы застешили используйте:
git stash list

Если у вас есть несколько stash изменений, вы можете использовать индекс для выбора нужного вам:
git stash apply stash@{<n>}
OR
git stash apply <n>
Возвращаем удаленные коммиты

Вы когда-нибудь юзали reset
с флагом --hard
? Если да, самое время обеспокоиться, так как команда полностью удаляет указанное количество коммитов.
Не паникуйте, reflog
команда поможет. Чтобы просмотреть изменения, которые вы недавно сделали, запустите:
git reflog show HEAD
OR
git reflog
Теперь вы можете просмотреть изменения, которые вы недавно делали.

Теперь, чтобы вернуть назад удаленный коммит юзайте команду:
git reset --hard <commit hash>
ПРИМЕЧАНИЕ. Если у вас есть какие-либо локальные модификации, эта команда также их почистит, поэтому было бы разумно использовать stash перед сбросом.
Cherry Pick
Cherry Pick позволяет скопировать коммит в другую ветку без мержа содержимого одной ветки в другую.
Черрипикнутть можно с помощью следующей команды:
git cherry-pick -x <commit hash>
OR
git cherry-pick <commit hash>
Настоятельно рекомендуется использовать флаг -x
, так как он будет генерировать стандартизированный commit message, информирующий пользователей о том, откуда оно черрипикнуто.
Rebase
Rebasing - это процесс перемещения или объединения последовательности коммитов в новый базовый коммит. Основная причина, по которой вы хотели бы использовать rebase в своем проекте, заключается в сохранении линейной истории проекта, что значительно упрощает просмотр истории коммитов.

Таким образом, rebase позволяет вам отработать последние изменения в любой ветке. Это также поможет вам в случае Fast Forward Merge, описанного в разделе «Merge стратегии».
Для rebase используйте:
git rebase <source branch>
Чтобы ввостановить визуализированый пример на картинке выше, то нужно было выполнить команду:
git rebase main
Учтите:
rebase создает новые коммиты при перезаписи истории. Таким образом, вам следует избегать rebase после того, как ветка будет отправлена в общедоступный репозиторий, поскольку это может вызвать проблемы, когда старые коммиты мешаются с новыми, и это будет выглядеть так, как будто эта часть истории вашего проекта внезапно исчезла.
Merge стратегии
Существует несколько стратегий слияния:
- Fast Forward
- Recursive
- Ours
- Octopus
- Resolve
- Subtree
Чаще всего используемые стратегии — Fast Forward и Recursive.
Fast Forward Merge
Fast Forward Merge подходит, когда бранча в которую мы мержим не содержит новых коммитов. В таком случае к нужному коммиту перемещается только указатель ветки. Он не добавляет никаких новых коммитов.
Пример мержа feature бранчи в master

Recursive Merge
Recursive Merge происходит, когда исходная и целевая ветки содержат новые коммиты. В таком случае в целевой ветке вводится новый коммит, объединяющий все изменения.
Пример мержа master в feature:

Вы также можете принудительно выполнить Recursive Merge используя:
git merge --no-ff
Стратегия Ours

git merge -s ours branch1 branch2 branchN
Ours позволяет работать с множеством веток. Выходной результат слияния всегда соответствует указателю HEAD текущей ветки. Эта стратегия называется «Наша», потому что она игнорирует все изменения из «чужих» веток. Ее назначение — объединение истории аналогичных функциональных веток.
Стратегия Octopus

git merge -s octopus branch1 branch2 branch3 branchN
Стратегия «Осьминог» применяется по умолчанию для более чем двух Head's. Когда передается больше одной ветки, «осьминог» включается автоматически. Если в слиянии есть конфликты, которые нужно разрешать вручную, эта стратегия блокирует попытку слияния. В основном она используется для объединения heads аналогичных функциональных веток.
Стратегия Resolve

Эта стратегия может разрешить только два указателя HEAD с помощью алгоритма трехстороннего слияния. Данная стратегия пытается выявлять неопределенности при перекрестном слиянии и считается в целом безопасной и быстрой.
git merge -s resolve branch1 branch2
Стратегия Subtree

git merge -s subtree branchA branchB
Это разновидность рекурсивной стратегии. При слиянии A и B, если B — дочернее поддерево A, сначала обновляется B, чтобы отразить древовидную структуру A. Кроме того, обновляется родительское дерево, которое является общим для A и B.