Close

Git - Hosting and Accessing Remote Repository over SSH

[Updated: Feb 26, 2019, Created: Feb 25, 2019]

In the last tutorial we saw how to host a central repository through local protocol (i.e. on the file system). In this tutorial we will do the same thing but over SSH protocol.

We are going to setup remote repository on a Linux Mint machine, which will be running on the local network. We will also clone the repository and pull/push the repository to/from Windows 10 machine (which will be acting as a client).

Setting up SSH and Git on the server

To host a Git repository via SSH, we need to run a SSH server on the Linux machine and of course we also need to install Git there.

Setting up SSH Server

Login to the Linux mint server. To check whether SSH server is installed and running, use following command:

joe@mint-smtx:~$ ps -A | grep sshd

Where sshd is SSH demon. If there's no output then we need to install OpenSSH.

First update the package lists:

joe@mint-smtx:~$ sudo apt-get update

Now install the OpenSSh server:

joe@mint-smtx:~$ apt-get install openssh-server

After above command has finished, the sshd must be running. Let's check that:

joe@mint-smtx:~$ ps -A | grep sshd
18678 ?        00:00:00 sshd

Now we can access the server machine via ssh.

Installing Git

Checking if Git is already installed:

joe@mint-smtx:~$ git --version

Command 'git' not found, but can be installed with:

sudo apt install git

Let's install git:

joe@mint-smtx:~$ sudo apt install git

Checking again:

joe@mint-smtx:~$ git --version
git version 2.17.1

Creating Git Remote Repository on the server

Let's create a folder 'my-project.git' under user home directory and initialize it as git bare repository:

joe@mint-smtx:~$ clear
joe@mint-smtx:~$ mkdir my-project.git
joe@mint-smtx:~$ cd my-project.git/
joe@mint-smtx:~/my-project.git$ git init --bare
Initialized empty Git repository in /home/joe/my-project.git/
joe@mint-smtx:~/my-project.git$ ls -la
total 40
drwxrwxr-x  7 joe joe 4096 Feb 26 02:02 .
drwxr-xr-x 15 joe joe 4096 Feb 26 02:01 ..
drwxrwxr-x  2 joe joe 4096 Feb 26 02:02 branches
-rw-rw-r--  1 joe joe   66 Feb 26 02:02 config
-rw-rw-r--  1 joe joe   73 Feb 26 02:02 description
-rw-rw-r--  1 joe joe   23 Feb 26 02:02 HEAD
drwxrwxr-x  2 joe joe 4096 Feb 26 02:02 hooks
drwxrwxr-x  2 joe joe 4096 Feb 26 02:02 info
drwxrwxr-x  4 joe joe 4096 Feb 26 02:02 objects
drwxrwxr-x  4 joe joe 4096 Feb 26 02:02 refs
joe@mint-smtx:~/my-project.git$

Getting Server IP address

We also need to know the Linux server's IP address on the local network so that the clients can access it via SSH. Let's use ifconfig command for that:

joe@mint-smtx:~$ ifconfig
enp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.13  netmask 255.255.255.0  broadcast 192.168.0.255
      .........

Creating project on the client machine

Now lets login to a windows 10 client machine and create our example project via git bash for windows.

joe@jpc MINGW64 /d/git-example
$ mkdir my-project

joe@jpc MINGW64 /d/git-example
$ cd my-project/

joe@jpc MINGW64 /d/git-example/my-project
$ git init
Initialized empty Git repository in D:/git-example/my-project/.git/

joe@jpc MINGW64 /d/git-example/my-project (master)
$ echo test-content > readMe.txt

joe@jpc MINGW64 /d/git-example/my-project (master)
$ git add -A

joe@jpc MINGW64 /d/git-example/my-project (master)
$ git commit -m "adding project"
[master (root-commit) 31b81c2] adding project
 1 file changed, 1 insertion(+)
 create mode 100644 readMe.txt

Pushing project from client to remote repository via SSH

Let's use push command:

joe@jpc MINGW64 /d/git-example/my-project (master)
$ git push ssh://192.168.0.13/home/joe/my-project.git master
joe@192.168.0.13's password:
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 221 bytes | 221.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://192.168.0.13/home/joe/my-project.git
 * [new branch]      master -> master

As seen above we used complete path 192.168.0.13/home/joe/my-project.git prefixed with ssh://

Over internet the ssh url would look like this: ssh://joe@host.example.com/home/joe/my-project.git

Viewing remote repository git logs

Instead of going to the server machine again, we can access it via Putty, or even git bash for windows comes with a ssh client, let's use that:

