Creating Local And Remote Hosting Server for Git Repositories
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.
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
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
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.
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:
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.
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