Git: удалённые репозитории, fetch, pull и push
Третья часть гида: связь с сервером, получение и отправка изменений, отслеживаемые ветки и совместная работа
Remote: управление адресами
| Команда | Вариант | Что делает |
| git remote | git remote | Имена удалённых репозиториев. |
| git remote -v | git remote -v | Имена и адреса (fetch и push). |
| git remote add | git remote add upstream https://github.com/original/repo.git | Добавить ещё один remote (например, оригинал для форка). |
| git remote rename | git remote rename origin gitlab | Переименовать remote. |
| git remote remove | git remote remove old-server | Удалить remote из настроек (на сервере ничего не меняется). |
| git remote set-url | git remote set-url origin git@github.com:user/repo.git | Сменить адрес (например, с HTTPS на SSH). |
| git remote set-url --push | git remote set-url --push origin git@backup:repo.git | Отдельный адрес только для отправки. |
| git remote show | git remote show origin | Подробно: ветки, отслеживание, что будет отправлено при push. |
| git remote prune | git remote prune origin | Удалить локальные ссылки на ветки, которых уже нет на сервере. |
| git ls-remote | git ls-remote --heads origin | Список веток и тегов на сервере без клонирования. |
Получение изменений: fetch и pull
| Команда | Вариант | Что делает |
| git fetch | git fetch origin | Скачать новые коммиты и обновить origin/*, не трогая свои ветки. |
| git fetch --all | git fetch --all --prune | Все remote, с удалением устаревших ссылок. |
| git fetch --tags | git fetch --tags origin | Подтянуть все теги. |
| git fetch origin ветка | git fetch origin feature/x:feature/x | Получить одну ветку и создать локальную с тем же именем. |
| git pull | git pull origin main | fetch и merge в текущую ветку. |
| git pull --rebase | git pull --rebase origin main | fetch и rebase: история остаётся линейной. |
| git pull --ff-only | git pull --ff-only | Только если можно без слияния; иначе ошибка, без неожиданных коммитов. |
| git pull --autostash | git pull --rebase --autostash | Временно спрятать локальные правки на время pull. |
| git log HEAD..origin | git log --oneline HEAD..origin/main | Что есть на сервере и нет у меня. |
| git log origin..HEAD | git log --oneline origin/main..HEAD | Что у меня есть и нет на сервере (то, что уйдёт при push). |
Отправка изменений: push
| Команда | Вариант | Что делает |
| git push | git push | Отправить текущую ветку в связанную с ней удалённую. |
| git push -u | git push -u origin feature/x | Отправить и связать локальную ветку с удалённой (при первом push). |
| git push origin | git push origin main:main | Явно: локальная ветка main в удалённую main. |
| git push origin --delete | git push origin --delete feature/old | Удалить ветку на сервере. |
| git push --tags | git push origin v1.4.0 | Отправить один тег. |
| git push --force | git push --force origin feature/x | Перезаписать ветку на сервере. Опасно: можно потерять чужие коммиты. |
| git push --force-with-lease | git push --force-with-lease origin feature/x | Безопасная перезапись: отказ, если на сервере появились чужие коммиты. |
| git push --dry-run | git push --dry-run origin main | Проверить, что будет отправлено, без реальной отправки. |
| git push --set-upstream | git push --set-upstream origin feature/x | То же, что -u. |
| git push --no-verify | git push --no-verify | Пропустить pre-push хуки (используйте осознанно). |
git push --force переписывает историю на сервере. Если кто-то уже скачал ветку, его локальные коммиты станут несовместимы. Всегда используйте --force-with-lease: команда откажется перезаписывать, если на сервере есть то, чего вы не видели.
Отслеживание веток
| Команда | Вариант | Что делает |
| git branch -vv | git branch -vv | Какая удалённая ветка связана и отстаёт ли локальная (ahead, behind). |
| git branch -u | git branch -u origin/main main | Задать связь вручную. |
| git rev-parse | git rev-parse --abbrev-ref @{u} | Имя upstream-ветки текущей ветки. |
| git checkout --track | git switch --track origin/feature/x | Создать локальную ветку из удалённой с отслеживанием. |
| git status | git 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 add | git submodule add https://github.com/lib/x.git vendor/x | Добавить подмодуль в папку vendor/x. |
| git submodule update | git submodule update --init --recursive | Инициализировать и обновить подмодули, включая вложенные. |
| git submodule status | git submodule status | Какой коммит зафиксирован для каждого подмодуля. |
| git submodule foreach | git submodule foreach 'git pull origin main' | Выполнить команду в каждом подмодуле. |
| git clone --recursive | git 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.