Github - Git Training Slides: Foundations

Post on 06-May-2015

1065 Views

Category:

Technology

6 Downloads

Preview:

Click to see full reader

DESCRIPTION

Slide deck with detailed step breakdown that explains how git works, together with simple examples that you can try out yourself. Slides originated from http://teach.github.com/articles/course-slides/ Author: https://twitter.com/matthewmccull

Transcript

Git FoundationsAn exploration of the Git toolbox

Offi

cial

trai

ning

cur

ricul

um v

3.1.

201

2, G

itHub

, Inc

.

Hello!

Matthew McCullough

@matthewmccull

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

Welcome

‣Questions, Pacing‣Ask questions at any time. Don't wait!‣Suggest course pacing slowing/speeding up

GitWhere’s this coming from?

Git

Git?

Open Source

Git?

bash scripts � C code

Git?

Git-nounBritish Slang. an unpleasant

or contemptible person

-Oxford English Dictionary

GitWhat is this thing?

GIT - the stupid content tracker

"git" can mean anything, depending on

your mood.

* random three-letter combination that

is pronounceable, and not actually

used by any

common UNIX command. The fact that it

is a mispronunciation of "get" may or

may not be

relevant.* stupid. contempti

ble and despicable. simple. Take your

pick from the dictionary of

slang.* "global informati

on tracker": you're in a good mood, an

d it actually works for you.

Angels sing, and a light suddenly fill

s the room.

* "goddamn idiotic truckload of sh*t":

when it breaks

Git is a fast, scalable, distributed r

evision control system with an unusual

ly rich

command set that provides both high-le

vel operations and full access to inte

rnals.

Git is an Open Source project covered

by the GNU General Public License. It

was originally

written by Linus Torvalds with help of

a group of hackers around the net. It

is currently

maintained by Junio C Hamano.

file trackercontent

Git?

centralized version control systems have matured

CVS

Subversion

PVCS

Perforce

ClearCaseSource

Safe

RCS

Folders

Git?

small improvements, but noradical innovation

Git?

Linus?

Git?

I did end up using CVS for 7 years at a commercial

company and I hate it with a passion...

The slogan of Subversion for a while was

"CVS done right"... and if you start with that

kind of slogan, there's nowhere you can go.

There is no way to do CVS right.-Linus Torvalds

VCS reboot

Git?

50% Distributed Version Control

Git?

50% Git Concepts

with

1997code co-op

2001arch

2003monotone

2003SVK

2003darcs

2005bazaar

2005mercurial

2005git

time to mature

most unique improvements

largest DVCS user base

SetupTesting Git

Setting up Git

Check your Git version... git --version

SetupWhat is a Git install?

Setting up Git

binaries on your $PATH

UsingCreating a repository

Creating A Repository

# Green field project$ git init newproject$ cd newproject# ...start coding

Creating A Repository

‣Create our first 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 -m”Initial import”

UsingWhat’s in .git?

Contents of .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

Three stage thinking

‣Explore the .git folder

ConfigurationDisplay

Configuring Git

Query existing configuration

Configuring Git

All entries

Configuring Git

#List all config valuesgit config --list

Configuring Git

Single entry

Configuring Git

#Query effective value of a single keygit config section.keygit config section.subsection.key

Configuring Git

#Show a specific config valuegit config user.namegit config user.email

ConfigurationLayers

Config Targets

git config --system#Saves to /etc/gitconfig

Config Targets

git config --global#Saves to ~/.gitconfig

Config Targets

git config --local#Saves to .git/config

Configuring Git

#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 __________

Config Targets

Git configuration reading & writing

targets local by default

ConfigurationInheritance

Config Inheritance

Query existing configuration by layer

Config Inheritance

#Query a single key in a single layergit config --<WHERE> section.keygit config --<WHERE> section.subsection.key

Config Inheritance

#List all system config valuesgit config --system --list

Config Inheritance

#List all global config valuesgit config --global --list

Config Inheritance

#List all local config valuesgit config --local --list

Config Inheritance

#List effective config valuesgit config --list

ConfigurationSet user identity

Set User Identity

any config 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

user identityauthenticationnot

Set User Identity

user identityauthenticationauthorization not

ConfigurationDisplay color

Set Console 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

Configuring Git

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

Set Console Color

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

when you need itColor

Set Console Color

Set Console Color

only when you need itColor

ConfigurationLine endings

Line Endings

line endings

Line Endings

VS

Line Endings

VSLF

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/Linuxgit config --global core.autocrlf input

#Force Windows to convert to platform# on checkout and to LF on commitgit 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

warn about conversion

Line Endings

#Never complain about line ending conversiongit 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 proceedgit config --global core.safecrlf true

ConfigurationSecure Sockets Host (SSH)

Configuring SSH

‣Generate an ssh key pair

Configuring SSH

ssh key pair

Configuring SSH

$ ssh-keygen -t rsa -C”For GitHub”

Configuring SSH

$ ssh-keygen -t rsa -C”For GitHub”

Configuring SSH

Configuring SSH

# Verify the files were created

$ cd ~/.ssh$ ls

Configuring SSH

Configuring 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

Configuring SSH

#GitHub sanity testssh -T git@github.com

> Hi matthewmccullough! You've successfully authenticated, but GitHub does not provide shell access.

Configuring SSH

#GitHub sanity test with verbose SSHssh -v git@github.com

>OpenSSH_5.2p1, OpenSSL 0.9.8l 5 Nov 2009debug1: Reading configuration data /Users/mccm06/.ssh/configdebug1: Reading configuration data /etc/ssh_configdebug1: Connecting to github.com [207.97.227.239] port 22.debug1: Connection established.debug1: identity file /Users/mccm06/.ssh/identity type -1debug1: identity file /Users/mccm06/.ssh/id_rsa type 1debug1: 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:3debug1: ssh_rsa_verify: signature correct...debug1: Trying private key: /Users/mccm06/.ssh/identitydebug1: Offering public key: /Users/mccm06/.ssh/id_rsadebug1: Remote: Forced command: gerve matthewmccullough

Using GitThree Stage Thinking

Three stage thinking

‣Edit‣Add‣Commit

Three stage thinking

Working Staging Repo

add

commit

edit

Three stage thinking

‣shopping cart‣put things in‣take things out‣purchase at register

Three stage thinking

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

add

commit

edit

SetupCommit Message Editor

Commit Message Editor

✓? Used the VI editor?

Commit Message Editor

Iy;WQ

Commit Message Editor

an alternate editor?

Commit Message Editor

$EDITOR environment variable

Option 1

Commit Message Editor

$ export EDITOR=<AnEditorOnYourPath>

Option 1

Commit Message Editor

GitPad wraps Notepad (or $EDITOR)

Option 2

Commit Message Editor

http://github.com/github/GitPad

Option 2

Commit Message Editor

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

Option 2

Commit Message Editor

Git-specific configuration option

Option 3

Commit Message Editor

#for TextMate on Macgit config --global core.editor "mate -w"

#for Notepad2 on Windowsgit config --global core.editor "notepad2.exe"

#for emacs on Linuxgit config --global core.editor "emacs"

Option 3

Commit Message Editor

Option 3

Commit Message Editor

‣Toggle to alternate editor

‣Make a commit

‣Test that the new editor pops up

Usage BasicsAdding & committing code

Three stage thinking

$ vi first.html

$ git status$ git add first.html$ git commit -m”First commit”

Three stage thinking

‣Write a sample HTML or TXT file

‣Inspect Git’s status

‣Add code (stage it)

‣Commit code

Usage BasicsDiff-ing changes

Three stage thinking

What has changed that we haven’t 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

Usage BasicsLimiting diff output

Limiting Diff Output

Word changes instead of entire lines?

Limiting Diff Output

git diff --color-words

Limiting Diff Output

$ git diffdiff --git a/first.txt b/first.txtindex cbb1543..e99dea9 100644--- a/first.txt+++ b/first.txt@@ -1,4 +1,4 @@-//Round the rugged rock+//Round the ragged rock

$ git diff --color-wordsdiff --git a/first.txt b/first.txtindex 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 diffdiff --git a/first.txt b/first.txtindex cbb1543..e99dea9 100644--- a/first.txt+++ b/first.txt@@ -1,4 +1,4 @@-//Round the rugged rock+//Round the ragged rock

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

Usage BasicsWhitespace diff

Limiting Diff Output

whitespace suppressed?

Limiting Diff Output

refactoring review

Limiting Diff Output

git diff -w

Limiting Diff Output

$ git diffdiff --git a/first.txt b/first.txtindex 09195c0..f2c3243 100644--- a/first.txt+++ b/first.txt@@ -1,4 +1,4 @@-//Foo-//Bar-//Baz+ //Foo+// Bar+//Baz▊

$ git diff -w$

Usage BasicsLimiting diff by type

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 filesgit 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 filesgit 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 filesgit diff --diff-filter=AM

Limiting Diff Output

$ git status -s -u

D READMEMM first.txt

$ git diff --diff-filter=M

diff --git a/first.txt b/first.txtindex 71b55ef..14e4853 100644--- a/first.txt+++ b/first.txt@@ -1,3 +1,3 @@-//Foo //Bar+//Baz

Only first.txt is reported

Usage BasicsReviewing history

Three stage thinking

view history of commits

Three stage thinking

# Show all historygit log

Three stage thinking

