Git Tutorial

Git is a software source code management (SCM) system, originally developed by Linus Torvalds in 2005 for the management of Linux kernel source code. Using Git greatly simplifies the source code management functions for a project and improves the overall efficiency of the software development process. Git has become a very popular source code management system is being used for software revision control for many prominent projects.

1. Differences from earlier SCM systems

The earlier SCM systems were centralized. A repository of software would be kept safe in a central server and programmers could check out code, work on it and commit their changes back to the central repository. Git is a distributed SCM system. The repository is always available with the working directory of the source code. So, after finishing a functionality, a programmer can commit the source to the local repository. For sharing of source code, remote repositories are maintained, where commits from the local repositories can be pushed. Also the latest commits can be fetched from remote repositories.

The previous SCM systems stored the base file and differences from the previous version (delta) for each file and for each version. So to generate a version, the system has to take the base files and apply deltas of versions between the first version and the version being generated. In the case of Git, the entire files are kept for each commit, except for the files that have not changed. For the files that have not changed, a pointer to the last changed object is kept. This has resulted in the simplification of software design and an improved efficiency at run-time.

2. Git concepts

2.1 Tree, working tree and Repository

The source code to be managed is organized in a directory tree structure. A working tree is a checked out copy of the software under SCM and is under use for further work. A repository contains all the data and associated pointers for all the commits made for the software under SCM. A repository contains blob objects for files, tree objects for tying multiple blob objects in a tree structure, commit objects, containing a tree object giving the directory tree at the time of commit and a reference to its parent commit object and tag objects that give identity to other commit objects. A repository is mostly stored in the .git directory, often in the top directory in the working tree itself.

2.2 Commits, HEAD and the master branch

A commit is a version or revision of software saved in the SCM system. The project history in Git, for a software under SCM, is the collection of commits in the chronological order for all the live branches of development. A branch of development is an independent parallel development activity. The default or the main branch is the master branch. The master branch is created when a repository is initialized. The tip of a branch is the head of the branch. The pointer HEAD (uppercase) points to the tip of the branch on which work is taking place.

Git: master branch for a software package under SCM

The rectangles represent the commits. Each commit is identified by 40 hexadecimal digit SHA-1 checksum. To refer to a commit, it is not necessary to say all the 40 characters; only the few characters that uniquely identify the checksum and the associated commit suffice. So, for example, in the figure above, only the first five characters of SHA-1 checksum are mentioned out of forty for each commit as these identify each commit uniquely in our small example project. The default number of abbreviated characters is 7 and bigger projects may require more, say first 12 characters out of 40 characters of SHA-1 checksum for uniquely identifying commits. Also, each commit refers to the previous parent commit. So there is a pointer in the backward direction for each commit, except for the first one.

Now, suppose we make a branch to quickly try an alternate algorithm for some function, call it try and switch to it, the above diagram would look like,

Git: master and try branches for a software package under SCM

2.3 Index or the Staging area

Git has a two stage commit process. Changes made in the working tree are first moved to an area called Staging area or the index. From the staging area, the changes are committed into the repository.

Git: Two step commit process

3. An example

We will use Git for source code management (SCM) of an example project. The example project is a Hello, World! program made into a project using the GNU build tools. The initial working tree is located in $HOME/hello and looks like this,

$ ls -ls
total 404
 36 -rw-rw-r-- 1 user1 user1  34939 Mar 28 23:32 aclocal.m4
  0 -rw-rw-r-- 1 user1 user1      0 Mar 28 23:45 AUTHORS
  4 drwxr-xr-x 2 user1 user1   4096 Mar 28 23:44 autom4te.cache
  0 -rw-rw-r-- 1 user1 user1      0 Mar 28 23:45 ChangeLog
  4 -rw-rw-r-- 1 user1 user1    746 Mar 28 23:45 config.h
  4 -rw-rw-r-- 1 user1 user1    625 Mar 28 23:44 config.h.in
 12 -rw-rw-r-- 1 user1 user1   8571 Mar 28 23:45 config.log
 32 -rwxrwxr-x 1 user1 user1  32396 Mar 28 23:45 config.status
