An Introduction To Git and Github: Prof. Andrew C.R. Martin, University College London November, 2018
An Introduction To Git and Github: Prof. Andrew C.R. Martin, University College London November, 2018
An Introduction To Git and Github: Prof. Andrew C.R. Martin, University College London November, 2018
November, 2018
This self-paced tutorial will take you through the basic use of Git and GitHub.
These are systems that allow you to maintain code and work that you are doing,
track changes, recover old versions and collaborate with other people. There are
many tutorials available on the Web or in books. I use this style for com-
mands you type, and this style for filenames. In places I use this style or
THIS STYLE for things that should be substituted with an appropriate filename
or word.
Contents
1 Introduction — what are Git and GitHub? 2
2 Installing Git 3
2.1 If you are using Linux. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 If you are using a Mac. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 If you are using Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
4 Configuring Git 5
1
12 Undoing changes 10
12.1 Before you commit... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
12.2 After you commit... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
12.3 Being more selective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
12.4 Retrieving an old version . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
13 Branching 13
13.1 Checking differences between branches . . . . . . . . . . . . . . . . . . . 14
13.2 Merging branches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
13.3 Deleting branches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
15 Downloading a repository 17
17 Summary 22
18 Command summary 23
18.1 Creating a local git repository . . . . . . . . . . . . . . . . . . . . . . . . . 23
18.2 Synchronizing your local repository with GitHub . . . . . . . . . . . . . 23
18.3 Changing and adding files . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
18.4 Looking at differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
18.5 Check out a repository from GitHub . . . . . . . . . . . . . . . . . . . . . 24
18.6 Creating branches for developing and testing new features . . . . . . . . 24
18.7 Undoing changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
18.8 Tags and releases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
19 Other tutorials 25
2
sorts of problems completely. What’s more, you can synchronize git with GitHub on
the web giving you a backup of what you have done, allowing you to collaborate with
others and to publish what you have done to share it with the outside world. Some
journals (such as F1000) are even requiring that people who write papers describing
code deposit it in GitHub. If you write code to do your research, you can ensure that
you tag your code in GitHub with a version number so that when you publish your
research you can tie it to a specific version of the code allowing you (and others) to
recover exactly the version of code that was used to create your results.
Git and GitHub are separate things, but linked. Git is the software that runs on
your computer and manages your files. You don’t need to use it with GitHub. GitHub
is an online platform that allows you to synchronise your local Git reporitory onto the
web. You can also use GitHub to browse other people’s repositories and download
code or documents without ever using Git.
2 Installing Git
2.1 If you are using Linux. . .
You probably have Git installed already — try typing
git --version
at the command line and see if it returns a version number. If it says the command
is not found, use your package manager to install it. If you are using a RedHat style
distribution (RedHat, CentOS or Fedora), type
sudo yum -y install git
or on the newer distributions
sudo dnf -y install git
If you are using a Debian-based distribution such as Ubuntu, then type
sudo apt-get git
3
Task:
Go to www.github.com and create an account. You probably want to select a fairly memorable
(and sensible!) user name — ideally this is something that you will continue to use throughout
your career.
As explained in the Introduction, one of the main things you will want to do with
GitHub is synchronize your local repository with it. GitHub requires you to log in
with your username and password. This would be rather a nuisance if everytime you
wanted to synchronize your local Git repository with GitHub you had to specify your
username and password. Fortunately a mechanism is provided to allow you to avoid
this1 . First you need to create yourself what is known as an SSH key:
1: Type the following:
cd
mkdir .ssh
cd .ssh
ssh-keygen
ssh-keygen will probably ask you where you want to save the key. Simply press
the Return key to accept the default.
ssh-keygen will then ask you to enter a passphrase. Simply press the Return
key so that no passphrase is generated. You will then have to press the Return key a
second time to confirm your (empty) passphrase.
Now if you type ls, you should find that you have two files called id_rsa (your
private key) and id_rsa.pub (your public key). Display your public key:
2: Type the following:
cat id_rsa.pub
1 This relies on using a public/private key pair for authentication. This is the same sort of thing
that is done for encrypting your bank details when you send them over the web. Take a look at en.
wikipedia.org/wiki/Public-key_cryptography if you want to know more
4
Task:
• In GitHub, click the menu item at the top right (it may be a picture of you if you have added
a profile picture) and choose Settings from the menu.
• Select SSH and GPG keys from the menu on the left.
• Enter a title for your SSH key in the box — this can be anything you like, but probably
something that identifies the computer you are using (e.g. Andrew’s Windows laptop)
• Cut and paste the whole of the public key that you displayed a moment ago (the content
of id_rsa.pub) into the Key box.
to get the public key into your clipboard so you can paste it into GitHub.
• Click Add SSH key at the bottom of this section of the web page.
4 Configuring Git
You need to type two lines to configure Git and link it to GitHub.
In the following commands:
5
Command Effect
Esc Enter command mode
i Insert text at cursor
A Move to end of line and insert text
r Replace a single character under the cursor
R Overwrite characters
:w Write the file
:q Quit the editor
:wq Write the file and quit the editor
Now you need to create a directory for your project repository and enter that di-
rectory. For this tutorial we will call it GitExercise:
5: Type the following:
cd ~/git
mkdir GitExercise
cd GitExercise
Note that it is a good idea to avoid spaces in directory (and file) names since you will
have to put the name in inverted commas or escape each of the spaces with a backslash
which can be a real nuisance!
We now need to tell Git that this is a Git repository:
6: Type the following:
git init
6
When you are done press the Esc key to return to command mode. To exit the editor,
press Esc to ensure you are in command mode, then type :wq Table 1 summarizes
the most useful commands.
Task:
Use a text editor to create a file in your ∼/git/GitExercise/ directory called proteins.txt
containing the following text:
Exit your editor and tell Git that you want to track this file:
7: Type the following:
git add proteins.txt
You only need to do this when you have a new file that you want to track with Git.
Having specified that the file should be tracked, we need to tell Git that we have
made changes to the file that we want it to record:
8: Type the following:
git commit -a -m "Initial version"
Strictly in this case the -a isn’t needed, but it will be whenever you do this in future
so we will put it in3 . The -m specifies the text that follows in double-inverted commas
is a comment (or message) briefly explaining what changes were made in this version.
If you forget to supply a message with -m then you will enter the (vim) where you
can enter text (See the notes above).
3 The-a tells Git to add the changes in this file to those that are being tracked by commit. You
already did that with git add which is always needed for a new file.
7
Having just committed your changes, you should receive the message:
On branch master
nothing to commit, working directory clean
Let’s create another file that isn’t being tracked just to see what happens:
10: Type the following:
touch foo.txt
git status
The touch command is used to set the date and time on a file to the current date and
time. If the file doesn’t exist, it creates it, so we are just using this to create an empty
file.
This time the output from git status should look something like:
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
foo.txt
nothing added to commit but untracked files present (use "git add" to track)
Git warns you that there are files present that aren’t being tracked. Since we only
created this file as a test, let’s delete it again:
11: Type the following:
rm foo.txt
This will list all the commits you have made with the comments that you specified
with -m. The commit line in the output will be followed by a random string of char-
acters — something like b5526a8ddb40925e01620e751ecc97b735464444. Don’t worry
about this for now; you will find out why it is useful in a minute.
Task:
Edit your proteins.txt file by adding a couple of extra lines to the end of the file. For example:
8
Now if we check the status we will be told that one of the files has been modified:
13: Type the following:
git status
modified: proteins.txt
no changes added to commit (use "git add" and/or "git commit -a")
We now have to commit the changes so that Git keeps track of them.
14: Type the following:
git commit -a -m "Added information on PFKM"
git log
Looking at the output from git log you should now see that there is a log mes-
sage for your changes.
If you make a mistake in this command (such as not using the corrent username
or repository name), you can delete the remote repository and start again with
git remote remove origin
9
Task:
Refresh the GitHub web page — you should now find that your proteins.txt file is listed on
the page. You should also see that there have been 2 commits reflecting what you did on the
command line.
From now on, after you make and commit changes, all you need to do is git push
(without the -u origin master) to ‘push’ your changes onto GitHub.
12 Undoing changes
12.1 Before you commit...
Let’s add something else to the proteins.txt file, but something that was clearly a
mistake.
Task:
Edit the proteins.txt file and add the following line to the end of the file:
If you now type git status you will be told that the file has been changed, but
that you haven’t committed the changes yet. At this stage, you can go back to the
version without the changes:
16: Type the following:
git checkout -- proteins.txt
cat proteins.txt
10
As you will see, the file has reverted back to what it was before you added the lines.
If you have modified more than one file and want to reset everything to the last
commit, you can also do
git reset --hard
to reset all the files.
Task:
Edit the proteins.txt file and add the following line to the end of the file:
Task:
Record the first 6 or 7 characters of most recent commit message (at the top of the log) which
is associated with the erroneous commit.
commit adbd940940ba3f1584d3bd77c4b048e2b0fcda3f
Author: AndrewCRMartin <[email protected]>
Date: Thu Sep 28 12:39:37 2017 +0100
commit 54f0e41a1c772dbde9002ab1252c634c6296ec77
Author: AndrewCRMartin <[email protected]>
11
Date: Thu Sep 28 11:16:08 2017 +0100
I can now return to the previous version by ‘reverting’ the latest commit which
contained the error:
18: Type the following:
git revert adbd940
(when you do this, replace adbd940 with whatever is appropriate from your Git log).
Note that the commit number that you supply is the one that you want to undo, not the one
you want to get back to!
The screen will change to a message saying:
# Please enter the commit message for your changes. Lines starting
# with ’#’ will be ignored, and an empty message aborts the commit.
# On branch master
#
# Changes to be committed:
# modified: proteins.txt
#
You have entered the vim text editor (see Section 6 and Table 1.) where you can add
other comments about the change, but we will simply accept the default message by
pressing the Esc key and typing the characters: :wq (colon, ‘w’, and ‘q’)4
If you now look at the proteins.txt file, you should find that the changes have
gone and we have returned to the file as it was.
Now push your changes to GitHub — you committed a change and then reverted
it which is effectively another commit. Git tracks everything, so even your mistake is
tracked and can be got back again if needed:
19: Type the following:
git push
NOTE! git revert can be used to undo any commit — not just the most recent
one. You simply specify the relevant commit identifier.
12
To obtain an older version of a particular file, you can use the command:
git checkout commitid -- filename
where commitid is the commit identifier of the version that we want to keep (i.e. the
commit containing the last good version of the file) and filename is the filename of
the file you want to obtain. Having done this you would also need to commit the
changes in the usual way with git commit.
Task:
Give it a try. Go back to the original commit, take a look at the proteins.txt file and then
return to the latest version.
13 Branching
Often we find that we have a version of a program (or script) that we are happy with,
but we want to add some new feature(s). Whenever we make changes we risk break-
ing the existing version. Git allows us to create experimental ‘branches’ where we can
develop new features before merging them back into the master repository.
This is also useful when we have multiple people working on a project. Each per-
son creates a branch for the feature or bug-fix they are working on and when they are
finished they merge it back into the master branch.
Suppose we want to modify our proteins file to include the length of each protein.
Adding that extra field to the file might well break some program that relied on the
file, so we will do it in a new branch called ‘protlength’.
We create a new branch using
git checkout -b branchname
(where -b tells checkout to create a new branch):
20: Type the following:
git checkout -b protlength
This has created a new branch and switched to using that branch. You can confirm
which branch you are currently using:
21: Type the following:
git branch
13
The ‘master’ branch is the default branch that we were using previously.
If we are using GitHub, we need to tell Git to link this new branch to GitHub. We
do this with the command5 :
22: Type the following:
git push -u origin protlength
Task:
Edit proteins.txt to add the protein lengths:
Once we have made our changes, we commit them and push them to GitHub:
23: Type the following:
git commit -a -m "Added protein lengths"
git push
Now take a look at proteins.txt — you will see that it no longer has the protein
lengths. Return to the ‘protlength’ branch:
25: Type the following:
git checkout protlength
and verify that proteins.txt now has the protein length information.
14
26: Type the following:
git diff master
This will show us the differences between the current (‘protlength’) branch and the
‘master’ branch.
If we use git diff by itself (with no following parameter), it will show us differ-
ences from the most recent commit.
We can also use git diff with a commit identifier to see the differences between
the current version and a specified commit or with two commit identifiers to see the
differences between two specific commits.
In any of these cases, if you are only interested in a particular file, just add the
filename on the end as well.
If you made a mistake somewhere and this doesn’t work, you may need to do:
git add proteins.txt
git commit -m " "
The merge is automatically committed, but we need to push the merged ‘master’
branch back to GitHub:
28: Type the following:
git push
Again take a look at proteins.txt to confirm that it now conains the protein length
information.
To delete the branch on GitHub as well, we need the following two extra commands:
15
30: Type the following:
git push origin --delete protlength
git remote prune origin
The first command specifies the tag that you wish to use for this version. You can
choose whatever tag you like, but ‘v1.0’ is probably a sensible option. The second
command makes sure that GitHub knows about the tag too.
On GitHub, we can then create a ‘release’ of our repository. A release provides a
ZIP file and a gzipped tar file that people can download. To do this, follow these steps:
1. Visit your repository on GitHub
2. Once you have created a tag (‘v1.0’) and pushed it to GitHub as described above,
you should see the text 1 release above the list of filenames in the repository.
Click this text.
3. You will be taken to a screen where it lists the v1.0 release and on the right you
will see a button labelled Draft a new release. Click this button.
4. Click in the box with the faint text ‘Tag version’ and type the tag you have used
— as soon as you start typing the letter ‘v’ it should list your tag and you can
click on it.
5. Enter a title for your release in the ‘Release title’ box — something like “First
release version”
6. In the box below you can type some information about this release. Typically for
a first release this again will be something like “first release”, but for subsequent
versions you might provide a list of the changes since the previous version. A
method for obtaining this is described below in Section 14.1.
16
14.1 Summarizing your changes
The git shortlog command gives you the commit messages (the comments you
provided with the -m option to git commit) without all the other information:
32: Type the following:
git shortlog
You can also obtain only the commit messages between two particular commits:
git shortlog commitid1..commitid2
The version that you have currently checked out can be abbreviated as HEAD so to
find the changes between a particular commit and the current version, you can use:
git shortlog commitid..HEAD
As usual tags are abbreviated ways of accessing commit identifiers, so if you have
created a tag for a particular version, you can use the tag name instead of the commit
identifier:
git shortlog tag..HEAD
Consequently, when you create a new release (say ‘v1.1’), you can obtain the
changes from the previous release (say ‘v1.0’) with:
git shortlog v1.0..HEAD
15 Downloading a repository
You are now going to download a second copy of your repository from GitHub. Nor-
mally this is unlikely to be something you would want to do on the same computer.
However, it is quite possible that you might have a copy of the repository on your
laptop and another on a desktop computer — actually this is a really useful way of
synchronizing and tracking changes across multiple machines keeping a backup on
the cloud at the same time. Personally I do this to synchronize my laptop, my desktop
at home and my machine at UCL. It is also possible that you might want to collaborate
with someone else such that you would have a copy and someone else would have a
copy.
Let’s start by creating a git2 folder that we can put the copy in (again you wouldn’t
normally do this; we are just pretending this is on another machine).
Start by creating a directory for your second copy:
33: Type the following:
mkdir ~/git2
Now we will ‘clone’ the repository so we have a second local copy in this other
directory. Replace USERNAME with your GitHub username in the following:
34: Type the following:
cd ~/git2
git clone [email protected]:USERNAME/GitExercise.git
You should find that you now have a GitExercise directory exactly as you had
before.
17
16 Managing multiple copies of a repository
We now have a repository in our ∼/git directory and a second copy in ∼/git2 which
we are pretending is on a different machine.
Let’s go to the ∼/git2 version and add another file — it doesn’t matter what this
is, we are just testing what happens. We will create a file, then add and commit it to
Git, finally pushing it to GitHub:
35: Type the following:
cd ~/git2/GitExercise
echo "Hello world" > hello.txt
git add hello.txt
git commit -a -m "Added hello.txt"
git push
Take a look at the GitHub page (refresh it if necessary) and you will see the new file is
present.
Now let’s go to the original version of our repository in ∼/git:
36: Type the following:
cd ~/git/GitExercise
ls
You can now check that the new file is present and look at the updated log of
commits that have been made:
38: Type the following:
ls
git log
18
Task:
Edit the file proteins.txt and add the following line to the start of the file:
Now we will add a line to the end of proteins.txt in the second repository:
41: Type the following:
cd ~/git2/GitExercise
Task:
Edit the file proteins.txt and add the following line to the end of the file:
You will find that Git refuses to push the changes to GitHub because the version of
the repository on GitHub has changed since you last synchronized. You should see a
message like:
To [email protected]:USERNAME/GitExercise.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to ’[email protected]:USERNAME/GitExercise.git’
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., ’git pull ...’) before pushing again.
hint: See the ’Note about fast-forwards’ in ’git push --help’ for details.
Instead you must pull down the changes to merge them with what you have done
before you can push:
43: Type the following:
git pull
19
This will automatically merge the changes on GitHub with the changes you have
made locally. The screen will change to a message saying something like:
Merge branch ’master’ of github.com:USERNAME/GitExercise
Before we continue, we will go to the other repository and pull down the merged
changes:
45: Type the following:
cd ~/git/GitExercise
git pull
Task:
Edit the proteins.txt file and change the line
to read
(it doesn’t really matter what change you make — just change something!)
20
Now we commit and push the change:
47: Type the following:
git commit -a -m "Changed the hemoglobin alpha line"
git push
Now we will go to the repository in ∼/git2 and make a different change to the
same line:
48: Type the following:
cd ~/git2/GitExercise
Task:
Edit the proteins.txt file and change the line
to read
(again it doesn’t really matter what change you make — just make sure you change something
different in the same line!)
As with the simple conflict earlier, you will find that the push has been rejected by
GitHub. As before you need to pull the changes from the server:
50: Type the following:
git pull
This time you should get a message that looks something like this showing that the
automatic merge has failed:
21
Have a look at the proteins.txt file and you will find a section that looks some-
thing like:
<<<<<<< HEAD
Hemoglobin-ALPHA Human HBA_HUMAN P69905 142
=======
Hemoglobin-alpha HUMAN HBA_HUMAN P69905 142
>>>>>>> 931daf596e8ec94552889074ba767e87d3b578fe
This indicates the region of conflict — the first section shows how the line looks in this
repository; the second section shows how it looks in the GitHub version.
Task:
Edit the proteins.txt file and fix the merge conflicts manually. You need to remove the lines
that start with <<<<<<<, ======= and >>>>>>> and then combine the remaining lines as you
see fit; probably you will want a single line that looks like:
Now you need to commit the changes and push them back to GitHub:
51: Type the following:
git commit -a -m "Merged conflicts in Hemoglobin alpha"
git push
Finally we will return to the other copy of the repository and pull down the
changes:
52: Type the following:
cd ~/git/GitExercise
git pull
17 Summary
This tutorial has given an overview of the most common things that you need to do
with Git and GitHub. They are extremely powerful systems and you can do a lot more
with them, but for most people this will cover almost all of your needs. Get into the
habit of committing regularly — every half hour or so and whenever you have made
any sort of significant change.
At a minimum, all you need to do having created a repository is to remember to
git add new files, git commit changes and git push them to GitHub. If you are
working by yourself, these three commands will cover 95% of your interaction with
Git. The other things described here (like going back to old versions of files) will cover
another 4%. The other 1% is used so rarely that most regular users of Git will have to
Google for help!
22
18 Command summary
18.1 Creating a local git repository
• Create a directory for your repository:
mkdir -p ∼/git/projectname
• If you create a new file, then you must add it to Git, commit it and push to
GitHub:
git add filename
git commit -a
git push
23
In any of these cases, if you are only interested in a particular file, just add the filename
on the end as well.
Note: if you pull a branch down on another machine, it may not be able to syn-
chronize changes by just doing git pull and git push. If this is the case, simply
type:
git pull origin feature
git push -u origin feature
Once you have done that you should just be able to do git pull and git push.
24
• Undo a commit:
git revert commitid
(where commitid is the commit identifier obtained from git log).
• Create a release (with a ZIP file and a gzipped tar file for download) on GitHub.
• Obtain a list of changes from the previous tagged version for use in the release
information using:
git shortlog oldtaglabel..HEAD
(where oldtaglabel is a tag or commit identifier of an earlier version).
19 Other tutorials
You are also recommended to look at some of these for more information:
• https://guides.github.com/activities/hello-world/
— A short overview from GitHub
• https://try.github.io/
— An online interactive tutorial from GitHub.
• https://www.tutorialspoint.com/git/
— An excellent introductory tutorial
• https://www.codecademy.com/learn/learn-git
— Another excellent introductory tutorial
• https://git-scm.com/docs/gittutorial
— A fairly long overview tutorial
• http://www.vogella.com/tutorials/Git/article.html
— A fairly long detailed tutorial
Note that these tutorials may suggest different ways of doing things from what has
been presented above. I have shown you what works for me!
25