Как конвертировать голый репозиторий git в обычный (на месте)?
У меня есть голый репозиторий git, но вам нужно получить доступ и просмотреть его содержимое поверх ssh (в файловом менеджере, например, в пользовательском режиме).
Я предполагаю, что могу клонировать его:
git clone -l <path_to_bare_repo> <new_normal_repo>
Однако мой репозиторий имеет размер около 20 ГБ, и у меня нет места для его дублирования. Есть ли способ конвертировать голый репозиторий на месте, чтобы в итоге получить рабочую копию?
Ответы
Ответ 1
Примечание: я проверил это в очень простом репозитории с 1 коммитом. Дважды проверьте это, прочитайте справочные страницы и всегда будьте рады, что вы сделали резервную копию, прежде чем следовать советам, которые вы нашли в StackOverflow. (Вы делаете резервную копию, верно?)
Чтобы преобразовать репозиторий --bare
в не-пустой:
- Создайте папку
.git
на верхнем уровне вашего хранилища. - Переместите элементы управления хранилищем (
HEAD branches config description hooks info objects refs
и т.д.) В только что созданный .git
. - Запустите
git config --local --bool core.bare false
чтобы преобразовать локальный git-репозиторий в non-bare. - (через комментарий Tamás Pap) После шага № 3 вы увидите, что вы находитесь на
master
филиале (или в зависимости от того, какая у вас основная ветвь), и все ваши файлы будут удалены, и удаление будет подготовлено. Это нормально. Просто вручную проверьте master
или выполните git reset --hard
, и все готово. - (чтобы решить проблему, о которой сообщил Ройи) Отредактируйте файл
.git/config
добавив строку fetch = +refs/heads/*:refs/remotes/origin/*
после url = <...>
в разделе [remote "origin"]
. В противном случае git fetch
не увидит origin/master
и другие ветки origin.
Эти шаги направлены в противоположном направлении от этого вопроса, "git-convert normal to bare repository" - в частности, обратите внимание на этот ответ, в котором говорится, что вышеуказанные шаги (я полагаю, в любом направлении) отличаются от выполнения git-clone
, Не уверен, что это имеет отношение к вам, но вы упомянули git clone
в этом вопросе.
Ответ 2
У меня был несколько иной сценарий:
Решение:
- клонировать голый репо в этом контенте в директории
.git
:
git clone --bare https://github.com/user/project .git
- Отметьте его как не-обнаженное репо:
git config --local --bool core.bare false
- reset индекс (в противном случае он считает, что все было удалено, так как
.git
bare repo не включает файл 'index
'.)
git reset HEAD -- .
Это восстанавливает .git/index
.
Я фактически трансформировал голый репо в не-голый, сохраняя контент, который я ранее получил.
full script, который я использую в течение многих лет, включает в себя следующие шаги:
cd /path/to/current/worktree
# That creates a .git directly at the right place
git clone --bare /url/of/repo .git
# restore the link between the local repo and its upstream remote repo
git config --local --bool core.bare false
git config --local remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
git fetch origin
git branch -u origin/master master
# reset the index (not the working tree)
git reset HEAD -- .
Но я верю принятое решение (с добавленным полезным git reset
шагом ADTC) проще.
Ответ 3
Чтобы упростить и объединить информацию в ответах:
Есть три отличия, которые отличают репо от обычной папки .git:
- core.bare имеет значение true в конфигурационном файле
- индексный файл и рабочее дерево не существует
- по умолчанию refspec для "источника" удаленного не генерируется
Таким образом, вы можете просто переместить ваш репозиторий в подпапку .git новой папки,
mkdir clone
mv bare.git clone/.git
Изменить core.bare:
cd clone
git config --local --bool core.bare false
Добавьте исходную ссылку по умолчанию, чтобы git fetch
и git push
выбирали те же значения по умолчанию, что и обычно:
git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
И сгенерируйте индексный файл и рабочее дерево:
git checkout master
Я рекомендую git checkout
а не git reset
для генерации файлов, на случай, если они случайно набраны в неправильном месте.
Ответ 4
Если у вас мало дискового пространства, расширение рабочего дерева путем преобразования в обычный репозиторий будет проблемой, но вы можете просматривать содержимое голого репо без его преобразования. Используйте git cat-file -p <commit-sha>
для любой фиксации, чтобы увидеть дерево, к которому оно относится. Используйте git cat-file -p <blob-sha>
, чтобы увидеть содержимое файла, на которое ссылается blob. Используйте git show <sha>:path
, где sha является либо фиксацией, либо деревом, чтобы увидеть содержимое blob по пути.
Ответ 5
Оригинальный вопрос о постели состоит в том, что у него недостаточно места, чтобы сделать что-то просто. Для тех, у кого достаточно места, ответ намного проще:
git clone foo.git foo
Ответ 6
Если вы не против работать с другой рабочей группой, то
git worktree add ../repo2
cd ..
git status # now works fine
Обратите внимание: это не клон.
Ответ 7
cd
в голый репо и сделай
- Или:
git config core.bare false
git reset --hard
- или же
git clone X.git X
(даст вам регулярное Git-репо с именем X)
Ответ 8
Нажимай-Deploy
Вместо того, чтобы конвертировать пустой пульт дистанционного управления в стандартный репозиторий, вы можете использовать сценарий post-receive в каталоге hooks, чтобы развернуть репозиторий в каталог развертывания.
Вот хороший пример настройки Push-to-Deploy
Для простоты, это пример содержания скрипта из ссылки выше. Он будет развертывать только толчки из "главной" ветки в каталог с именем "deploy", который находится на том же уровне, что и родительский каталог репозитория:
#!/usr/bin/env ruby
# post-receive
# 1. Read STDIN (Format: "from_commit to_commit branch_name")
from, to, branch = ARGF.read.split " "
# 2. Only deploy if master branch was pushed
if (branch =~ /master$/) == nil
puts "Received branch #{branch}, not deploying."
exit
end
# 3. Copy files to deploy directory
deploy_to_dir = File.expand_path('../deploy')
'GIT_WORK_TREE="#{deploy_to_dir}" git checkout -f master'
puts "DEPLOY: master(#{to}) copied to '#{deploy_to_dir}'"