136 -rwxrwxr-x 1 user1 user1 139215 Mar 28 23:44 configure
  4 -rw-rw-r-- 1 user1 user1    168 Mar 28 23:30 configure.ac
  0 lrwxrwxrwx 1 user1 user1     32 Mar 28 23:45 COPYING -> /usr/share/automake-1.11/COPYING
  0 lrwxrwxrwx 1 user1 user1     32 Mar 28 23:45 depcomp -> /usr/share/automake-1.11/depcomp
  4 drwxrwxr-x 2 user1 user1   4096 Mar 29 08:59 doc
 12 -rwxrwxr-x 1 user1 user1  11240 Mar 28 23:45 hello
 84 -rw-rw-r-- 1 user1 user1  85878 Mar 28 23:45 hello-1.0.tar.gz
  4 -rw-rw-r-- 1 user1 user1    131 Mar 28 23:28 hello.c
  8 -rw-rw-r-- 1 user1 user1   6440 Mar 28 23:45 hello.o
  0 lrwxrwxrwx 1 user1 user1     32 Mar 28 23:45 INSTALL -> /usr/share/automake-1.11/INSTALL
  0 lrwxrwxrwx 1 user1 user1     35 Mar 28 23:45 install-sh -> /usr/share/automake-1.11/install-sh
 24 -rw-rw-r-- 1 user1 user1  20679 Mar 28 23:45 Makefile
  4 -rw-rw-r-- 1 user1 user1     47 Mar 28 23:29 Makefile.am
 24 -rw-rw-r-- 1 user1 user1  21013 Mar 28 23:45 Makefile.in
  0 lrwxrwxrwx 1 user1 user1     32 Mar 28 23:45 missing -> /usr/share/automake-1.11/missing
  0 -rw-rw-r-- 1 user1 user1      0 Mar 28 23:45 NEWS
  0 -rw-rw-r-- 1 user1 user1      0 Mar 28 23:45 README
  4 -rw-rw-r-- 1 user1 user1     23 Mar 28 23:45 stamp-h1
  4 drwxrwxr-x 2 user1 user1   4096 Mar 29 09:01 tmp

3.1 Putting the project under Git

The first job is to get started with Git for the project. We need to import the project under Git. This is quite straightforward and simple. Just go to the project directory and execute the commands,

$ cd ~/hello
$ git init
Initialized empty Git repository in /home/user1/hello/.git/

At this stage, the status of the project is that the Git repository has been initialized and we need to do the first time import of the project files into the Git repository. The git status command gives the status,

$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	.deps/
	AUTHORS
	COPYING
	ChangeLog
	INSTALL
	Makefile
	Makefile.am
	Makefile.in
	NEWS
	README
	aclocal.m4
	autom4te.cache/
	config.h
	config.h.in
	config.log
	config.status
	configure
	configure.ac
	depcomp
	doc/
	hello
	hello-1.0.tar.gz
	hello.c
	hello.o
	install-sh
	missing
	stamp-h1
	tmp/

nothing added to commit but untracked files present (use "git add" to track)

We will add files to the repository but first let's first make a .gitignore file in the project root directory. .gitignore contains a list of files which need not be tracked and Git can just ignore these files.

# .gitignore

# temporary files
autom4te.cache/
tmp/

# object files
*.o

# generated files
aclocal.m4
config.h.in
config.log
config.status
configure
Makefile
Makefile.in
*.tar.gz
hello

Now, if we see the status, we get a smaller list of untracked files.

$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	.deps/
	.gitignore
	AUTHORS
	COPYING
	ChangeLog
	INSTALL
	Makefile.am
	NEWS
	README
	config.h
	configure.ac
	depcomp
	doc/
	hello.c
	install-sh
	missing
	stamp-h1

nothing added to commit but untracked files present (use "git add" to track)

We can add these files to the repository with the git add command.

$ git add .
$ 
$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   .deps/hello.Po
	new file:   .gitignore
	new file:   AUTHORS
	new file:   COPYING
	new file:   ChangeLog
	new file:   INSTALL
	new file:   Makefile.am
	new file:   NEWS
	new file:   README
	new file:   config.h
	new file:   configure.ac
	new file:   depcomp
	new file:   doc/hello.doc
	new file:   hello.c
	new file:   install-sh
	new file:   missing
	new file:   stamp-h1

