git Server Solutions

A good server solution for selfhosting is gitea. It is a lightweight server with webui that can easily be deployed as Docker container. It has no advanced features like pipelines, but comes with all basic functionalities, like user management repository browsing in the webui or issue tracking if needed.


Cheatsheet

Check past git commands

Use the following command to show past git actions on the local machine:

git reflog

Squash commits together when merging

Ti combine all commits of a branch when merging it into another one use squash.

git merge --squash <branch_name>

When committing after the merge use -m option to create a completely new commit message or ommit this option to get into an editor mode with an editable commit log from the merged branch.

Reset past git commands with reflog / reset

Warning

Only use this feature when working on local changes or on a repository only used by one single person. If something is already pushed to the server and gets altered with git reset things can go wrong if other users already pulled the wrong repository state.

When a commit or another command went wrong you can check the reference log of past actions using

git reflog

Then undo past actions using

git reset --hard HEAD@{<target_log_position>}

Hooks

Deploy with post-receive

Via the post-receive hook it is quite easy to deploy the repository at the git server. This can be useful if the data or scripts have to be available on it for further automation. The post-receuive hook for such a task if gitea is used could look like this:

#!/bin/bash
 
# Info: always make sure when initialy deploying this script tht it is executable!
# Info: make sure that the deploy folders are exiting when initialy deploying this repository!
 
LOCAL_DEPLOY_TARGET="<the_local_target_directory>"
GIT_DIR="<path_to_the_git_directory>"
BRANCH="main"
 
while read oldrev newrev ref
do
	# only checking out the master (or whatever branch you would like to deploy)
	if [ "$ref" = "refs/heads/$BRANCH" ];
	then
		echo "Ref $ref received. Checking out ${BRANCH} branch to local deploy folder..."
		git --work-tree=$LOCAL_DEPLOY_TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
 
		echo "Updating git server hooks..."
		# gitea uses a custom hook set up. 
		# user hook scripts have to be deployed in the respective 
		# folder rather than directly as for instance post-receive hook.
		cp $LOCAL_DEPLOY_TARGET/hooks/* $GIT_DIR/hooks/post-receive.d/
	else
		echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server."
	fi
done

Deploying with this method can be further advanced by using SSH to deploy the repository to a specific remote server. This is explained in Deploy with post-receive over SSH

Deploy with post-receive over SSH

Info

Check out Troubleshooting for information on common problems.

git reporitories can easily be deployed to a remote server via the scp command. Set up a SSH connection between all corresponding network clients via RSA key and set up the following post-receive hook (Deploy with post-receive) for the main branch for deployment over SSH:

#!/bin/bash
REMOTE_IP="<remote_IP>"
REMOTE_USER="<remote_user_name>"
REMOTE_TARGET="<remote_deploy_path>"
LOCAL_TARGET="<local_deploy_path>"
GIT_DIR="<git_repo_path>"
BRANCH="main"
 
while read oldrev newrev ref
do
    # only checking out the master (or whatever branch you would like to deploy)
    if [ "$ref" = "refs/heads/$BRANCH" ];
    then
        echo "Ref $ref received. Deploying ${BRANCH} branch to production..."
        git --work-tree=$LOCAL_TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
        scp $LOCAL_TARGET/src/* $REMOTE_USER@$REMOTE_IP:$REMOTE_TARGET
        # some additional commands can be placed here to restart deployed services.
    else
        echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server."
    fi
done