"fetch -all" в git голом репозитории не синхронизирует локальные ветки с удаленными

Я пытаюсь периодически синхронизировать открытый репозиторий git, мои локальные ветки создаются с помощью опции "--track". вот моя конфигурация (без лишних вещей):

[core]
        bare = true
[remote "origin"]
        url = [email protected]: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

Вместо копирования файлов ref вокруг (плохо плохо!) используйте git update-ref

Обратите внимание, что при нажатии вместо того, чтобы тянуть, вы можете легко получить то, что вам было бы довольно легко, до открытого репозитория.

Используйте это:

 git clone --mirror . /tmp/bareclone

создать голый репозиторий, который вы хотите полностью синхронизировать Теперь, чтобы синхронизировать все ветки с зеркалом bareclone, используйте

 git push /tmp/bareclone --mirror

Учтите, что это также приведет к удалению любых головок, которые не находятся в исходном репо, но (все еще) находятся в bareclone. Также обратите внимание, что вы можете использовать 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)

Примечание: если вы хотите принудительно обновить (например, когда нет быстрого перетаскивания из-за восходящей переадресации, reset, ветки фильтра или исправленного фиксации (в вообще - любая перезаписанная история) замените echo "$ref:$ref" на echo "+$ref:$ref"; (Спасибо Dov)

3. Полный monty

Это также может быть объединено, поэтому вы также можете иметь удаленное определение. Я бы рекомендовал это, потому что это будет означать, что локальные ветки фактически отслеживают их из пультов, и у вас будут лучшие варианты изоляции/восстановления, если вы случайно скроете некоторые локальные коммиты в этих ветвях с помощью этих мощных команд извлечения

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