The command git add . puts the files in the staging area. Next, we try to the commit the work with the git commit command.

$ git commit -m "First commit."

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'user1@thishost.(none)')

Git needs our email id and name before we can do the first commit. We execute the config commands to set these and do the first commit.

$ git config --global user.email "user1@example.com"
$ git config --global user.name "Joe Bloggs"
$ git commit -m "First commit."
[master (root-commit) 0bb1127] First commit.
 17 files changed, 180 insertions(+)
 create mode 100644 .deps/hello.Po
 create mode 100644 .gitignore
 create mode 100644 AUTHORS
 create mode 120000 COPYING
 create mode 100644 ChangeLog
 create mode 120000 INSTALL
 create mode 100644 Makefile.am
 create mode 100644 NEWS
 create mode 100644 README
 create mode 100644 config.h
 create mode 100644 configure.ac
 create mode 120000 depcomp
 create mode 100644 doc/hello.doc
 create mode 100644 hello.c
 create mode 120000 install-sh
 create mode 120000 missing
 create mode 100644 stamp-h1

3.2 git tag

We can add a tag like v1.0 to our commit.

$ git tag -a v1.0 -m "Version 1.0"

3.3 git log

By default, tags refer to the commit pointed by the HEAD. We can see the log,

$ git log --decorate --all --oneline --graph
* 0bb1127 (HEAD, tag: v1.0, master) First commit.

3.4 Branching

Suppose we wish to keep the main software version (master) safe and make a few changes in a copy and try it out. We, basically, need the branching functionality of Git. It is easy to branch in Git. First, let us check the branches we have.

$ git branch
* master
$

As expected, we just have the master branch. We make a new branch,

$ git branch alt
$ git branch
  alt
* master

This makes a new branch alt. We can switch to the new branch, alt,

$ git checkout alt
Switched to branch 'alt'
$ git branch
* alt
  master
$

Now we can make the changes in software and do the testing. We modify files in the working tree. We have only modified files and not done any Git operation like putting the modified files in the staging area. We can get a list of unstaged changes with the git diff command.

$ git status
On branch alt
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   hello.c

no changes added to commit (use "git add" and/or "git commit -a")
$ git diff
diff --git a/hello.c b/hello.c
index ba4fb67..41757db 100644
--- a/hello.c
+++ b/hello.c
@@ -6,5 +6,5 @@
 
 main ()
 {
-    printf ("Hello world!\n");
+    printf ("Hello, the brave new World!\n");
 }

If we want to discard the changes in hello.c, we can do that with the git checkout command,

$ git checkout -- hello.c
$ git status
On branch alt
nothing to commit, working directory clean

and we back to the state after the first commit. But suppose we are satisfied with the git diff output and we wish to move the changed files to the staging area,

$ git status
On branch alt
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

	modified:   hello.c

no changes added to commit (use "git add" and/or "git commit -a")
$
$ # dry run: what would a git add . command do?
$ git add -n .
add 'hello.c'
$ git add .

The command git add -n . does a dry run and tells which files would be staged. The next command, git add . puts the files in the staging area. If you wish to unstage a file, the command would be,

git reset HEAD <file>...

The next step is to commit the changes.

$ git commit -m "Minor modification."
[alt 4d646aa] Minor modification.
 1 file changed, 1 insertion(+), 1 deletion(-)

The -m option adds the message to the commit. It is possible to combine the staging and commit commands in a single command,

git commit -a -m <msg>

Before the commit, if we wish to see the changes that are being committed, the command is

git diff --cached

As mentioned above, git diff --cached needs to be given after the changes have been staged and before the git commit command.

3.5 Merging branch with master

We committed work on the alt branch. Now, it is time to merge the alt branch with the master branch.

$ git checkout master
Switched to branch 'master'
$ git merge alt
Updating 0bb1127..4d646aa
Fast-forward
 hello.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git status
On branch master
nothing to commit, working directory clean

While switching branches, git checkout <branch> does not discard the local changes. git checkout manual page says,

git checkout <branch>
To prepare for working on <branch>, switch to it by updating the index and the files in the working tree, and by pointing HEAD at the branch. Local modifications to the files in the working tree are kept, so that they can be committed to the <branch>.

