写点什么

git 普通库与裸库

作者:SkyFire
  • 2021 年 12 月 29 日
  • 本文字数:1638 字

    阅读完需:约 5 分钟

git普通库与裸库

git 普通库与裸库

创建一个 git 仓库的时候,有两种方式:


git init example
复制代码



git init --bare example
复制代码


这两个有什么区别呢?


使用git init创建的仓库被称为普通库,使用git init --bare创建的库被称为裸库。


普通库不仅包含了版本控制信息,还含了项目所有的源文件,而裸库只包含了版本控制信息。


举例如下:


  • 普通库


在/tmp 目录下创建一个普通库 test


cd /tmpgit init test
复制代码


查看文件:


cd testls -a
复制代码


结果:


./  ../  .git/
复制代码


查看.git 中的文件:


cd .git ls -a
复制代码


结果:


./  ../  branches/  config  description  HEAD  hooks/  info/  objects/  refs/
复制代码


创建一个文件,加入版本控制,提交:(普通库是可以直接操作的)


cd /tmp/testtouch a git add agit commit -m "first commit"
复制代码


将仓库克隆到/tmp/test2


git clone skyfire@localhost:/tmp/test /tmp/test2
复制代码


在 test2 下建立一个新文件,加入版本控制,并且提交:


cd /tmp/test2touch bgit add b git commit -m "add b"
复制代码


尝试推送:


git push
复制代码


此时会报出如下错误:


Enumerating objects: 3, done.Counting objects: 100% (3/3), done.Delta compression using up to 4 threadsCompressing objects: 100% (2/2), done.Writing objects: 100% (2/2), 226 bytes | 226.00 KiB/s, done.Total 2 (delta 0), reused 0 (delta 0)remote: error: refusing to update checked out branch: refs/heads/masterremote: error: By default, updating the current branch in a non-bare repositoryremote: is denied, because it will make the index and work tree inconsistentremote: with what you pushed, and will require 'git reset --hard' to matchremote: the work tree to HEAD.remote: remote: You can set the 'receive.denyCurrentBranch' configuration variableremote: to 'ignore' or 'warn' in the remote repository to allow pushing intoremote: its current branch; however, this is not recommended unless youremote: arranged to update its work tree to match what you pushed in someremote: other way.remote: remote: To squelch this message and still keep the default behaviour, setremote: 'receive.denyCurrentBranch' configuration variable to 'refuse'.To localhost:/tmp/test ! [remote rejected] master -> master (branch is currently checked out)error: failed to push some refs to 'skyfire@localhost:/tmp/test'
复制代码


因为 remote 仓库当前也在 master 分支,并且是可以直接操作的,所以如果此时向 remote 的当前分支 push 代码,可能会将正在修改的代码覆盖掉。因此只能向非当前分支 push 修改:


git branch devgit push origin dev
复制代码


这样就可以正常 push 了。如果实在需要 push 到 master 怎么办呢?可以将远程的当前分支切换到非 master 分支:


cd /tmp/testgit checkout devcd /tmp/test2git checkout mastergit push origin master
复制代码


  • 裸库


接下来说说裸库的情况。


先将刚才建立的仓库删除:


cd /tmprm -rf test test2
复制代码


创建裸库:


git init --bare test
复制代码


查看文件:


cd testls -a
复制代码


结果:


./  ../  branches/  config  description  HEAD  hooks/  info/  objects/  refs/
复制代码


可以看到,test 下的文件与普通库 test/.git 下的文件一样。


尝试建立一个文件,并将其加入版本控制:


touch a git add a
复制代码


此时会报错:


fatal: this operation must be run in a work tree
复制代码


说明裸库并不具备直接操作的能力。


将仓库克隆到/tmp/test2


git clone skyfire@localhost:/tmp/test /tmp/test2
复制代码


在 test2 下建立一个新文件,加入版本控制,并且提交:


cd /tmp/test2touch bgit add b git commit -m "add b"
复制代码


尝试推送:


git push
复制代码


推送成功。

总结

裸库与普通库的总结如下:

  • 裸库

由版本控制文件组成,不能直接操作,可以在远端直接推送,通常用于多人协作,版本库放在远端服务器。

  • 普通库

由源代码+裸库组成,可以直接操作,但是不能在远端直接推送代码到当前分支,通常用于本地版本控制。

发布于: 刚刚
用户头像

SkyFire

关注

还未添加个人签名 2018.10.13 加入

还未添加个人简介

评论

发布
暂无评论
git普通库与裸库