Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке refspec і як Git вирішує, які гілки завантажувати при fetch і куди їх записувати?

Refspec - правило відповідності між ref-ами віддаленого репозиторію і вашого локального. Його формат:

+<джерело>:<призначення>
  • джерело - ref на тому боці, звідки беремо;
  • призначення - куди записати локально;
  • + - дозволити оновлення без fast-forward (наприклад, після force push на сервері).

Refspec за замовчуванням записується при git clone чи git remote add:

# .git/config
[remote "origin"]
    url = git@github.com:acme/shop.git
    fetch = +refs/heads/*:refs/remotes/origin/*

Читається так: «усі гілки сервера (refs/heads/*) записати як refs/remotes/origin/*». Звідси й з'являються origin/main, origin/feature-x - це ваші локальні копії стану гілок сервера на момент останнього fetch.

Що можна налаштувати:

# завантажувати лише main і релізні гілки
fetch = +refs/heads/main:refs/remotes/origin/main
fetch = +refs/heads/release/*:refs/remotes/origin/release/*

# додатково отримувати pull request-и GitHub
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

Після цього git fetch створить origin/pr/142 для кожного PR, і будь-який з них можна переглянути локально.

Refspec у командах:

git fetch origin main                    # лише main, результат у FETCH_HEAD і origin/main
git fetch origin pull/142/head:pr-142    # PR одразу в локальну гілку pr-142
git push origin feature:review/feature   # запушити локальну feature під іншим ім'ям
git push origin :old-branch              # порожнє джерело - видалити гілку на сервері
git push origin HEAD:refs/for/main       # Gerrit: відправити на рецензію

Push теж використовує refspec: git push origin main - скорочення для main:main. Налаштування push.default визначає, що відправляє git push без аргументів (simple - поточну гілку в однойменну upstream).

Корисні наслідки:

  • origin/main оновлюється лише при fetch/pull, а не сам по собі - тому «origin/main відстає від GitHub» лікується git fetch;
  • fetch --prune (чи fetch.prune=true) видаляє origin/* для гілок, видалених на сервері;
  • у CI з великим репозиторієм вузький refspec (лише потрібна гілка) суттєво зменшує обсяг завантаження.

Докладніше в документації: Pro Git: refspec

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання