- Session 1: The Basics
- Session 2: Undoing Things
- Session 3: Using git with svn
- Session 4: Branching and Merging
- Session 5: Working with Remotes
- What’s Git
- Git vs SVN
- Installation and setup
- Creating your first Git repository
- Adding and committing files
- Viewing changes and previous commits
Interactively:
$ git help <verb>
$ git <verb> --help
$ man git-<verb>
Online:
- version control system
- open source
created by the same dudes that created Linux
At the heart of GitHub
(this will make sense later)
Git is an extremely fast, efficient, distributed version control system ideal for the collaborative development of software
GitHub is the best way to collaborate with others. Fork, send pull requests and manage all your public and private Git repositories.
- think of it as SVN viewer, bugzilla and reviewboard combined
- SVN is a centralised version control system
- everyone contributes to a single repository
- Git is a distributed version control system
- each clone is a full mirror of the repository
- you can contribute to multiple repositories
Read more about the different types of version control systems.
- each clone is a full mirror of the repository
- works offline
- works even when the repository you push to is down
- works very well with several remote repositories
- fast because most operations are run locally
- branching is easy and even encouraged
- merging is much easier
- allows for better collaboration across teams
- commit early, commit often, commit without fear
- key changes are versioned and safe
- branch for features
- branch for experiments
- branch for testing
- collaborate with others
- no more sharing code on pastebin, email or ping
Try it:
$ git
$ git config --global user.name $USER
$ git config --global user.email $USER@example.com
# Make it look pretty
$ git config --global color.ui true
$ mkdir ~/git-training
$ cd ~/git-training
# this will initialise the git-training directory
# as a git repository
$ git init
Git will reply: Initialized empty Git repository in .git/
.git/
is where Git stores the metadata and object database for the repository- We’ll come back to it later
$ git status
# Nothing to commit
$ touch README
$ git status
(…)
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# README
nothing added to commit but untracked files present (use "git add" to track)
- untracked
- file isn’t under version control
- committed (unmodified)
- file is safely stored in the repository’s database
- modified
- file has changed but hasn’t been committed yet
- staged
- modified file has been marked in its current version as ready to be committed
- git directory
- where committed files live
- working directory
- where modified and untracked files live
- staging (aka index)
- where staged files live
$ git add README
$ git status
(…)
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: README
$ git commit
# Or with an inline commit message
$ git commit -m 'Added README.'
[master (root-commit) 454a516] Added README.
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README
Where:
master
is the branch the file was committed to454a516
is the SHA-1 checksum which uniquely identifies the commit0 files changed, 0 insertions(+), 0 deletions(-)
because the file was empty and git is looking at the file’s contentsmode 100644 README
because the file was added with644
permissions, i.e. world readable but only writeable by the owner (rw-r--r--
)
$ echo 'This is my Git training repository.' > README
$ touch hello
$ 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: README
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# hello
no changes added to commit (use "git add" and/or "git commit -a")
$ git add hello
$ git commit -m "Added hello."
$ git add README
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README
#
Heads up: If you make another change to the file:
$ echo "-- $USER" >> README
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README
#
# 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: README
#
Now README
is listed as both staged and unstaged.
Git stages a file exactly as it is when you run the git add
command. If you commit now, the version of README
as it was when you last ran the git add command is how it will go into the commit, not the version of the file as it looks in your working directory when you run git commit
. If you modify a file after you run git add
, you have to run git add
again to stage the latest version of the file:
$ git add README
$ git commit -m "Added some notes to README."
[master dc1ae3d] Added some notes to README.
1 files changed, 2 insertions(+), 0 deletions(-)
$ echo `date` >> README
$ echo 'Hello World.' > hello
$ git status -s # -s for short output
M README
M hello
$ git diff
diff --git a/README b/README
index 627b264..75a69aa 100644
--- a/README
+++ b/README
@@ -1,2 +1,3 @@
This is my Git training repository.
--castroad
+Mon Apr 2 15:02:28 PDT 2012
diff --git a/hello b/hello
index e69de29..f534deb 100644
--- a/hello
+++ b/hello
@@ -0,0 +1 @@
+Hello World.
$ git add README
$ git diff
diff --git a/hello b/hello
index e69de29..f534deb 100644
--- a/hello
+++ b/hello
@@ -0,0 +1 @@
+Hello World.
After adding the file a regular git diff
doesn’t report any changes to that file. Instead do:
$ git diff --staged
diff --git a/README b/README
index 627b264..75a69aa 100644
--- a/README
+++ b/README
@@ -1,2 +1,3 @@
This is my Git training repository.
--castroad
+Mon Apr 2 15:02:28 PDT 2012
If you want to see all changes since the last commit (including both staged and unstaged files):
$ git diff HEAD
diff --git a/README b/README
index 627b264..75a69aa 100644
--- a/README
+++ b/README
@@ -1,2 +1,3 @@
This is my Git training repository.
--castroad
+Mon Apr 2 15:02:28 PDT 2012
diff --git a/hello b/hello
index e69de29..f534deb 100644
--- a/hello
+++ b/hello
@@ -0,0 +1 @@
+Hello World.
Where HEAD
points to the latest commit (the tip of the branch you’re in).
Sometimes you don’t need the fine grain control the staging area offers and just want to commit all the files you’ve changed.
$ git status -s
M README
M hello
$ git commit -a -m "Added a date to README and 'hello world' to hello."
$ git mv README README.txt
$ git rm hello
Move and delete operations are performed on tracked files so they are automatically staged. Don’t forget to commit the changes.
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: README -> README.txt
# deleted: hello
#
$ git commit -m "Renamed README and deleted hello."
$ git log
commit b736ad1d23ea8449e7cadd8a0c738bfd8dd0049c
Author: Adriano Castro <ad@adrianocastro.net>
Date: Mon Apr 2 15:05:21 2012 -0700
Renamed README and deleted hello.
commit 4ff1af9ac2eae232d732b801a227c66c132a3543
Author: Adriano Castro <ad@adrianocastro.net>
Date: Mon Apr 2 15:05:02 2012 -0700
Added a date to README and 'hello world' to hello.
commit b80e06b60b7db9db9c8e29cd2afad813e84ed444
Author: Adriano Castro <ad@adrianocastro.net>
Date: Mon Apr 2 15:02:25 2012 -0700
Added some notes to README.
(…)
To view the actual changes (for patching, code reviews, etc):
# Show only the last 2 commits
$ git log -p -2
(…)
Other options:
- `--stat`: abbreviated stats for each commit
- `--oneline`: one liner simple output
$ git log --oneline
b736ad1 Renamed README and deleted hello.
4ff1af9 Added a date to README and 'hello world' to hello.
b80e06b Added some notes to README.
5de611b Added hello.
ed7d7ff Added README.
$ git show 4ff1af9
(…)
$ git log --oneline
b736ad1 Renamed README and deleted hello.
4ff1af9 Added a date to README and 'hello world' to hello.
b80e06b Added some notes to README.
5de611b Added hello.
ed7d7ff Added README.
$ git diff b80e06b..4ff1af9
(…)
$ touch test.diff test.wip test.bak
$ mkdir artifacts
$ touch artifacts/report.txt
$ git status -s
?? artifacts/
?? test.bak
?? test.diff
?? test.wip
$ vi .gitignore
1 # Temp files
2 *.bak
3 *.wip
4 *.diff
5
6 # Unnecessary folders
7 artifacts/
$ git status -s
?? .gitignore
$ git add .gitignore
$ git commit -m "Added a .gitignore file."
- Git is not SVN
- It has a staging area
- And uses SHA-1 checksums to identify single commits