Consider the scenario: You are working on the master branch. Suddenly you get an idea and you make a branch temp. You checkout temp, make changes in files but do not commit. Then you switch to the master branch. You might be surprised to find changes still there in the files. The idea seems to be that the user has made changes which might still be needed and should not be discarded. To get the pure copy of the master branch (i.e., completely discard changes in the temp branch), use the -f flag in the git checkout command.

$ git branch temp
$ git checkout temp
Switched to branch 'temp'
$ # make changes
$ vi hello.c
$ git status
On branch temp
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   hello.c

no changes added to commit (use "git add" and/or "git commit -a")
$ git checkout master
M	hello.c
Switched to branch 'master'
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   hello.c

no changes added to commit (use "git add" and/or "git commit -a")
$ git checkout temp
M	hello.c
Switched to branch 'temp'
$ git checkout -f master
Switched to branch 'master'
$ git branch -d temp
Deleted branch temp (was 4d646aa).

4. Git on a server

Till now, the discussion focused on a local repository; the repository and the working tree were on the same computer. However, for any collaboration, the repository needs to be available on a server so that the other users can access it. We will use the term, Git server. Broadly, there are two kinds of users, those who have the write access to the repository and can push data to it and the others users who only have the read access to the repository and can only clone, fetch or pull data from the repository. The work required to create a remote repository is mostly an exercise in system administration. We will provide the read and write access via the SSH and the read-only access using the Git protocol.

4.1 Configuring the SSH protocol on the Git Server

4.1.1 Create a user

Create a user git on the remote Git server. The home directory for git is /home/git and the shell is the git-shell, which is a restricted login shell for Git SSH access.

