我有一个裸露的git存储库,但需要通过ssh(在类似于用户体验的文件管理器中)访问和浏览其内容。
我想我可以克隆它:
git clone -l <path_to_bare_repo> <new_normal_repo>
但是,我的存储库大小约为20GB,我没有足够的空间来复制它。有没有一种方法可以将裸存储库原位转换为最终的工作副本?
我有一个裸露的git存储库,但需要通过ssh(在类似于用户体验的文件管理器中)访问和浏览其内容。
我想我可以克隆它:
git clone -l <path_to_bare_repo> <new_normal_repo>
但是,我的存储库大小约为20GB,我没有足够的空间来复制它。有没有一种方法可以将裸存储库原位转换为最终的工作副本?
git show
和git cat-file
Answers:
注意:我在一个非常简单的1提交存储库中对此进行了测试。仔细检查一下,阅读手册页,在遵循在StackOverflow上找到的建议之前,总是很高兴自己已经备份了。(您要备份,对吗?)
要将--bare
存储库转换为非裸存储库:
.git
在存储库的顶层创建一个文件夹。HEAD branches config description hooks info objects refs
等)移动到.git
您刚刚创建的内容中。git config --local --bool core.bare false
以将本地git-repository转换为non-bare。master
(或主分支所在的那个分支)中,所有文件都被删除,并进行了删除。那很正常 只需手动结帐master
,或执行git reset --hard
,就可以完成。.git/config
文件添加行。否则将看不到和其他来源的分支。fetch = +refs/heads/*:refs/remotes/origin/*
url = <...>
[remote "origin"]
git fetch
origin/master
这些步骤与该问题的方向相反,即“将普通库转换为裸仓库”(尤其是注意将答案转换为裸仓库),该步骤指出上述步骤(我认为是任一方向)与执行a的步骤不同git-clone
。虽然不确定是否与您有关,但是您git clone
在问题中提到了这一点。
我有一个稍微不同的情况:
解:
.git
目录中克隆该内容中的裸仓库:git clone --bare https://github.com/user/project .git
git config --local --bool core.bare false
.git
裸露的回购协议不包含文件“ index
”) git reset HEAD -- .
.git/index
。我已经有效地将裸仓库变成了非裸仓库,同时保留了以前的内容。我使用多年
的完整脚本涉及以下步骤:
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 -- .
但是,我确实确认接受的解决方案(通过ADTC添加了有用的git reset
步骤)更为简单。
.git
在最初由存档(非git)制成的工作树(您知道是您的仓库)中获得一个子文件夹。我无法签出非裸仓库,因为我在其中签出的文件夹不为空。git clone --no-checkout
在子文件夹中执行非裸操作将迫使我将其上移.git
一个级别。做一个简单的克隆使我可以.git
在需要的地方直接创建子文件夹。您可以在此处查看脚本:github.com/VonC/compileEverything/blob/…–
.git
。我确实.git
通过了一个裸克隆,然后将该.git
文件夹转换为一个非裸文件夹,然后执行git reset
git以使git意识到工作树已经存在。这正是github.com/VonC/compileEverything/blob/…所做的。
为了简化和合并答案中的信息:
有三个区别使裸仓库与普通的.git文件夹不同:
因此,您只需将裸仓库移到新文件夹的.git子文件夹中,
mkdir clone
mv bare.git clone/.git
更改core.bare:
cd clone
git config --local --bool core.bare false
添加默认来源refspec进行制作git fetch
并git push
选择与往常相同的默认值:
git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
并生成索引文件和工作树:
git checkout master
我建议git checkout
不要git reset
生成文件,以防意外将其键入错误的位置。
原始张贴者的问题是没有足够的空间来简单地做事。对于那些确实有足够空间的人,答案要简单得多:
git clone foo.git foo
如果磁盘空间不足,则通过转换为常规存储库来扩展工作树将是一个问题,但是您可以浏览裸存储库的内容而无需对其进行转换。用于git cat-file -p <commit-sha>
任何提交,以查看其引用的树。使用git cat-file -p <blob-sha>
查看由BLOB引用的文件的内容。使用git show <sha>:path
sha为提交或树的位置时,可以在path处查看blob的内容。
cd
进入裸仓库并做
git config core.bare false
git reset --hard
git clone X.git X
(将为您提供名为X的常规git repo)
如果您不介意在其他工作树上工作,那么
git worktree add ../repo2
cd ..
git status # now works fine
请注意,这不是克隆。
一键部署
您可以使用hooks目录中的post-receive脚本来将存储库扩展到部署目录,而不是将裸机远程转换为标准存储库。
为了便于参考,这是上面链接中的脚本内容示例。它将仅将从“ master”分支的推送部署到与存储库的父目录处于同一级别的名为“ 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}'"
.git
目录并将bare
config中的参数设置为false,则它的行为应类似于常规存储库,您可以在其中git checkout
获取文件。