Obsidian Git 插件配合 Git 服务器的 Git Hook 实现分布式存储
- 实现背景
- 原本希望在 Windows 平台使用 Obsidian Git 插件推送本地仓库到多个远程仓库,但是没有找到 Git 插件如何配置推送到多个远程仓库。
- 通过 ChatGPT 发现 Git 有 Git Hook,可以在执行特定命令前或后,执行脚本。原本想使用 Git 客户端的 Git Hook,但是不论是在推送前还是在推送后,都会导致递归,因为脚本执行的是推送,但是推送就会执行这个脚本,导致递归。
- 后面希望在本地搭建一个 Git 服务器,使用 Git 服务端的 Git Hook (hooks/post-receive,这个文件名的意思就是在 Git 服务器接收到推送后执行这个脚本)
- 搭建 Git 服务器有两种实现方式,一种是 https ,一种是 ssh 。很明显,https 比 ssh 难,故准备在 Windows 搭建 SSH 服务器,因为 Windows 设置 —> 应用和功能 —> 可选功能 ,里面可以安装 OpenSSH 服务器,但是安装前需要确保 Windows 更新服务在运行中。
- 安装了 OpenSSH 服务器后,在用户主目录(用户名 user ,用户主目录就是
C:\Users\user
)创建一个 test.git 文件夹,进入这个文件夹执行 git init --bare
(而不是 git init
因为 Git 服务器不需要工作区, 这条命令会把原本 git init
生成的 .git 文件夹下的内容生成在当前文件夹下,hooks 文件夹下就是 Git Hook 存放的地方) 命令,在 cmd 执行 git clone user@localhost:test.git
,发现命令执行失败,没有这个 Git 仓库,但是的确是存在的,使用 scp 命令可以成功下载。故上谷歌搜索查询,发现国外一个网友遇到了同样的问题,原来是因为 Windows 平台的 OpenSSH 服务器兼容 Windows路径,但是Windows 平台的 Git 不兼容 Windows 路径,只支持 Linux 路径。所以才导致 git clone user@localhost:test.git
命令失败。网友采用在 Windows 平台安装 Cygwin ,然后在 Cygwin(Cygwin 是一个在 Windows 平台的模拟类 Linux 环境的软件) 安装 linux 的 OpenSSH 服务器解决了这个问题。
- windows安装Git和Cygwin
- windows安装open ssh客户端
- 前提是windows更新服务在运行
- powershell (管理员身份运行)
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
- 重启 (重启才可以使用ssh命令)
- Cygwin安装Open SSH server和vim (可以随时打开安装包安装其他软件包)
- Cygwin (管理员身份运行)
ssh-host-config
(初始化open ssh server)
yes
yes
直接回车
vim /etc/sshd_config
(安全性考虑的配置)
ListenAddress 127.0.0.1
ListenAddress ::1
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
ssh-keygen -t ed25519
(创建ed25519密钥对)
一直回车
cat id_ed25519.pub > authorized_keys
(信任这个公钥)
mkdir /cygdrive/c/users/Administrator/.ssh
cp -p /home/Administrator/.ssh/id_ed25519 /cygdrive/c/users/Administrator/.ssh
cp -p /home/Administrator/.ssh/id_ed25519.pub /cygdrive/c/users/Administrator/.ssh
- windows资源管理器
- 编辑
C:\Users\Administrator\.ssh\id_ed25519
文件的权限,删除除了administrator用户之外所有用户和组的权限。
- cmd
net start cygsshd
(启动Cygwin模拟的open ssh server服务)
ssh administrator@localhost
yes
- 配置Cygwin远程仓库,使用cmd克隆该仓库,然后新添加文件推送到Cygwin远程仓库
- Cygwin (管理员身份运行)
cd ~ && mkdir -p UNGIIN/test.git
cd UNGIIN/test.git && git init --bare
- cmd
git clone administrator@localhost:UNGIIN/test.git
git config --global user.email "[email protected]"
git config --global user.name "UNGIIN"
cd test && echo test > test.txt && git add test.txt && git commit -m "test"
git push origin main
cd .. && rd /s /q test
git clone administrator@localhost:UNGIIN/test.git
cd test && dir
(有test.txt文件,说明推送成功)
- 配置Cygwin远程仓库的Git Hook,实现接收推送时,启动推送到其他远程仓库
- 前提
- 如果是git代码托管网站,需要注册一个账户,然后创建一个名为test的仓库,然后去设置里面添加公钥,公钥内容就是上面创建的
id_ed25519
文件内容。
- 本文使用github、gitee、gitcode作为三个需要推送的网站。
- Cygwin (管理员身份运行)
git config --global user.email "[email protected]"
git config --global user.name "UNGIIN"
cd ~/UNGIIN/test.git
git remote add gitcode [email protected]:UNGIIN/test.git
git remote add gitee [email protected]:ungiin/test.git
git remote add github [email protected]:UNGIIN/test.git
cd hooks
vim post-receive
#!/bin/bash
echo "UNGIIN: git push gitcode main --force"
git push gitcode main --force
echo "UNGIIN: git push gitee main --force"
git push gitee main --force
echo "UNGIIN: git push github main --force"
git push github main --force
ssh -T [email protected]
yes
ssh -T [email protected]
yes
ssh -T [email protected]
yes
- cmd (进入本地仓库)
echo push > test.txt
git add test.txt && git commit -m push
git push origin main
(出现如下信息,说明成功)
C:\Users\Administrator\test>git push origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 248 bytes | 248.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
remote: UNGIIN: git push gitcode main --force
remote: remote: Start Git Hooks Checking [PASSED]
remote: To gitcode.com:UNGIIN/test.git
remote: * [new branch] main -> main
remote: UNGIIN: git push gitee main --force
remote: remote: Powered by GITEE.COM [1.1.5]
remote: remote: Set trace flag f94c73b1
remote: To gitee.com:ungiin/test.git
remote: * [new branch] main -> main
remote: UNGIIN: git push github main --force
remote: To github.com:UNGIIN/test.git
remote: + f1fa468...e7ba3eb main -> main (forced update)
To localhost:UNGIIN/test.git
e2cbcb1..e7ba3eb main -> main