Git is a software source code management (SCM) system, originally developed by Linus Torvalds in 2005 for 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 and is being used by many prominent projects. In this tutorial, we will look at basic Git concepts, commands and examples which should be adequate to get started with using Git.
1. Differences from earlier source code management systems
The earlier source code management 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 the source control 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 the source control system. 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 source control system. The project history in Git, for a software under source control, 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.
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,
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.
3. An example
We will use Git for source code control 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, a systemd service unit is to be created in the directory /lib/systemd/system. The file, git.service, with the following contents does the job.
# [Unit] Description=The git daemon provides read access of Git repositories. Documentation=man:git(1) [Service] ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/home/git/ /home/git Restart=always RestartSec=500ms StandardOutput=syslog StandardError=syslog SyslogIdentifier=git-daemon User=nobody Group=nogroup [Install] WantedBy=multi-user.target
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. Next, we enable and start the daemon.
$ sudo systemctl enable git Created symlink /etc/systemd/system/multi-user.target.wants/git.service → /lib/systemd/system/git.service. $ sudo systemctl start git $ systemctl status git ● git.service - The git daemon provides read access of Git repositories. Loaded: loaded (/lib/systemd/system/git.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2021-08-17 19:30:00 IST; 7s ago Docs: man:git(1) Main PID: 18294 (git) Tasks: 2 (limit: 6922) Memory: 1.3M CGroup: /system.slice/git.service ├─18294 /usr/bin/git daemon --reuseaddr --base-path=/home/git/ /home/git └─18295 /usr/lib/git-core/git-daemon --reuseaddr --base-path=/home/git/ /home/git Aug 17 19:30:00 OpenSpace systemd[1]: Started The git daemon provides read access of Git repositories..
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,
https://github.com/<user-name>/<project-name>
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