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 (лише потрібна гілка) суттєво зменшує обсяг завантаження.