$ sudo addgroup git
Adding group `git' (GID 1004) ...
Done.
$ sudo adduser --home /home/git --shell /usr/bin/git-shell --ingroup git git
Adding user `git' ...
Adding new user `git' (1004) with group `git' ...
Creating home directory `/home/git' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for git
Enter the new value, or press ENTER for the default
	Full Name []: Git
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] Y
$ cd /home/git
$ sudo mkdir .ssh
$ ls -lsa
total 36
 4 drwxr-xr-x 3 git  git  4096 Mar 29 15:02 .
 4 drwxr-xr-x 8 root root 4096 Mar 29 15:01 ..
 4 -rw-r--r-- 1 git  git   220 Mar 29 15:01 .bash_logout
 4 -rw-r--r-- 1 git  git  3637 Mar 29 15:01 .bashrc
12 -rw-r--r-- 1 git  git  8980 Mar 29 15:01 examples.desktop
 4 -rw-r--r-- 1 git  git   675 Mar 29 15:01 .profile
 4 drwxr-xr-x 2 root root 4096 Mar 29 15:02 .ssh
$ sudo chown git:git .ssh

4.1.2 Generate SSH keys and copy Public key to the Git Server

Next, the SSH keys need to be generated on the local system.

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa): ./id_rsa
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in ./id_rsa.
Your public key has been saved in ./id_rsa.pub.
The key fingerprint is:
0e:66:2b:85:9f:fb:b8:e7:5f:4e:dc:09:55:2c:12:c3 
$ ls -lsa
total 52
 4 drwxr-xr-x   2 user   user    4096 May 15 04:29 .
40 drwxr-xr-x 121 user  user   36864 May 15 04:27 ..
 4 -rw-------   1 user   user    1679 May 15 04:29 id_rsa
 4 -rw-r--r--   1 user   user     396 May 15 04:29 id_rsa.pub
$

id_rsa is the private key which needs to be copied to ~/.ssh directory on the local system. id_rsa.pub is the corresponding public key which needs to be copied to the remote Git server. On the local system,

$ cp id_rsa ~/.ssh
$ scp id_rsa.pub git-server:tmp
user@git-server's password: 
id_rsa.pub                                                    100%  396     0.4KB/s   00:00    
$ cd ~/.ssh
$ ssh-add ./id_rsa
Identity added: ./id_rsa (./id_rsa)

On the remote Git server, copy the id_rsa.pub file to /home/git/.ssh/authorized_keys.

$ cd ~/tmp
$ sudo cp id_rsa.pub /home/git/.ssh/authorized_keys
$ sudo chown git:git /home/git/.ssh/authorized_keys

Similarly public and private keys for all other users who would have write access to the repository need to be generated. The public keys of these users need to be transferred to the Git-server and appended to the file /home/git/.ssh/authorized_keys. For example, on the remote Git server, assuming that public keys, id_rsa_alice.pub, id_rsa_bob.pub and id_rsa_carol.pub have been transferred to the ~/tmp directory,

cd ~/tmp
sudo cat id_rsa_alice.pub >> /home/git/.ssh/authorized_keys
sudo cat id_rsa_bob.pub >> /home/git/.ssh/authorized_keys
sudo cat id_rsa_carol.pub >> /home/git/.ssh/authorized_keys
$ sudo chown git:git /home/git/.ssh/authorized_keys
$ sudo chmod 700 /home/git/.ssh
$ sudo chmod 600 /home/git/.ssh/authorized_keys

A user, say Alice, needs to copy the file id_rsa_alice containing her private key to the $HOME/.ssh directory on her local system. Also, Alice needs to add the following entries to the $HOME/.ssh/config file on the local system,

#alice account
Host git-server-alice
     Host name git-server
     User git
     IdentityFile ~/.ssh/authorized_keys

git-server should be replaced by the actual Git server host name.

Finally, go to the /etc/ssh directory on the remote Git server and open the file sshd_config in a text editor. Ensure that the following entries are enabled as below:

RSAAuthentication yes
PubkeyAuthentication yes

4.1.3 Create an empty repository on the Git Server

On the remote Git server,
$ cd /home/git
$ sudo mkdir hello
$ cd hello
$ sudo git --bare init
Initialized empty Git repository in /home/git/hello/
$ ls -lsa
total 40
4 drwxr-xr-x 7 root root 4096 Mar 29 15:33 .
4 drwxr-xr-x 4 git  git  4096 Mar 29 15:32 ..
4 drwxr-xr-x 2 root root 4096 Mar 29 15:33 branches
4 -rw-r--r-- 1 root root   66 Mar 29 15:33 config
4 -rw-r--r-- 1 root root   73 Mar 29 15:33 description
4 -rw-r--r-- 1 root root   23 Mar 29 15:33 HEAD
4 drwxr-xr-x 2 root root 4096 Mar 29 15:33 hooks
4 drwxr-xr-x 2 root root 4096 Mar 29 15:33 info
4 drwxr-xr-x 4 root root 4096 Mar 29 15:33 objects
4 drwxr-xr-x 4 root root 4096 Mar 29 15:33 refs
$ cd ..
$ sudo chown -R git:git hello
$ ls -lsa hello
total 40
4 drwxr-xr-x 7 git git 4096 Mar 29 15:33 .
4 drwxr-xr-x 4 git git 4096 Mar 29 15:32 ..
4 drwxr-xr-x 2 git git 4096 Mar 29 15:33 branches
4 -rw-r--r-- 1 git git   66 Mar 29 15:33 config
4 -rw-r--r-- 1 git git   73 Mar 29 15:33 description
4 -rw-r--r-- 1 git git   23 Mar 29 15:33 HEAD
4 drwxr-xr-x 2 git git 4096 Mar 29 15:33 hooks
4 drwxr-xr-x 2 git git 4096 Mar 29 15:33 info
4 drwxr-xr-x 4 git git 4096 Mar 29 15:33 objects
4 drwxr-xr-x 4 git git 4096 Mar 29 15:33 refs

4.1.4 Push the repository data from the local system to the Git server

With the bare repository in place on the remote Git server, we can push the repository data from the local system to the remote Git server. The following steps need to be done on the local system.

$ git remote add origin git@git-server:/home/git/hello
$ git push origin master --tags
Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 875 bytes | 0 bytes/s, done.
Total 9 (delta 5), reused 0 (delta 0)
To 192.168.2.243:repo/hello
   f574e13..edc5764  master -> master
 * [new tag]         v1.0 -> v1.0

By default, git push does not push the tags to the remote repository. By using the --tags option, the tag objects are transferred as well.

4.2 Setting up a local repository from remote repository

The most common way is to use the git clone command, assuming that the remote repository supports the git protocol, which is mostly the case. We will look at git clone command a little later; in this section will use the SSH or the Local protocol. We can get the remote repository with the git fetch command.

$ mkdir hello
$ cd hello
$ # Initialize an empty repository
$ git init
Initialized empty Git repository in /home/user1/mu/hello/.git/
$ git remote add origin git@git-server:/home/git/hello
$ git fetch 
remote: Counting objects: 35, done.
...
$ git checkout master
Branch master set up to track remote branch master from origin.
Already on 'master'
$ ls -ls
total 28
0 -rw-rw-r-- 1 user1 user1    0 Apr 14 20:00 AUTHORS
0 -rw-rw-r-- 1 user1 user1    0 Apr 14 20:00 ChangeLog
...

After the initial checkout, we can fetch the updates of the remote repository to the local system with the git fetch command. This gets the commits which are available on the remote repository but are not there in the local repository. git fetch stores these in the local repository. Then, we can execute the git merge command to merge the local repository with the current working tree.

$ git fetch
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From 192.168.2.243:repo/hello
   edc5764..952b40d  master     -> origin/master
 * [new tag]         v2.1       -> v2.1
$ git merge

4.3 Configuring the Git protocol for read-only access

Git protocol enables anonymous read access of the repository for all people. There is a daemon process that acts as a server and listens on port 9418. To enable the Git protocol, the following command has to run as a daemon on the remote Git server,

git daemon --reuseaddr --base-path=/home/git/ /home/git/

For the Git daemon to serve the repository, we need an empty file named git-daemon-export-ok in the parent directory of the repository on the remote Git server.

$ cd /home/git/hello
$ sudo touch git-daemon-export-ok
$ sudo chown git:git git-daemon-export-ok

To get the daemon running, an upstart script, /etc/init/git-daemon.conf, is made with following contents on the remote Git server.

# git-daemon
#
# This service provides the Git protocol for read only access of Git repositories

start on runlevel [2345]
stop on runlevel [!2345]

respawn
exec /usr/bin/git daemon --user=nobody --group=nogroup --reuseaddr --base-path=/home/git/ /home/git

It is recommended that the Git daemon is run with the user-id of a user having read access to the repository only. So user-id nobody with the group nogroup just work fine for us. To run this daemon without shutting down the system,

$ sudo initctl start git-daemon
git-daemon start/running, process 3128
$ ps -ef | grep git
root      3128     1  0 16:34 ?        00:00:00 /usr/bin/git daemon --user=nobody --group=nogroup --reuseaddr --base-path=/home/git/ /home/git
nobody    3130  3128  0 16:34 ?        00:00:00 git-daemon --user=nobody --group=nogroup --reuseaddr --base-path=/home/git/ /home/git

With the daemon running on the Git server, we can try to clone the repository at the local system.

$ mkdir new
$ cd new
$ git clone git://git-server/hello
Cloning into 'hello'...
remote: Counting objects: 21, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 21 (delta 2), reused 0 (delta 0)
Receiving objects: 100% (21/21), done.
Resolving deltas: 100% (2/2), done.
Checking connectivity... done.

5. GitHub

GitHub is a popular web based Git hosting website. Instead of going through the process of configuring a Git server, it is possible to host project code on GitHub. GitHub is the largest code host in the world.

5.1 Using GitHub

We will use GitHub as the server and create a remote repository for HelloWorld on it for sharing the project code with others and also having a safe copy of the repository at a more reliable location. The work on the local system is not affected and is the same as that described above.

For a project hosted on GitHub, the URL is of the form,

scheme://github.com/<user-name>/<project-name>

The scheme could be https, git or ssh.

We will create a repository for our project HelloWorld on GitHub. GitHub has a link marked + on all its pages near the top right corner. Clicking + gives a menu with New Repository as an item. Clicking on New Repository leads to a form where we can enter the repository details. We enter hello as the repository name, enter a description, make the repository public and, since we have the local repository, we do not initialize the repository with a README. Finally, we click the Create repository button.

Next, we need to tell Git on the local system regarding the remote repository for hello on GitHub. On the local system, we give the command,

$ git remote add github-hello https://github.com/<user-name>/hello.git

And, we push the repository to GitHub with the command,

$ git push github-hello master

Now, we have the remote repository for hello on GitHub. Anyone can get hello repository with the command,

$ git clone https://github.com/<user-name>/hello.git

6. References