搭建简易git服务器(基于macOS)
本文基于macOS,未在Windows下测试,Windows用户请自己对应一下,一般都大同小异。
如果我们要搭建一个git服务器来做代码版本管理,一般都是使用gitlab、gitea、Gogs等开源的git服务器,搭建之后它是类似github的。
但是我现在是想研究git pull
、git push
、git fetch
这些命令运行前后,git服务器与客户端之间的数据变化,所以我们可以搭建一个简易的git服务器。
何为远程?
我们使用github(或者自己公司搭建的git服务器)时,进行git pull
、git push
、git fetch
这些操作,都会认为在与“远程”服务器交互,毕竟你的git服务器是安装在远程的服务器上(可能是公司自己的服务器,也可能是阿里云/腾讯云之类的)。
然而其实在网络世界里,“远程”这个概念,不一定是物理上的远程,“远程”仅仅是指通过某种网络协议交互数据。
比如,如果我在阿里云安装一个nginx,搭建了一个网站,那么这个网站是在“服务器上”,那如果我在自己电脑上安装一个nginx,也把这个网站搭建起来,通过:http://www.abcd.com
这样的链接访问(其中www.abcd.com
不用注册,在/etc/hosts
文件中添加指向127.0.0.1即可),这样我也是在访问网站,那这是不是远程呢?其实这也算是远程,无非就是ip不一样。
所以,如果我在我自己电脑上启动一个git服务器,那么对我的git客户端来说,它就是一个git“远程仓库”,只不过这个“远程”仓库也在自己电脑上而已。
启动git服务
有人可能会说,你都没说怎么安装,怎么就直接启动了?没错,我没有说安装,因为git客户端和服务器是一体的,它也可以启动一个服务当服务器用,事实上很多命令都这样,比如rsync
,你当客户端用它就是客户端,你给它加个配置文件启动一个后台进程,那它就是rsync服务器,这一点对于熟悉使用Linux命令的朋友来说,应该并不陌生。
首先你要准备一个文件夹作为git服务器数据存储文件夹(你git push
的数据,肯定要有地方存)
mkdir ~/git-server/
然后进入该文件夹
cd ~/git-server/
进入文件夹后,在该文件夹下执行以下命令,就可以启动一个git服务,--base-path=.
表示根目录为当前目录(就是数据存储目录)
git daemon --base-path=. --export-all --enable=receive-pack --reuseaddr --informative-errors --verbose
如下图所示,启动后它会显示“Ready to rumble”,rumble是轰隆隆的声音的意思,机器运转的声音就是“轰隆隆”的,所以它的意思就是现在已经准备好开始运转了(control+C
或者关闭终端都会终于这个“服务器”的服务,因为我们只是测试,所以就这样就行)
在服务器创建仓库
如果你想把你的项目数据推送到github,你得先在github创建一个仓库,github是在网页上创建的,那我们这个简易服务器要怎么创建呢?———— 其实跟在客户端创建可以说是一样的!
假设我要在git服务器里创建一个test
仓库,首先要进入“git-server”文件夹,并在它下边创建一个“test”文件夹,这个文件夹就是就是用来存储数据的文件夹(用来接收客户端git push
上传数据,或git pull
从这里拉取数据),这就相当于你在github上创建一个仓库名为“test”的仓库
cd ~/git-server/
mkdir test
当然我们刚刚创建的“test”文件夹还不是一个git仓库,因为还没有初始化呢,所以我们要初始化一下
# 先进入test文件夹
cd ~/git-server/test/
# 然后执行裸初始化
git init --bare
加了--bare
,表示的是直接在当前文件夹下生成git仓库骨架,如果没有加--bare
,它会在当前文件夹下生成一个.git
文件夹,并把git仓库骨架文件生成到.git
文件夹里面。
因为服务器不需要工作目录存储文件,它只需要git仓库用来存储版本文件,所以要加个--bare
,当然你也可以不加,那样就有工作目录,只不过谁也不会拿服务器数据仓库当工作目录用,所以就放在那儿也没用,既然这样那还不如不要它,所以我们要加个--bare
,骨架的意思是文件结构
当然你也可以在~/git-server/
文件夹下执行
git init --bare test
这样同样也是在test中生成git仓库骨架,只不过它会自动创建一个文件夹,不需要我们手动创建再cd进去。
生成的git仓库骨架如下所示
test
├── HEAD
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ ├── push-to-checkout.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
8 directories, 17 files
好了,我们已经在我们的git服务器上创建好了一个仓库了,现在你就把它想像成一个远程git仓库,现在你在把它clone下来
# 进入我想放代码的文件夹
cd ~/Code/
# 把刚刚我们在git服务器上的test仓库(test项目)克隆下来
git clone git://localhost/test
解释,从远程仓库克隆项目,都是通过网络,你可以有很多协议,github一般用https协议或者ssh协议(就是[email protected]
开头的),而由于我这个不是公共网络,别人获取不到,所以我用最简单的“git协议”来获取(即git://
)。
其中localhost就是域名,如果你觉得localhost看起来不太像远程,那么我完全可以这样
git clone git://github2.com/test
当然由于github2.com
并不是真实存在的,所以我们要在/etc/hosts
文件中添加一个配置,来让它生效
127.0.0.1 github2.com
还有人说,人家github的链接后面一般都是有.git
结尾的,比如现在比较火的go语言,它是开源的,它在github上的克隆链接是
https://github.com/golang/go.git
其实我们也可以这样,只需要在刚刚创建“test”文件夹的时候,把文件夹的名字改成“test.git”就行了
cd ~/git-server/
mkdir test.git
这样的话,你的链接就会变成
git clone git://github2.com/test.git
这样看上去,是不是像多了?当然,人家是https://
开头,我们是git://
开头,这只是协议不同,如果我们要配置https://
开头,还得要加个nginx或者apache服务器,比较麻烦,由于我们现在只是测试git客户端与服务器交互时,两边数据的变化,所以我就不搞那个了。
当然,前面的操作我都没有做,所以我还是用的localhost,如下图所示
因为我服务器创建仓库的时候,没有东西,所以它会提示“warning: 您似乎克隆了一个空仓库”。
如果你在github上创建一个仓库,并须不要勾选下图中的三个选项,创建后,再把它clone下来,也会有同样的提示,就是指仓库里没有任何文件,是刚初始化的仓库而已
又讲远程仓库
前面我说过了,“远程仓库”只不过是指通过网络协议与本地仓库进行数据交互的那个仓库,并不是说它一定要在远程的某个服务器上,它可以在你的电脑里,也可以在你另一台电脑上(如果你有两台电脑的话)。
如果是在另一台电脑上,你就不能写localhost了,你可以像我前面说的那样,还是使用github2.com
这个域名
git clone git://github2.com/test.git
只不过,你要去/etc/hosts
里,把刚刚的ip指向改一下,刚刚是把github2.com
指向127.0.0.1
表示指向本机,现在你把它改成指向你另一台电脑的ip(局域网ip就行),如果另一台电脑也是macOS,按住option
键,点击无线网线图标就能看到它的ip,假设它的ip为192.168.1.36
,那么你在/etc/hosts
里这样写就行
192.168.1.36 github2.com
那如果你真的是在阿里云或者其它买的服务器上启动的git服务呢?其实还是一样的,只需要在/etc/hosts
里把github2.com
指向的ip改成你那台买的服务器的ip就行了,当然你需要在你买的服务器上先开放端口,git://
协议默认是9418端口,而且因为是公网,我们这种启动方式是没有密码的,虽然可以用,但非常不安全,不建议在公司搞没有密码的git服务器,这里只不过是讲原理。
总结
通过搭建简易的git服务器,我们清楚了,其实git服务器端的git仓库存储,与我们本地的.git
文件夹内容架构是一样的。