Pages

Monday, March 4, 2019

Git - Understanding Repositories

A repository contains the history of a collection of files starting from a certain directory. The process of copying a git repository using git tool is called cloning. Once the cloning is done and repository is available on our local machine we can have the complete history of the repository on our local machine.

Git has 2 types of repositories - bare and non-bare repository

Non - bare repositories : this is by default type of repository that we will use most of the times. When there is a repository available and a user clone the repository , the repo that comes to our local machine is called the non-bare repository. The .git directory will be available inside this non-bare repositories.

Bare repositories - these are the types of repositories that are created on the server for sharing changing from the developers.


How things work?Most times a server admin will create a bare repository on the server. He then configures the ssh. On the other hand , user who want to add changes to this repository first clone this bare repository using the ssh communication. Once they clone the repo, a local copy will be available to this which is a non-bare repo. They then commit changes to the local repo. They then configure their local git with the remote location of the bare repo ( server ). Finally they push the changes from their local to the remote repo.

Create a bare repository - Creating a bare repo can be done by using the “git init --bare” command as below,
jagadishAvailable$Wed Feb 20@ mkdir project.git
jagadishAvailable$Wed Feb 20@ cd project.git/
jagadishproject.git$Wed Feb 20@ git init --bare
Initialized empty Git repository in /Volumes/Available/project.git/
jagadishproject.git$Wed Feb 20@ ls -alrt
total 24
drwxrwxr-x  14 root admin  544 Feb 20 06:29 ..
drwxr-xr-x   4 jagadish admin  136 Feb 20 06:29 refs
drwxr-xr-x   4 jagadish admin  136 Feb 20 06:29 objects
drwxr-xr-x   3 jagadish admin  102 Feb 20 06:29 info
drwxr-xr-x  13 jagadish admin  442 Feb 20 06:29 hooks
-rw-r--r--   1 jagadish admin   73 Feb 20 06:29 description
-rw-r--r--   1 jagadish admin  111 Feb 20 06:29 config
drwxr-xr-x   2 jagadish admin   68 Feb 20 06:29 branches
-rw-r--r--   1 jagadish admin   23 Feb 20 06:29 HEAD
drwxr-xr-x  10 jagadish admin  340 Feb 20 06:29 .

In the above, i have created a directory “project.git” and inside the project.git, ran the “git init --bare” command which will create a bare repository. I created the bare repository as user jagadish. I have the credentials for the user.

Generate public/Private RSA Key Pairs - in order for the communication to happen between the server machine ( remote repo ) and the clients, we need to configure the ssh communicate between them. Let’s say that we have a user root from a different machine who wants to clone the remote repo and make some changes to the code. Once done he wants to push them back to the remote repo.
 

In order to configure the remote repo, use the “ssh-keygen” command available. I Am running the ssh-keygen command as root user on the client machine

[root@vx111a docker]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
8e:d3:a5:5d:f6:a4:7f:5b:b0:e1:1e:5e:f3:3c:16:63 root@vx111a.jas.com

The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| |
| |
| S . o + |
| + + o = E |
| o + . . *.=|
| . + *=|
| =o=|
+-----------------+

Once this is done , we will now have the Public key and private keys available. The public key is available in the ~/.ssh/ id_rsa.pub file. Never share the private key file.
Copy the public key file to the server machine - Once we have the public key, we need to add that to the server machine ( remote repo ) for further all communications. We can use the “ssh-copy-id” command to copy our public key to the remote machine. 

