Skip to content

Git - Create Operation

To collaborate with a team, you need a shared remote repository. While services like GitHub, GitLab, and Bitbucket are popular for hosting remote repositories, understanding how to set up your own Git server can be beneficial. This chapter covers creating a self-hosted remote Git repository.

On your server, you might want a dedicated user for Git operations. These commands are for a Linux server.

# Run these commands as root or with sudo on the server
[root@gitserver ~]# groupadd gitdevs
# Add new user 'gituser' to 'gitdevs' group, create home directory, set shell
[root@gitserver ~]# useradd -G gitdevs -d /home/gituser -m -s /bin/bash gituser
# Set password for the new user
[root@gitserver ~]# passwd gituser

You’ll be prompted to enter and confirm the new password:

Changing password for user gituser.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

A ‘bare’ repository in Git is one that doesn’t have a working directory (no checked-out files). It only contains the Git version history and metadata. This is what you need for a shared central repository. By convention, bare repository names end with .git.

Log in as gituser (or your chosen user) on the server:

[gituser@gitserver ~]$ pwd
/home/gituser
[gituser@gitserver ~]$ mkdir myproject.git
[gituser@gitserver ~]$ cd myproject.git/
[gituser@gitserver myproject.git]$ git init --bare
Initialized empty Git repository in /home/gituser/myproject.git/

The myproject.git directory now contains the bare repository structure (hooks, info, objects, refs, etc.).

To securely connect to the Git server, users typically use SSH keys. Each user (e.g., Tom) generates an SSH key pair (public and private keys) on their local machine.

On Tom’s local machine:

[tom@local-machine ~]$ ssh-keygen -t rsa -b 4096 -C "tom@example.com"

Follow the prompts. You can press Enter to accept default file locations and optionally set a passphrase for added security.

Generating public/private rsa key pair.
Enter file in which to save the key (/home/tom/.ssh/id_rsa): [Press Enter]
Enter passphrase (empty for no passphrase): [Enter passphrase or Press Enter]
Enter same passphrase again: [Confirm passphrase or Press Enter]
Your identification has been saved in /home/tom/.ssh/id_rsa
Your public key has been saved in /home/tom/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx tom@example.com
The key's randomart image is:
+---[RSA 4096]----+
| o.o=B*Oo|
| *.=o=*o|
| . =. o.=|
| o . . |
| S . . |
| . .|
| E.|
| .o|
| ..|
+----[SHA256]-----+

This creates id_rsa (private key, keep it secret!) and id_rsa.pub (public key) in the ~/.ssh directory.

Server-Side: Add Public Keys to authorized_keys

Section titled “Server-Side: Add Public Keys to authorized_keys”

Tom needs to provide his public key (id_rsa.pub) to the server administrator, or if he has access, add it to the gituser’s ~/.ssh/authorized_keys file on the server. The ssh-copy-id command is an easy way to do this from Tom’s machine:

[tom@local-machine ~]$ ssh-copy-id gituser@gitserver.example.com

He will be prompted for gituser’s password on the server. This command appends Tom’s public key to /home/gituser/.ssh/authorized_keys on the server. Repeat this for every developer (e.g., Jerry).

Client-Side: Clone or Add Remote, and Push Changes

Section titled “Client-Side: Clone or Add Remote, and Push Changes”

Now Tom can interact with the remote repository. If it’s a new project, he can initialize a local repository, add files, commit, add the remote, and push.

On Tom’s local machine, in his project directory:

[tom@local-machine tom_project]$ git init -b main
Initialized empty Git repository in /home/tom/tom_project/.git/
[tom@local-machine tom_project]$ echo "# My Project" > README.md
[tom@local-machine tom_project]$ git add README.md
[tom@local-machine tom_project]$ git commit -m "Initial commit"
[main (root-commit) 19ae206] Initial commit
1 file changed, 1 insertion(+)
create mode 100644 README.md

Now, add the self-hosted repository as a remote named origin:

[tom@local-machine tom_project]$ git remote add origin gituser@gitserver.example.com:/home/gituser/myproject.git

And push the main branch to the remote repository:

[tom@local-machine tom_project]$ git push -u origin main

The output will look something like:

Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 242 bytes | 242.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To gitserver.example.com:/home/gituser/myproject.git
* [new branch] main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

Tom’s changes are now on the self-hosted remote repository. Other developers (like Jerry, once his SSH key is added) can clone this repository using git clone gituser@gitserver.example.com:/home/gituser/myproject.git.

Note: While master was traditionally the default branch name, main is now widely adopted as a more inclusive default. We’ve used main in this updated example.