3.0 KiB
Introduction
This document describes how to setup a Git hook to enable the update of a repository when a new commit is received.
This effectively is an implementation of a Push-to-Deploy update/continuous integration strategy.
For the described approach to work, the Git server and the deployment target must be running on the same machine. However, the files do not need to be accessible by both Git and the application server. That is why a safe indirection over root is necessary.
The deployment tree is a working directory of the Git repository. This has the advantage that no files accidentally get overwritten by Git. For example, for projects using PHP, this might be important. Although the increased amount of storage space is a tradeoff, it can be optimized by reducing the history depth of the repository from time to time. A brief hint hereof can be found at the end of this document.
The main work of the implementation is done by a universal script. Actually, it could be used in any situation where a safe update of a repository is needed.
Files
The following files are used to describe the implementation:
/path/to/main.git
The main bare repository receiving the updates./path/to/deploy-target
The deployment target directory. It is a working directory of a git repository./path/to/safe-update
The safe update script which is listed below.
Universal Safe Update
Copy the file git-safe-update.sh and make it executable.
It can be used to update any repository. It takes two arguments:
- Path of a non-bare Git repository
- Intended owner of the files
The chown
line at the end of the script is the reason
why the script needs to be run as root.
The chapter below describes how to configure sudo
to enable root access.
Note that the user always knows what is going on in case of a failure.
Git Hook
Install the following script as the post-receive
hook.
In this case to /path/to/main.git/hooks/post-receive
.
It executes safe-update
only when the master branch is updated.
#!/bin/sh
read oldid newid ref
if [ "$ref" = "refs/heads/master" ]; then
sudo /path/to/safe-update /path/to/deploy-target www-data.www-data
fi
Deployment Target Git Configuration
Because the Git repository lies on the same machine,
and is owned by a different user, it is safer to use
a file:
URL as the remote.
The master branch is assumed to be a deployable version.
Hence, use the following command to add the remote:
cd /path/to/deploy-target
git init
git remote add -t master origin file:///path/to/main.git
git fetch --depth=1
git checkout master
Sudo Configuration
Paste the following line to /etc/sudoers.d/safe-update
or append it to /etc/sudoers
:
git ALL=(root) NOPASSWD: /path/to/safe-update
This enables user git
to run safe-update
as root
without password.
So be careful..!
Miscellaneous
To "forget" old git history, I had success with the following commands:
rm -r .git/objects
mkdir .git/objects
git fetch --depth=1