在树莓派上搭建 GIT 服务器并设置 Hooks

这篇笔记记录了在树莓派上搭建一个小型 Git 服务器的基本步骤,包括添加 SSH 密钥访问、创建裸仓库,以及使用 post-receive hook 将 master 分支部署到工作目录。

1. 设置 Git 环境

安装 Git 并创建一个专用的 git 用户:

sudo apt-get update
sudo apt-get install git
sudo adduser git

使用专用用户可以将仓库访问权限与普通系统用户分开。

2. 生成 SSH 密钥对

在每台客户端机器上生成密钥对:

ssh-keygen -t rsa -C "user@lazying.art"

私钥保留在客户端,例如:

/home/pi/.ssh/id_rsa

将每个客户端的公钥添加到服务器上 Git 用户的 authorized keys 文件中:

/home/git/.ssh/authorized_keys

确保 .ssh 目录和文件权限符合 SSH 的要求:

sudo mkdir -p /home/git/.ssh
sudo chmod 700 /home/git/.ssh
sudo chmod 600 /home/git/.ssh/authorized_keys
sudo chown -R git:git /home/git/.ssh

3. 初始化服务器端仓库

创建用于存放裸仓库的目录,并初始化一个仓库:

mkdir Git
cd Git
sudo git init --bare sample.git
sudo chown -R git:git sample.git

裸仓库是 Git 服务器的常见格式。它保存 Git 数据,但不保留已检出的工作树。

若要将 git 用户限制为只能执行 Git 操作,编辑 /etc/passwd

sudo vim /etc/passwd

将该用户的 shell 从 Bash:

git:x:1001:1001:,,,:/home/git:/bin/bash

改为 git-shell

git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

在做这个修改之前,先确认系统中存在 git-shell

which git-shell

4. 将代码推送到 Git 服务器

在客户端的项目目录中,配置 Git 身份并推送第一次提交:

git config --global user.email "you@example.com"
git config --global user.name "Your Name"
git add .
git commit -m "init commit"
git push -u origin master

如果还没有添加远程仓库,先添加它。请将主机和路径替换为你的服务器信息:

git remote add origin git@192.168.1.108:/home/pi/Git/sample.git

5. 设置部署 Hook

在裸仓库中创建 post-receive hook:

vim sample.git/hooks/post-receive

添加 hook 脚本:

#!/bin/bash
TARGET="/home/webuser/deploy-folder"
GIT_DIR="/home/webuser/www.git"
BRANCH="master"

while read oldrev newrev ref
do
    # Only check out the branch that should be deployed.
    if [ "$ref" = "refs/heads/$BRANCH" ];
    then
        echo "Ref $ref received. Deploying ${BRANCH} branch to production..."
        git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
    else
        echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server."
    fi
done

然后设置所有者和执行权限:

chown git:git hooks/post-receive
chmod +x hooks/post-receive

当一次 push 触发该 hook 时,Git 应该会打印远程服务器返回的输出。由权限问题导致的部署失败可能类似这样:

Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 237 bytes | 23.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
remote: Ref refs/heads/master received. Deploying master branch to production...
remote: error: unable to create file main.py (Permission denied)
remote: error: unable to create file test.py (Permission denied)
remote: Already on 'master'
To 192.168.1.108:/home/pi/Git/printer.git
   2e6a796..6085cd0  master -> master

这表示 hook 已经运行,但 git 用户无法写入部署目录。将部署目录的所有者改为 git

chown git:git /path/to/deployment/directory/

修复权限后,一次成功的 push 可能类似这样:

Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 239 bytes | 21.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
remote: Ref refs/heads/master received. Deploying master branch to production...
remote: Already on 'master'
To 192.168.1.108:/home/pi/Git/printer.git
   6085cd0..b83c0d5  master -> master

常用客户端 Git 命令

设置全局 Git 用户名和邮箱:

git config --global user.name "username"
git config --global user.email "user@example.com"

克隆一个新建的远程仓库,添加 README,并推送:

git clone https://git.aiiage.com:9999/song.yl/ReID.git
cd ReID
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master

将已有的本地文件夹推送到新的远程仓库:

cd existing_folder
git init
git remote add origin https://git.aiiage.com:9999/song.yl/ReID.git
git add .
git commit -m "Initial commit"
git push -u origin master

将已有 Git 仓库指向新的远程仓库,并推送所有分支和标签:

cd existing_folder
git remote rename origin old-origin
git remote add origin https://git.aiiage.com:9999/song.yl/ReID.git
git push -u origin --all
git push -u origin --tags

参考:yllifesong,CSDN,<https://blog.csdn.net/yllifesong/article/details/81041156>。

Leave a Reply