如何将普通的Git存储库转换为裸存储库?

时间:2010-02-04 13:18:18

标签: git version-control git-clone git-bare git-non-bare-repository

如何将'普通'Git存储库转换为裸存储库?

主要区别似乎是:

  • 在普通的git存储库中,您在存储库中有一个.git文件夹,其中包含所有相关数据,所有其他文件构建您的工作副本

  • 在一个裸Git存储库中,没有工作副本,文件夹(我们称之为repo.git)包含实际的存储库数据

17 个答案:

答案 0 :(得分:556)

简而言之:用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到新位置不同(见下文)。

答案 1 :(得分:235)

你的方法看起来会起作用;裸存储库的文件结构就是.git目录中的内容。但我不知道是否有任何文件实际更改,所以如果失败,你可以做

git clone --bare /path/to/repo

您可能需要在不同的目录中执行此操作以避免名称冲突,然后您可以将其移回到您想要的位置。您可能需要将配置文件更改为指向原始仓库所在的位置。

答案 2 :(得分:113)

我认为以下链接会有所帮助

GitFaq: How do I make existing non-bare repository bare?

$ mv repo/.git repo.git
$ git --git-dir=repo.git config core.bare true
$ rm -rf repo

答案 3 :(得分:64)

除非你特别想要或需要在文件系统上旋转位,否则创建一个非裸存储库的裸版本真的很简单(在这里的其他几篇文章中提到)。它是git核心功能的一部分:

git clone --bare existing_repo_path bare_repo_path

答案 4 :(得分:10)

还请考虑使用

git clone --mirror path_to_source_repository

来自documentation

  

设置源存储库的镜像。这意味着 - 不好。与--bare相比, - mirror不仅将源的本地分支映射到目标的本地分支,它还映射所有引用(包括远程跟踪分支,注释等)并设置refspec配置,以便所有这些引用被目标存储库中的git远程更新覆盖。

答案 5 :(得分:7)

我只是想推送到网络路径上的存储库,但git不会让我这样做,除非该存储库被标记为裸。 我只需要改变它的配置:

git config --bool core.bare true

除非你想保持文件整洁,否则不需要弄乱文件。

答案 6 :(得分:6)

我已经阅读了答案,我已经这样做了:

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

答案 7 :(得分:4)

这是我认为最安全和最简单的。这里没有任何内容没有说明。我只想看到一个答案,显示一个安全的逐步程序。您从要裸露的存储库(repo)中启动一个文件夹。我采用了上面隐含的约定,即裸存储库文件夹的扩展名为.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

答案 8 :(得分:4)

只需阅读

Pro Git Book: 4.2 Git on the Server - Getting Git on a Server

直到

{{1}}

然后将 my_project.git 添加到服务器

主要是,#42试图指出的答案。当然可以重新发明轮子; - )

答案 9 :(得分:3)

这是一个小的BASH函数,可以在基于UNIX的系统上添加到.bashrc或.profile。添加后,重新启动shell或通过调用source ~/.profilesource ~/.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消息,并且不会发生文件系统更改。

答案 10 :(得分:1)

通过移动.git目录来删除文件和删除的方法不干净,并且不使用“git”方法来做一些应该简单的事情。这是我发现的将普通仓库转换为裸仓库的最干净的方法。

首先将clone / path / to / normal / repo转换为名为repo.git的裸仓库

git clone --bare /path/to/normal/repo

接下来删除指向/ path / to / normal / repo

的原点
cd repo.git
git remote rm origin

最后,您可以删除原始回购。你可以在那时将repo.git重命名为repo,但是表示git存储库的标准约定是something.git,所以我个人会这样做。

完成所有这些后,您可以克隆新的裸仓库(实际上会创建一个正常的仓库,也就是如何将其从裸露转换为正常)

当然,如果您有其他上游,您需要记下它们,并更新您的裸仓库以包含它。但同样,它可以用git命令完成。请记住,手册页是你的朋友。

答案 11 :(得分:1)

如果您有一个存储库,其中包含很少的本地签出分支/ refs / heads / *和几个远程分支分支remotes / origin / * AND,如果您想将其转换为BARE存储库,其中所有分支都在/ refs / heads /中*

您可以执行以下操作来保存历史记录。

  1. 创建一个裸存储库
  2. cd进入具有本地签出分支和远程分支的本地存储库
  3. git push / path / to / bare / repo + refs / remotes / origin / :refs / heads /

答案 12 :(得分:0)

我使用以下脚本来读取一个文本文件,其中包含我所有SVN repos的列表并将它们转换为GIT,然后使用git clone --bare转换为裸git repo

#!/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 Web服务器用户,需要通过HTTP推送更改的权限

答案 13 :(得分:0)

这是gitglossary裸仓库的定义:

裸存储库通常是一个带有.git后缀的适当命名的目录,该目录没有受版本控制的任何文件的本地检出副本。也就是说,通常会出现在隐藏的.git子目录中的所有Git管理和控制文件都直接存在于repository.git目录中,而没有其他文件存在并检出。通常,公共存储库的发布者会提供裸存储库。

我到达这里是因为我正在玩“本地存储库”,并且希望能够做我想做的任何事情,就好像它是一个远程存储库一样。我只是在玩耍,试图学习git。我假设这是任何想阅读此答案的人的情况。

我希望获得专家意见或一些特定的反例,但是(在翻阅我发现的git源代码后)似乎只是转到文件.git/config并设置 core bare 属性设置为 true ,git将允许您对存储库进行远程操作。即.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。该功能的其余部分可能用于以下情况:

  1. core.bare未定义(即不是true还是false)
  2. 没有工作树(即.git子目录是主目录)

稍后我将对其进行实验,但这似乎表明设置 core.bare = true 等同于从 core.bare 中删除配置文件并正确设置目录。

无论如何,设置 core.bare = true 当然可以使您继续使用它,但是我不确定项目文件的存在是否会导致其他操作出错。这很有趣,我认为有指导意义,可以推送到存储库并查看本地发生了什么(即运行git status并理解结果)。

答案 14 :(得分:-1)

首先,backup您现有的回购:

(a)  mkdir backup

(b)  cd backup

(c)  git clone non_bare_repo

其次,运行以下内容:

git clone --bare -l non_bare_repo new_bare_repo

答案 15 :(得分:-4)

用于完成上述所有操作的一个班轮:

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)

答案 16 :(得分:-9)

哇,有多少人对此表示赞赏,这简直太令人惊讶了,特别是考虑到似乎没有一个人停下来问为什么这个人正在做他正在做的事情。

裸机器人和非裸机器人存储库之间的唯一区别是非裸机版本具有工作副本。你需要一个简单的回购的主要原因是如果你想让它可供第三方使用,你实际上无法直接处理它,所以在某些时候你将不得不克隆它,此时你是回到正常的工作副本版本。

话虽这么说,要转换为裸仓库所有你需要做的就是确保你没有待处理的提交然后只是:

rm -R * && mv .git/* . && rm -R .git

你去,裸露的回购。