# Show all history with filenamesgit log --stat

Three stage thinking

# Show all history with patchesgit log --patchgit log -p

Three stage thinking

# Limit the output entriesgit log -1git log -3git log -5

Three stage thinking

# Control the output formatgit log --pretty=full

Three stage thinking

# Control the output formatgit log --pretty=fuller

Three stage thinking

# Control the output formatgit log --pretty=email

Three stage thinking

# Control the output formatgit log --pretty=raw

Three stage thinking

# Control the output formatgit log --pretty=format:<pattern>

Three stage thinking

# Limit the output to added filesgit log --diff-filter=A

Usage Basics+Ignoring files

Ignoring Files

Untracked TrackedUnmodified

TrackedModified

TrackedStaged

Ignored

commit

add

edit

add

rm

ignore

Ignoring Files

suppressing files 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*.tmptargetoutput/!special.log

Ignoring Files

‣ Ignore files via local .gitignore

Usage Basics+Open source .gitignores

Open Source Ignores

Preconfigured .gitignore files

Open Source Ignores

http://github.com/github/gitignore

copy and paste(the one time it’s OK to do it)

Usage Basics+Global ignores

Global Ignore

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 .gitignoresthumbs.db.DS_Store

Global Ignore

‣ Ignore files via global ~/.gitignore

Usage Basics+Removing files

The Git File Workflow

Untracked TrackedUnmodified

TrackedModified

TrackedStaged

Ignored

commit

add

edit

add

rm

ignore

The Git File Workflow

Removing Files

The Git File Workflow

# Directly remove & stage$ git rm <FILENAME>

The Git File Workflow

# 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 Workflow

# Remove with OS or tool# then follow up with git add$ rm <FILENAMES>$ git add -u .

The Git File Workflow

‣ Remove files

Usage Basics+Moving files

The Git File Workflow

Untracked TrackedUnmodified

TrackedModified

TrackedStaged

Ignored

commit

add

edit

add

rm

ignore

The Git File Workflow

Moving Files

The Git File Workflow

# Directly move & stage$ git mv <FILENAME> <NEWFILENAME>

The Git File Workflow

# Move with OS or tool,mv <FILENAME> <NEWFILENAME># Then follow up with git addgit add -A .

The Git File Workflow

‣ Rename (move) files

‣ View history of the move

Usage Basics+Similarity index

Similarity Index

no "move" primitive

Similarity Index

“similarity index”

Similarity Index

score of sameness

Usage Basics+Similarity index for moves

Similarity Index

# Move with OS or tool,$ mv <FILENAME> <NEWFILENAME>

# Follow up by staging everything$ git add -A .

# Renames showinggit status

# No renames showing?git log --stat

why no renames in history?

Similarity Index

# Renames showngit log --stat -M

Similarity Index

‣ Rename (move) files with changes

‣ Essentially, a refactoring workflow

Usage Basics+Similarity index for copies

Similarity Index

# Copies & renames shown# (superset of -M)git log --stat -C

Similarity Index

‣Copy a file to a new filename

‣ Add and commit it

‣ Log it using our -C option

“For performance reasons, by

default, -C option finds copies only if the original file

of the copy was modified in

the same changeset. ”

Similarity Index

‣Modify a file and copy it (in the same commit)

‣ Log using the -C option

“ The --find-copies-harder flag makes the

command inspect unmodified files as

candidates for the source of copy. This

is a very expensive operation for large

projects, so use it with caution. Giving

more than one -C option has the same

effect.”

Similarity Index

# Copies & renames shown# (superset of -M)git log --stat -C -Cgit log --stat --find-copies-harder

Similarity Index

‣ Log the same file using our -C -C option

Usage Basics+Similarity index for blame

Similarity Index

# File authoring showngit blame rerere.c

Similarity Index

# True source of code showngit blame rerere.c -C

Similarity Index

5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 1) #include "cache.h"c455c87c (Johannes Schindelin 2008-07-21 19:03:49 +0100 2) #include "string-list.h"5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 3) #include "rerere.h"5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 4) #include "xdiff-interface.h"dea4562b (Junio C Hamano 2009-12-25 15:51:32 -0800 5) #include "dir.h"dea4562b (Junio C Hamano 2009-12-25 15:51:32 -0800 6) #include "resolve-undo.h"dea4562b (Junio C Hamano 2009-12-25 15:51:32 -0800 7) #include "ll-merge.h"8588567c (Junio C Hamano 2010-01-16 23:28:46 -0800 8) #include "attr.h"5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 9) ac49f5ca (Martin von Zweigbergk 2011-02-16 05:47:44 -0500 10) #define RESOLVED 0ac49f5ca (Martin von Zweigbergk 2011-02-16 05:47:44 -0500 11) #define PUNTED 1ac49f5ca (Martin von Zweigbergk 2011-02-16 05:47:44 -0500 12) #define THREE_STAGED 2ac49f5ca (Martin von Zweigbergk 2011-02-16 05:47:44 -0500 13) void *RERERE_RESOLVED = &RERERE_RESOLVED;ac49f5ca (Martin von Zweigbergk 2011-02-16 05:47:44 -0500 14) 5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 15) /* if rerere_enabled == -1, fall back to detection of .git5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 16) static int rerere_enabled = -1;5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 17) 5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 18) /* automatically update cleanly resolved paths to the inde5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 19) static int rerere_autoupdate;5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 20) 5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 21) static char *merge_rr_path;5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 22) 90056966 (SZEDER Gábor 2009-02-14 23:21:04 +0100 23) const char *rerere_path(const char *hex, const char *file)5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 24) {90056966 (SZEDER Gábor 2009-02-14 23:21:04 +0100 25) return git_path("rr-cache/%s/%s", hex, file);5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 26) }5b2fd956 (Stephan Beyer 2008-07-09 14:58:57 +0200 27)

Similarity Index

5b2fd956 rerere.c (Stephan Beyer 2008-07-09 14:58:57 +0200 1) #include "cache.h"c455c87c rerere.c (Johannes Schindelin 2008-07-21 19:03:49 +0100 2) #include "string-list.h"5b2fd956 rerere.c (Stephan Beyer 2008-07-09 14:58:57 +0200 3) #include "rerere.h"5b2fd956 rerere.c (Stephan Beyer 2008-07-09 14:58:57 +0200 4) #include "xdiff-interface.h"dea4562b rerere.c (Junio C Hamano 2009-12-25 15:51:32 -0800 5) #include "dir.h"dea4562b rerere.c (Junio C Hamano 2009-12-25 15:51:32 -0800 6) #include "resolve-undo.h"dea4562b rerere.c (Junio C Hamano 2009-12-25 15:51:32 -0800 7) #include "ll-merge.h"8588567c rerere.c (Junio C Hamano 2010-01-16 23:28:46 -0800 8) #include "attr.h"5b2fd956 rerere.c (Stephan Beyer 2008-07-09 14:58:57 +0200 9) ac49f5ca rerere.c (Martin von Zweigbergk 2011-02-16 05:47:44 -0500 10) #define RESOLVED 0ac49f5ca rerere.c (Martin von Zweigbergk 2011-02-16 05:47:44 -0500 11) #define PUNTED 1ac49f5ca rerere.c (Martin von Zweigbergk 2011-02-16 05:47:44 -0500 12) #define THREE_STAGED 2ac49f5ca rerere.c (Martin von Zweigbergk 2011-02-16 05:47:44 -0500 13) void *RERERE_RESOLVED = &RERERE_RESOLVED;ac49f5ca rerere.c (Martin von Zweigbergk 2011-02-16 05:47:44 -0500 14) b4372ef1 builtin-rerere.c (Johannes Schindelin 2007-07-06 13:05:59 +0100 15) /* if rerere_enabled == -1, fall back to detection of .gitb4372ef1 builtin-rerere.c (Johannes Schindelin 2007-07-06 13:05:59 +0100 16) static int rerere_enabled = -1;b4372ef1 builtin-rerere.c (Johannes Schindelin 2007-07-06 13:05:59 +0100 17) 121c813f builtin-rerere.c (Junio C Hamano 2008-06-22 02:04:31 -0700 18) /* automatically update cleanly resolved paths to the inde121c813f builtin-rerere.c (Junio C Hamano 2008-06-22 02:04:31 -0700 19) static int rerere_autoupdate;121c813f builtin-rerere.c (Junio C Hamano 2008-06-22 02:04:31 -0700 20) 658f3650 builtin-rerere.c (Johannes Schindelin 2006-12-20 17:39:41 +0100 21) static char *merge_rr_path;658f3650 builtin-rerere.c (Johannes Schindelin 2006-12-20 17:39:41 +0100 22) 90056966 rerere.c (SZEDER Gábor 2009-02-14 23:21:04 +0100 23) const char *rerere_path(const char *hex, const char *file)5b2fd956 rerere.c (Stephan Beyer 2008-07-09 14:58:57 +0200 24) {90056966 rerere.c (SZEDER Gábor 2009-02-14 23:21:04 +0100 25) return git_path("rr-cache/%s/%s", hex, file);5b2fd956 rerere.c (Stephan Beyer 2008-07-09 14:58:57 +0200 26) }5b2fd956 rerere.c (Stephan Beyer 2008-07-09 14:58:57 +0200 27)

NetworkOffline design

Offline

‣ Local repository is a full copy of the remote

‣Clone fetches all branches and tags

‣Almost all activities happen offline (local disk)

‣Offline activities are push-ed to remotes

More available connectivity

More demand to work without connectivity?

Offline

nice benefit,but wrong reason

Offline

batched network access

Offline

Offline

Checkout a branchAdd changesCommit changesBranch changesLog historyGrep historyStash pending changesTag a commitRemove a fileMerge a branchRewrite history

Offline

give up incremental revision numbers

Offline

‣ Using every command offline

NetworkCloning protocols

Cloning Repositories

‣Git supports many cloning protocols‣file‣git‣ssh‣http

Cloning Repositories

‣file‣git clone file://myrepos/project‣git clone /myrepos/project

Cloning Repositories

‣git‣git clone git://server/project.git

Cloning Repositories

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

‣ git clone user@server:project.git

Cloning Repositories

‣http (dumb)‣ git clone http://server/project.git‣ git clone https://server/project.git

Cloning Repositories

‣http (smart)‣git clone http://server/project.git‣git clone https://server/project.git

Cloning Repositories

‣ Clone hellogitworld

‣ git clone

NetworkProxy servers

Cloning Repositories

‣Git Configuration‣ git config --global http.proxy “<URL>”

NetworkSpeed

‣git: git‣hg: mercurial‣bzr: bazaar

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

git svn

Init

git svn

Status

git svn

Diff

git svn

Tag

git svn

Log

git svn

Commit (Lg)

git svn

Commit (Sm)

git c svn c

Branch

Speed

Speed

‣ Add, commit and push 1000 files

NetworkNamespaces

Namespaces

Local Remote Upstream

Namespaces

#List local branchesgit branch

Namespaces

Local Remote Upstream

Namespaces

#List remote branchesgit branch -r

Namespaces

Local Remote Upstream

Namespaces

#List all branchesgit branch -a

Namespaces

Local Remote Upstream

Namespaces

#List upstream branchesgit ls-remote origin

Namespaces

Local Remote Upstream

NetworkNamespace operations

Namespaces

Local Remote Upstream

commit

fetch

push

clone clone clone

push

pull pull pull

NetworkThe commit lifecycle

Namespaces

Commit

Push

Pull

Namespaces

‣git commit

‣ Transactionally save code snapshot‣Commit to local branch‣Operate on local disk

Namespaces

Commit

Push

Pull

Namespaces

‣git push <remote>

‣Send code to an upstream server‣Update remote branches

Namespaces

Commit

Push

Pull

Namespaces

‣git pull <remote>

‣ Retrieve upstream objects‣ Update remote branch‣Merge changes into local branch‣ Commit the merge to the local branch

Namespaces

Local Remote Upstream

commit

fetch

push

clone clone clone

push

pull pull pull

NetworkRemotes

Remotes

Remotes are just symbolic names

Remotes

You can have as many as you like

Remotes

The default name is origin if you’ve cloned

Remotes

Remote-tracking branches are locally immutable (conceptually)

Remotes

Local Remote Upstream

Remotes

‣ Adding remotes

‣ Fetching from remotes (upstream)

NetworkPruning deletions

‣ Purge remote branches that have been removed from an upstream repository

‣ git remote prune <REMOTENAME>

Remotes

‣Deleting upstream branches

‣Pruning locally

ArchitecturePlumbing 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

git-add git-am git-archive git-bisect git-branch git-bundle git-checkout git-cherry-pick git-citool git-clean git-clone git-commit

git-describe git-diff git-fetch git-format-patch git-gc git-grep git-gui git-init git-log git-merge git-mv git-notes git-pull git-push git-

rebase git-reset git-revert git-rm git-shortlog git-show git-stash git-status git-submodule git-tag gitk git-config git-fast-export git-fast-import git-filter-branch git-lost-found git-mergetool git-pack-refs 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 git-merge-tree git-rerere git-rev-parse git-show-branch git-verify-tag

git-whatchanged git-archimport git-cvsexportcommit git-cvsimport git-cvsserver git-imap-send git-quiltimport git-request-pull git-send-

email git-svnPo

rcel

ain

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 git-

symbolic-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 git-ls-tree git-merge-base git-name-rev git-pack-redundant git-rev-list git-show-index git-show-ref git-tar-tree git-unpack-file git-var git-verify-pack git-daemon git-fetch-pack git-http-backend 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-ref-

format git-fmt-merge-msg git-mailinfo git-mailsplit git-merge-one-file git-patch-id git-peek-remote git-sh-setup git-stripspace

Plum

bing

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

AliasesCommand shortcuts

Aliases

‣Shortcuts for common commands

‣Create your own recipe

‣Largely the same as shell aliases

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/config/.gitconfig

ArchitectureStorage

Typical SCMs use delta storage

Storage

CVS / Subversion / darcs / Mercurial

Storage

Storage

v1 v2 v3 v4

File A

File B

File C

File A

File B File B

File C

v5

File A

File BFile B

Δ Δ

ΔΔ ΔΔΔ

Checkin

Checkin Checkin Che

ckin

Che

ckin

Che

ckin

Che

ckin

Che

ckin

Check

in

Checkin

Checkin

Delta storage gets slower as the history of a file gets longer

Storage

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

Storage

v1 v2 v3 v4

File A

File B

File C

File A

File B File B

File C

v5

File A

File BFile B

File A File A

File C File C File C

hard link to existing identical blobs

Storage

Storage

v1 v2 v3 v4

File A

File B

File C

File A

File B File B

File C

v5

File A

File BFile B

File A File A

File C File C File Cß

zlib deflates each blob at commit

Storage

Storage

v1 v2 v3 v4

File A

File B

File C

File A

File B File B

File C

v5

File A

File BFile B

File A File A

File C File C File C

zlib deflates the entire repo

Storage

Storage

v1 v2 v3 v4

File A

File B

File C

File A

File B File B

File C

v5

File A

File BFile B

File A File A

File C File C File C

Storage

2100 MB became 205 MB

Act I

ArchitectureHashes

Hashes

centralized VCSs use sequential revision numbers

Hashes

Git uses a SHA-1 hash

Hashes

40 hex characters (20 bytes)

Hashes

9AB223D28B1AA46EF1780B22F304982E39872C34

Hashes

Hashes

9AB223D28B1AA46EF1780B22F304982E39872C34

<html><body>

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

</body></html>

9AB223D28B1AA46EF1780B22F304982E39872C34

use as little of it as is unique

Hashes

ArchitectureHash shortcuts

commitish & treeish

Hashes

commitish

Hashes

= shorthand for commit hashes

treeish

Hashes

= shorthand for tree hashes

9AB22Fa certain commit

Hashes

9AB22F^one commit before a certain commit

Hashes

9AB22F^^two commits before a certain commit

Hashes

9AB22F~5five commits before a certain commit

Hashes

9AB223..56CD77between these two commits

Hashes

HEADthe most recent commit on this branch

Hashes

HEAD^one commit before the most recent commit

Hashes

HEAD~2two commits before the most recent commit

Hashes

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

Hashes

masterthe most recent commit on this branch

Hashes

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

Hashes

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

Hashes

remotes/origin/masterthe most recent commit on this remote tracking branch

Hashes

origin/masterthe most recent commit on this remote tracking branch

Hashes

Hashes

Navigate with commitish oncommit, status, & log

ArchitectureHash relationships

Hashes

‣Blob‣Tree‣Commit‣Tag

Hashes

treetree: 7e8b1 webblob: 9ab16 index.html

a10b3 treeblob: 8d162 logo.jpgblob: 51d22 draw.js

7e8b1commit

tree: a10b3parent: nilauthor: Firdcommitter: Matthewmessage:

Major refactoringof the web content.

c67db

blob<html>

<body></body></html>

9ab16

blob//Some more javascriptvar renderSize

51d22

blob7D 8D B3 7F BD 12 9F E97B 78 9D 3F 5C A6 72 CB

8d162

Hashes

v1 v2 v3

committree: 9a87bparent: nilauthor: Firdcommitter: Matthewmessage:

Major refactoringof the Javascript renderingengine.

c67db

committree: b22c1parent: c67dbauthor: Timcommitter: Firdmessage:

Minor update to HTML

9bd21

committree: b22c1parent: 9bd21author: Johnnycommitter: Joemessage:

New language transations

1c2d7

Hashes

RELEASE_1.0 HEAD

bug979branch

commitc67db

commit9bd21

commit1c2d7

commit8c2d1

commit1bdcd

commit2daa1

BranchingCreating branches

Branches

default branch name is master

Branches

master doesn’t have any special privileges

Branches

Local Remote Upstream

Branches

# Creating a branchgit branch <BRANCHNAME>

RELEASE_1.0 HEAD

bug979branch

commitc67db

commit9bd21

commit1c2d7

commit8c2d1

commit1bdcd

commit2daa1

Hashes

‣Create a new local branch from HEAD

Branches

# Creating a branchgit branch <BRANCHNAME> HEAD

Branches

# Creating a branchgit branch <BRANCHNAME> <REF>

RELEASE_1.0 HEAD

bug979branch

commitc67db

commit9bd21

commit1c2d7

commit8c2d1

commit1bdcd

commit2daa1

Hashes

‣Create a new local branch from a branch

BranchingBranch as experiments

Branches

What do cheap branches enable?

Branches

‣Experimentation

Branches

‣Experimentation

