/ web

Продвинутые Git команды из курса (часть 2)

Поиск по истории

Доступность комитов

Dot Dot notation

показывает комиты которые доступны из одой ветки, но не доступны из другой
git log feature..master

--------------2020-04-29---23.52.27

Dot Dot Dot notation

показывает комиты которые доступны для каждой из веток, но не для обоих сразу
(зачем это может быть нужно узнаете позже)
git log feature...master

Визуализация веток

git log master feature --graph
--------------2020-04-29---23.52.27-1

можем использовать команду show-branch, чтобы покзать только те ветки, которые нужны
git show-branch master feature expretimental
--------------2020-04-30---12.25.13

Проверка того какие бранчи вмержены в мастер, а какие нет производится командами
git branch --merged
git branch --no-merged

Посмотреть какие комиты между HEAD и другой невмерженной веткой (experimental)
git log HEAD..experimental

Также посмотреть невмерженные комиты можно при помощи
git show-branch --topic master feature experiment
--------------2020-04-30---12.33.36

Иногда мы хотим вмержить отдельный комит (например с помощью cherry pick) и нам нужно знать, является ли этот комит эквивалентным по содержанию комиту в нашей ветке (но имеет другой комит id). Такой комит называтся prime. Звучит сложно и непонятно (оно так и есть, но будет понятно позже).
--------------2020-04-30---12.38.36

git log --cherry-mark --left-right --no-merges master...experimental

--------------2020-04-30---12.40.50

Комиты, которые недоступны из ветки master в ветке experimental помечаются знком >, те что недоступны из ветки experimental знаком <, а те что эквивалентны помечаются знаком =

Можно использовать параметры --left-only и --right-only в зависимости от ветки, которая нас интересует

Три точки значит что мы указываем список комитов, который доступны из одной ветки или из другой, но не из обоих сразу, при этом фильтруем мерджи --no-merges.

git log --cherry-pick --left-right --no-merges master...experimental показывает комиты без эквивалетности (только те, которых не хватает в какой либо ветке)

git log --cherry-pick --right-only --no-merges master...experimental покажет только те комиты, которых не хватает в мастере

Короткая запись для этого git log --cherry master...experimental

Посмотреть список мерджей из фичи в мастер можно так
git log --merges feature..master

--------------2020-04-30---12.49.13

самый последний мердж комит можно глянуть так
git log --merges --ancestry-path feature..master

Поиск изменений в файлах

git log --follow filename
git log --follow --patch filename - покажет изменения прямо в коде

Найти комит в котором удалена строка "calculator" можно командой -S
git log -Scalculator

Также можно использовать regex, который будет искать добвление или удаление строки (но не изменение)

git log -S".*is.*" --pickaxe-regex

--------------2020-04-30---12.56.31

Чтобы найти именно изменение, нужно использовать опцию -G
git log -Gcalculator
git log -Gcalculator --stat - с более подробной инфой

Поиск изменений (например функции substract в файле calculator.с) с помощью опции -L (language-aware diff, git >= 1.8.4)

git log -L:substract:calculator.c

--------------2020-04-30---13.04.26

В git можно настроить языковые парсеры для разных языков программирования через .gitattributes файл в репозитории. Подробнее тут

Поиск по автору

git log --author="name"
git log --commiter="name"
git log --commiter="name" --since="1 week" --until="2 days ago" - c фильтром по времени
git blame filename - показывает авторов для каждой строки

git blame master..feature filename - blame для комитов из feature branch
git blame filename -L:substract - с поиском по фунции substract

Можно поигарться и посмотреть статистику по числу комитов топ 10 авторов репозитория:
git shortlog -s -n | head -10
-s - суммируем общее число комитов по автору
-n - сортировка по числу
--------------2020-04-30---13.16.23

Работа с ветками

Показать ветки:
git branch --all
git show-ref --heads
--------------2020-04-30---23.22.38

git branch -d experimental удалят ветку с предупреждением, если есть незамерженные в master комиты

git branch -D experimental удаляет без доп вопросов

