Программирование и IT
git pull
Команда git pull приносит из удалённого репозитория чужие коммиты и сразу вливает их в твою текущую ветку. Это две операции подряд, и почти все трудности с pull растут из второй — из того, каким способом он соединяет истории.
В этой статье
Две операции под одним именем#
git pull — это git fetch плюс соединение. Сначала git скачивает из
удалённого репозитория новые коммиты и обновляет служебные указатели вида
origin/main. Затем вливает origin/main в ту ветку, где ты стоишь, —
слиянием или перебазированием, смотря по настройке.
Первая половина безопасна всегда: скачанное лежит отдельно и твоих файлов
не касается. Вторая меняет рабочий каталог и может упереться в конфликт.
Отсюда практический вывод: когда не уверен в состоянии проекта, делай
эти шаги по отдельности.
fetch, когда надо сначала посмотреть#
From https://github.com/example/notes
4f1c2ab..8b2d5e9 main -> origin/main
Локальная ветка main осталась на месте, но теперь есть с чем сравнить:
Первая команда перечислит коммиты, которых у тебя нет, вторая покажет
построчную разницу по конкретному файлу. Посмотрели — и только потом
вливаешь: git merge origin/main или сразу git pull.
Синтаксис и способы соединения#
| Ключ | Как соединяет |
|---|---|
--rebase |
переносит твои коммиты поверх скачанных, история остаётся линейной |
--no-rebase |
обычное слияние, при расхождении появляется коммит слияния |
--ff-only |
вливает только перемоткой; при расхождении просто отказывает |
--autostash |
сам откладывает незакоммиченные правки и возвращает их после |
Чтобы не указывать способ каждый раз, его задают настройкой один раз на
машину:
Пример: обычное обновление#
Updating 4f1c2ab..8b2d5e9
Fast-forward
README.md | 4 ++++
1 file changed, 4 insertions(+)
Слово Fast-forward означает лучший случай: своих коммитов у тебя не было,
указатель ветки просто переехал вперёд. Если бы ты успел закоммитить
что-то своё, git соединил бы две истории и вывел
Merge made by the 'ort' strategy — как устроено такое слияние, разобрано
в статье про git merge.
Пример: pull с перебазированием#
Successfully rebased and updated refs/heads/main.
Твои коммиты пересоздаются поверх чужих — с новыми хешами, но с тем же
содержимым. История получается линейной, без «ёлочки» из коммитов слияния.
Именно этим способом чаще всего отвечают на отказ сервера при отправке —
см. git push. Важное ограничение: перебазировать стоит
только свои неотправленные коммиты, иначе у коллег останется старая версия
тех же изменений.
Когда pull останавливается#
hint: You have divergent branches and need to specify how to reconcile them.
fatal: Need to specify how to reconcile divergent branches.
Git видит расхождение и не хочет выбирать за тебя. Ответ — одна из настроек
pull.rebase true, pull.rebase false или pull.ff only.
error: Your local changes to the following files would be overwritten by merge:
README.md
Please commit your changes or stash them before you merge.
Aborting
Незакоммиченные правки столкнулись с приходящими. Закоммить их, либо
отложи командой git stash, обновись и верни git stash pop, либо
разово запусти git pull --autostash.
Третий случай — конфликт: файл изменили и ты, и коллега, в одних и тех же
строках. Git оставит в файле разметку конфликта и будет ждать решения.
Как откатиться#
Обновление не доведено до конца — отмени ту половину, что застряла:
или git rebase --abort, если тянули с --rebase. Обе команды возвращают
ветку и файлы ровно в то состояние, что было до команды.
Pull уже завершился, а результат не нравится:
ORIG_HEAD — записанное git положение ветки до последней крупной
операции. Команда стирает незакоммиченные правки, поэтому убедись, что
терять нечего. Если и это не помогло, прежнее положение ветки всегда можно
найти в git reflog. Перечень остальных повседневных команд —
в шпаргалке.
План по этапам
- Прибрать рабочий каталогЗакоммитить или отложить правки: git pull не любит незавершённую работу.
- Скачать и посмотретьgit fetch, затем git log --oneline main..origin/main — что именно приедет.
- Выбрать способЛинейная история — --rebase; сохранить точку соединения — обычное слияние.
- Разобрать конфликтыПоправить файлы, git add, затем --continue соответствующей команды.
- Проверить результатgit status чист, git log --oneline --graph -10 показывает ожидаемую картину.
Начать изучать эту тему у себя
План ляжет в твой репозиторий: отмечай этапы, веди конспект — история изменений покажет, как ты продвинулся.
Проверь себя
1.Чем git fetch отличается от git pull?
2.Pull остановился с «Your local changes would be overwritten by merge». Что делать?
3.Какой ключ обновит ветку без коммита слияния, перенеся твои коммиты поверх чужих?
Источники
-
Pro Git, книга на русскомГлавы про удалённые репозитории и перебазированиебесплатно
-
Справка git pullКлючи и связь с fetch и mergeбесплатно
-
Справка git fetchЧто именно обновляет скачиваниебесплатно
Было полезно?