裸仓库
在局域网下对仓库进行同步,除了自己搭建Git服务外,还有一种方式,就是搭建一个专用于同步代码的裸仓库。
裸仓库是一种没有工作目录、不存储任何实际文件的仓库。裸仓库中只包含了版本历史信息和索引,没有文件副本。它只是一个包含Git版本控制所需的元数据的文件夹。
裸仓库通常用于共享代码的中央仓库,在团队协作中扮演着重要的角色。由于裸仓库没有工作目录,因此不能在上面进行实际的编辑和修改文件的操作,仅仅是用来存储并共享版本控制的历史记录。
裸仓库的用处与优点如下:
- 分布式开发与协作。
- 版本控制的中心仓库。
- 提高性能和节省空间。
由于裸仓库可以使用Git创建,所以它可以在局域网环境中对代码进行同步。
裸仓库没有工作目录,但是它可以被其它(局域网中的)拥有权限的任何人clone
、push
和pull
。
创建裸仓库
假设要为一个myapp
创建一个用于同步代码,可以为其初始化一个裸仓库:
git init --bare myapp.git
一般初始化工作仓库的命令是git init
,而--bare
参数表示的是初始化一个裸仓库。裸仓库一般使用.git
作为结尾。就像从Github之类的网站上clone
时一样,那些仓库的URL常常以.git
做为后缀。
裸仓库和工作仓库的区别
一般工作仓库的config
:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
裸仓库的config
:
[core]
repositoryformatversion = 0
filemode = true
bare = true
sharedrepository = 1
对比工作仓库和裸仓库的config
,可以很明显地看出它们在config
上最直接的区别就是裸仓库的bare
是true
。
关联裸仓库
创建好裸仓库之后,就可以在原本的仓库中将裸仓库添加到远程仓库中。
例如:
git remote add local_origin ssh://linner@localhost/repo/myapp.git
Git远程仓库不仅支持HTTP/HTTPS和Git协议,还支持本地协议(file://
)、SSH协议(ssh://
)。
当然在添加远程仓库之前,也需要对仓库或服务进行一些配置。例如使用SSH协议,最好实现为两台服务器交换公钥。
Git 钩子
通过Git钩子(Git Hooks)可以很方便地在进行提交或拉取时进行一些自定义操作。例如在提交代码后,自动Pull代码,然后部署项目。
Git钩子是Git提供的,在进行一些操作时(例如
commit
、push
、pll
等操作)执行的一些脚本。
常见的Git钩子有:
- 本地钩子:
pre-commit
prepare-commit-msg
commit-msg
post-commit
post-checkout
pre-rebase
- 服务端钩子:
pre-receive
update
post-receive
Git钩子在Git仓库中是存储在特定目录下的一系列脚本文件。在工作仓库中,它们被存储在工作根目录的.git\hooks
目录中;在裸仓库中,它们被存储在仓库根目录的hooks
目录中。
在初始化仓库(git init
)之后,Git会提供一些使用钩子的案例(其中对钩子进行了简单的说明和一些代码示例)。它们在hooks
目录中,这些由Git创建的钩子脚本文件,都是以.sample
做为后缀。你可以将.sample
后缀删除后启用它们,Git会在特定时刻自动执行钩子中的脚本。
Git Hooks具体的使用方式可以查看https://git-scm.com/docs/githooks#_hooks。
自动 Pull 代码
通过Git提供的钩子,我们可以很方便地定制一些流程(偷懒)。
我的个人博客网站是由Hugo构建,然后通过Github挂载在Netlify上。在编写完一篇文章后需要将Markdown编译成静态网页的形式,然后提交到Git仓库中。
由于一些限制,例如网络不佳(Netlify在国内的访问速度还是可以的)、设备断网或者是在无法访问到外网(本地局域网之外)的情况下,可能无法顺畅地浏览个人博客中的内容。
为此,我在本地使用Docker创建了两个容器。一个容器是用于编辑博文内容并且将内容编译成网页格式;另一个容器是用于将 Linner’s Blog 挂载到本地。这样在上述的一些特殊情况下,我依然可以顺畅地浏览我的个人博客网站。
创建两个容器是为了区分两个容器的职责。这是基于分布式理念,让特定的工作交给特定的容器去处理。这样在我无需编辑博客时,我可以将用于编辑博客的容器关闭,让PC上更多的资源可以为我所用。当然,区分容器也降低了由于依赖环境冲突所造成的风险。
由于将编辑和浏览分为了两个容器,为了让两个容器上的Git仓库可以在任何时候都能互通,我使用了裸仓库和钩子来同步这两个仓库。
将两个容器的公钥相互交换(交换之前使用了Docker Network让两个容器能够连通),然后在裸仓库中使用post-receive
钩子,在将编译完成之后的网页提交到裸仓库后,让用于浏览的容器可以自动将编译完成好的内容pull
下来。
在post-receive
中,我使用的是最简单最直接的方式:
ssh root@my-site "git -C /root/myblog pull"
评论