Update on April 28, 2023

SSH Keys

A git server stores all pushed changes and change histories of a repository. A git server allows one to view the changes and to roll back the changes. Although you cannot visually view the source files on a get server, the server has enough information to recreate the source code at any commit point.

The tutorial assumes that assumes that communications between git clients and a git server are over SSH. It also assumes SSH keys are used so that client is not prompted for a password every time the client communicates with the server. authenticate the user. See Generating and Setting Up SSH Keys.

The tutorial assumes that there are two git clients and one git server. It also assumes that the following global variables for git have been set:

Setting Up a Git Server

On the git server make a new directory for the repository. It is customary that this directory has the extension ".git"[]

For example:

mkdir hello_world.git
cd hello_world.git

Initialize the server repository with the --bare option:

git init --bare

You will get message that git is using the name 'master' for the initial branch.

The following files and/or directories should be present in the sever repository:
 
branches, config, description, HEAD, hooks, info, objects and refs.

ls

You should never modify any files in the server repository.

However, the clients that use the server do require access to the files and directories.

sudo chown remote_user:remote_user *

or grant access to everyone:

sudo chmod -R 777 .

We now have a sever repository with no source files that you can clone to a client.

Client_1

Go to the parent directory of where you want the client repository stored.

Clone the server repository:

git clone {server_user}@{server_ip_addr}:/home/server_user/server_repo

Note the colon, :, after the server_ip_addr. This is because we are using the ssh protocol and not http.

You will get a warning that apparently you are cloning an empty directory.

Verify that the repository, hello_world.git, is now on client_1:

ls

There should be only one hidden file, ".git" in this directory:

cd hello_world.git
ls -alh

The hidden file ".git" should contain the same files and directories that were not hidden on the server repository. More precisely, the following files and or directories should be in ".git": branches, config, description, HEAD, hooks, info, objects and refs.

cd .git
ls

Client_2

Repeats the steps for cloning the empty server repository on client_1 for client_2.

Make Changes on a Client and Push them to the Server

This is where you would copy or move source files from an existing project into a client repository. To keep it simple, we are just going to create a file:

echo "Hello World" >> hello_world.txt

Stage and commit the files:

git add --all
git commit -m "added file hello_world.txt"

Push the file from the client to server:

git push

Pull Files from the Server to the Client

On Client_2, Go to the directory hello_world.git :

git pull

Verify that client_2 contains the file hello_world.txt.

ls

Git Remote, Git Push & Git Pull

A git remote is basically a shortcut for a url and path to a repository. The syntax is:

git remote add <name> <url:path>

To list the remote names and their url:path's

git remote -v

When the hello_world.git repository was cloned, git automatically created a remote named "origin" back to the server repository. To see this, on either client_1 or client_2 go to the directory hello_world.git and execute the above command.

However, many git tutorials, will explicitly have you create the remote. That is:

git remote add origin server_user@server_ip_addr:path_to_repo_on_server

There is nothing magic about the name "origin", it is just the default name that git uses when you clone a repository. In the above command, any name could have been chosen for the remote.

Many tutorials also use the longer form of push. That is:

git push origin master

Where master is the master branch of the client repository.

Similarly for pull, they use:

git pull origin/master

Where origin/master is the branch on the server repository that you are pulling into the active branch on the client.

The git pull command is actually a combination of two commands:

git fetch origin/master
git merge origin/master

There is nothing magic about the name "master". It just the default name for the branch that git automatically creates when you initialize (git init) a repository. In 2020, GitHub decided to use the name "main: for their default branch. If you want to use the name " main" for the default branch, after you initialize the empty repository on the server, you can change the name of master to main:

git branch --move master main

Do this before you clone the server repository on to the clients.

References:

  1. SpaceRex - How to Self-Host Git Server on Raspberry Pi
  2. How to Set Up a Private Git Server
  3. 4.4 git on the server - setting up the server
  4. Git remote - Tutorials -Bitbucket
  5. Git-Hub_-_Pushing commits to a remote repository
  6. How do I do an initial push to a remote repository with Git?