Віддалені репозиторії Git: clone, fetch, pull, push, fork
Що таке remote і origin/main, різниця між fetch і pull, push нової гілки, force-with-lease, робота через fork з upstream і корисні рецепти синхронізації.
Remote — це адреса з ім'ям
Віддалений репозиторій (remote) — інша копія вашого репозиторію: на GitHub, GitLab, Bitbucket, власному сервері чи навіть у сусідній папці. Щоб не писати адресу щоразу, їй дають коротке ім'я. Після git clone адреса, звідки клонували, автоматично зветься origin.
git remote -vorigin git@github.com:olena/notes-app.git (fetch)
origin git@github.com:olena/notes-app.git (push)| Дія | Команда |
|---|---|
| додати | git remote add origin git@github.com:olena/notes-app.git |
| змінити адресу | git remote set-url origin git@github.com:olena/new-name.git |
| перейменувати | git remote rename origin github |
| видалити | git remote remove origin |
| детально (гілки, відстеження) | git remote show origin |
SSH чи HTTPS
SSH git@github.com:user/repo.git |
HTTPS https://github.com/user/repo.git |
|
|---|---|---|
| Вхід | SSH-ключ, налаштовується раз | токен (не пароль!) через credential helper |
| Через корпоративний проксі | часто заблоковано (порт 22) | працює майже завжди |
| Для CI | deploy key | токен у секретах CI |
Перейти з HTTPS на SSH: git remote set-url origin git@github.com:user/repo.git. Налаштування ключів — у нотатці «Встановлення і налаштування Git».
Порт 22 заблокованоGitHub приймає SSH і на порту 443. У
~/.ssh/config:Host github.com HostName ssh.github.com Port 443 User git
git clone
git clone git@github.com:olena/notes-app.git # у папку notes-app
git clone git@github.com:olena/notes-app.git my-notes # у папку my-notes
git clone -b develop git@github.com:olena/notes-app.git # одразу на гілку develop
git clone --depth 1 https://github.com/torvalds/linux.git # лише останній коміт (швидко)
git clone --recurse-submodules <url> # разом із сабмодулямиRemote-tracking гілки: що таке origin/main
Після clone чи fetch у вас з'являються гілки виду origin/main. Це локальні копії стану сервера на момент останнього fetch, лише для читання. Вони не оновлюються самі: якщо колега щойно запушив коміт, ви його не побачите, поки не зробите git fetch.
| Гілка | Де живе | Хто рухає |
|---|---|---|
main |
у вас | ви — комітами, merge, reset |
origin/main |
у вас, копія стану сервера | лише git fetch / git pull / git push |
main на GitHub |
на сервері | git push (ваш і колег) |
Зв'язок локальної гілки з віддаленою називається upstream (tracking). Саме завдяки йому git status пише «ahead 2, behind 1», а git pull і git push знають, куди йти без аргументів:
git branch -vv* main 3a4b5c6 [origin/main: ahead 1, behind 1] Додати пошук
feature/search 9c0d1e2 [origin/feature/search] Фільтр за тегами
experiment 1f2e3d4 Спроба нового парсераexperiment не має upstream — її ніколи не пушили.
git fetch — подивитися, що нового, нічого не чіпаючи
git fetch # origin
git fetch --all # усі remote
git fetch --prune # + прибрати origin/* гілки, видалені на серверіfetch оновлює лише origin/*. Ваші гілки й файли не змінюються — це завжди безпечно. Далі можна подивитися, що прийшло:
git log --oneline main..origin/main # нові коміти на сервері, яких у вас немає
git log --oneline origin/main..main # ваші коміти, яких немає на сервері
git diff main origin/main # різниця у файлахgit pull — забрати й влити
git pull = git fetch + вливання origin/<гілка> у поточну гілку. Як саме вливати — визначають налаштування:
| Налаштування | Якщо гілки розійшлися |
|---|---|
pull.rebase = false |
merge-коміт «Merge branch 'main' of …» |
pull.rebase = true |
ваші коміти переставляються поверх серверних (лінійно) |
pull.ff = only |
помилка — вирішуйте вручну (найобережніше) |
Якщо нічого не налаштовано, а гілки розійшлися, сучасний Git зупиниться:
hint: You have divergent branches and need to specify how to reconcile them.
...
fatal: Need to specify how to reconcile divergent branches.Оберіть раз і назавжди (найпопулярніший варіант — rebase):
git config --global pull.rebase truegit push — відправити свої коміти
git push # поточну гілку в її upstream
git push origin main # явно: локальну main в origin/main
git push -u origin feature/search # нову гілку + запам'ятати upstreamЩоб не писати -u origin <гілка> для кожної нової гілки:
git config --global push.autoSetupRemote true
git switch -c feature/export
git push # гілка створиться на сервері самаPush відхилено
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:olena/notes-app.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally.На сервері є коміти, яких немає у вас (ситуація зі схеми вище). Не робіть --force! Заберіть зміни й повторіть:
git pull --rebase
git pushВаріант (non-fast-forward) з тим самим змістом зазвичай з'являється після того, як ви переписали власну історію (rebase, amend). Якщо гілка лише ваша — git push --force-with-lease, детальніше в нотатці «Rebase».
Видалити гілку на сервері
git push origin --delete feature/searchТеги
git push теги не відправляє:
git push origin v1.2.0 # один тег
git push --tags # усі локальні тегиРобота через fork
Якщо прав на запис у репозиторій немає (open source або чужа команда), працюють через fork — вашу копію репозиторію на GitHub.
# 1. На GitHub: кнопка Fork → github.com/you/project
# 2. Клонуємо свій fork
git clone git@github.com:you/project.git
cd project
# 3. Додаємо оригінал як upstream
git remote add upstream https://github.com/author/project.git
git remote -vorigin git@github.com:you/project.git (fetch)
origin git@github.com:you/project.git (push)
upstream https://github.com/author/project.git (fetch)
upstream https://github.com/author/project.git (push)Робота над задачею:
git fetch upstream
git switch -c fix/typo-in-docs upstream/main # гілка від свіжого оригіналу
# ... правки, коміти ...
git push -u origin fix/typo-in-docs # у свій fork
# 4. На GitHub: Compare & pull request → в author/projectОновити свій main із оригіналу:
git switch main
git fetch upstream
git merge --ff-only upstream/main
git push origin mainНа GitHub для цього ще є кнопка Sync fork.
Не працюйте прямо в main свого forkТримайте
mainfork-а точною копієюupstream/main, а кожну задачу — у своїй гілці. Тоді синхронізація завжди fast-forward і без конфліктів.
Корисні рецепти
Взяти гілку колеги:
git fetch
git switch feature/payments # Git сам створить локальну гілку з upstream origin/feature/paymentsСкинути локальну гілку до стану сервера (всі локальні коміти й зміни в ній буде втрачено!):
git fetch origin
git reset --hard origin/mainЩо я ще не запушив:
git log --oneline @{u}.. # @{u} — upstream поточної гілкиПрив'язати існуючу гілку до віддаленої:
git branch -u origin/feature/searchПерейменувати master на main:
git branch -m master main
git push -u origin main
# на GitHub: Settings → Branches → default branch → main
git push origin --delete masterПеренести репозиторій на інший сервер з усією історією:
git clone --mirror git@old-server:team/app.git
cd app.git
git push --mirror git@github.com:team/app.gitШпаргалка
| Команда | Що робить |
|---|---|
git remote -v |
список remote |
git remote add upstream <url> |
додати ще один remote |
git fetch --all --prune |
оновити знання про всі сервери |
git log main..origin/main |
що нового на сервері |
git pull --rebase |
забрати й поставити свої коміти зверху |
git push -u origin <гілка> |
перший push нової гілки |
git push --force-with-lease |
push після rebase, не затираючи чужого |
git push origin --delete <гілка> |
видалити гілку на сервері |
git branch -vv |
гілки з upstream і ahead/behind |
git reset --hard origin/main |
стати точно як сервер |
Збережіть статтю собі
Увійдіть, щоб імпортувати її у власні нотатки, відмічати вивчене, ставити лайки й питати спільноту. Реєстрація безкоштовна: вхід через Google займає кілька секунд.
Увійти через Google Інші способи входу