Команда Git Pull

Мы уже рассмотрели git merge, теперь перейдем к pull.

Команда pull забирает изменения из удаленного репозитория и интегрирует их с изменениями в локальном репозитории.

Пример использования

Чтобы забрать изменения из удаленной ветки dev репозитория origin и слить их с изменениями в текущей ветке, где мы находимся, выполним:

git pull origin dev

Это аналогично двум последовательным командам:

git fetch origin
git merge origin/dev

Обратите внимание, что перед выполнением команды pull все текущие изменения должны быть закоммичены, так же, как перед выполнением команды merge. Иначе слияние не выполнится.

Параметры по умолчанию

Если попробовать выполнить pull без параметров, находясь в ветке master:

git pull

команда выполнится. Но с какой же веткой происходит в этом случае слияние? По умолчанию это ветка master репозитория origin.  (При клонировании удаленного репозитория по умолчанию ему дается имя origin). То есть команда аналогична:

git pull origin master

Как видите, для ветки master заданы параметры по умолчанию. Можно их задать и для других веток. Связывание локальной ветки и удаленной ветки называется отслеживанием ветки.

Настройка отслеживаемой ветки

Давайте сделаем так, чтобы, когда мы находимся в локальной ветке dev, по умолчанию слияние происходило с веткой dev репозитория origin. Перейдем в ветку dev и выполним команду:

git branch -u origin/dev

Эта команда связало локальную ветку dev с удаленной веткой origin/dev.

Теперь когда мы находимся на локальной ветке dev и выполняем pull без параметров, слияние происходит по умолчанию с удаленной веткой dev:

git pull

То есть теперь вышеприведенная команда без параметров будет аналогична команде с параметрами:

git pull origin dev

git pull vs. git fetch

git fetch  просто обновляет локальную копию удаленного репозитория. То есть все копии удаленных веток (которые записываются через слеш — например, origin/master) будут содержать самый последний коммит из удаленного репозитория.

Но при этом содержимое локальных веток, в том числе той, на которой вы находитесь, не меняется. В папках  остаются те же файлы. Команда fetch безвредна и ее можно делать сколько угодно раз. Иногда даже пишут скрипт, который выполняет git fetch в фоновом режиме.

Команда pull же состоит из fetch и merge. То есть помимо обновления копии удаленного репозитория на вашем компьютере, она еще и реально меняет содержимое папок, с которыми вы работаете. Вливает удаленную ветку в текущую.

git pull —rebase

Рассмотрим команду pull с параметром rebase:

git pull --rebase

На результат слияния параметр —rebase не влияет, единственное, что он делает — меняет вид истории коммитов.

До команды pull

Допустим, мы разветвились с удаленным репозиторием на коммите D:

before pull
До pull

Наши локальные коммиты с момента разветвления — это нижние E, F, G, а в удаленном репозитории с тех пор появились коммиты A, B, C. Нам надо их накатить сверху на наши коммиты E, F, G, что собственно и делает команда pull.

Обычный pull

Но тут возможны нюансы. По умолчанию делается дополнительный коммит H, который и включает все изменения из удаленной ветки:

git pull

pull —rebase

Если же мы выполним:

git pull --rebase

то история локальных коммитов будет выглядеть по другому (при том же результате слияния файлов):

git pull --rebase
git pull —rebase

При просмотре истории коммитов мы просто увидим ряд коммитов из основной ветки A, B, C, идущих за нашими локальными E, F, G. Кому-то такой вид выглядит чище, хотя разницы в итоговом содержимом файлов нет.

git pull force

Насильно выполнить git pull нельзя.  Она не перезапишет локальные изменения, если есть конфликт. Конфликт все равно придется разрешать.

Если же требуется получить данные из удаленной ветки, перезаписав локальные изменения, то делается это в два этапа. Сначала обновить локальную копию удаленного репозитория:

git fetch --all

Далее, допустим надо перезаписать содержимое текущей ветки данными из ветки master репозитория origin:

git reset --hard origin/master

Если надо перезаписать содержимое текущей ветки данными из другой ветки dev репозитория origin:

git reset --hard origin/dev

Но будьте внимательны с опцией —hard, она действительно затирает коммиты текущей ветки безвозвратно. Если надо их сохранить, то перед выполнением команды создайте новую ветку — в нее все сохранится:

git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/dev

Что еще интересно: коммиты reset —hard затирает, а если в папке были просто неотслеживаемые файлы, то они не будут затронуты.

Итоги

Команда pull — на любителя, потому что не всем нравится автоматически сливать ветки. Гораздно прозрачнее делать отдельно fetch и merge.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *