Script for git tutorial screencasts¶
These are the scripts I used for two short screencasts introducing git.
Script for introduction to git repository¶
In the terms of the git parable, snapshot is the same thing as a commit.
Our own version of the git parable
git config --global user.name "Matthew Brett"
git config --global user.email "matthew.brett@gmail.com"
Change to home directory:
cd ~
A git repository consists of a working directory (or working tree) with a hidden subdirectory containing the files that git uses to store and track snapshots.
First make the working directory:
mkdir thrilling_paper
cd thrilling paper
This is our working directory.
There are no files in the directory at the moment.
Let’s start the paper:
vim nobel_prize.txt
then:
How the brain works
-------------------
It sends electrical messages around and that adds up to everything.
Let’s make an analysis script as well:
import random
the_number = random.randint(0, 50)
while the_number != 42:
print("Oops, try again")
the_number = random.randint(0, 50)
print("The answer is", the_number)
Now let’s say we’re ready to start making snapshots with git.
First we make a git repository to store the snapshots and history:
git init
ls
The directory .git is hidden:
ls -a
ls .git
The directory has various things in it.
In fact we will find that the refs directory will store the bookmarks for our branches and tags, and the objects directory will store our file and directory snapshots.
We haven’t taken any snapshots yet, so there is nothing in the objects directory:
ls .git/objects
git status
Notice that the files are ‘untracked’. That means that git has never previously taken a snapshot of these files, and so far assumes they should not go into our snapshots.
As you remember from the git parable, before we do a snapshot, we first put
the stuff that will go into the snapshot, into the staging area. We do that
with git add
.
Now let’s add nobel_prize.txt to the staging area:
git add nobel_prize.txt
What just happened? First, we can see that a snapshot of nobel_prize.txt has gone into the staging area:
git status
Second, behind the scenes, git has made a copy of the file and put it into its objects directory:
ls .git/objects
The file has a filename that comes from its hash. Don’t worry about that for now. We can even get git to fetch this stored copy of nobel_prize.txt for us, with git show. Don’t worry about the details of this command:
git show :nobel_prize.txt
This is the snapshot of the file that has gone into the staging area.
If we now change the file in the working tree, it will be different from the snapshot version.
Edit nobel_prize.txt:
I have discovered the electrical impulses in the brain change when I think
about being famous.
The copy of nobel_prize.txt in the working directory contains a new sentence. But the snapshot stored copy is the same as it was when we took the snapshot:
git show :nobel_prize.txt
Now what happens when I do a git status?:
git status
The green shows the initial snapshot I did of this file, into the staging area. The red ‘not staged for commit’ shows that the file that is in the working tree is different from the file in the staging area. The redness of the red text is warning me that I may want to update my copy in the staging area. I’ll do that now:
git add nobel_prize.txt
git status
Notice that I now have two files in the objects directory - these correspond
to the first snapshot I made of nobel_prize.txt
and the second that I just
made. This reminds us that git is very careful to make use we don’t
accidentally lose our backups. Even though we probably don’t care about the
first version of the file, git will keep it for us for a month or so, in the
‘objects’ directory, in case we want it. Eventually though, git will do a
housekeeping clearout, and that backup will disappear, unless it is part of
any of the full snapshots (commits) that will come on to soon.
Now I will also add analysis_script.txt:
git add analysis_script.txt
git status
So now both files are in the staging area, and the versions in the staging area are the same as the versions in the working tree.
Of course we now have another file in .git/objects because there is now a snapshot of analysis_script there.
Notice that git tells us that that these changes in the staging area are ready to be committed.
A commit, as we remember, is one recorded state of the working tree - a snapshot of the working tree.
Let’s do the commit.
I’m first going to do the commit as I would normally do it:
git commit
Git opened my text editor for me and shows me some helpful information about what is going into this commit.
I then type a message about this commit to remind me (and any else looking at this later) what this commit is for.
Then git will save this message with the record of this snapshot, along with my name and email address, from the configuration we did at the start of this video.
But in this case, I’m not going to do what I normally do, and I’m going to close this without saving.
I’m doing this so you can follow along. When you first get started with git, you may not have your favorite text editor set up to work with git, and so you may get an error or some confusing text editor opening up to type the message. You will then need to set up your text editor properly. Google is your friend.
So, just to show you how it works, if your text editor isn’t set up right, I’ll use the -m flag to pass the message, so git doesn’t open the editor:
git commit -m "First snapshot of my files"
Git helpfully tells us what went into the snapshot.
Now I can look at the short history of the project:
git log
Script for video on git history and git branches¶
The next step in understanding git is understanding how git connects commits together with the commit parents, and how git stores branches and tags as bookmarks.
First let’s look at branches.
You can see from the commit message that git seems to be on a “branch” called “master”.
“master” is the default branch, the branch that git creates by default.
We can see which branch we are on using git branch
:
git branch
At the moment we only have one branch “master”
As we saw in the git parable, a “branch” is just a label that points to a particular snapshot. Remember a snapshot is a “commit” in git terminology.
Remember that git log showed us the identifier for the commit - the commit hash:
git log
We can also see which commit the branch is pointing at by using the -v
flag:
git branch -v
As you can see the output tells us that the “master” branch is pointing to the git commit that starts with ‘d839074’ - the same hash reported by git log.
In the git parable, we stored the branch positions in a text file, and git
does something very similar. Git records the current position of each branch
in a tiny text file in the .git/refs/heads
directory. Here is the current
contents of .git/refs/heads/master
- the current position of the master
branch:
cat .git/refs/heads/master
As you can see it points to the commit (snapshot) hash we see in the output
from git log
and from git branch -v
.
Now let’s make a new commit.
I’ll now make some edits to nobel_prize.txt
. First I delete the last
sentence. Now I add:
I am starting to feel famous while I write this paper.
I do git status to show me what has changed between the working tree and the staging area:
git status
Sure enough, the nobel_prize.txt
paper has new changes that the staging
area does not know about.
Remember that the staging area always starts off the contents of the last commit.
In fact, we can ask git to tell us exactly what changes there are in the
working tree, compared to the staging area, with the git diff
command:
git diff
Git diff only works well on simple text files like the files in our working tree. The new lines are in green with a plus. Any deleted lines are in red with a minus sign preceding.
OK - I am happy to add these changes to the staging area for the new commit:
git add nobel_prize.txt
git status
All seems ready.
Let’s make the new commit:
git commit -m "More inspiring thoughts"
Let’s look at the history of our project now:
git log
The project has two commits, the commit we have just done, and the first commit.
The first line for each commit gives the SHA1 hash (unique identifier) for this commit.
Our new commit points back to the first commit to record the history, that our latest commit follows on from the first commit.
We can see that by using the --parents
flag to git log:
git log --parents
We still have the hash of our commit at the beginning of the first line. After that, for our second commit, we have the “parent” of this commit. The parent is the first commit. You can see the parent of the second commit is the same as the hash for the first commit. This is how git records the line of history between the commits.
How about the branch? Remember that the position of the branch should move when we make a commit. The branch position moves from pointing to the previous commit, to point to the current commit. As we remember, the current commit is:
git log
Here is the position of the ‘master’ branch now:
git branch -v
You can see that the branch position has moved to point to the latest commit.
You won’t be surprised to see that git stored this information in the
.git/refs/heads/master
file:
cat .git/refs/heads/master
You now know most of the important things you need to know to understand git.