Примечание. Сложный метод, описанный ниже, требуется только в том случае, если "клонированный" репозиторий является рабочим репозиторием (т. е. не голым репозиторием, в котором вы фиксируете, используя отдельные компоновка пультов), а не голый (или зеркальный) репозиторий. Если «cloned.git» является пустым репозиторием, достаточно выполнить git clone --bare
(или git clone --mirror
), чтобы восстановить исходный репозиторий «report.git» (как, например, алинрус написал).
Предполагая, что вы использовали конфигурацию по умолчанию и современный Git, что означает макет «отдельные пульты», у вас будут ветки удаленного отслеживания «report.git» в пространстве имен «remotes/origin» (или «remotes/report»).
Чтобы воссоздать репозиторий «report.git», вам нужно будет один раз нажать (или получить) из веток удаленного отслеживания в обычные ветки, вернув обычную спецификацию fetch refspec (по крайней мере, для веток: теги всегда зеркалируются). Таким образом, refspec для однократного нажатия (или выборки) будет выглядеть примерно так: refs/remotes/origin/*:refs/heads/*
плюс refs/tags/*:refs/tags/*
.
Пример сеанса восстановления
Предположим, что оригинальный репозиторий «report.git» содержит две ветки: «master» и «next» и не содержит тегов (теги отображаются 1-1, так что в любом случае они не должны быть проблемой):
$ git init --bare report.git
# ...
[report.git] $ git branch -a
* master
next
Пусть репозиторий «cloned/.git» будет обычным (не голым и не зеркальным) клоном «report.git»:
$ git clone [email protected]:report.git cloned
Initialized empty Git repository in /tmp/jnareb/cloned/.git/
# ...
[cloned] $ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/next
[cloned] $ git remote show origin
* remote origin
Fetch URL: [email protected]:report.git
Push URL: [email protected]:report.git
HEAD branch: master
Remote branches:
master tracked
next tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
Конечно, статус ваших филиалов и количество ваших локальных филиалов могут отличаться в зависимости от вашей ситуации. Это всего лишь простой пример.
Теперь давайте удалим или, что еще лучше, переименуем (отодвинем в сторону) исходный репозиторий «report.git», чтобы проверить нашу операцию восстановления.
$ mv report.git report-copy.git
Теперь мы восстанавливаем состояние «report.git», которое было при последней операции извлечения/вытягивания в «cloned/.git»:
$ git init report.git # push won't create new repository
# move to 'cloned' repository
[cloned] $ git push [email protected]:report.git 'refs/remotes/origin/*:refs/heads/*'
Counting objects: 12, done.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (12/12), 839 bytes, done.
Total 12 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (12/12), done.
warning: updating the current branch
# long warning about pushing into current branch
To [email protected]:report.git
* [new branch] origin/HEAD -> HEAD
* [new branch] origin/master -> master
* [new branch] origin/next -> next
Теперь вы можете сравнить «report.git» и «report-copy.git», если они идентичны. Если бы «report.git» был не голым, они могли бы отличаться, потому что push не обновил бы рабочий каталог (и вам нужно было бы сделать git reset --hard HEAD
или git checkout
в «report.git» самостоятельно), но это голый репозиторий, не так ли?
HTH (надеюсь, что это поможет).
person
Jakub Narębski
schedule
07.11.2009