"fetch --all" в репозитории git bare не синхронизирует локальные ветви с удаленными
Я пытаюсь периодически синхронизировать репозиторий git bare, мои локальные ветки создаются с использованием опции --track. вот мой конфиг (без лишних вещей):
[core]
bare = true
[remote "origin"]
url = git@github.com:Ummon/D-LAN.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "website"]
remote = origin
merge = refs/heads/website
Я должен использовать команду "cp" для обновления локальных веток:
git fetch --all
cp -r refs/remotes/origin/* refs/heads
Есть ли более элегантное решение?
1 ответ
Вместо копирования файлов ссылок вокруг (плохо плохо!) Используйте git update-ref
Обратите внимание, что вы можете легко получить то, что хотели, в пустом хранилище, когда нажимаете вместо того, чтобы тянуть.
Использовать этот:
git clone --mirror . /tmp/bareclone
чтобы создать пустой репозиторий, который вы хотите полностью синхронизировать сейчас, чтобы синхронизировать все ветви с зеркалом bareclone, используйте
git push /tmp/bareclone --mirror
Обратите внимание, что при этом также будут удалены все головы, которых нет в репо-источнике, но (все еще) они находятся в бэклоне. Также обратите внимание, что вы можете использовать send-pack вместо push там, потому что этот интерфейс довольно низкоуровневый и фактически реализован send-pack
НТН
Как заметил комментатор, я чуть-чуть избежал этой темы, поскольку кажется невозможным сразу сделать обратное. Тем не менее, вы можете пройти долгий путь к цели, сделав что-то немного продвинутое, например
1. Простой, безопасный и довольно неинтересный.
git fetch $url -- $(git ls-remote -h $url |
while read sha ref; do echo "$ref:refs/remotes/fetched/${ref#refs/heads/}"; done)
Установите `url=git://your.server/project.git', например
Я убедился, что ссылки созданы в умеренно безопасном месте. Эффект очень похож на выполнение.
git remote add fetched $url --fetch
Так что ничего особенного нет, но он показывает вам, как использовать сантехнические команды для достижения этого, так что теперь мы можем адаптировать их к нашим потребностям:
2. Получить непосредственно в местные филиалы (головы)
Теперь, если вы уверены, что знаете, что делаете, вы можете использовать следующий стиль для локального дублирования веток:
git init --bare .
git fetch $url -- $(git ls-remote -h $url |
while read sha ref; do echo "$ref:$ref"; done)
Примечание: если вы хотите принудительно обновить (например, когда нет ускоренной перемотки вперед из-за перебазирования, сброса, ветвления фильтра или исправленной фиксации в восходящем потоке (в общем случае - любая переписанная история), замените
echo "$ref:$ref"
отecho "+$ref:$ref"
; (Спасибо, Dov Grobgeld)
3. Полный Монти
Это также может быть объединено, так что вы также можете иметь удаленное определение. Я бы порекомендовал это, потому что это будет означать, что локальные ветви на самом деле отслеживают ветки с удаленных устройств, и у вас будут лучшие варианты изоляции / восстановления, если вы случайно повредите некоторые из локальных коммитов в этих ветвях с помощью этих мощных команд извлечения.
git init --bare .
git remote add fetched $url --fetch
git for-each-ref --format='%(refname:short)' -- 'refs/remotes/fetched/' |
while read ref; do git branch -t "$(basename "$ref")" "$ref"; done
Веселись, HTH