Как преобразовать обычный Git-репозиторий в пустой?
Как я могу преобразовать "нормальный" Git-репозиторий в пустой?
Основным отличием, кажется, является:
в обычном git-хранилище у вас есть
.git
папка внутри репозитория, содержащая все соответствующие данные и все остальные файлы для создания вашей рабочей копиив голом репозитории Git нет рабочей копии и папки (назовем ее
repo.git
) содержит фактические данные хранилища
18 ответов
Короче говоря: заменить содержимое repo
с содержанием repo/.git
, а затем скажите репозиторию, что он теперь пустой.
Для этого выполните следующие команды:
cd repo
mv .git ../repo.git # renaming just for clarity
cd ..
rm -fr repo
cd repo.git
git config --bool core.bare true
Обратите внимание, что это отличается от выполнения git clone --bare
на новое место (см. ниже).
Ваш метод выглядит так, как будто он будет работать; файловая структура чистого репозитория - это то, что находится внутри каталога.git. Но я не знаю, действительно ли какие-либо файлы были изменены, поэтому, если это не сработает, вы можете просто сделать
git clone --bare /path/to/repo
Вам, вероятно, потребуется сделать это в другом каталоге, чтобы избежать конфликта имен, а затем вы можете просто переместить его туда, куда вам нужно. И вам может понадобиться изменить конфигурационный файл так, чтобы он указывал, где находится исходное хранилище.
Я думаю, что следующая ссылка будет полезна
GitFaq: Как мне сделать существующий не-пустой репозиторий голым?
$ mv repo/.git repo.git
$ git --git-dir=repo.git config core.bare true
$ rm -rf repo
Если вы специально не хотите или не хотите вертеть биты в файловой системе, действительно просто создать пустую версию не пустого хранилища (упомянутое здесь в нескольких других постах). Это часть основной функциональности git:
git clone --bare reponame bare_reponame
Пожалуйста, также подумайте об использовании
git clone --mirror path_to_source_repository
Из документации:
Установите зеркало исходного хранилища. Это подразумевает --bare. По сравнению с --bare, --mirror не только сопоставляет локальные ветви источника с локальными ветвями цели, но и отображает все ссылки (включая ветви с удаленным отслеживанием, заметки и т. Д.) И устанавливает конфигурацию refspec таким образом, чтобы все эти ссылки перезаписываются удаленным обновлением git в целевом хранилище.
Я просто хотел отправить в репозиторий по сетевому пути, но git не позволил бы мне сделать это, если этот репозиторий не был помечен как пустой. Все, что мне нужно, это изменить его конфигурацию:
git config --bool core.bare true
Не нужно возиться с файлами, если вы не хотите держать его в чистоте.
Я прочитал ответы и сделал это:
cd repos
mv .git repos.git
cd repos.git
git config --bool core.bare true # from another answer
cd ../
mv repos.git ../
cd ../
rm -rf repos/ # or delete using a file manager if you like
это оставит содержимое repos/.git
как голый repos.git
Просто читать
Pro Git Book: 4.2 Git на сервере - Получение Git на сервере
которые сводятся к
$ git clone --bare my_project my_project.git
Cloning into bare repository 'my_project.git'...
done.
Затем поместите my_project.git на сервер
В основном это то, на что пытался указать ответ № 42. Несомненно, можно было бы заново изобрести колесо;-)
Вот то, что я считаю самым безопасным и простым. Здесь ничего не указано выше. Я просто хочу увидеть ответ, который показывает безопасную пошаговую процедуру. Вы запускаете одну папку из репозитория (репо), который хотите обнажить. Я принял соглашение, подразумеваемое выше, что голые папки репозитория имеют расширение.git.
(1) Backup, just in case.
(a) > mkdir backup
(b) > cd backup
(c) > git clone ../repo
(2) Make it bare, then move it
(a) > cd ../repo
(b) > git config --bool core.bare true
(c) > mv .git ../repo.git
(3) Confirm the bare repository works (optional, since we have a backup)
(a) > cd ..
(b) > mkdir test
(c) > cd test
(d) > git clone ../repo.git
(4) Clean up
(a) > rm -Rf repo
(b) (optional) > rm -Rf backup/repo
(c) (optional) > rm -Rf test/repo
Вот небольшая функция BASH, которую вы можете добавить в ваш.bashrc или.profile в системе на основе UNIX. После добавления оболочка либо перезапускается, либо файл перезагружается с помощью вызова source ~/.profile
или же source ~/.bashrc
,
function gitToBare() {
if [ -d ".git" ]; then
DIR="`pwd`"
mv .git ..
rm -fr *
mv ../.git .
mv .git/* .
rmdir .git
git config --bool core.bare true
cd ..
mv "${DIR}" "${DIR}.git"
printf "[\x1b[32mSUCCESS\x1b[0m] Git repository converted to "
printf "bare and renamed to\n ${DIR}.git\n"
cd "${DIR}.git"
else
printf "[\x1b[31mFAILURE\x1b[0m] Cannot find a .git directory\n"
fi
}
После вызова в каталоге, содержащем каталог.git, он внесет соответствующие изменения для преобразования хранилища. Если при вызове отсутствует каталог.git, появится сообщение FAILURE и никаких изменений в файловой системе не произойдет.
Методы, которые говорят об удалении файлов и обмана с перемещением каталога.git, не чисты и не используют метод "git" для выполнения чего-то, что должно быть простым. Это самый чистый метод, который я нашел для преобразования обычного репо в голое репо.
Первый клон / путь / к / нормальному / репо в голое репо с именем repo.git
git clone --bare /path/to/normal/repo
Затем удалите источник, который указывает на / path / to / normal / repo
cd repo.git
git remote rm origin
Наконец, вы можете удалить свой оригинальный репо. В этот момент вы можете переименовать repo.git в repo, но стандартным соглашением для обозначения репозитория git является some.git, так что я бы лично оставил это так.
Сделав все это, вы можете клонировать свое новое голое репо (которое фактически создает нормальное репо, а также то, как вы бы преобразовали его из голого в обычное)
Конечно, если у вас есть другие апстримы, вы захотите записать их и обновить свой репо, чтобы включить его. Но опять же, все это можно сделать с помощью команды git. Помните, что страницы руководства - ваш друг.
В случае, если у вас есть хранилище с несколькими локальными извлеченными ветками / refs / head /* и несколькими удаленными ветками удаленных веток /origin/* И если вы хотите преобразовать это в хранилище BARE со всеми ветками в / refs /head /*
Вы можете сделать следующее, чтобы сохранить историю.
- создать голое хранилище
- перейдите в локальный репозиторий, в котором есть локальные извлеченные ветви и удаленные ветви
- git push / path / to / bare / repo + refs / remotes / origin /: refs / heads /
Вот определение чистогорепозитория из gitglossary:
Чистый репозиторий обычно представляет собой каталог с соответствующим именем с суффиксом.git, в котором нет локально извлеченной копии любого из файлов, находящихся под контролем версий. То есть все административные и управляющие файлы Git, которые обычно присутствуют в скрытом подкаталоге.git, вместо этого находятся непосредственно в каталоге repository.git, и никакие другие файлы не присутствуют и не извлекаются. Обычно издатели публичных репозиториев делают доступными голые репозитории.
Я приехал сюда, потому что играл с "локальным репозиторием" и хотел иметь возможность делать все, что захочу, как если бы это был удаленный репозиторий. Я просто играл, пытаясь узнать о git. Я предполагаю, что это ситуация для тех, кто хочет прочитать этот ответ.
Я хотел бы получить экспертное мнение или некоторые конкретные контрпримеры, однако кажется, что (после рывка в некотором исходном коде git, который я нашел) просто переход к файлу .git/config
и установив основной атрибут обнажить к истинному, мерзавец позволит вам делать все, что вы хотите сделать в хранилище удалено. Т.е. следующие строки должны существовать в.git/config
:
[core]
...
bare = true
...
(Это примерно то, что команда git config --bool core.bare true
подойдет, что, вероятно, рекомендуется для более сложных ситуаций)
Мое оправдание этого утверждения состоит в том, что в исходном коде git, похоже, есть два разных способа тестирования, является ли репо пустым или нет. Один из них - проверка глобальной переменнойis_bare_repository_cfg
. Это устанавливается во время некоторой фазы настройки выполнения и отражает значение, найденное в.git/config
файл. Другой - функцияis_bare_repository()
. Вот определение этой функции:
int is_bare_repository(void)
{
/* if core.bare is not 'false', let's see if there is a work tree */
return is_bare_repository_cfg && !get_git_work_tree();
}
У меня нет ни времени, ни опыта, чтобы сказать это с абсолютной уверенностью, но насколько я могу судить, есть ли у вас bare
атрибут установлен на true
в .git/config
, это всегда должно возвращаться 1
. Остальная часть функции, вероятно, предназначена для следующей ситуации:
- core.bare не определен (т.е. ни истина, ни ложь)
- Нет рабочего дерева (т.е. подкаталог.git является основным каталогом)
Я поэкспериментирую с этим, когда смогу позже, но это, кажется, указывает на то, что установка core.bare = true эквивалентна удалению core.bare из файла конфигурации и правильной настройке каталогов.
В любом случае, установка core.bare = true позволит вам перейти к нему, но я не уверен, что наличие файлов проекта приведет к тому, что некоторые другие операции не сработают. Это интересно, и я полагаю, поучительно нажать в репозиторий и посмотреть, что произошло локально (т.е. запуститьgit status
и разобраться в результатах).
Я использовал следующий скрипт, чтобы прочитать текстовый файл со списком всех моих репозиториев SVN и преобразовать их в GIT, а затем использовать git clone --bare для конвертации в голое репозиторий git.
#!/bin/bash
file="list.txt"
while IFS= read -r repo_name
do
printf '%s\n' "$repo_name"
sudo git svn clone --shared --preserve-empty-dirs --authors-file=users.txt file:///programs/svn/$repo_name
sudo git clone --bare /programs/git/$repo_name $repo_name.git
sudo chown -R www-data:www-data $repo_name.git
sudo rm -rf $repo_name
done <"$file"
list.txt имеет формат
repo1_name
repo2_name
и users.txt имеет формат
(no author) = Prince Rogers <prince.rogers.nelson@payesley.park.org>
www-data - пользователь веб-сервера Apache, необходимо разрешение для передачи изменений через HTTP
Первый, backup
ваш существующий репо:
(a) mkdir backup
(b) cd backup
(c) git clone non_bare_repo
Во-вторых, запустите следующее:
git clone --bare -l non_bare_repo new_bare_repo
Добавлено 2:
после написания ответа понял, что принятый ответ, скорее всего, приведет к тому же результату на моем ПК, если за ним последует
git add *
.
У меня исчезли файлы из рабочей папки (только остались), опять красиво и компактно:
git switch --orphan some_new_branch_name
Затем конвертируйте в голый, если хотите:
git config --bool core.bare true
Таким образом сохраняется конфигурация, включая удаленную ссылку:
$ git config --list
core.repositoryformatversion=0
core.filemode=true
core.bare=true
remote.origin.url=https://github.com/vmatare/thinkfan.git
remote.origin.fetch=+refs/*:refs/*
remote.origin.mirror=true
Добавлено:
В комментариях упоминается, что он не будет удалять «любые файлы, игнорируемые git», в этом случае их необходимо дополнительно удалить вручную (или сам репозиторий, который
.git
подпапку переместить в другое место).
Примечания:
до
core.bare true
некоторые действия привели к ошибкам:
$ git fetch --all
Fetching origin
fatal: Refusing to fetch into current branch refs/heads/devel of non-bare repository
error: Could not fetch origin
не были перечислены в выводе после этого. Для дальнейшего тестирования я сделал
git checkout master
Я получил файлы обратно и снова нет
some_new_branch_name
на выходе
git branch
, так что я думаю новый
orphan
ветка не будет добавлена в репозиторий, если там не будет выполнена какая-то работа (и/или выполнены коммиты).
Для выполнения всех вышеперечисленных операций:
for i in `ls -A .`; do if [ $i != ".git" ]; then rm -rf $i; fi; done; mv .git/* .; rm -rf .git; git config --bool core.bare true
(не обвиняйте меня, если что-то взрывается, и у вас не было резервных копий:P)
Вау, просто удивительно, как много людей вмешалось в это, особенно учитывая, что не кажется, что ни один человек не остановился, чтобы спросить, почему этот человек делает то, что он делает.
ЕДИНСТВЕННАЯ разница между голым и не голым репозиторием git заключается в том, что у не голой версии есть рабочая копия. Основная причина, по которой вам нужно пустое хранилище, заключается в том, что если вы хотите сделать его доступным для третьей стороны, вы не можете работать над ним напрямую, поэтому в какой-то момент вам придется его клонировать, и в этот момент вы Вернемся к обычной версии рабочей копии.
При этом, чтобы конвертировать в голое репо, все, что вам нужно сделать, это убедиться, что у вас нет ожидающих коммитов, а затем просто:
rm -R * && mv .git/* . && rm -R .git
Вот и все, голое репо.