По факту удаляется референс на эту бранч. Head ветки на самом деле переходит в статус dangling. Это значит что он больше недоступен из других комитов
Этот комит можно посмотреть с помощью команды
git fsck --dangling --no-progress

--------------2020-04-30---23.27.54

Все предки данного комита тоже становятся недоступными, но их можно посмотреть так git fsck --unreachable --no-progress

Восстановить ветку можно через

git branch experimental hash - где hash - хеш комита из результата команды git fsck --dangling

Слияние

  1. Fast Forward - head одной бранчи является предком для другой бранчи и слияние можно произвести просто передвинув Head вперед
  2. True merge - когда есть комиты у одной бранчи недоступные для другой. Приходится делать мердж комит
  3. Ребейз - переносит изменения одной ветки относительно последнего комита другой ветки. Далее можно сделать fast forward merge
    По факту rebase = merge, только не все комиты сразу, а по очереди по одному

FF
--------------2020-05-01---00.13.00
TM
--------------2020-05-01---00.14.42
Rebase
--------------2020-05-01---00.15.39

Можно сделать тру мердж даже если по идее есть возможность для фаст форварда
git merge feature --no-ff

Приемущества ff в линейности истории.
Недостаток - если есть косяки мержа, трудно понять где ошибка, а если бы это был тру мерж, то очевидно косяк в мерж комите.

Когда какой способ выбрать?

  • если мержите 2 публичные ветки - то лучше тру мердж
  • если приватную ветку с публичной - то лучше ребейз и фаст форвард, а если возникнут проблемы, то правило консистентности комитов должно помочь быстро найти ошибку

--------------2020-05-01---00.38.40

cherry-pick

cherry-pick позволяет смержить выбранный комит из ветки в другую

git cherry-pick feature - смержит последний комит из feature в текущую ветку

можно смержить целый промежуток комитов через .. при этом первый указазнный не будет включен. Например чтобы смержить ВСЕ комиты с начала ветки через две точки нужно сделать так

git cherry-pck $(git merge-base master feature)..feature

Резрешение конфликтов

Чтобы отменить конфликтный мерж можно использовать
git merge --abort

Чтобы понять какой комит в ветках содержит конфликт можно посмотреть лог с параметрами --merge
git log --merge --name-only

--------------2020-05-01---11.59.42

Если все еще не понятно как разрешить конфликт, можно посмотреть все версии файла - в том числе и актуального родителя для обоих веток

git merge-base HEAD MEARGE_HEAD

--------------2020-05-01---11.57.56

Он выдаст наиболее актуальный базовый комит
Если есть общий родитель для этих веток, то можно сделать three way merge, который сравнивает изменения в файле не только между ветками, но и с общим родителем

git checkout --conflict=diff3 calclator.c

--------------2020-05-01---19.19.48
Он покажет еще изменения относительно base комита
Можно прописать в настройках чтобы git всегда добавлял base часть: merge.conflictStyle diff3

Если вы знаете какая версия должна быть выбрана при конфликте, то можно сразу выбрать опцию —ours или —theirs при checkout
git checkout —ours calculator.c

Сохраненные резолвы конфликтов

Например мы хотим понять, что наша фича ветка совместима с мастером. Мы хотим сделать тестовый мерж. При мерже появились конфликты и мы их зарезолвили и сделали комит. Не пушаем в master, нам достаточного и этого. Потом мы поняли что все окей и хотим сделать рябейз чтобы сохранить линейность истории. Ресетаем мастер, к исходному состоянию и делаем ребейз. Опять появляется конфликт, но в этот раз git говорит что уже знает как его резолвить, потому что мы резолвили эти же файлы в мерже!

--------------2020-05-01---19.28.50

--------------2020-05-01---19.32.01

Часть 3
Часть 1

Кстати, завел личный блог Sleepless Tech в Telegram про разработку и DIY, заходите!

И присоединяйтесь к каналам FrontEndDev и Web Stack в Telegram, чтобы не пропустить самое интересное из мира Web!