‣Safe experimentation

Branches

Better reuse of units of work

Hashes

‣Create a branch for an experiment

‣Delete the failed experiment

BranchingBranch frequency

Branches

When should you branch?

Branches

The answer is always

Branches

Branches isolate volatile work

Branches

Branches cost a mere 20 bytes

Branches

We’ve always wanted to branch oftenIt’s just been too expensive, polluting, or ceremonious

Hashes

‣Show branches on the Git project

BranchingBranch lifetimes

Branches

‣Branched by lifetime‣ Product‣ Integration‣ Feature‣ Story‣ Idea

Branches

product

integration

feature

story

idea

product

v1.0 integration

story1 story2

v1.5 integration

story3

Branches

Branches

Local Remote Upstream

Integ

Product

Integ

Product

Integ

Product

Branches

Local Remote Upstream

Idea

Story

Feature FeatureFeature

Integ

Product

Integ

Product

Integ

Product

Branches

Local Remote Upstream

Idea

Story

Feature FeatureFeature

Integ

Product

Integ

Product

Integ

Product

Branches

‣Branch from the master branch

‣Merge from the topic branch

‣Destroy the topic branch

BranchingStashes

Stash

super quick branch

Stash

local-only branch

Stash

‣Numbered branch‣Stack based implementation‣Push, Peek, and Pop operations

(But has direct entry access too)

Stash

creating a stash

Stash

# Stash your pending changesgit stash

Stash

inspecting the stash

Stash

# List your stashesgit stash list

Stash

noting the stash

Stash

# Stash your pending changesgit stash save “<Message>”

Stash

# List your stashesgit stash list

Stash

using the stash

Stash

# Merge & delete the latest stashgit stash pop

Stash

# Merge & delete a stashgit stash pop stash@{0}

Stash

# Merge & keep the latest stashgit stash apply

Branches

‣Stash modified changes

‣Stash staged changes

‣Apply stashed changes

Stash

converting a stash

Stash

# Convert a stash to a branchgit stash branch <newbr>

Stash

# Convert a stash to a branchgit stash branch <newbr> stash@{3}

Branches

‣Convert a stash to a branch

TaggingTag uses

tags as a first class data type

tagging as a cheap operation

New ways to use tags?

Tagging

‣Tagging at each level of approval‣Dev‣CM‣QA‣Production

TaggingTag types

Tagging

reference, annotated and signed tag types

TaggingReference tag

Tagging

reference tag...

Tagging

# Tag HEADgit tag <TAGNAME>

Tagging

# Tag an existing refgit tag <TAGNAME> <REF>

Tagging

# List known tagsgit tag

Tagging

# Show a tag’s contentsgit show tag

Tagging

‣Tag a revision

‣Start a branch from a tag

TaggingAnnotated tag

Tagging

annotated tag...

Tagging

git tag -a <TAGNAME>

Tagging

git show <TAGNAME>

Tagging

‣Tag a revision with an annotated tag

TaggingSigned tag

Tagging

signed tag...

Tagging

git tag -s <TAGNAME>

Tagging

git show <TAGNAME>

Tagging

‣Tag a revision with a signed tag

TaggingTransmitting tags

Tagging

Tags don't push by default

Tagging

# Push all tagsgit push <remote> <tag>

Tagging

# Push all tagsgit push --tags

‣Push a specific tag‣Push all tags

Tagging

Tags do fetch by default

‣Fetch all tags

Tagging

but the refspec doesn’t say to

‣Inspect .git/config refspec

MergingThe basics

Merging

very traditional merge of a branch

Merging

git checkout mastergit merge <featurebranch>

a32

2e2

e69

d19

8b3

Branch

Mas

ter/T

runk

/Mai

nLat

est

Merging

Recursive

Merge

9f1 Mergee698b3

strategy: recursiveresult: no conflicts

a32

e69

d19

Branch

Mas

ter/T

runk

/Mai

nLat

est

Merging

Fast Forward

Merge

Merge

a32

e69

d19

Mas

ter/T

runk

/Mai

nLat

est

Merging

FF

Merge

strategy: recursiveresult: fast forward

a32

2e2

e69

d19

8b3

Branch

Mas

ter/T

runk

/Mai

nLat

est

Merging

Conflicting

Merge

Merge

9f1e698b3

Fix Conflict

strategy: recursiveresult: conflicting

MergingOctopus

Merging

git checkout mastergit merge <fb1> <fb2> <fb3>

strategy: octopus

MergingSubtree

Merging

git checkout mastergit merge -s subtree <fb1>

Merging

git checkout mastergit merge --squash -s subtree <fb1>

strategy: subtree

Tagging

‣Merge a local branch‣Merge a remote branch

RebasingWhat is rebasing?

