Отправить проект на сервер, забрать чужие изменения, работать с нескольких компьютеров
git fetch и git pull, читать «ahead / behind»Удалённый репозиторий (remote) — копия репозитория на сервере. Технически это такой же репозиторий Git, как у вас, только к нему обращаются по сети. Git ничего не отправляет и не забирает сам: обмен происходит только по вашим командам.
| Команда | Направление | Что делает |
|---|---|---|
git clone | сервер → вы | Скачать репозиторий целиком, один раз |
git push | вы → сервер | Отправить свои коммиты |
git fetch | сервер → вы | Забрать чужие коммиты, не трогая ваши файлы |
git pull | сервер → вы | fetch и сразу слияние в текущую ветку |
В курсе сервер — GitFlic (gitflic.ru). Репозиторий на GitFlic называется проектом. Всё, что ниже, кроме шагов в веб-интерфейсе, одинаково для GitVerse, GitLab и GitHub.
Зарегистрируйтесь на gitflic.ru. Имя пользователя (логин) войдёт в адреса всех ваших проектов — выбирайте короткое, латиницей. Почту в профиле укажите ту же, что в git config user.email: тогда GitFlic свяжет ваши коммиты с профилем.
Git-хостинг должен знать, что отправляете именно вы. Надёжный способ — SSH-ключ: пара файлов, закрытый ключ остаётся на компьютере, открытый отдаётся серверу. Пароль при этом по сети не передаётся.
# создать ключ; на вопрос о файле — Enter, пароль ключа — по желанию
$ ssh-keygen -t ed25519 -C "anna@example.ru"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/anna/.ssh/id_ed25519):
Your identification has been saved in /home/anna/.ssh/id_ed25519
Your public key has been saved in /home/anna/.ssh/id_ed25519.pub
# вывести открытый ключ, чтобы скопировать
$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH8k...q2Vd anna@example.ru
Скопируйте строку целиком и добавьте её в GitFlic: настройки профиля, раздел SSH-ключей. Проверка связи:
$ ssh -T git@gitflic.ru
При первом подключении SSH спросит, доверять ли серверу, — ответьте yes. Если ключ принят, сервер ответит приветствием и закроет соединение; Permission denied (publickey) означает, что ключ не добавлен или добавлен не тот.
.pub. Файл id_ed25519 без расширения — закрытый ключ: он не пересылается, не выкладывается и не копируется в репозиторий. Кто его получил, может отправлять код от вашего имени.https://gitflic.ru/project/…, Git спросит логин и пароль или токен доступа из настроек профиля. Он удобен, если SSH закрыт сетью (так бывает в учебных классах и офисах). Команды Git в обоих случаях одинаковые, различается только адрес.Создайте на GitFlic новый проект: имя латиницей (например, portfolio), видимость — открытый, без README и других файлов. Пустой проект нужен, чтобы в нём не было коммитов, которых нет у вас. После создания GitFlic покажет адрес для SSH и HTTPS.
$ cd ~/portfolio
$ git remote add origin git@gitflic.ru:anna-smirnova/portfolio.git
$ git remote -v
origin git@gitflic.ru:anna-smirnova/portfolio.git (fetch)
origin git@gitflic.ru:anna-smirnova/portfolio.git (push)
$ git push -u origin main
Enumerating objects: 15, done.
...
To gitflic.ru:anna-smirnova/portfolio.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.
origin — принятое имя основного удалённого репозитория. Это просто псевдоним адреса.-u связывает локальную main с origin/main. Дальше хватает git push и git pull без аргументов.https://gitflic.ru/project/anna-smirnova/portfolio — там файлы, история коммитов и ветки.Остальные ветки отправляются так же — по одной, при первой отправке с -u:
$ git push -u origin feature/contacts
Клонирование — скачать проект, которого у вас ещё нет: чужой или свой на другой компьютер. Remote origin и связь веток настраиваются автоматически.
$ git clone git@gitflic.ru:anna-smirnova/portfolio.git
Cloning into 'portfolio'...
$ cd portfolio
$ git log --oneline -n 2
c71b4a0 (HEAD -> main, origin/main) Merge branch 'feature/projects'
f3a01c9 Исправить телефон в контактах
# открытый проект можно скачать и без ключа, по HTTPS
$ git clone https://gitflic.ru/project/anna-smirnova/portfolio.git
У себя Git хранит последнее известное состояние веток сервера: origin/main, origin/feature/contacts. Это отслеживаемые ветки — вы в них не коммитите, они обновляются при fetch и pull.
$ git fetch
From gitflic.ru:anna-smirnova/portfolio
c71b4a0..8d3f2e6 main -> origin/main
$ git status
On branch main
Your branch is behind 'origin/main' by 2 commits, and can be fast-forwarded.
$ git log --oneline main..origin/main # что пришло с сервера
8d3f2e6 Добавить фото в раздел «Обо мне»
1a7c5b0 Исправить ссылку на резюме
$ git pull
Updating c71b4a0..8d3f2e6
Fast-forward
| git status говорит | Что значит | Что делать |
|---|---|---|
up to date | Совпадает с сервером (на момент последнего fetch) | Ничего |
ahead by 2 | У вас 2 коммита, которых нет на сервере | git push |
behind by 2 | На сервере 2 коммита, которых нет у вас | git pull |
have diverged | Новые коммиты и там, и тут | git pull, при конфликте — разрешить |
git status сравнивает с тем, что Git знал на момент последнего fetch, а не с сервером прямо сейчас. Утром, перед работой, — git fetch или git pull.Коллега отправил коммиты в main, пока вы работали. Ваша отправка будет отклонена: сервер не принимает push, который выбросил бы чужие коммиты.
$ git push
To gitflic.ru:anna-smirnova/portfolio.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'gitflic.ru:anna-smirnova/portfolio.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. ...
Решение — забрать чужие коммиты, слить со своими и отправить снова:
$ git pull # fetch + merge; при конфликте — как в модуле 06
$ git push
git push --force. Принудительная отправка перезаписывает ветку на сервере вашей версией, и коммиты коллеги пропадут. В общих ветках — никогда. Если без неё не обойтись в своей личной ветке — git push --force-with-lease: она откажет, если на сервере появилось что-то, чего вы не видели.git pull в новой версии Git пишет «You have divergent branches and need to specify how to reconcile them», задайте поведение один раз: git config --global pull.rebase false — pull будет сливать, как описано в этом модуле..pub — на GitFlic, закрытый — никомуgit push -u origin ветка, дальше — git pushfetch только скачивает, pull скачивает и сливаетgit pull, затем git push; не --force