Git: удалённые репозитории, fetch, pull и push

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

Remote: управление адресами

КомандаВариантЧто делает
git remotegit remoteИмена удалённых репозиториев.
git remote -vgit remote -vИмена и адреса (fetch и push).
git remote addgit remote add upstream https://github.com/original/repo.gitДобавить ещё один remote (например, оригинал для форка).
git remote renamegit remote rename origin gitlabПереименовать remote.
git remote removegit remote remove old-serverУдалить remote из настроек (на сервере ничего не меняется).
git remote set-urlgit remote set-url origin git@github.com:user/repo.gitСменить адрес (например, с HTTPS на SSH).
git remote set-url --pushgit remote set-url --push origin git@backup:repo.gitОтдельный адрес только для отправки.
git remote showgit remote show originПодробно: ветки, отслеживание, что будет отправлено при push.
git remote prunegit remote prune originУдалить локальные ссылки на ветки, которых уже нет на сервере.
git ls-remotegit ls-remote --heads originСписок веток и тегов на сервере без клонирования.

Получение изменений: fetch и pull

КомандаВариантЧто делает
git fetchgit fetch originСкачать новые коммиты и обновить origin/*, не трогая свои ветки.
git fetch --allgit fetch --all --pruneВсе remote, с удалением устаревших ссылок.
git fetch --tagsgit fetch --tags originПодтянуть все теги.
git fetch origin веткаgit fetch origin feature/x:feature/xПолучить одну ветку и создать локальную с тем же именем.
git pullgit pull origin mainfetch и merge в текущую ветку.
git pull --rebasegit pull --rebase origin mainfetch и rebase: история остаётся линейной.
git pull --ff-onlygit pull --ff-onlyТолько если можно без слияния; иначе ошибка, без неожиданных коммитов.
git pull --autostashgit pull --rebase --autostashВременно спрятать локальные правки на время pull.
git log HEAD..origingit log --oneline HEAD..origin/mainЧто есть на сервере и нет у меня.
git log origin..HEADgit log --oneline origin/main..HEADЧто у меня есть и нет на сервере (то, что уйдёт при push).

Отправка изменений: push

КомандаВариантЧто делает
git pushgit pushОтправить текущую ветку в связанную с ней удалённую.
git push -ugit push -u origin feature/xОтправить и связать локальную ветку с удалённой (при первом push).
git push origingit push origin main:mainЯвно: локальная ветка main в удалённую main.
git push origin --deletegit push origin --delete feature/oldУдалить ветку на сервере.
git push --tagsgit push origin v1.4.0Отправить один тег.
git push --forcegit push --force origin feature/xПерезаписать ветку на сервере. Опасно: можно потерять чужие коммиты.
git push --force-with-leasegit push --force-with-lease origin feature/xБезопасная перезапись: отказ, если на сервере появились чужие коммиты.
git push --dry-rungit push --dry-run origin mainПроверить, что будет отправлено, без реальной отправки.
git push --set-upstreamgit push --set-upstream origin feature/xТо же, что -u.
git push --no-verifygit push --no-verifyПропустить pre-push хуки (используйте осознанно).
git push --force переписывает историю на сервере. Если кто-то уже скачал ветку, его локальные коммиты станут несовместимы. Всегда используйте --force-with-lease: команда откажется перезаписывать, если на сервере есть то, чего вы не видели.

Отслеживание веток

КомандаВариантЧто делает
git branch -vvgit branch -vvКакая удалённая ветка связана и отстаёт ли локальная (ahead, behind).
git branch -ugit branch -u origin/main mainЗадать связь вручную.
git rev-parsegit rev-parse --abbrev-ref @{u}Имя upstream-ветки текущей ветки.
git checkout --trackgit switch --track origin/feature/xСоздать локальную ветку из удалённой с отслеживанием.
git statusgit status -sbКороткий статус с информацией о расхождении с сервером.

Работа с форками и несколькими remote

# Клонируем свой форк
git clone git@github.com:me/project.git
cd project

# Добавляем оригинальный репозиторий
git remote add upstream git@github.com:team/project.git
git fetch upstream

# Обновляем свою main от оригинала и отправляем в свой форк
git switch main
git merge --ff-only upstream/main
git push origin main

# Ветка для задачи
git switch -c fix/parser
# ...коммиты...
git push -u origin fix/parser

Подмодули

КомандаВариантЧто делает
git submodule addgit submodule add https://github.com/lib/x.git vendor/xДобавить подмодуль в папку vendor/x.
git submodule updategit submodule update --init --recursiveИнициализировать и обновить подмодули, включая вложенные.
git submodule statusgit submodule statusКакой коммит зафиксирован для каждого подмодуля.
git submodule foreachgit submodule foreach 'git pull origin main'Выполнить команду в каждом подмодуле.
git clone --recursivegit clone --recurse-submodules URLКлонировать сразу вместе с подмодулями.

Синхронизация перед работой: типичная проверка

git status -sb                     # куда отстаём и опережаем
git fetch --all --prune           # обновить информацию о сервере
git log --oneline HEAD..origin/main   # что пришло
git pull --rebase --autostash     # подтянуть без лишних merge-коммитов
git push                          # отправить свои коммиты
Настройте git config --global push.default current и git config --global pull.rebase true. Тогда git push отправит текущую ветку, а git pull не будет создавать лишние коммиты слияния.
Для доступа по SSH добавьте ключ в ssh-agent и используйте адрес вида git@host:repo.git. Так не придётся вводить пароль при каждом fetch или push.