"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

Другие вопросы по тегам