Глиф Учебники

Урок 6. Удалённые репозитории: clone, push, pull, fetch

Курс «Git» · урок 6 из 9 · 5 минут чтения

До сих пор история жила только у вас на диске. Удалённый репозиторий (remote) — копия проекта на сервере: на GitHub, GitLab, своём сервере или даже в другой папке. С ним обмениваются коммитами: отправляют свои (push) и забирают чужие (fetch, pull). Так проект попадает на другой компьютер, к коллегам и заодно в резервную копию.

Создайте пустой репозиторий на сервере

На GitHub, GitLab и похожих сервисах новый репозиторий создаётся кнопкой в веб-интерфейсе: задаётся имя (например, todo) и видимость — публичный или закрытый. Если локальный репозиторий у вас уже есть, не добавляйте при создании файлы README, .gitignore и лицензию: иначе на сервере появится свой первый коммит, не связанный с вашей историей, и первая отправка не пройдёт. Если уже добавили — решение в справке rejected — non-fast-forward.

После создания сервис показывает адрес репозитория — в двух видах:

https:// github.com / ivan / todo.git git@ github.com : ivan / todo.git сервер владелец репозиторий протокол пользователь git для входа по SSH HTTPS — имя и токен SSH — SSH-ключ
Оба адреса ведут к одному репозиторию: сервер github.com, владелец ivan и репозиторий todo.git, но по HTTPS вход идёт по имени и токену, а по SSH — по ключу.

Свяжите и отправьте

В папке своего репозитория (вместо https://github.com/ivan/todo.git — адрес, который показал сервис):

Bash
git remote add origin https://github.com/ivan/todo.git
git push -u origin main

origin — короткое имя удалённого репозитория; так его принято называть, хотя имя может быть любым. git push -u origin main отправляет ветку main в origin, а -u запоминает связь: дальше хватит просто git push и git pull. В конце вывода Git сообщит:

Текст
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

Проверить, с каким сервером связан репозиторий:

Терминал
$ git remote -v
origin    https://github.com/ivan/todo.git (fetch)
origin    https://github.com/ivan/todo.git (push)

Вход по HTTPS

GitHub не принимает пароль от учётной записи для работы Git по HTTPS: вместо пароля нужен токен (personal access token), созданный в настройках учётной записи, или вход по SSH-ключу. В Git for Windows обычно ставится Git Credential Manager — при первой отправке он сам открывает окно входа в учётную запись и запоминает доступ. У GitLab и других сервисов похожие правила — смотрите их справку.

Токен даёт доступ к вашим репозиториям, как пароль. Не вставляйте его в адрес репозитория, в код и в сообщения коммитов: всё это видно другим. Выдавайте токену только нужные права и срок действия.

Склонируйте проект

Обратная задача — получить копию существующего репозитория:

Терминал
$ git clone https://github.com/ivan/todo.git
Cloning into 'todo'...

Появится папка todo со всеми файлами и всей историей, а origin уже будет указывать на сервер. Подробнее — в справке Как клонировать репозиторий.

Заберите изменения: fetch и pull

Кто-то отправил на сервер новые коммиты. Получить их можно двумя способами:

Ваш компьютер origin/main main main fetch двигает только origin/main, pull ещё и вливает новое в main Сервер origin main новый коллега отправил git fetch git pull fetch + слияние
git fetch приносит с сервера новый коммит и сдвигает только origin/main, а git pull после этого ещё и вливает его в вашу ветку main.

После git fetch команда git status подскажет, что делать:

Терминал
$ git status
On branch main
Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Сам git status с сервером не связывается: он сравнивает с тем, что скачано последним fetch или pull. Разница подробно — в справке Чем pull отличается от fetch.

Ветки разошлись

Если и у вас, и на сервере есть новые коммиты, git pull в свежих версиях Git может остановиться с подсказкой You have divergent branches and need to specify how to reconcile them и ошибкой fatal: Need to specify how to reconcile divergent branches. Git просит один раз выбрать способ объединения. Для начала подойдёт слияние — как в уроке о ветках:

Bash
git config --global pull.rebase false
git pull

Git создаст коммит слияния и откроет редактор с готовым сообщением — сохраните и закройте его. После этого отправка пройдёт: git push.

Отправку отклонили

Если на сервере есть коммиты, которых нет у вас, git push откажется: ! [rejected] main -> main (fetch first) или (non-fast-forward). Это защита, а не поломка: сначала заберите чужое через git pull, при конфликте решите его, потом снова git push. Подробно — в справке rejected — non-fast-forward.

У вас ваш git push rejected Сервер origin чужой этого коммита у вас нет git pull — забрать чужой коммит и слить со своим git push теперь проходит на сервере оба коммита
git push отклонён, потому что на сервере есть чужой коммит, которого у вас нет; git pull забирает его и сливает с вашим, и после этого отправка проходит, а на сервере остаются оба коммита.

Частые ошибки

Коротко

Проверьте себя

1. Что делает ключ -u в git push -u origin main?
2. Чем git fetch отличается от git pull?
3. git push ответил rejected (fetch first). Что сделать?
4. Что значит error: src refspec main does not match any?