rebasing is not a merge

Rebasing

rebasing is a preparation for a merge

Rebasing

Merges weave multiple old changes intoa 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

RebasingRebasing on a branch

Rebasing

git pull --rebase

Retrieve upstream changes and relocate your local changes to the end

Rebasing

Rebasing

git pull --rebase

# is the same asgit checkout mastergit rebase origin/master

Rebasing

git checkout <featurebranch>git rebase master

a32

2e2

8b3

Mas

ter/

Trun

k/M

ainL

ates

t

Rebasing

e69

d19

Branch

a32

2e2

8b3

e69

d19

Branch

Mas

ter/

Trun

k/M

ainL

ates

t

Rebase

Rebasing

a32

2e2

e69'

d19'

8b3 Branch

Mas

ter/

Trun

k/M

ainL

ates

t

Rebasing

Rebase

a32

2e2

e69'

d19'

8b3 Branch

Mas

ter/

Trun

k/M

ainL

ates

t

Merge

Rebasing

Rebasing

‣Rebase topic branch on master

RebasingInteractive rebasing

Rework your work so it makes sense to the team

Rebasing

Rebasing

git checkout myfeaturebranch# Replay the last 5 commitsgit rebase -i HEAD~5

a32

2e2

8b3

Mas

ter/

Trun

k/M

ainL

ates

t

Rebasing

e69

d19

a32

2e2

Mas

ter/

Trun

k/M

ainL

ates

t

Rebasing

e69

d19

a32

2e2

Mas

ter/

Trun

k/M

ainL

ates

t

Rebasing

e69

d19

a32

2e2

Mas

ter/

Trun

k/M

ainL

ates

t

Rebasing

e69

d19

a32

2e2

Mas

ter/

Trun

k/M

ainL

ates

t

Rebasing

e69

d19

a32

2e2

Mas

ter/

Trun

k/M

ainL

ates

t

Rebasing

e69

d19

a32

Mas

ter/

Trun

k/M

ainL

ates

t

Rebasing

e69

d19

2e2

Rebasing

‣Interactively rebase a single branch

WorkflowsUsage Models

Usage Models

Central Repo

Ce

nt

ra

liz

ed

Usage Models

Blessed Repo

Dic

ta

to

rs

hip

Usage Models

Certified Repo

Development Repo

Int

eg

ra

tio

n M

an

ag

ed

ContinuousIntegration

Server

Usage Models

Cu

st

om

+ P

ub

lic

Co

nt

rib

Customized

� P

riva

te

Pub

lic �

GitHub

Usage Models

Mirror

Development Repo

Mir

ro

re

d

Mirror

Certified Repo

UndoClean

Clean

clean purges untracked files

respects ignored and tracked

Clean

# Dry-run remove filesgit clean -n

Clean

# Dry-run remove files, dirsgit clean -nd

Clean

# Remove filesgit clean -f

Clean

# Remove files, dirsgit clean -fd

Undo

‣Clean untracked files

Clean

# 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

Undo

‣Clean ignored files

UndoRevert

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

8b3 '

Revert

a32

2e2

d19'

8b3

Revert

a32

2e2

d19'

8b3

Revert

8b3 '

Revert

# Revert a single commitgit revert <ref>

Revert

‣Revert a single change

Revert

# Revert a range of commitsgit revert <ref1>..<ref2>

Revert

# Revert a range of commitsgit revert <old>..<new>

Revert

must have the old..new refs

in the right order

UndoAmend

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 file

Git-SVNCloning

git-svn

‣Subversion protocol bridge from Git

‣Round-trip integration

‣Transactions in Git == transactions in SVN

git-svn

# Clone one branchgit svn clone <svnurl>

git-svn

# Clone all branches, tagsgit svn clone --stdlayout <svnurl>

git-svn

‣ Alternate conversion tool‣ svn2git

‣ https://github.com/nirvdrum/svn2git

‣ Converts tags to Git tags

Git-SVNUpdating

git-svn

‣Fetch new changes‣git svn rebase

git-svn

‣Send new changes‣git svn dcommit

Git-SVNSVN Externals

git-svn

‣ 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 propget svn:externals <MODULE>

‣ git svn clone --stdlayout <THEURL>

‣ git submodule add <THESUBFOLDER>

‣ git submodule init

‣ git submodule update

git-svn

‣ SVN Externals helper script

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

Git FoundationsAn exploration of the Git toolbox

Offi

cial

trai

ning

cur

ricul

um v

3.1.

201

2, G

itHub

, Inc

.

Credits

‣ Images sourced from:‣ AmbientIdeasPhotography.com‣ Hand Tools

‣ Flickr Creative Commons‣ Clock: http://www.flickr.com/photos/7729940@N06/4019157830

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

top related