使用 git-daemon

有时需要临时分享一个仓库给朋友,我们可以用 SSH 协议:

git clone ssh://catroll@192.168.64.234/home/catroll/Projects/catroll/lego

其实 git-daemon 是一个更好的方法。

使用方法

我的项目全部在 /home/catroll/Projects/ 目录下。

ls /home/catroll/Projects/catroll/
drwxrwxr-x  6 catroll catroll 4.0K 12月 21 10:51 gfw
drwxrwxr-x  7 catroll catroll 4.0K 6月  22  2016 lego
...

比如,我要将 catroll/gfw 分享出去,只需要在这个项目的 .git 目录下创建一个 git-daemon-export-ok 文件,然后把 daemon 跑起来就行了。

cd /home/catroll/Projects/
touch catroll/gfw/.git/git-daemon-export-ok
git daemon --base-path=. --enable=receive-pack --reuseaddr --verbose

解释:

  • --base-path=. 指定 Git 仓库的父目录
  • --enable=receive-pack 允许 push
  • --reuseaddr
  • --verbose 打印详细信息

如果直接放开 Base 目录下的所有子目录访问权限,则可以使用 --export-all 参数。

这样我们就可以 git clone git://localhost/catroll/gfw 来克隆仓库了,并且推送也是有效的哦。

问题

实际使用过程中,如果远程仓库也是一个工作目录,并且处在推送分支上,会报错:

对象计数中: 3, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 246 bytes | 0 bytes/s, 完成.
Total 3 (delta 1), reused 0 (delta 0)
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git://localhost/catroll/gfw
 ! [remote rejected] master -> master (branch is currently checked out)
error: 无法推送一些引用到 'git://localhost/catroll/gfw'

总之,是说这样容易引发一些什么问题。只好切换到其他分支上去等待这边 push 完成。

所以,和别人“非一次性”代码仓库同步时,最佳实践还是另外弄一个专用的裸仓库目录来跑 git-daemon。

此外,git-daemon 还有很多参数(比如 --inetd),如果需要更加复杂功能的时候再来研究。

参考