You are on page 1of 537

Ofcial

training curriculum v3.1.0

2012, GitHub, Inc.

Git Foundations
An exploration of the Git toolbox

Hello!

cCullough
atthew M
M
mccull
@matthew

Ma hew who?
Open source contributor
Build tool book co-author
Continuous integration book co-author
5 year Git evangelist
VP of Training at GitHub

Questions, Pacing

any time. Don't wait!


Ask questions atpacing slowing/speeding up
Suggest course

Welcome

Git
Wheres this coming from?

Git

Open Source
Git?

bash scripts

C code

Git?


Git?

Git

-noun
asa nt
unple
ng. an
ritish Sla
B
er son
tible p
temp
r con
o
Dictionar y
ord English
-Oxf

name

myself.
ts after
y projec
all m
astard, and I
egotistical b
I'm an

st Linux, now
Fir

git.

inus Torvalds
-L

Git
What is this thing?

cker
upid content tra
GIT - the st
r mood.
depending on you
nything,
any
"git" can mean a
actually used by
t
le, and no
ay not be
t is pronounceab
bination tha
f "get" may or m
etter com
ciation o
* random three-l
t is a mispronun
ct that i
command. The fa
ary of
common UNIX
from the diction
our pick
relevant.
. simple. Take y
espicable
ntemptible and d
or you.
* stupid. co
actually works f
, and it
slang.
e in a good mood
e r" : y o u ' r
nformation track
he room.
* "global i
suddenly fills t
a light
breaks
Angels sing, and
f sh*t": when it
uckload o
ddamn idiotic tr
rich
* "go
ith an unusually
system w
als.
revision control
distributed
access to intern
calable,
and full
Git is a fast, s
level operations
th highthat provides bo
inally
command set
nse. It was orig
blic Lice
ntly
e GNU General Pu
net. It is curre
covered by th
project
round the
oup of hackers a
s an Open Source
Git i
lp of a gr
Torvalds with he
written by Linus
C Hamano.
tained by Junio
main

content tracker
le

centralized version control systems have matured

Git?

Subversion
Perforce

Source
Safe

PVCS

Clear
Case

CVS

RCS
Folders

Git?

small improvements, but no

radical innovation
Git?

Linus?
Git?

a commercial
for 7 years at
up using CVS
I did end
ith a passion...
y and I hate it w
compan
or a while was
of Subversion f
The slogan
tart with that
"... and if you s
done right
"CVS
e you can go.
, there's nowher
kind of slogan

o CVS right.
no way to d
There is

-Linus Torvalds

VCS reboot
Git?

50% Distributed Version Control

with
50% Git Concepts
Git?

1997
code co-op

2001
arch

2003
monotone

2003
SVK

2003
darcs

2005
bazaar

2005
mercurial

2005
git

time to mature

most unique improvements

largest DVCS user base

Setup
Testing Git

Check your Git version...


git --version

Setting up Git

Setup
What is a Git install?

binaries on your $PATH

Setting up Git

Using
Creating a repository

#
$
$
#

Green field project


git init newproject
cd newproject
...start coding

Creating A Repository

Create our rst repository

Creating A Repository

or if you already have source code

Creating A Repository

# Legacy project tree


$ cd existingproject
$ git init
# Add all the code
$ git add .
$ git commit -mInitial import
Creating A Repository

Using
Whats in .git?

.git
!"" COMMIT_EDITMSG
!"" HEAD
!"" MERGE_RR
!"" config
!"" description
!"" hooks
# !"" pre-commit.sample
# $"" update.sample
!"" index
!"" info
# $"" exclude
!"" logs
# !"" HEAD
# $"" refs
#
$"" heads
#
$"" master
!"" objects
# !"" 54
# # $"" 3b9bebdc6bd5c4b22136034a95dd097a57d3dd
# !"" info
# $"" pack
!"" refs
!"" heads
# $"" master
$"" tags
Contents of .git

Explore the .git folder

Three stage thinking

Conguration
Display

Query existing conguration

Conguring Git

All entries

Conguring Git

#List all config values


git config --list

Conguring Git

Single entry

Conguring Git

#Query effective value of a single key


git config section.key
git config section.subsection.key

Conguring Git

#Show a specific config value


git config user.name
git config user.email

Conguring Git

Conguration
Layers

git config --system


#Saves to /etc/gitconfig

Cong Targets

git config --global


#Saves to ~/.gitconfig

Cong Targets

git config --local


#Saves to .git/config

Cong Targets

#Configure a setting in a .git repository

git config __________


git config --local __________
#Configure a setting in the user's home dir

git config --global __________


#Configure a setting in the Git install dir
# e.g. /usr/local/Cellar/git/1.7.x/etc/gitconfig

git config --system __________


Conguring Git

Git conguration reading & writing

targets

local by default
Cong Targets

Conguration
Inheritance

Query existing conguration by layer

Cong Inheritance

#Query a single key in a single layer


git config --<WHERE> section.key
git config --<WHERE> section.subsection.key

Cong Inheritance

#List all system config values


git config --system --list

Cong Inheritance

#List all global config values


git config --global --list

Cong Inheritance

#List all local config values


git config --local --list

Cong Inheritance

#List effective config values


git config --list

Cong Inheritance

Conguration
Set user identity

any cong at any layer

Set User Identity

#List the current config


git config --global user.name "Fird Birfle"
git config --global user.email "fird@birfle.com"

Set User Identity

just a string
Set User Identity

user identity

Set User Identity

identity
not user authentication

Set User Identity

authorization
identity
not user authentication

Set User Identity

Conguration
Display color

console color

Set Console Color

git config --global color.ui always

Set Console Color

git log \
--graph \
--decorate \
--simplify-by-decoration \
--abbrev-commit \
--date=relative \
--pretty=oneline \
--all

Set Console Color

git log \
--graph \
--decorate \
--simplify-by-decoration \
--abbrev-commit \
--date=relative \
--pretty=oneline \
--all \
| more
Conguring Git

Bleh!
Set Console Color

output destination detection

Set Console Color

git config --global color.ui auto

# or the identical effect with...


git config --global color.ui true

Set Console Color

git log \
--graph \
--decorate \
--simplify-by-decoration \
--abbrev-commit \
--date=relative \
--pretty=oneline \
--all \
| more
Set Console Color

Color when you need it

Set Console Color

Color only when you need it

Set Console Color

Conguration
Line endings

line endings

Line Endings

VS
Line Endings

LF

VS
CRLF
Line Endings

default is to do

nothing
Line Endings

http://help.github.com/dealing-with-lineendings/

Line Endings

#Force files to be LF in the repo,


# even on Mac/Linux
git config --global core.autocrlf input

#Force Windows to convert to platform


# on checkout and to LF on commit
git config --global core.autocrlf true

Line Endings

#Force files to be LF during `add`


git config --global core.autocrlf input

#Force Windows to convert to CRLF


# on checkout and to LF on `add`
git config --global core.autocrlf true

Line Endings

warn about conversion

#Never complain about line ending conversion


git config --global core.safecrlf false

#Warn, but allow line ending conversion to proceed


#(the default)
git config --global core.safecrlf warn

#Do not allow line ending conversion to proceed


git config --global core.safecrlf true

Line Endings

Conguration
Secure Sockets Host (SSH)

Generate an ssh key pair

Conguring SSH

ssh key pair


Conguring SSH

$ ssh-keygen -t rsa -CFor GitHub

Conguring SSH

$ ssh-keygen -t rsa -CFor GitHub

Conguring SSH

Conguring SSH

# Verify the files were created


$ cd ~/.ssh
$ ls

Conguring SSH

Conguring SSH

id_rsa is the private half of the key

Keep this uncompromisingly secret

id_rsa.pub is the public half of the key

Give this away freely

Conguring SSH

#GitHub sanity test


ssh -T git@github.com
> Hi matthewmccullough! You've successfully
authenticated, but GitHub does not provide
shell access.

Conguring SSH

#GitHub sanity test with verbose SSH


ssh -v git@github.com
>OpenSSH_5.2p1, OpenSSL 0.9.8l 5 Nov 2009
debug1: Reading configuration data /Users/mccm06/.ssh/config
debug1: Reading configuration data /etc/ssh_config
debug1: Connecting to github.com [207.97.227.239] port 22.
debug1: Connection established.
debug1: identity file /Users/mccm06/.ssh/identity type -1
debug1: identity file /Users/mccm06/.ssh/id_rsa type 1
debug1: identity file /Users/mccm06/.ssh/id_dsa type 2
...
debug1: Host 'github.com' is known and matches the RSA host key.
debug1: Found key in /Users/mccm06/.ssh/known_hosts:3
debug1: ssh_rsa_verify: signature correct
...
debug1: Trying private key: /Users/mccm06/.ssh/identity
debug1: Offering public key: /Users/mccm06/.ssh/id_rsa
debug1: Remote: Forced command: gerve matthewmccullough
Conguring SSH

Using Git
Three Stage Thinking

Edit
Add
Commit
Three stage thinking

Working

Staging

Repo

edit
add
commit
Three stage thinking

Three stage thinking

shopping cart
put things in
take things out
purchase at register

Three stage thinking

database transaction
update values

insert rows

delete rows

commit transaction

Three stage thinking

only

one staging area


Three stage thinking

Working

Staging

Repo

edit
add
commit
Three stage thinking

Setup
Commit Message Editor

Commit Message Editor

Used the VI editor?

I
y
;WQ
Commit Message Editor

an alternate editor?

Commit Message Editor

O
n
io

pt

$EDITOR environment variable

Commit Message Editor

O
n
io

pt

1
$ export EDITOR=<AnEditorOnYourPath>

Commit Message Editor

O
n
io

pt

2
GitPad wraps Notepad (or $EDITOR)

Commit Message Editor

O
n
io

pt

http://github.com/github/GitPad

Commit Message Editor

O
n
io

pt

2
Run GitPad
...registers & wraps Notepad as the editor

Commit Message Editor

O
n
io

pt

Git-specic conguration option

Commit Message Editor

O
n
io

pt

#for TextMate on Mac


git config --global core.editor "mate -w"

3
#for Notepad2 on Windows
git config --global core.editor "notepad2.exe"

#for emacs on Linux


git config --global core.editor "emacs"

Commit Message Editor

O
n
io

pt

3
Commit Message Editor


Make a commit

Test that the new editor pops up

Toggle to alternate editor

Commit Message Editor

Usage Basics
Adding & committing code

$ vi first.html
$ git status
$ git add first.html
$ git commit -mFirst commit
Three stage thinking


Inspect Gits status

Add code (stage it)

Commit code

Write a sample HTML or TXT le

Three stage thinking

Usage Basics
Diff-ing changes

What has changed that we


havent committed?

Three stage thinking

# Show the unstaged changes


$ git diff

Three stage thinking

Working

Staging

Repo

$ git diff
Three stage thinking

# Show the staged changes


$ git diff --staged

Three stage thinking

Working

Staging

Repo

$ git diff --staged


Three stage thinking

# Show uncommitted changes


$ git diff HEAD

Three stage thinking

Working

Staging

Repo

$ git diff HEAD


Three stage thinking

Usage Basics
Limiting diff output

Word changes instead of entire lines?

Limiting Diff Output

git diff --color-words

Limiting Diff Output

$ git diff
diff --git a/first.txt b/first.txt
index cbb1543..e99dea9 100644
--- a/first.txt
+++ b/first.txt
@@ -1,4 +1,4 @@
-//Round the rugged rock
+//Round the ragged rock
$ git diff --color-words
diff --git a/first.txt b/first.txt
index cbb1543..e99dea9 100644
--- a/first.txt
+++ b/first.txt
@@ -1,4 +1,4 @@
//Round the ruggedragged rock
Limiting Diff Output

git diff --word-diff

Limiting Diff Output

$ git diff
diff --git a/first.txt b/first.txt
index cbb1543..e99dea9 100644
--- a/first.txt
+++ b/first.txt
@@ -1,4 +1,4 @@
-//Round the rugged rock
+//Round the ragged rock
$ git diff --word-diff
diff --git a/first.txt b/first.txt
index cbb1543..e99dea9 100644
--- a/first.txt
+++ b/first.txt
@@ -1,4 +1,4 @@
//Round the [-rugged-]{+ragged+} rock
Limiting Diff Output

Usage Basics
Whitespace diff

whitespace suppressed?

Limiting Diff Output

refactoring review
Limiting Diff Output

git diff -w
Limiting Diff Output

$ git diff
diff --git a/first.txt b/first.txt
index 09195c0..f2c3243 100644
--- a/first.txt
+++ b/first.txt
@@ -1,4 +1,4 @@
-//Foo
-//Bar
-//Baz
+ //Foo
+//
Bar
+//Baz
$ git diff -w
$
Limiting Diff Output

Usage Basics
Limiting diff by type

#
#
#
#
#
#
#
#
#

Added (A)
Copied (C)
Deleted (D)
Modified (M)
Renamed (R)
Type changed (T)
Unmerged (U)
Unknown (X)
Pairing Broken (B)

# Only show changes in added files


git diff --diff-filter=A
Limiting Diff Output

#
#
#
#
#
#
#
#
#

Added (A)
Copied (C)
Deleted (D)
Modified (M)
Renamed (R)
Type changed (T)
Unmerged (U)
Unknown (X)
Pairing Broken (B)

# Only show changes in modified files


git diff --diff-filter=M
Limiting Diff Output

#
#
#
#
#
#
#
#
#

Added (A)
Copied (C)
Deleted (D)
Modified (M)
Renamed (R)
Type changed (T)
Unmerged (U)
Unknown (X)
Pairing Broken (B)

# Only show changes in added or modified files


git diff --diff-filter=AM
Limiting Diff Output

$ git status -s -u
D README
MM first.txt
$ git diff --diff-filter=M
diff --git a/first.txt b/first.txt
index 71b55ef..14e4853 100644
--- a/first.txt
+++ b/first.txt
@@ -1,3 +1,3 @@
-//Foo
Only rst.txt is
//Bar
reported
+//Baz

Limiting Diff Output

Usage Basics
Reviewing history

view history of commits

Three stage thinking

# Show all history


git log

Three stage thinking

# Show all history with filenames


git log --stat

Three stage thinking

# Show all history with patches


git log --patch
git log -p

Three stage thinking

# Limit
git log
git log
git log

the output entries


-1
-3
-5

Three stage thinking

# Control the output format


git log --pretty=full

Three stage thinking

# Control the output format


git log --pretty=fuller

Three stage thinking

# Control the output format


git log --pretty=email

Three stage thinking

# Control the output format


git log --pretty=raw

Three stage thinking

# Control the output format


git log --pretty=format:<pattern>

Three stage thinking

# Limit the output to added files


git log --diff-filter=A

Three stage thinking

Usage Basics+
Ignoring les

Ignored

Untracked

Tracked
Unmodied

Tracked
Modied

Tracked
Staged

ignore
add
edit
add
commit
rm

Ignoring Files

suppressing les from being


reported as untracked

Ignoring Files

glob patterns

Ignoring Files

$ vim .gitignore
#Add glob patterns, one per line
*.log
*.tmp

Ignoring Files

in-memory recursive evaluation

Ignoring Files

$ vim .gitignore
#Add glob patterns, one per line
*.log
*.tmp
target
output/
!special.log

Ignoring Files

Ignore les via local .gitignore

Ignoring Files

Usage Basics+
Open source .gitignores

Precongured .gitignore les

Open Source Ignores

http://github.com/github/gitignore
Open Source Ignores

copy and paste


(the one time its OK to do it)

Usage Basics+
Global ignores

Global .gitignore ?

Global Ignore

off by default

Global Ignore

$ git config --global


core.excludesfile "~/.gitignore"

Global Ignore

$ vim ~/.gitignore

# Operating system and editor temp files


# Generally redundant over project .gitignores
thumbs.db
.DS_Store

Global Ignore

Ignore les via global ~/.gitignore

Global Ignore

Usage Basics+
Removing les

Ignored

Untracked

Tracked
Unmodied

Tracked
Modied

Tracked
Staged

ignore
add
edit
add
commit
rm

The Git File Workow

Removing Files

The Git File Workow

# Directly remove & stage


$ git rm <FILENAME>

The Git File Workow

# Remove with OS or tool,


# not integrated with Git
$ rm <FILENAME>
# Staging area says it is
# deleted but not staged
$ git status
# Put deletion into staging
$ git rm <FILENAME>

The Git File Workow

# Remove with OS or tool


# then follow up with git add
$ rm <FILENAMES>
$ git add -u .

The Git File Workow

Remove les

The Git File Workow

Usage Basics+
Moving les

Ignored

Untracked

Tracked
Unmodied

Tracked
Modied

Tracked
Staged

ignore
add
edit
add
commit
rm

The Git File Workow

Moving Files

The Git File Workow

# Directly move & stage


$ git mv <FILENAME> <NEWFILENAME>

The Git File Workow

# Move with OS or tool,


mv <FILENAME> <NEWFILENAME>
# Then follow up with git add
git add -A .

The Git File Workow

Rename (move) les


View history of the move

The Git File Workow

Usage Basics+
Similarity index

no "move" primitive

Similarity Index

similarity index

Similarity Index

score of

sameness
Similarity Index

Usage Basics+
Similarity index for moves

# Move with OS or tool,


$ mv <FILENAME> <NEWFILENAME>
# Follow up by staging everything
$ git add -A .
# Renames showing
git status
# No renames showing?
git log --stat
Similarity Index

why no renames in history?

# Renames shown
git log --stat -M

Similarity Index

Rename (move) les with changes


Essentially, a refactoring workow

Similarity Index

Usage Basics+
Similarity index for copies

# Copies & renames shown


# (superset of -M)
git log --stat -C

Similarity Index

Copy a le to a new lename


Add and commit it
Log it using our -C option

Similarity Index

asons, by
mance re
r perfor
Fo
on finds
, -C opti
default
iginal file
f the or
ies only i
cop
dified in
y was mo
the cop
of
angeset.
same ch
the

Modify a le and copy it (in the same commit)


Log using the -C option

Similarity Index

makes the
-harder flag
find-copies
The -ified files as
pect unmod
command ins
copy. This
source of
ates for the
candid
for large
ive operation
a very expens
is
ion. Giving
it with caut
ts, so use
projec
as the same
-C option h
re than one
mo
effect.

# Copies & renames shown


# (superset of -M)
git log --stat -C -C
git log --stat --find-copies-harder

Similarity Index

Log the same le using our -C -C option

Similarity Index

Usage Basics+
Similarity index for blame

# File authoring shown


git blame rerere.c

Similarity Index

# True source of code shown


git blame rerere.c -C

Similarity Index

5b2fd956
c455c87c
5b2fd956
5b2fd956
dea4562b
dea4562b
dea4562b
8588567c
5b2fd956
ac49f5ca
ac49f5ca
ac49f5ca
ac49f5ca
ac49f5ca
5b2fd956
5b2fd956
5b2fd956
5b2fd956
5b2fd956
5b2fd956
5b2fd956
5b2fd956
90056966
5b2fd956
90056966
5b2fd956
5b2fd956

(Stephan Beyer
(Johannes Schindelin
(Stephan Beyer
(Stephan Beyer
(Junio C Hamano
(Junio C Hamano
(Junio C Hamano
(Junio C Hamano
(Stephan Beyer
(Martin von Zweigbergk
(Martin von Zweigbergk
(Martin von Zweigbergk
(Martin von Zweigbergk
(Martin von Zweigbergk
(Stephan Beyer
(Stephan Beyer
(Stephan Beyer
(Stephan Beyer
(Stephan Beyer
(Stephan Beyer
(Stephan Beyer
(Stephan Beyer
(SZEDER Gbor
(Stephan Beyer
(SZEDER Gbor
(Stephan Beyer
(Stephan Beyer

2008-07-09
2008-07-21
2008-07-09
2008-07-09
2009-12-25
2009-12-25
2009-12-25
2010-01-16
2008-07-09
2011-02-16
2011-02-16
2011-02-16
2011-02-16
2011-02-16
2008-07-09
2008-07-09
2008-07-09
2008-07-09
2008-07-09
2008-07-09
2008-07-09
2008-07-09
2009-02-14
2008-07-09
2009-02-14
2008-07-09
2008-07-09

14:58:57
19:03:49
14:58:57
14:58:57
15:51:32
15:51:32
15:51:32
23:28:46
14:58:57
05:47:44
05:47:44
05:47:44
05:47:44
05:47:44
14:58:57
14:58:57
14:58:57
14:58:57
14:58:57
14:58:57
14:58:57
14:58:57
23:21:04
14:58:57
23:21:04
14:58:57
14:58:57

+0200
+0100
+0200
+0200
-0800
-0800
-0800
-0800
+0200
-0500
-0500
-0500
-0500
-0500
+0200
+0200
+0200
+0200
+0200
+0200
+0200
+0200
+0100
+0200
+0100
+0200
+0200

1)
2)
3)
4)
5)
6)
7)
8)
9)
10)
11)
12)
13)
14)
15)
16)
17)
18)
19)
20)
21)
22)
23)
24)
25)
26)
27)

#include
#include
#include
#include
#include
#include
#include
#include

"cache.h"
"string-list.h"
"rerere.h"
"xdiff-interface.h"
"dir.h"
"resolve-undo.h"
"ll-merge.h"
"attr.h"

