我如何将一个“正常”的Git存储库转换为一个裸库?
主要的区别似乎是:
在普通的Git存储库中,您在存储库中有一个.git文件夹,其中包含所有相关数据和构成工作副本的所有其他文件 在裸Git存储库中,没有工作副本,文件夹(让我们称之为repo.git)包含实际的存储库数据
我如何将一个“正常”的Git存储库转换为一个裸库?
主要的区别似乎是:
在普通的Git存储库中,您在存储库中有一个.git文件夹,其中包含所有相关数据和构成工作副本的所有其他文件 在裸Git存储库中,没有工作副本,文件夹(让我们称之为repo.git)包含实际的存储库数据
当前回答
以下是来自gitglossary的裸库定义:
裸存储库通常是一个适当命名的、后缀为.git的目录,该目录不包含任何受修订控制的文件的本地签出副本。也就是说,通常出现在隐藏的. Git子目录中的所有Git管理和控制文件都直接出现在存储库中。取而代之的是Git目录,并且没有其他文件存在并签出。公共存储库的发布者通常会提供裸存储库。
我来到这里是因为我正在使用“本地存储库”,并希望能够像使用远程存储库一样做任何我想做的事情。我只是玩玩,想了解一下git。我假设任何想读这个答案的人都会遇到这种情况。
我想要一个专家的意见或一些具体的反例,然而,似乎(在我找到的一些git源代码中)简单地转到.git/config文件并将核心属性设置为true, git会让你远程对存储库做任何你想做的事情。例如,在.git/config中应该存在以下行:
[core]
...
bare = true
...
(这大致是命令git config——bool core。完全真实就可以了,这可能是建议处理更复杂的情况)
我对这种说法的理由是,在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();
}
我没有时间也没有专业知识来绝对自信地说这一点,但据我所知,如果你在.git/config中将裸属性设置为true,这应该总是返回1。函数的其余部分可能用于以下情况:
核心。Bare没有定义(即既非真也非假) 没有工作树(例如。git子目录是主目录)
我以后会用它做实验,但这似乎表明设置核心。Bare = true相当于去除核心。从配置文件和设置正确的目录。
无论如何,设定核心。bare = true当然会让你推到它,但我不确定项目文件的存在是否会导致一些其他操作出错。推送到存储库并查看本地发生了什么(即运行git status并理解结果)是很有趣的,我认为这很有指导意义。
其他回答
删除文件和移动.git目录的方法是不干净的,没有使用“git”方法来做一些应该简单的事情。这是我发现的将正常回购转换为裸回购的最干净的方法。
第一个克隆/path/to/normal/repo到一个名为repo.git的裸repo
git clone --bare /path/to/normal/repo
接下来删除指向/path/to/normal/repo的原点
cd repo.git
git remote rm origin
最后,您可以删除原来的回购。你可以重命名repo。在这一点上,Git的回购,但标准约定,以表示一个Git存储库是什么。git,所以我个人会这样做。
一旦你完成了所有这些,你可以克隆你的新裸回购(这实际上创建了一个正常的回购,也是你如何将它从裸转换为正常)
当然,如果你有其他的上行流,你会想要记录它们,并更新你的裸回购以包括它。但是同样,这一切都可以用git命令来完成。请记住手册页是您的朋友。
以下是来自gitglossary的裸库定义:
裸存储库通常是一个适当命名的、后缀为.git的目录,该目录不包含任何受修订控制的文件的本地签出副本。也就是说,通常出现在隐藏的. Git子目录中的所有Git管理和控制文件都直接出现在存储库中。取而代之的是Git目录,并且没有其他文件存在并签出。公共存储库的发布者通常会提供裸存储库。
我来到这里是因为我正在使用“本地存储库”,并希望能够像使用远程存储库一样做任何我想做的事情。我只是玩玩,想了解一下git。我假设任何想读这个答案的人都会遇到这种情况。
我想要一个专家的意见或一些具体的反例,然而,似乎(在我找到的一些git源代码中)简单地转到.git/config文件并将核心属性设置为true, git会让你远程对存储库做任何你想做的事情。例如,在.git/config中应该存在以下行:
[core]
...
bare = true
...
(这大致是命令git config——bool core。完全真实就可以了,这可能是建议处理更复杂的情况)
我对这种说法的理由是,在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();
}
我没有时间也没有专业知识来绝对自信地说这一点,但据我所知,如果你在.git/config中将裸属性设置为true,这应该总是返回1。函数的其余部分可能用于以下情况:
核心。Bare没有定义(即既非真也非假) 没有工作树(例如。git子目录是主目录)
我以后会用它做实验,但这似乎表明设置核心。Bare = true相当于去除核心。从配置文件和设置正确的目录。
无论如何,设定核心。bare = true当然会让你推到它,但我不确定项目文件的存在是否会导致一些其他操作出错。推送到存储库并查看本地发生了什么(即运行git status并理解结果)是很有趣的,我认为这很有指导意义。
如果你有一个存储库,只有很少的本地签出分支/refs/heads/*和很少的远程分支分支/origin/* and,如果你想把它转换成一个BARE存储库,所有分支都在/refs/heads/*中
您可以执行以下操作保存历史记录。
创建裸存储库 CD到具有本地签出分支和远程分支的本地存储库中 Git push /path/to/bare/repo +refs/remotes/origin/:refs/heads/
下面是一个小BASH函数,您可以将它添加到基于UNIX的系统上的.bashrc或.profile中。一旦添加,shell要么重新启动,要么通过调用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消息,并且不会发生文件系统更改。
我使用下面的脚本读取一个文本文件,其中包含我所有的SVN repo,并将它们转换为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有这个格式
(无作者)=罗杰斯王子<prince.rogers.nelson@payesley.park.org>
www-data是Apache web服务器用户,需要权限才能通过HTTP推送更改