Like most other people, I maintain a certain number of projects on GitHub, typically the ones for which I can or which to publish the code. For some other developments for which I need to collaborate with other people but I don't want to publish the code (for instance, Kaggle competitions, I use private repositories in BitBucket). While all these services provide very convenient functionalities, may be you want to have total control over your git repositories for truly private stuff. If that is the case, keep reading.


  • A hosting provider that allows you to SSH into your account. I have DreamHost, but many others may work.
  • A sheel to run git, ssh and other necessary commands.

And that's pretty much it. I assume you know how to copy your SSH identity between your local host and your server. If you don't, read this.


First, start by logging into your remote account and create a general directory structure. Shouldn't take long:

me@remote(~)$ mkdir ~/git

That wasn't hard. All the repositories we will create will live under that directory. Now let's cd inside and start our first repo:

me@remote(~)$ cd git
me@remote(~/git)$ git init --bare example.git
Initialized empty Git repository in /home/me/git/example.git/

We're almost there. Now let's just clone it on our local machine:

me@local(~)$ git clone me@remote:git/example.git

And that's it. We will receive a warning because we are cloning an empty repository. It doesn't matter, it works as expected:

me@local(~)$ cd example

me@local(~/example)$ vi readme.txt # whatever

me@local(~/example)$ git add readme.txt

me@local(~/example)$ git commit readme.txt -m "First commit!"
[master (root-commit) c2f2399] First commit!
 1 file changed, 1 insertion(+)
 create mode 100644 readme.txt

me@local(~/example)$ git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 236 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To me@remote:git/example.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

And now we are done: we have our own private repository.

Update: if this is too simple and you would like some more complete solution, some people are recommending GitLab or