Intro to Git I
(11/4/2014)
Introduction
Tonight, we looked at git, a tool for managing revisions of files.
You can put a single file under git version control, but git is equally happy to work with a collection of files in a single directory tree. Git allows you to take snapshots ("commits") of the directory tree, and associate comments with individual snapshots.
Given a collection of snapshots, git allows you to look back at history. For example, you can ask git to restore a specific snapshot, or to show changes between two snapshots.
You can also use git to synchronize files between two different computers; we'll explore this in the next class. Tonight, we're going to focus on the git basics: editing files, and committing your changes.
Installing Git
For tonight's class, we'll want to install git and gitk.
$ sudo apt-get install git gitk
apt-get is debian's package manager. If you're using a different package manager (yum, zypper, etc), just change the command line accordingly.
Looking at a git repository
For our first exercise, let's download ("clone") a public git repository, and see what's inside.
$ git clone git://git.mayfirst.org/mfpl/puppet Initialized empty Git repository in /home/srevilak/puppet/.git/ remote: Counting objects: 24884, done. remote: Compressing objects: 100% (10000/10000), done. remote: Total 24884 (delta 15688), reused 21853 (delta 13318) Receiving objects: 100% (24884/24884), 3.05 MiB | 1.89 MiB/s, done. Resolving deltas: 100% (15688/15688), done.
$ cd puppet
$ ls -la 4 drwxr-xr-x 6 srevilak staff 4096 Nov 5 12:42 ./ 12 drwxr-xr-x 62 srevilak staff 12288 Nov 5 12:42 ../ 4 drwxr-xr-x 8 srevilak staff 4096 Nov 5 12:42 .git/ 4 -rw-r--r-- 1 srevilak staff 25 Nov 5 12:42 .gitignore 4 drwxr-xr-x 2 srevilak staff 4096 Nov 5 12:42 helper/ 4 drwxr-xr-x 3 srevilak staff 4096 Nov 5 12:42 manifests/ 4 drwxr-xr-x 3 srevilak staff 4096 Nov 5 12:42 modules/
The repository we've just cloned contains three directories (helper, manifests, and modules), and one file (.gitignore). The ".git" directory is where git keeps its versioning information.
Let's browse a little history, using gitk.
$ gitk
gitk is a graphical program. When it starts, you should see something like this:
I've used red lettering to describe what the different panels mean. Essentially, you're looking a change history: you can see who made each change, when, and the actual differences. Try clicking around in the top three panels to see what the different changes are.
Making and using your own git repository
Suppose we're writing a newsletter, and want to use git to keep track of changes. Let's make a new directory for our newsletter work, and create a git repository in that directory.
$ cd nl $ git init Initialized empty Git repository in /home/srevilak/nl/.git/
That's all there is to creating a repository. Let's ask git for some information about the repository we just created
$ git status # On branch master # # Initial commit # nothing to commit (create/copy files and use "git add" to track)
Nothing interesting yet -- git is just saying "you haven't asked me to track any files".
Let's create a file, and commit it.
$ touch hello.txt $ git add hello.txt $ git commit
The first line (touch hello.txt) creates an empty file called "hello.txt".
The second line (git add) tells git that you'd like to include hello.txt in the next snapshot.
The third line (git commit) creates the new snapshot. After typing "git commit", git should open an editor, and ask you to provide a commit message -- a comment about the snapshot you're about to create. You can give a comment like "added hello.txt", save, then exit the editor.
At this point, we can go back and review history
$ git log commit 08d55e16aaf97f91c71822b42aa5845e1614e5ff Author: Steve Revilak <steve@srevilak.net> Date: Wed Nov 5 12:49:49 2014 -0500 added hello.txt
"git log" shows information about commits made to the repository; like a non-graphical gitk. Here, you see that I've made one commit, with the comment "added hello.txt".
Now, let's change hello.txt, and run git status.
$ echo "hello" >> hello.txt $ git status # On branch master # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: hello.txt # no changes added to commit (use "git add" and/or "git commit -a")
Note the output from "git status". Git is saying "you've modified hello.txt -- use 'git add' to incorporate this file into the next snapshot, or 'git checkout' to undo the modifications."
With text-based files, git can show you exactly what changed:
$ git diff diff --git a/hello.txt b/hello.txt index e69de29..ce01362 100644 --- a/hello.txt +++ b/hello.txt @@ -0,0 +1 @@ +hello
"diff" shows differences between files (like what we saw in gitk's lower left panel). In this case, git is showing us the difference between the last snapshot, and the current state of the files. "+hello" means that the line "hello" was added to hello.txt.
Let's add hello.txt to the snapshot, and commit the changes.
$git add hello.txt $ git commit -m "very rough draft of the hello file" [master a0bc7c0] very rough draft of the hello file 1 files changed, 1 insertions(+), 0 deletions(-)
Above, I used the "-m" option to specify a commit message on the command line. Try running "git log" and verify that you see a second commit with this message.
Here's an example that uses git to undo a change.
$ echo "A questionable change to hello.txt" >> hello.txt $ git diff diff --git a/hello.txt b/hello.txt index ce01362..1b2eab7 100644 --- a/hello.txt +++ b/hello.txt @@ -1 +1,2 @@ hello +A questionable change to hello.txt
The first command added "A questionable change to hello.txt" to the file hello.txt. The second command uses "git diff" to see the change. Now, suppose I don't like the questionable change, and want to git rid of it.
$ git checkout -- hello.txt $ git status # On branch master nothing to commit (working directory clean)
The first line (git checkout) tells git "replace hello.txt with the copy from the last commit". The second line uses "git status" to check for changed files; the response "working directory clean" tells us that there are no uncommitted changes. In other words, we've backed out our questionable change.
Now, take a look at hello.txt, and verify that "A questionable change ..." is no longer there.