Wednesday, May 21, 2014

[git] 建立以及使用Git的bare repo

git repo分为bare和non-bare两种. non-bare repo最最常见, 它包括一个working tree(你提交到这个git repo里的文件和目录结构)以及一个.git文件夹(其中有各种git系统文件). 而bare repo仅仅有系统文件. 一般在git server上,所有的repo都是以bare形式存在的. 通常除了admin以外,大家是不需要和bare repo打交道的.

不过事事无绝对, 我就在工作中遇到这样的一个问题需要和bare repo打交道: 我的所有源代码都放在一个远端的git的repo(比如放在github上), 可是由于某些缘故我或者不能或者不愿意在我工作环境里直接和github上的repo同步. 一个折衷的方案就是在一台自己的server上建立这个github上的repo, 然后在我的工作环境中首先和server上得 repo同步, 然后再登陆到server上把server里地repo和github上的repo同步.
这样造成的问题就是server上的repo必须得是bare. 如果它含有working tree, 那么就算将server上的repo里的.git目录作为upstream加入, pull的时候没有问题, 但push的时候也会有问题
$ git remote add some_remote_name ssh://apc999@myhost/home/apc999/some-repo/.git
$ git pull some_remote_name master
.. works file ...
$ git push --set-upstream ssh://apc999@myhost/home/apc999/some-repo/.git master
...
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to '/home/apc999/some-repo'

如何使用bare repo

1 建立一个bare的git repo

$ git clone --bare my_project_on_github my-project.git
注意上面命令和普通git clone不一样的地方在于参数--bare. 普通的git clone命令会生成一个working tree和.git文件夹, 而--bare这样复制出来的bare repo就不包括working tree.

2 bare和 non-bare repo的转换

比如你的/home/apc999/my-project是一个git working tree
$ cd /home/apc999/my-project
$ git config --bool core.bare true

3 更新bare repo

注意, 在一个bare repo里, 不能使用git pull来更新这个repo. 而需要使用git fetch