Creating Local And Remote Hosting Server for Git Repositories

Chandan Kumar
The Startup
Published in
6 min readDec 3, 2020

Have you ever wondered how GitHub stores and serves your git repository?

In this article we’ll be knowing features of git, using which it makes easy for others to create a hosting platform for git repositories.

We’ll not be going in details of how GitHub works but will be exploring how we can build something similar to it for hosting your git repositories, from where you can clone and perform other git related things.

Before going to remote servers let’s just create a local git server and in order to do that we need to know few things in advance.

git init

The git init command creates a new Git repository. It can be used to convert an existing, un-versioned project to a Git repository or initialise a new, empty repository. Most other Git commands are not available outside of an initialised repository, so this is usually the first command you'll run in a new project.

Executing git init creates a .git subdirectory in the current working directory, which contains all of the necessary Git metadata for the new repository. This metadata includes subdirectories for objects, refs, and template files. A HEAD file is also created which points to the currently checked out commit.

Bare repositories — — git init — bare

git init — bare Initialise an empty Git repository, but omit the working directory. Shared repositories should always be created with the --bare flag. Conventionally, repositories initialised with the --bare flag end in .git. For example, the bare version of a repository called my-project should be stored in a directory called my-project.git.

A bare Git repository is typically used as a Remote Repository that is sharing a repository among several different people. You don’t do work right inside the remote repository so there’s no Working Tree (the files in your project that you edit), just bare repository data.

demo diagram for a bare central repo

The --bare flag creates a repository that doesn’t have a working directory, making it impossible to edit files and commit changes in that repository. You would create a bare repository to git push and git pull from, but never directly commit to it. Central repositories should always be created as bare repositories because pushing branches to a non-bare repository has the potential to overwrite changes. Think of --bare as a way to mark a repository as a storage facility, as opposed to a development environment. This means that for virtually all Git workflows, the central repository is bare, and developers local repositories are non-bare.

Creating bare repository in local

We can create a bare repository by using the git init — bare command

Initialisation of a new bare repo

Here I’ve initialised a bare git repository by calling it server.git as mentioned above it has to be associated with .git, we can also see that it has created a repo with name server.git and it has basic .git directory contents. We can see it doesn’t have any source and tree that means we cannot use it directly.

Cloning bare repository from local path

As we have created a central repository now it’s time to clone it

cloning bare repository from local path

We can do it by simply using the git command and giving the bare repository path. It’s like any empty git repository and we can have commits in it.

Let’s go inside server and add file to make commit.

creating commit

Commit is ready now, and we can make a push, but before that let’s have a look at .git/config file where we can see the remote location details:

git config file

We can see the origin path is the local location from where we have cloned it, and any push will go there.

Cloning as second repo

As we now have committed and pushed the changes to the central repo let’s clone it in other repo to see if we gets the first commit there

Great!! we now have verified that the the bare repository works as a central repository, it’s time to make the commit from the second cloned repo and take pull in the other.

creating a new commit inside the server_2 repo which is newly cloned
taking pull and checking logs

We have now created the local git server successfully, the flow is complete now, there’s a central repo from where there are two clones server and server_2 and both can now commits to same repo and can take pulls from the same.

Creating a remote server

The most common use case for git init --bare is to create a remote central repository.

Imagine having an AWS remote machine somewhere which you can access via ssh and can use all the features that we have done with the local setup.

The process of creating the the repos will be same just that the paths will get changed while accessing from the remote machine.

First, you SSH into the server that will contain your central repository. Then, you navigate to wherever you’d like to store the project. Finally, you use the --bare flag to create a central storage repository. Developers would then clone my-project.git to create a local copy on their development machine.

This is cool, but still not so cool, as we can only see the code by cloning them there is no central place like GitHub from where we can see the code.

We can do so using code, there are some really useful libraries in node which can help you doing the same.

This are just two examples of tools which you can use to create repos in remote servers via code. These also provides the ability to get to specific version and parse the blob contents into files.

NodeGit : https://github.com/nodegit/nodegit

Here is a sample repo which has used both the packages in order to create the GUI for the same purpose : https://github.com/dheeraj-p/git-center-server

--

--