GIT Server Buildup and Hooks Setting Up on Raspberry Pi

This note records the basic steps for building a small Git server on a Raspberry Pi, adding SSH key access, creating a bare repository, and using a post-receive hook to deploy the master branch to a working directory.

1. Set up the Git environment

Install Git and create a dedicated git user:

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

A dedicated user keeps repository access separate from normal system users.

2. Generate an SSH key pair

On each client machine, generate a key pair:

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

The private key stays on the client, for example:

/home/pi/.ssh/id_rsa

Add each client’s public key to the Git user’s authorized keys file on the server:

/home/git/.ssh/authorized_keys

Make sure the .ssh directory and file permissions are acceptable to 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. Initialize the server-side repository

Create a directory for bare repositories and initialize one:

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

A bare repository is the normal format for a Git server. It stores Git data but does not keep a checked-out working tree.

To restrict the git user to Git operations, edit /etc/passwd:

sudo vim /etc/passwd

Change the user’s shell from Bash:

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

to git-shell:

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

Before making this change, verify that git-shell exists on your system:

which git-shell

4. Push code to the Git server

In the project directory on the client, configure Git identity and push the first commit:

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

If the remote has not been added yet, add it first. Replace the host and path with your server details:

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

5. Set up a deployment hook

Create a post-receive hook inside the bare repository:

vim sample.git/hooks/post-receive

Add the hook script:

#!/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

Then set ownership and execution permissions:

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

When a push triggers the hook, Git should print output from the remote server. A failed deployment caused by permissions may look like this:

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

This means the hook ran, but the git user could not write to the deployment directory. Change the owner of the deployment directory to git:

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

After fixing permissions, a successful push may look like this:

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

Common client-side Git commands

Set the global Git user name and email:

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

Clone a newly created remote repository, add a README, and push it:

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

Push an existing local folder to a new remote repository:

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

Point an existing Git repository at a new remote and push all branches and tags:

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

Reference: yllifesong, CSDN, <https://blog.csdn.net/yllifesong/article/details/81041156>.

Leave a Reply