joe@jpc MINGW64 /
$ ssh joe@192.168.0.13
joe@192.168.0.13's password:
Last login: Tue Feb 26 03:12:31 2019 from 192.168.0.3
joe@mint-smtx:~$ cd my-project.git/
joe@mint-smtx:~/my-project.git$ git log
commit 31b81c201585f16fc983e85534869b7c8bece003 (HEAD -> master)
Author: joe <joe@example.com>
Date:   Tue Feb 26 01:59:53 2019 -0600


    adding project
joe@mint-smtx:~/my-project.git$

The logs are as expected.

Cloning remote project from a new client

On the client machine, let's create a new directory representing another client (other than the original one /d/git-example/my-project) and clone the remote project via ssh:

joe@jpc MINGW64 /d/git-example
$ mkdir other-client

joe@jpc MINGW64 /d/git-example
$ cd other-client/

joe@jpc MINGW64 /d/git-example/other-client
$ mkdir my-project

joe@jpc MINGW64 /d/git-example/other-client
$ cd my-project/

joe@jpc MINGW64 /d/git-example/other-client/my-project
$ git clone ssh://192.168.0.13/home/joe/my-project.git .
Cloning into '.'...
joe@192.168.0.13's password:
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

joe@jpc MINGW64 /d/git-example/other-client/my-project (master)
$ ls -la
total 5
drwxr-xr-x 1 joe 197121  0 Feb 26 02:29 ./
drwxr-xr-x 1 joe 197121  0 Feb 26 02:28 ../
drwxr-xr-x 1 joe 197121  0 Feb 26 02:29 .git/
-rw-r--r-- 1 joe 197121 13 Feb 26 02:29 readMe.txt

joe@jpc MINGW64 /d/git-example/other-client/my-project (master)
$ git log
commit 31b81c201585f16fc983e85534869b7c8bece003 (HEAD -> master, origin/master, origin/HEAD)
Author: joe <joe@example.com>
Date:   Tue Feb 26 01:59:53 2019 -0600

    adding project

Pushing new changes

Let's add a new file to our new client project and push that to the central repository:

joe@jpc MINGW64 /d/git-example/other-client/my-project (master)
$ echo some-content > newFile.txt

joe@jpc MINGW64 /d/git-example/other-client/my-project (master)
$ git add -A && git commit -m "new changes"
[master 287dc9b] new changes
 1 file changed, 1 insertion(+)
 create mode 100644 newFile.txt

joe@jpc MINGW64 /d/git-example/other-client/my-project (master)
$ git remote -v
origin  ssh://192.168.0.13/home/joe/my-project.git (fetch)
origin  ssh://192.168.0.13/home/joe/my-project.git (push)

joe@jpc MINGW64 /d/git-example/other-client/my-project (master)
$ git push origin master
joe@192.168.0.13's password:
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 278 bytes | 278.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://192.168.0.13/home/joe/my-project.git
   31b81c2..287dc9b  master -> master

This time we used the repository reference name 'origin' instead of the whole url (check out last tutorial's 'Tracking of repository' section).

Checking git log on remote repository again

joe@jpc MINGW64 /
$ ssh joe@192.168.0.13
joe@192.168.0.13's password:
Last login: Tue Feb 26 03:21:24 2019 from 192.168.0.3
joe@mint-smtx:~$ cd my-project.git/
joe@mint-smtx:~/my-project.git$ git log
commit 287dc9b7ce059a3986c851c75885e72aafe4d36a (HEAD -> master)
Author: joe <joe@example.com>
Date:   Tue Feb 26 02:33:33 2019 -0600

    new changes

commit 31b81c201585f16fc983e85534869b7c8bece003
Author: joe <joe@example.com>
Date:   Tue Feb 26 01:59:53 2019 -0600

    adding project

The new changes are showing up in the logs.

Pulling the new changes

Let's go to our original client project /d/git-example/my-project and pull the new changes from the remote repository via ssh:

joe@jpc MINGW64 /d/git-example/my-project (master)
$ git pull ssh://192.168.0.13/home/joe/my-project.git
joe@192.168.0.13's password:
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ssh://192.168.0.13/home/joe/my-project
 * branch            HEAD       -> FETCH_HEAD
Updating 31b81c2..287dc9b
Fast-forward
 newFile.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 newFile.txt

joe@jpc MINGW64 /d/git-example/my-project (master)
$ ls
newFile.txt  readMe.txt

joe@jpc MINGW64 /d/git-example/my-project (master)
$ git log
commit 287dc9b7ce059a3986c851c75885e72aafe4d36a (HEAD -> master)
Author: joe <joe@example.com>
Date:   Tue Feb 26 02:33:33 2019 -0600

    new changes

commit 31b81c201585f16fc983e85534869b7c8bece003
Author: joe <joe@example.com>
Date:   Tue Feb 26 01:59:53 2019 -0600

    adding project

See Also