You don't need a git hosting service to manage and share your git repo. All you need is a server which is:

  • accessible via SSH (to yourself, not others), for pushing changes, and
  • has a public accessible HTTP server (for others to clone)

Firstly, on the remote server, let's prepare a bare repo:

1
2
mkdir repo.git; cd repo.git
git init --bare

Also, move repo.git directory to a place under HTTP server directory. I put it under ~/html/git/ so there can host multiple git repos.

Now, with SSH, you should be able to push changes via SSH already:

1
2
3
4
5
# In your git repo:
# ~USER is standard UNIX way to expand into USER's home directory
URL=ssh://USER@SERVER/~USER/path/to/repo
git remote set-url origin "$URL"
git push

Now, exposing the repo to HTTP mostly following this guide:

1
2
3
# in the bare repo:
git update-server-info
mv hooks/post-update.sample hooks/post-update

Note:

  1. the hook calls update-server-info, so everytime there's a push, the server info is updated (needed to serve the repo via HTTP).
  2. the default hook script seems to have a bug in it:
1
exec git-update-server-info

On my system git-update-server-info does not exit. So I've to change it to

1
exec git update-server-info
  1. I host the repo on a public unix system, so I have umask 077. So, in order for the updated git repo to be always exposed to public (HTTP), I need to chmod all subdir/files to go+rX. So I also do this in the post-update hook:
1
2
3
4
5
6
7
8
9
10
11
12
# hooks/post-update

(
exec git update-server-info
)

# Note that the hooks of a bare repo is always run with PWD set to the repo
# root, but just to be safe, let's make sure it looks like a git repo:
if test -f HEAD; then
echo "updating repo permission..."
chmod -R go+rX .
fi
  1. exec must be in a sub-shell, otherwise commands following it won't run echo "Updating server info..."

  2. the hook is run in a bare repo's root dir (link)

  3. When you push remotely, the output of the hooks are shown in the git push output.

After these steps, you can pull it from HTTP:

  1. Pull it from HTTP
1
git pull http://$SERVER_URL/path/to/repo_dir repo.http
  1. Test that repo changes and file permissions are are indeed updated via the hooks:
1
2
# Make some change to the repo and push via SSH
git push ssh://USER@SERVER/~USER/path/to/repo

Then pull via HTTP again

1
2
# in repo.http/
git pull

Make sure you see the update