[root@test-machine ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub jagadish@192.168.31.177
/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"

The authenticity of host '192.168.31.177 (192.168.31.177)' can't be established.
ECDSA key fingerprint is SHA256:lMv3LvIWIsG9MI7ipWHXXP9PZfIrPsSN6KpWrQrDWPI.
ECDSA key fingerprint is MD5:46:92:90:50:0f:7f:ee:e6:2d:07:a6:96:0e:95:e1:90.
Are you sure you want to continue connecting (yes/no)? yes
/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'jagadish@192.168.31.177'"
and check to make sure that only the key(s) you wanted were added.

I got the Ip address of the remote machine and used the command “ssh-copy-id -i ~/.ssh/id_rsa.pub jagadish@192.168.31.177”. This will ask for a password and once we enter , it will add the public key of this machine to the remote machine. Once successfully added, we can login to the remote machine using the ssh command.

Now that the communication is success, we now need to clone the repo from the server to the local machine with user root as below,

[root@test-machine ~]# git clone jagadish@192.168.31.177:/Volumes/Available/project.git
Cloning into 'project'...
warning: You appear to have cloned an empty repository.

Once i run the “git clone” command by passing the repo location from the server machine, i was able to clone the repo to my local machine. We then see a directory with the name project. Once we move inside the project we can .git directory available. This is one of the difference between bare and non-bare repositories. In a non-bare repository, the .git directory is created in the project. For the bare repositories, the .git directory is not created but multiple files are created. These files are the same files that exist in .git location of a non-bare repo.

Configuring the Git - Now that we were able to clone the code from the remote machine we now need to configure the git with certain parameters. The include username, email etc. the most important of the configuration is the remote repo configuration.

Configure user name and email - To configure user name and email ID, run the below

git config --global user.email "root@example.com"
git config --global user.name "rootUser"

Configure the Remote Repo location - Once we have done the basic configuration , we need to configure the remote repo location. Once we make any changes to the code, we need to push them to the remote repo location so that the changes are available on the server for other users and clients. To configure the remote repo location run the below,

[root@test-machine project]# git remote add origin jagadish@192.168.31.177:/Volumes/Available/project.git

This will add the origin ( remote repo location ) details to the current git. In order to check that use the command “git remote -v” as,
[root@test-machine project]# git remote -v
origin    jagadish@192.168.31.177:/Volumes/Available/project.git (fetch)
origin    jagadish@192.168.31.177:/Volumes/Available/project.git (push)

Now that we have configured both user configuration and the repo details, let's push some code to the local repo and push the changes to the remote repo

[root@test-machine project]# echo “hello world” >> one

[root@test-machine project]# git add one

[root@test-machine project]# git commit -m "first file: one commit by root user"

[master (root-commit) 424fbce] first file: one commit by root user
1 file changed, 1 insertion(+)
create mode 100644 one

Review the Changes - Once our changes has been committed, lets review them before they were pushed to the remote repo. This can be done by using the “git log” command as below,

[root@test-machine project]# git log
commit 424fbce5183e1fe14b42a4c16e23b1fe1a7bc0f2
Author: rootUser
Date:   Wed Feb 20 02:58:25 2019 +0000

   first file: one commit by root user

This command will show the details of the commit history. It will show you all the commits that happened until now on the repository.

Similar to the “git log” command, “git show” command also gives details about the latest commit with few additional details as,

[root@test-machine project]# git show
commit 424fbce5183e1fe14b42a4c16e23b1fe1a7bc0f2
Author: rootUser
Date:   Wed Feb 20 02:58:25 2019 +0000

   first file: one commit by root user

diff --git a/one b/one
new file mode 100644
index 0000000..6d8f933
--- /dev/null
+++ b/one
@@ -0,0 +1 @@
+this is the first one file

Change the Commit Comments - If we want to change the comment added during the last commit, we can do that by using the “amend” option with “git commit” command as,

[root@test-machine project]# git commit --amend -m "changed comments by amend command"
[master a1bfd95] changed comments by amend command
1 file changed, 1 insertion(+)
create mode 100644 one
[root@test-machine project]# git log
commit a1bfd951ee1916637aeddf4ee824678bf5a4a8d4
Author: rootUser
Date:   Wed Feb 20 02:58:25 2019 +0000

   changed comments by amend command

Push the changes to the master - Now let’s push the code to the master repo using,

[root@test-machine project]# git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 240 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To jagadish@10.135.114.53:/Volumes/Available/project.git
* [new branch]      master -> master

Convert a Git repo to Bare repo - Converting a normal Git repository to a bare repository is not directly support by Git.You can convert it manually by moving the content of the .git folder into the root of the repository and by removing all others files from the working tree. Afterwards you need to update the Git repository configuration with the git config core.bare true command.

As this is officially not supported, you should prefer cloning a repository with the --bare option.

No comments :

Post a Comment