"fetch --all" в репозитории git bare не синхронизирует локальные ветви с удаленными - PullRequest
10 голосов
/ 06 апреля 2011

Я пытаюсь периодически синхронизировать репозиторий 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 Ответ

19 голосов
/ 06 апреля 2011

Вместо копирования файлов ссылок (плохо, плохо!) Используйте 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)

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...