#define RESOLVED 0
#define PUNTED 1
#define THREE_STAGED 2
void *RERERE_RESOLVED = &RERERE_RESOLVED;
/* if rerere_enabled == -1, fall back to detection of .git
static int rerere_enabled = -1;
/* automatically update cleanly resolved paths to the inde
static int rerere_autoupdate;
static char *merge_rr_path;
const char *rerere_path(const char *hex, const char *file)
{
return git_path("rr-cache/%s/%s", hex, file);
}

Similarity Index

5b2fd956
c455c87c
5b2fd956
5b2fd956
dea4562b
dea4562b
dea4562b
8588567c
5b2fd956
ac49f5ca
ac49f5ca
ac49f5ca
ac49f5ca
ac49f5ca
b4372ef1
b4372ef1
b4372ef1
121c813f
121c813f
121c813f
658f3650
658f3650
90056966
5b2fd956
90056966
5b2fd956
5b2fd956

rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
builtin-rerere.c
builtin-rerere.c
builtin-rerere.c
builtin-rerere.c
builtin-rerere.c
builtin-rerere.c
builtin-rerere.c
builtin-rerere.c
rerere.c
rerere.c
rerere.c
rerere.c
rerere.c

(Stephan Beyer
(Johannes Schindelin
(Stephan Beyer
(Stephan Beyer
(Junio C Hamano
(Junio C Hamano
(Junio C Hamano
(Junio C Hamano
(Stephan Beyer
(Martin von Zweigbergk
(Martin von Zweigbergk
(Martin von Zweigbergk
(Martin von Zweigbergk
(Martin von Zweigbergk
(Johannes Schindelin
(Johannes Schindelin
(Johannes Schindelin
(Junio C Hamano
(Junio C Hamano
(Junio C Hamano
(Johannes Schindelin
(Johannes Schindelin
(SZEDER Gbor
(Stephan Beyer
(SZEDER Gbor
(Stephan Beyer
(Stephan Beyer

2008-07-09
2008-07-21
2008-07-09
2008-07-09
2009-12-25
2009-12-25
2009-12-25
2010-01-16
2008-07-09
2011-02-16
2011-02-16
2011-02-16
2011-02-16
2011-02-16
2007-07-06
2007-07-06
2007-07-06
2008-06-22
2008-06-22
2008-06-22
2006-12-20
2006-12-20
2009-02-14
2008-07-09
2009-02-14
2008-07-09
2008-07-09

14:58:57
19:03:49
14:58:57
14:58:57
15:51:32
15:51:32
15:51:32
23:28:46
14:58:57
05:47:44
05:47:44
05:47:44
05:47:44
05:47:44
13:05:59
13:05:59
13:05:59
02:04:31
02:04:31
02:04:31
17:39:41
17:39:41
23:21:04
14:58:57
23:21:04
14:58:57
14:58:57

+0200
+0100
+0200
+0200
-0800
-0800
-0800
-0800
+0200
-0500
-0500
-0500
-0500
-0500
+0100
+0100
+0100
-0700
-0700
-0700
+0100
+0100
+0100
+0200
+0100
+0200
+0200

1)
2)
3)
4)
5)
6)
7)
8)
9)
10)
11)
12)
13)
14)
15)
16)
17)
18)
19)
20)
21)
22)
23)
24)
25)
26)
27)

#include
#include
#include
#include
#include
#include
#include
#include

"cache.h"
"string-list.h"
"rerere.h"
"xdiff-interface.h"
"dir.h"
"resolve-undo.h"
"ll-merge.h"
"attr.h"

#define RESOLVED 0
#define PUNTED 1
#define THREE_STAGED 2
void *RERERE_RESOLVED = &RERERE_RESOLVED;
/* if rerere_enabled == -1, fall back to detection of .git
static int rerere_enabled = -1;
/* automatically update cleanly resolved paths to the inde
static int rerere_autoupdate;
static char *merge_rr_path;
const char *rerere_path(const char *hex, const char *file)
{
return git_path("rr-cache/%s/%s", hex, file);
}

Similarity Index

Network
Ofine design

Local repository is a full copy of the remote


Clone fetches all branches and tags
Almost all activities happen ofine (local disk)
Ofine activities are push-ed to remotes
Ofine

More available connectivity

More demand to work without


connectivity?

nice benet,
but wrong reason

Ofine

batched network access

Ofine

Ofine

Checkout a branch
Add changes
Commit changes
Branch changes
Log history
Grep history
Stash pending changes
Tag a commit
Remove a le
Merge a branch
Rewrite history

Ofine

give up incremental revision numbers

Ofine

Using every command ofine

Ofine

Network
Cloning protocols

Git supports many cloning protocols

le
git
ssh
http
Cloning Repositories

le

git clone file://myrepos/project


git clone /myrepos/project

Cloning Repositories

git

git clone git://server/project.git

Cloning Repositories

ssh

git
git

clone git+ssh://user@server:project.git
clone user@server:project.git

Cloning Repositories

http (dumb)

git
git

clone http://server/project.git
clone https://server/project.git

Cloning Repositories

http (smart)

git
git

clone http://server/project.git
clone https://server/project.git

Cloning Repositories

Clone hellogitworld
git clone

Cloning Repositories

Network
Proxy servers

Git Conguration

git

config --global http.proxy <URL>

Cloning Repositories

Network
Speed


hg: mercurial

bzr: bazaar

git: git

Init

Status

Diff
Branch

git

svn

git

Tag

Log

svn

Commit (Lg)

git

svn

Commit (Sm)

git c

git

svn

git

svn

git

svn

git

svn c

svn

data from http://whygitisbetterthanx.com/#git-is-fast

Speed

Add, commit and push 1000 les

Speed

Network
Namespaces

Local

Remote

Upstream

Namespaces

#List local branches


git branch

Namespaces

Local

Remote

Upstream

Namespaces

#List remote branches


git branch -r

Namespaces

Local

Remote

Upstream

Namespaces

#List all branches


git branch -a

Namespaces

Local

Remote

Upstream

Namespaces

#List upstream branches


git ls-remote origin

Namespaces

Local

Remote

Upstream

Namespaces

Network
Namespace operations

Local

clone

Remote

clone

Upstream

clone

commit
push

push
fetch

pull

pull

pull

Namespaces

Network
The commit lifecycle

ll

Pu

Pu

sh

Commit

Namespaces

git

commit

Transactionally save code snapshot


Commit to local branch
Operate on local disk

Namespaces

ll

Pu

Pu

sh

Commit

Namespaces

git push <remote>

Send code to an upstream server


Update remote branches

Namespaces

ll

Pu

Pu

sh

Commit

Namespaces

git

pull <remote>

Retrieve upstream objects


Update remote branch
Merge changes into local branch
Commit the merge to the local branch
Namespaces

Local

clone

Remote

clone

Upstream

clone

commit
push

push
fetch

pull

pull

pull

Namespaces

Network
Remotes

Remotes are just symbolic names

Remotes

You can have as many as you like

Remotes

The default name is origin if youve cloned

Remotes

Remote-tracking branches are locally immutable


(conceptually)

Remotes

Local

Remote

Upstream

Remotes

Adding remotes
Fetching from remotes (upstream)

Remotes

Network
Pruning deletions

Purge remote branches that have been removed from an


upstream repository

git

remote prune <REMOTENAME>


Pruning locally

Deleting upstream branches

Remotes

Architecture
Plumbing and Porcelain

Plumbing and Porcelain

Command Composition

Plumbing is the set of low level utilities

Command Composition

Porcelain is the set of end user commands

Command Composition

Porcelain is comprised of plumbing

Command Composition

Command Composition

Porcelain
Plumbing

git-add git-am git-archive git-bisect git-branch git-bundle gitcheckout git-cherry-pick git-citool git-clean git-clone git-commit
git-describe git-diff git-fetch git-format-patch git-gc git-grep gitgui git-init git-log git-merge git-mv git-notes git-pull git-push gitrebase git-reset git-revert git-rm git-shortlog git-show git-stash
git-status git-submodule git-tag gitk git-config git-fast-export gitfast-import git-filter-branch git-lost-found git-mergetool git-packrefs git-prune git-reflog git-relink git-remote git-repack git-replace
git-repo-config git-annotate git-blame git-cherry git-count-objects
git-difftool git-fsck git-get-tar-commit-id git-help git-instaweb gitmerge-tree git-rerere git-rev-parse git-show-branch git-verify-tag
git-whatchanged git-archimport git-cvsexportcommit git-cvsimport gitcvsserver git-imap-send git-quiltimport git-request-pull git-sendemail git-svn

git-apply git-checkout-index git-commit-tree git-hash-object git-index-pack git-merge-file


git-merge-index git-mktag git-mktree git-pack-objects git-prune-packed git-read-tree gitsymbolic-ref git-unpack-objects git-update-index git-update-ref git-write-tree git-cat-file
git-diff-files git-diff-index git-diff-tree git-for-each-ref git-ls-files git-ls-remote gitls-tree git-merge-base git-name-rev git-pack-redundant git-rev-list git-show-index git-showref git-tar-tree git-unpack-file git-var git-verify-pack git-daemon git-fetch-pack git-httpbackend git-send-pack git-update-server-info git-http-fetch git-http-push git-parse-remote
git-receive-pack git-shell git-upload-archive git-upload-pack git-check-attr git-check-refformat git-fmt-merge-msg git-mailinfo git-mailsplit git-merge-one-file git-patch-id git-peekremote git-sh-setup git-stripspace

pull is comprised of fetch + merge

Command Composition

checkout -b is comprised of branch + checkout

Command Composition

log HEAD is comprised of rev-parse + log

Command Composition

Aliases
Command shortcuts


Create your own recipe

Largely the same as shell aliases

Shortcuts for common commands

Aliases

# Alias for status as 's'


git config --global alias.s "status -u -s"

Aliases

Add an alias

Aliases

# Alias for log with file name as 'l'


git config --global alias.l "log --stat -C"

Aliases

# Alias showing all branches to 'br'


git config --global alias.br "branch -a"

Aliases

# Alias for commit-no-staging to 'cns'


git config --global alias.cns "commit -a"

Aliases

# Alias for shell pull then push to 'sync'


$ git config --global alias.sync
"!git pull && git push"

Aliases

# Alias for crummy-commit-file-quick


$ git config --global alias.ccfq
"!sh -c 'git add $1 && git commit -m\"Placeholder\"' -"

Aliases

Matthew's Aliases

https://github.com/matthewmccullough/git-workshop/blob/master/
workbook/examples/cong/.gitcong

Aliases

Architecture
Storage

Typical SCMs use delta storage

Storage

CVS / Subversion / darcs / Mercurial

Storage

v1

v2

File C

File B

v4

v5

File A

File A
File B

v3

File A

File B

File B

File B

File C

Storage

eck

in

kin

Ch

Checkin

ckin
he

Chec

kin
ec
h

in
k

ec
h

k
in

C
h
ec

C
hec
kin

Delta storage gets slower as the history


longer

kin
e
of ha cle
C

gets

Checkin

Storage

Checkin

Git uses DAG storage

Storage

Directed Acyclic Graph

Storage

Storage

Copy of the entire tree per checkin

Storage

cp -r srcfolder srcfolder.prev

Storage

Why?

Storage

v1

v2

v3

v4

v5

File A

File A

File A

File A

File A

File B

File B

File B

File B

File B

File C

File C

File C

File C

File C

Storage

hard link to existing identical blobs

Storage

v1

v2

v3

v4

v5

File A

File A

File A

File A

File A

File B

File B

File B

File B

File B

File C

File C

File C

File C

File C

Storage

zlib deates each blob at commit

Storage

v1

v2

v3

v4

v5

File A

File A

File A

File A

File A

File B

File B

File B

File B

File B

File C

File C

File C

File C

File C

Storage

zlib deates the entire repo

Storage

v1

v2

v3

v4

v5

File A

File A

File A

File A

File A

File B

File B

File B

File B

File B

File C

File C

File C

File C

File C

Storage

Act I

2100 MB became

205 MB

Storage

Architecture
Hashes

centralized VCSs use sequential revision numbers

Hashes

Git uses a SHA-1 hash

Hashes

Hashes

40 hex characters
(20 bytes)

Hashes

9AB223D28B1AA46EF1780B22F304982E39872C34

Hashes

<html>
<body>
<p>This is a test</p>
<img src="http://ai.com/icon.gif">
</body>
</html>

9AB223D28B1AA46EF1780B22F304982E39872C34

9AB223D28B1AA46EF1780B22F304982E39872C34

Hashes

use as little of it as is unique

Hashes

Architecture
Hash shortcuts

commitish & treeish

Hashes

commitish

= shorthand for commit hashes

Hashes

treeish

= shorthand for tree hashes

Hashes

9AB22F
a certain commit

Hashes

9AB22F^
one commit before a certain commit

Hashes

9AB22F^^
two commits before a certain commit

Hashes

9AB22F~5
ve commits before a certain commit

Hashes

9AB223..56CD77
between these two commits

Hashes

HEAD
the most recent commit on this branch

Hashes

HEAD^
one commit before the most recent commit

Hashes

HEAD~2
two commits before the most recent commit

Hashes

HEAD..HEAD^^^
between the given recent commits

Hashes

master
the most recent commit on this branch

Hashes

master^^
two commits before the most recent commit on this branch

Hashes

master~5
ve commits before the most recent commit on this branch

Hashes

remotes/origin/master
the most recent commit on this remote tracking branch

Hashes

origin/master
the most recent commit on this remote tracking branch

Hashes

Navigate with commitish on


commit, status, & log

Hashes

Architecture
Hash relationships

Blob
Tree
Commit
Tag
Hashes

8d162

blob

c67db

commit

7e8b1
a10b3

tree:
parent:
author:
committer:
message:

a10b3
nil
Fird
Matthew

Major refactoring
of the web content.

tree:
blob:

tree

7e8b1 web
9ab16 index.html

blob:
blob:

tree
8d162 logo.jpg
51d22 draw.js

9ab16

7D 8D B3 7F BD 12 9F E9
7B 78 9D 3F 5C A6 72 CB

51d22

blob

//Some more javascript


var renderSize

blob

<html>

<body></body>
</html>

Hashes

v1
c67db

commit

tree:
parent:
author:
committer:
message:

9a87b
nil
Fird
Matthew

Major refactoring
of the Javascript rendering
engine.

v2
9bd21

commit

tree:
parent:
author:
committer:
message:

b22c1
c67db
Tim
Fird

Minor update to HTML

v3
1c2d7

commit

tree:
parent:
author:
committer:
message:

b22c1
9bd21
Johnny
Joe

New language transations

Hashes

c67db

commit

9bd21

commit

1c2d7

commit

8c2d1

commit
HEAD

RELEASE_1.0

1bdcd

commit

2daa1

commit

bug979branch

Hashes

Branching
Creating branches

default branch name is master

Branches

master doesnt have any special privileges

Branches

Local

Remote

Upstream

Branches

# Creating a branch
git branch <BRANCHNAME>

Branches

c67db

commit

9bd21

commit

1c2d7

commit

8c2d1

commit
HEAD

RELEASE_1.0

1bdcd

commit

2daa1

commit

bug979branch

Create a new local branch from HEAD

Hashes

# Creating a branch
git branch <BRANCHNAME> HEAD

Branches

# Creating a branch
git branch <BRANCHNAME> <REF>

Branches

c67db

commit

9bd21

commit

1c2d7

commit

8c2d1

commit
HEAD

RELEASE_1.0

1bdcd

commit

2daa1

commit

bug979branch

Create a new local branch from a branch

Hashes

Branching
Branch as experiments

What do cheap branches enable?

Branches

Experimentation

Branches


Safe experimentation

Experimentation

Branches

Better reuse of units of work

Branches

Create a branch for an experiment


Delete the failed experiment

Hashes

Branching
Branch frequency

When should you branch?

Branches

The answer is always

Branches

Branches isolate volatile work

Branches

Branches cost a mere 20 bytes

Branches

Weve always wanted to branch often

Its just been too expensive, polluting, or ceremonious

Branches

Show branches on the Git project

Hashes

Branching
Branch lifetimes

Branched by lifetime

Product
Integration
Feature
Story
Idea
Branches

product
integration
feature
story
idea

Branches

product
v1.0 integration
story1

story2

v1.5 integration
story3

Branches

Local

Remote

Upstream

Integ

Integ

Integ

Product

Product

Product

Branches

Local

Remote

Upstream

Feature

Feature

Feature

Integ

Integ

Integ

Product

Product

Product

Idea
Story

Branches

Local

Remote

Upstream

Feature

Feature

Feature

Integ

Integ

Integ

Product

Product

Product

Idea
Story

Branches

Branch from the master branch


Merge from the topic branch
Destroy the topic branch
Branches

Branching
Stashes

super quick branch

Stash

local-only branch
Stash


Stack based implementation

Push, Peek, and Pop operations

Numbered branch

(But has direct entry access too)

Stash

creating a stash
Stash

# Stash your pending changes

git stash

Stash

inspecting the stash


Stash

# List your stashes

git stash list

Stash

noting the stash


Stash

# Stash your pending changes

git stash save <Message>

Stash

# List your stashes

git stash list

Stash

using the stash


Stash

# Merge & delete the latest stash

git stash pop

Stash

# Merge & delete a stash

git stash pop stash@{0}

Stash

# Merge & keep the latest stash

git stash apply

Stash

Stash modied changes


Stash staged changes
Apply stashed changes
Branches

converting a stash
Stash

# Convert a stash to a branch

git stash branch <newbr>

Stash

# Convert a stash to a branch

git stash branch <newbr> stash@{3}

Stash

Convert a stash to a branch

Branches

Tagging
Tag uses

tags as a rst class data type

tagging as a cheap operation

New ways to use tags?

Tagging at each level of approval

Dev
CM
QA
Production

Tagging

Tagging
Tag types

reference,
annotated and
signed tag types
Tagging

Tagging
Reference tag

reference tag...

Tagging

# Tag HEAD
git tag <TAGNAME>

Tagging

# Tag an existing ref


git tag <TAGNAME> <REF>

Tagging

# List known tags


git tag

Tagging

# Show a tags contents


git show tag

Tagging

Tag a revision
Start a branch from a tag

Tagging

Tagging
Annotated tag

annotated tag...

Tagging

git tag -a <TAGNAME>

Tagging

git show <TAGNAME>

Tagging

Tag a revision with an annotated tag

Tagging

Tagging
Signed tag

signed tag...

Tagging

git tag -s <TAGNAME>

Tagging

git show <TAGNAME>

Tagging

Tag a revision with a signed tag

Tagging

Tagging
Transmitting tags

Tags don't

push by default

Tagging

# Push all tags


git push <remote> <tag>

Tagging

# Push all tags


git push --tags

Tagging

Push a specic tag


Push all tags

Tags do

fetch by default

Tagging

Fetch all tags

but the refspec doesnt say to

Tagging

Inspect .git/cong refspec

Merging
The basics

very traditional merge of a branch

Merging

git checkout master


git merge <featurebranch>

Merging

a32

Master/Trunk/MainLatest

e
iv
s
r
u e
c g
e r
R e
M

Bra
nch
d19

2e2
e69

8b3
8b3

e69

9f1

ge
er
M
Merging

strategy: recursive
result: no conicts

a32

Master/Trunk/MainLatest

d
r
a
w
r
o
F
t rge
s e
a
F M

Bra
nch
d19

e69

ge
er
M
Merging

Master/Trunk/MainLatest

F
F e
g
r
e
M

a32

d19

e69

Merging

strategy: recursive
result: fast forward

Bra
nch

a32

Master/Trunk/MainLatest

g
in
t
ic
l
f
n ge
o
r
C
e
M

d19
2e2
e69

8b3
8b3

Fix Conict

e69

9f1

ge
er
M
Merging

strategy: recursive
result: conicting

Merging
Octopus

git checkout master


git merge <fb1> <fb2> <fb3>

Merging

strategy: octopus

Merging
Subtree

git checkout master


git merge -s subtree <fb1>

Merging

git checkout master


git merge --squash -s subtree <fb1>

Merging

strategy: subtree


Merge a remote branch

Merge a local branch

Tagging

Rebasing
What is rebasing?

rebasing is not a merge

Rebasing

rebasing is a preparation for a merge

Rebasing

Merges weave multiple old changes into


a new unifying commit

Rebasing

Rebase reorders the chosen commits


before your branch work

Rebasing

simulates team members taking turns working


(one person at a time)

Rebasing

Rebasing
Rebasing on a branch

git pull --rebase

Rebasing

Retrieve upstream changes and


relocate your local changes to the end

Rebasing

git pull --rebase


# is the same as
git checkout master
git rebase origin/master
Rebasing

git checkout <featurebranch>


git rebase master

Rebasing

a32

Master/Trunk/MainLatest

2e2
8b3

Bra
nch
d19
e69

Rebasing

a32

8b3

Bra
nch
d19
e69

Rebase

Master/Trunk/MainLatest

2e2

Rebasing

a32

8b3

Bra
nch
d19'
e69'

Rebase

Master/Trunk/MainLatest

2e2

Rebasing

a32

8b3

Bra
nch
d19'

ge

r
Me

Master/Trunk/MainLatest

2e2

e69'

Rebasing

Rebase topic branch on master

Rebasing

Rebasing
Interactive rebasing

Rework your work so it


makes sense to the team

Rebasing

git checkout myfeaturebranch


# Replay the last 5 commits
git rebase -i HEAD~5

Rebasing

Master/Trunk/MainLatest

a32
2e2
8b3
d19
e69

Rebasing

Master/Trunk/MainLatest
a32

2e2

d19
e69

Rebasing

Master/Trunk/MainLatest
a32

2e2

d19
e69

Rebasing

Master/Trunk/MainLatest
a32

2e2

d19
e69

Rebasing

Master/Trunk/MainLatest
a32
d19
2e2

e69

Rebasing

Master/Trunk/MainLatest
a32

d19

2e2
e69

Rebasing

Master/Trunk/MainLatest
a32

d19

e69 2e2

Rebasing

Interactively rebase a single branch

Rebasing

Workows
Usage Models

Centralized

Central
Repo

Usage Models

Dictatorship

Blessed
Repo

Usage Models

Certied
Repo
Continuous
Integration
Server

ntegration Managed

Development Repo

Usage Models

Private

Customized

Public

Custom + Public Contrib

GitHub

Usage Models

Certied
Repo

Mirror

Development Repo

Mirrored

Mirror

Usage Models

Undo
Clean

clean purges untracked les


respects ignored and tracked

Clean

# Dry-run remove files

git clean -n

Clean

# Dry-run remove files, dirs

git clean -nd

Clean

# Remove files

git clean -f

Clean

# Remove files, dirs

git clean -fd

Clean

Clean untracked les

Undo

# Also remove ignored files

git clean -xf

Clean

# Also remove ignored files, dirs

git clean -xdf

Clean

# Only list ignored files

git clean -Xn

Clean

# Only remove ignored files

git clean -Xf

Clean

Clean ignored les

Undo

Undo
Revert

revert negates one or more commits

Revert

new commit at the end of HEAD

Revert

no pointer to old ref in revert commit

Revert

comment references the old one

Revert

a32
2e2
8b3
8b3 '
d19'

Revert

a32
2e2
8b3

Re
ve
r

d19'
8b3 '

Revert

# Revert a single commit


git revert <ref>

Revert

Revert a single change

Revert

# Revert a range of commits


git revert <ref1>..<ref2>

Revert

# Revert a range of commits


git revert <old>..<new>

Revert

must have the old..new refs


in the right

order

Revert

Undo
Amend

amend

rewrites the last commit

Amend

git commit --amend

Amend

Amend a bad commit message

Amend

git add <missingfile>


git commit --amend

Amend

Amend a missing le

Amend

Git-SVN
Cloning

Subversion protocol bridge from Git


Round-trip integration
Transactions in Git == transactions in SVN

git-svn

# Clone one branch


git svn clone <svnurl>

git-svn

# Clone all branches, tags


git svn clone --stdlayout <svnurl>

git-svn

Alternate conversion tool

svn2git
https://github.com/nirvdrum/svn2git
Converts tags to Git tags

git-svn

Git-SVN
Updating

Fetch new changes

git

svn rebase

git-svn

Send new changes

git

svn dcommit

git-svn

Git-SVN
SVN Externals

SVN Externals

No direct support
Represented as separate repos
Git points at a stable snapshot
SVN Externals follow changes on a branch

git-svn

Externals cloning process


svn
git
git
git
git

propget svn:externals <MODULE>


svn clone --stdlayout <THEURL>
submodule add <THESUBFOLDER>
submodule init
submodule update

git-svn

SVN Externals helper script

https://github.com/andrep/git-svn-clone-externals

git-svn

Ofcial

training curriculum v3.1.0

2012, GitHub, Inc.

Git Foundations
An exploration of the Git toolbox

@matthewmccull
matthew@github.com
github.com/training

Images sourced from:

AmbientIdeasPhotography.com

Hand Tools

Clock: http://www.ickr.com/photos/7729940@N06/4019157830

Linus Torvalds: http://en.wikipedia.org/wiki/File:Linus_Torvalds.jpeg

Flickr Creative Commons


Wikipedia

Credits

You might also like