Git 101 tutorial presentation

Preview:

DESCRIPTION

 

Citation preview

Git 101Scott Chacon

Introduction

Me

Scott Chacon

git-scm.com

http://gitref.org

http://progit.org

schacon@gmail.com

@chacontwitter

</me>

What is Git?

“distributed version control system”

what is version control?

what is version control?what do we use it for?

imagine a world with no version control tools

what would you do?

downsides?

who doesn’t use version control?

who doesn’t use version control?

rhetorical question

what project is this?• thousands of developers

• working all across the world

• used on millions of computers

• runs 90% of the supercomputers in the world

• runs my phone

• 11 years with no version control system

• has an adorable mascot

1991-2002

no version control

how did they do it?

main dude

main.clibrary.clibrary.h

main dude

main.clibrary.clibrary.h

ver-1.0.zip

main dude

main.clibrary.clibrary.h

ver-1.0.zip

you

main dude

main.clibrary.clibrary.h

ver-1.0.zip

you

main dude

main.clibrary.clibrary.h

ver-1.0.zip

you

v1/main.cv1/library.cv1/library.h

main dude

main.clibrary.clibrary.h

ver-1.0.zip

you

v1/main.cv1/library.cv1/library.h

cp -Rf v1 patch

main dude

main.clibrary.clibrary.h

ver-1.0.zip

you

v1/main.cv1/library.cv1/library.h

cp -Rf v1 patch

patch/main.cpatch/library.cpatch/library.h

main dude

main.clibrary.clibrary.h

ver-1.0.zip

you

v1/main.cv1/library.cv1/library.h

cp -Rf v1 patch

patch/main.cpatch/library.cpatch/library.h

main dude

main.clibrary.clibrary.h

ver-1.0.zip

you

v1/main.cv1/library.cv1/library.h

cp -Rf v1 patch

patch/main.cpatch/library.c*patch/library.h

diff -u v1 patch

main dude

main.clibrary.clibrary.h

ver-1.0.zip

you

v1/main.cv1/library.cv1/library.h

cp -Rf v1 patch

patch/main.cpatch/library.c*patch/library.h

diff -u v1 patch

$ git diff v1 patchdiff --git a/v1/library.c b/patch/library.cindex 0be4b5f..0120580 100644--- a/v1/library.c+++ b/patch/library.c@@ -19,7 +19,7 @@ static struct { { "detachedhead", &advice_detached_head }, }; -int git_default_config(const char *var, const char *value)+int YO_MOMMA_IS_FAT(const char *var, const char *value) { const char *k = skip_prefix(var, "advice."); int i;

main dude

main.clibrary.clibrary.h

ver-1.0.zip

you

v1/main.cv1/library.cv1/library.h

cp -Rf v1 patch

patch/main.cpatch/library.c*patch/library.h

diff -u v1 patch

email

main dude

main.clibrary.clibrary.h

you

v1/main.cv1/library.cv1/library.h

cp -Rf v1 patch

patch/main.cpatch/library.c*patch/library.h

diff -u v1 patch

ver-1.0.zip

ver-1.1.zip

ver-1.0.zip

ver-1.1.zip

ver-1.2.zip

now imagine...

main dude

main.clibrary.clibrary.h

V1

main dude

main.clibrary.clibrary.h

you

V1main.clibrary.clibrary.h

V1

main dude

main.clibrary.clibrary.h

you

V1main.clibrary.clibrary.h

V1

main.clibrary.c*library.h

V2

main dude

main.clibrary.clibrary.h

you

V1

main.c*library.clibrary.h

V3

main.clibrary.clibrary.h

V1

main.clibrary.c*library.h

V2

main dude

main.clibrary.clibrary.h

you

V1

main.c*library.clibrary.h

V3

main.clibrary.clibrary.h

V1

main.clibrary.c*library.h

V2main.clibrary.c*library.h

V2

main dude

main.clibrary.clibrary.h

you

V1

main.c*library.clibrary.h

V3

main.clibrary.clibrary.h

V1

main.clibrary.c*library.h

V2main.clibrary.c*library.h

V2

main.c*library.c*library.h

V4

main dude

main.clibrary.clibrary.h

you

V1

main.c*library.clibrary.h

V3

main.clibrary.clibrary.h

V1

main.clibrary.c*library.h

V2main.clibrary.c*library.h

V2

main.c*library.c*library.h

V4

main dude

main.clibrary.clibrary.h

you

V1

main.c*library.clibrary.h

V3

main.clibrary.clibrary.h

V1

main.clibrary.c*library.h

V2main.clibrary.c*library.h

V2

main.c*library.c*library.h

V4

main dude

main.clibrary.clibrary.h

you

V1

main.c*library.clibrary.h

V3

main.clibrary.clibrary.h

V1

main.clibrary.c*library.h

V2main.clibrary.c*library.h

V2

main.c*library.c*library.h

V4

Snapshots, not Patches

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

Basic Git

First Steps

$ git config --global user.name “Scott Chacon”

$ git config --global user.email “schacon@gmail.com”

Getting a Repo

Create One

git init

$ touch hello_world.rb$ git init$ git add .$ git commit -m ‘first commit’

$ touch hello_world.rb$ git init$ git add .$ git commit -m ‘first commit’

$ tree -a.|-- .git| |-- HEAD| |-- branches| |-- config| |-- description| |-- hooks| | |-- post-commit.sample| | |-- post-receive.sample| | |-- ...| | |-- pre-rebase.sample| | `-- update.sample| |-- info| | `-- exclude| |-- objects| | |-- info| | `-- pack| |-- refs| | |-- heads| | `-- tags| `-- remotes`-- hello_world.rb

11 directories, 25 files

$ tree -a.|-- .git| |-- HEAD| |-- branches| |-- config| |-- description| |-- hooks| | |-- post-commit.sample| | |-- post-receive.sample| | |-- ...| | |-- pre-rebase.sample| | `-- update.sample| |-- info| | `-- exclude| |-- objects| | |-- info| | `-- pack| |-- refs| | |-- heads| | `-- tags| `-- remotes`-- hello_world.rb

11 directories, 25 files

$ tree -a.|-- .git| |-- HEAD| |-- branches| |-- config| |-- description| |-- hooks| | |-- post-commit.sample| | |-- post-receive.sample| | |-- ...| | |-- pre-rebase.sample| | `-- update.sample| |-- info| | `-- exclude| |-- objects| | |-- info| | `-- pack| |-- refs| | |-- heads| | `-- tags| `-- remotes`-- hello_world.rb

11 directories, 25 files

$ touch hello_world.rb$ git init$ git add .$ git commit -m ‘first commit’

$ touch hello_world.rb$ git init$ git add .$ git commit -m ‘first commit’

$ tree -a.|-- .git| |-- COMMIT_EDITMSG| |-- HEAD| |-- branches| |-- config| |-- description| |-- hooks| | |-- applypatch-msg.sample| | `-- update.sample| |-- index| |-- info| | `-- exclude| |-- logs| | |-- HEAD| | `-- refs| | `-- heads| | `-- master| |-- objects| | |-- 32/09658ac8d80bc9726d3a33d77e3dfc5fe6035e| | |-- 53/9cd7886a627841d525a78d45cbc6396be20b41| | |-- e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391| | |-- info| | `-- pack| |-- refs| | |-- heads| | | `-- master| | `-- tags| `-- remotes`-- hello_world.rb

17 directories, 33 files

$ tree -a.|-- .git| |-- COMMIT_EDITMSG| |-- HEAD| |-- branches| |-- config| |-- description| |-- hooks| | |-- applypatch-msg.sample| | `-- update.sample| |-- index| |-- info| | `-- exclude| |-- logs| | |-- HEAD| | `-- refs| | `-- heads| | `-- master| |-- objects| | |-- 32/09658ac8d80bc9726d3a33d77e3dfc5fe6035e| | |-- 53/9cd7886a627841d525a78d45cbc6396be20b41| | |-- e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391| | |-- info| | `-- pack| |-- refs| | |-- heads| | | `-- master| | `-- tags| `-- remotes`-- hello_world.rb

17 directories, 33 files

$ tree -a.|-- .git| |-- COMMIT_EDITMSG| |-- HEAD| |-- branches| |-- config| |-- description| |-- hooks| | |-- applypatch-msg.sample| | `-- update.sample| |-- index| |-- info| | `-- exclude| |-- logs| | |-- HEAD| | `-- refs| | `-- heads| | `-- master| |-- objects| | |-- 32/09658ac8d80bc9726d3a33d77e3dfc5fe6035e| | |-- 53/9cd7886a627841d525a78d45cbc6396be20b41| | |-- e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391| | |-- info| | `-- pack| |-- refs| | |-- heads| | | `-- master| | `-- tags| `-- remotes`-- hello_world.rb

17 directories, 33 files

Clone One

git clone

$ git clone git://github.com/schacon/ticgit.gitInitialized empty Git repository in /private/tmp/ticgit/.git/remote: Counting objects: 591, done.remote: Compressing objects: 100% (267/267), done.remote: Total 591 (delta 253), reused 587 (delta 252)Receiving objects: 100% (591/591), 73.05 KiB, done.Resolving deltas: 100% (253/253), done.$ cd ticgit/$ lsLICENSE! ! Rakefile! examples! note! ! ticgit.gemspecREADME!! bin!! lib!! spec$

$ git clone git://github.com/schacon/ticgit.gitInitialized empty Git repository in /private/tmp/ticgit/.git/remote: Counting objects: 591, done.remote: Compressing objects: 100% (267/267), done.remote: Total 591 (delta 253), reused 587 (delta 252)Receiving objects: 100% (591/591), 73.05 KiB, done.Resolving deltas: 100% (253/253), done.$ cd ticgit/$ lsLICENSE! ! Rakefile! examples! note! ! ticgit.gemspecREADME!! bin!! lib!! spec$

$ git clone git://github.com/schacon/ticgit.gitInitialized empty Git repository in /private/tmp/ticgit/.git/remote: Counting objects: 591, done.remote: Compressing objects: 100% (267/267), done.remote: Total 591 (delta 253), reused 587 (delta 252)Receiving objects: 100% (591/591), 73.05 KiB, done.Resolving deltas: 100% (253/253), done.$ cd ticgit/$ lsLICENSE! ! Rakefile! examples! note! ! ticgit.gemspecREADME!! bin!! lib!! spec$

$ git clone git://github.com/schacon/ticgit.gitInitialized empty Git repository in /private/tmp/ticgit/.git/remote: Counting objects: 591, done.remote: Compressing objects: 100% (267/267), done.remote: Total 591 (delta 253), reused 587 (delta 252)Receiving objects: 100% (591/591), 73.05 KiB, done.Resolving deltas: 100% (253/253), done.$ cd ticgit/$ ls.git LICENSE! ! Rakefile! examples! note! !ticgit.gemspec README!! bin!! lib!! spec$

A Basic Workflow

A Basic Workflow

Edit files

Stage the changes

Review your changes

Commit the changes

working directory

repository

index

git add

git commit

working directory

repository

index

git add

git commit

a working copy of your project

working directory

repository

index

git add

git commit

object database

working directory

repository

index

git add

git commit

“staging”

A Basic Workflow

Edit files

Stage the changes

Review your changes

Commit the changes

$ find ../app.yaml./index.yaml./main.py

#!/usr/bin/env pythonimport wsgiref.handlersfrom google.appengine.ext import webapp

class MainHandler(webapp.RequestHandler):

def get(self): self.response.out.write('Hello world!')

def main(): application = webapp.WSGIApplication([('/', MainHandler)], debug=True) wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__': main()~ ~ "main.py" 16L, 402C

$ vim main.py

#!/usr/bin/env pythonimport wsgiref.handlersfrom google.appengine.ext import webapp

# this program prints out ‘hello world’

class MainHandler(webapp.RequestHandler):

def get(self): self.response.out.write('Hello world!')

def main(): application = webapp.WSGIApplication([('/', MainHandler)], debug=True) wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__': main()~ ~ "main.py" 16L, 402C

$ vim main.py

$ git status

$ git status# On branch master# Changed but not updated:# (use "git add <file>..." to update what will be committed)##modified: main.py#no changes added to commit (use "git add" and/or "git commit -a")

$ git status# On branch master# Changed but not updated:# (use "git add <file>..." to update what will be committed)##modified: main.py#no changes added to commit (use "git add" and/or "git commit -a")

$ git status# On branch master# Changed but not updated:# (use "git add <file>..." to update what will be committed)##modified: main.py#no changes added to commit (use "git add" and/or "git commit -a")

$ git status# On branch master# Changed but not updated:# (use "git add <file>..." to update what will be committed)##modified: main.py#no changes added to commit (use "git add" and/or "git commit -a")

STAGED

A Basic Workflow

Edit files

Stage the changes

Review your changes

Commit the changes

git add

working directory

repository

index

git add

git commit

working directory

repository

index

git add

git commit

$ git add main.py$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)##modified: main.py#

# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)##modified: main.py#

$ git add main.py$ git status

# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)##modified: main.py#

$ git add main.py$ git status

THAT ARE STAGED

$ vim app.yamlapplication: chaconversion: 1runtime: pythonapi_version: 1

handlers:- url: .* script: main.py~ ~ ~ "app.yaml" 8L, 101C

application: chaconversion: 1runtime: pythonapi_version: 1

handlers:- url: .* script: main.py~ ~ ~ "app.yaml" 8L, 101C

$ vim app.yaml

application: chaconversion: 2runtime: pythonapi_version: 1

handlers:- url: .* script: main.py~ ~ ~ "app.yaml" 8L, 101C

$ vim app.yaml

$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: main.py## Changed but not updated:# (use "git add <file>..." to update what will be committed)## modified: app.yaml#

$ vim main.py#!/usr/bin/env pythonimport wsgiref.handlersfrom google.appengine.ext import webapp

# this program prints out ‘hello world’

class MainHandler(webapp.RequestHandler):

def get(self): self.response.out.write('Hello world!')

def main(): application = webapp.WSGIApplication([('/', MainHandler)], debug=True) wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__': main()~ ~ "main.py" 16L, 402C

#!/usr/bin/env pythonimport wsgiref.handlersfrom google.appengine.ext import webapp

# this program prints out ‘hello world’

class MainHandler(webapp.RequestHandler):

def get(self): self.response.out.write('Hola world!')

def main(): application = webapp.WSGIApplication([('/', MainHandler)], debug=True) wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__': main()~ ~ "main.py" 16L, 402C

$ vim main.py

#!/usr/bin/env pythonimport wsgiref.handlersfrom google.appengine.ext import webapp

# this program prints out ‘hello world’

class MainHandler(webapp.RequestHandler):

def get(self): self.response.out.write('Hola Mundo!')

def main(): application = webapp.WSGIApplication([('/', MainHandler)], debug=True) wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__': main()~ ~ "main.py" 16L, 402C

$ vim main.py

# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: main.py## Changed but not updated:# (use "git add <file>..." to update what will be committed)## modified: app.yaml# modified: main.py#

$ git status

# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: main.py## Changed but not updated:# (use "git add <file>..." to update what will be committed)## modified: app.yaml# modified: main.py#

$ git status

Staged

# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: main.py## Changed but not updated:# (use "git add <file>..." to update what will be committed)## modified: app.yaml# modified: main.py#

$ git status

Unstaged

# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: main.py## Changed but not updated:# (use "git add <file>..." to update what will be committed)## modified: app.yaml# modified: main.py#

$ git status

#!/usr/bin/env pythonimport wsgiref.handlersfrom google.appengine.ext import webapp

# this program prints out ‘hello world’

class MainHandler(webapp.RequestHandler):

def get(self): self.response.out.write('Hola Mundo!')

def main(): application = webapp.WSGIApplication([('/' debug=True) wsgiref.handlers.CGIHandler().run(applicat

if __name__ == '__main__': main()

#!/usr/bin/env pythonimport wsgiref.handlersfrom google.appengine.ext import webapp

# this program prints out ‘hello world’

class MainHandler(webapp.RequestHandler):

def get(self): self.response.out.write('Hello World!')

def main(): application = webapp.WSGIApplication([('/' debug=True) wsgiref.handlers.CGIHandler().run(applicat

if __name__ == '__main__': main()

Staged In Working Directory

#!/usr/bin/env pythonimport wsgiref.handlersfrom google.appengine.ext import webapp

# this program prints out ‘hello world’

class MainHandler(webapp.RequestHandler):

def get(self): self.response.out.write('Hola Mundo!')

def main(): application = webapp.WSGIApplication([('/' debug=True) wsgiref.handlers.CGIHandler().run(applicat

if __name__ == '__main__': main()

#!/usr/bin/env pythonimport wsgiref.handlersfrom google.appengine.ext import webapp

# this program prints out ‘hello world’

class MainHandler(webapp.RequestHandler):

def get(self): self.response.out.write('Hello World!')

def main(): application = webapp.WSGIApplication([('/' debug=True) wsgiref.handlers.CGIHandler().run(applicat

if __name__ == '__main__': main()

Staged In Working Directory

You have to stage a file after you edit it

You have to stage a file after you edit it

You have to stage a file after you edit it

$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: app.yaml# modified: main.py#

$ git add app.yaml main.py

A Basic Workflow

Edit files

Stage the changes

Review your changes

Commit the changes

git commit

working directory

repository

index

git add

git commit

working directory

repository

index

git add

git commit

$ git commit

# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: app.yaml# modified: main.py#~ ~ ~ ~ ".git/COMMIT_EDITMSG" 10L, 279C

descriptive commit message# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: app.yaml# modified: main.py#~ ~ ~ ~ ".git/COMMIT_EDITMSG" 10L, 279C

$ git commit

descriptive commit message# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: app.yaml# modified: main.py#~ ~ ~ ~ ".git/COMMIT_EDITMSG" 10L, 279C

$ git commit

$ git commitCreated commit 77d3001: descriptive commit message 2 files changed, 4 insertions(+), 2 deletions(-)

A Basic Workflow

Edit files

Stage the changes

Review your changes

Commit the changes

vim / emacs / etc

git add (file)

repo status

git commit

A Basic Workflow

Edit files

Stage the changes

Review your changes

Commit the changes

vim / emacs / etc

git add (file)

repo status

git commit

A Basic Workflow

Edit files

Stage the changes

Review your changes

Commit the changes

vim / emacs / etc

git add (file)

repo status

git commit

A Basic Workflow

Edit files

Stage the changes

Review your changes

Commit the changes

vim / emacs / etc

git add (file)

git status

git commit

A Basic Workflow

Edit files

Stage the changes

Review your changes

Commit the changes

vim / emacs / etc

git add (file)

git status

git commit

A Basicer Workflow

Edit files

Stage and Commit

vim / emacs / etc

git commit -a

What’s going on here?

$ git commitCreated commit 77d3001: descriptive commit message 2 files changed, 4 insertions(+), 2 deletions(-)

$ git commitCreated commit 77d3001: descriptive commit message 2 files changed, 4 insertions(+), 2 deletions(-)

77d3001

77d3001a1de6bf8f5e431972fe4d25b01e595c0b

77d3001a1de6bf8f5e431972fe4d25b01e595c0b

77d3001a1de6bf8f5e431972fe4d25b01e595c0b

commit size

ae668..

tree

parent

author

committermy commit message goes hereand it is really, really cool

c4ec5

a149e

Scott

Scott

77d3001a1de6bf8f5e431972fe4d25b01e595c0b

commit size

ae668..

tree

parent

author

committermy commit message goes hereand it is really, really cool

c4ec5

a149e

Scott

Scott

tree c4ec543b0322744e55c5efc9b6c4e449d398dbffparent a149e2160b3f7573768cdc2fce24d0881f3577e1author Scott Chacon <schacon@gmail.com> 1223402504 -0700committer Scott Chacon <schacon@gmail.com> 1223402504 -0700

descriptive commit message

77d3001a1de6bf8f5e431972fe4d25b01e595c0b

commit size

ae668..

tree

parent

author

committermy commit message goes hereand it is really, really cool

c4ec5

a149e

Scott

Scott

77d3001a1de6bf8f5e431972fe4d25b01e595c0b

commit size

ae668..

tree

parent

author

committermy commit message goes hereand it is really, really cool

c4ec5

a149e

Scott

Scott

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

commit size

ae668..

tree

parent

author

committermy commit message goes hereand it is really, really cool

c4ec5

a149e

Scott

Scott

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

commit size

tree

parent

author

committerthis is the previous commitand I am very proud of it

2de54

38def

Scott

Scott

commit size

ae668..

tree

parent

author

committermy commit message goes hereand it is really, really cool

c4ec5

a149e

Scott

Scott

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

commit size

tree

parent

author

committerthis is the previous commitand I am very proud of it

2de54

38def

Scott

Scott

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

commit size

ae668..

tree

parent

author

committermy commit message goes hereand it is really, really cool

c4ec5

a149e

Scott

Scott

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

commit size

tree

parent

author

committerthis is the previous commitand I am very proud of it

2de54

38def

Scott

Scott

commit size

tree

parent

author

committerthis is the commit before thatand I'm not sure why

2fe65

90ecd

Scott

Scott

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

commit size

tree

parent

author

committerthis is the commit before thatand I'm not sure why

2fe65

90ecd

Scott

Scott

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

commit size

ae668..

tree

parent

author

committermy commit message goes hereand it is really, really cool

c4ec5

a149e

Scott

Scott

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

commit size

tree

parent

author

committerthis is the previous commitand I am very proud of it

2de54

38def

Scott

Scott

commit size

tree

parent

author

committerthis is the commit before thatand I'm not sure why

2fe65

90ecd

Scott

Scott

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

commit size

tree

parent

author

committerthis is the commit before thatand I'm not sure why

2fe65

90ecd

Scott

Scott

app.yaml

index.yaml

main.py

./ c4e

03e

1d3

3d5

48e 77da1438d

c4e

3d5

1d3

03e

f46

23f

30e

67e

32a

5b1

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

git checkout ae635

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

git checkout ae635

Working DirectoryIndex

Rakefile

README

simplegit.rb

./

lib/

./Rakefile

./README

./lib/simplegit.rb

./

./lib/ c36

3d4

03e

5b1

1d3

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

Working DirectoryIndex

Rakefile

README

simplegit.rb

./

lib/

./Rakefile

./README

./lib/simplegit.rb

./

./lib/ c36

3d4

03e

5b1

1d3

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

Working DirectoryIndex

Rakefile

README

simplegit.rb

./

lib/

./Rakefile

./README

./lib/simplegit.rb

./

./lib/ c36

3d4

03e

5b1

1d3

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

Working DirectoryIndex

Rakefile

README

simplegit.rb

./

lib/

./Rakefile

./README

./lib/simplegit.rb

./

./lib/ c36

3d4

03e

5b1

1d3

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

Working DirectoryIndex

Rakefile

README

simplegit.rb

./

lib/

./Rakefile

./README

./lib/simplegit.rb

./

./lib/ c36

3d4

03e

5b1

1d3

git add

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

Working DirectoryIndex

Rakefile

README

simplegit.rb

./

lib/

./Rakefile

./README

./lib/simplegit.rb

./

./lib/ c36

3d4

03e

5b1

1d3

git add

34f

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

Working DirectoryIndex

Rakefile

README

simplegit.rb

./

lib/

./Rakefile

./README

./lib/simplegit.rb

./

./lib/ c36

3d4

03e

5b1

1d3

git commit

34f

a083da34f

ae9

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

Working DirectoryIndex

Rakefile

README

simplegit.rb

./

lib/

./Rakefile

./README

./lib/simplegit.rb

./

./lib/ c36

3d4

03e

5b1

1d334f

a083da34f

ae9

Repository

3d4

03e

ae6

5b1

1d3

c36

f46

23f

6fe

30e

67e

32a

ffe

38d

5b1

1d3

254

a14

d23

2d3

48e

735

de3

c4ec4e

77d

3d5

Working DirectoryIndex

Rakefile

README

simplegit.rb

./

lib/

./Rakefile

./README

./lib/simplegit.rb

./

./lib/ c36

3d4

03e

5b1

1d334f

a083da34f

ae9

object model

blob

commit

tree

C1}directory list

file contents

pointer to a snapshot

object model

blob

commit

tree

C1}directory list

file contents

pointer to a snapshot

ref

commit commitcommit

tree

treeblob

tree

treeblob

tree

treeblob

blob

Bulk Staging

working directory

repository

index

working directory

repository

index

git add

working directory

repository

index

git addgit add

git add

working directory

repository

index

git add

git commit

git add -u

git commit -a

working directory

repository

git commit -aindex

git commit -agit add -ugit commit

Patch Staging

git add -p

$ 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: ticgit.gemspec#no changes added to commit (use "git add" and/or "git commit -a")

$ 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: ticgit.gemspec#no changes added to commit (use "git add" and/or "git commit -a")

$ git add -pdiff --git a/ticgit.gemspec b/ticgit.gemspecindex 9c32bd4..a44667b 100644--- a/ticgit.gemspec+++ b/ticgit.gemspec@@ -1,7 +1,7 @@ Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.name = "ticgit"- s.version = "0.3.5"+ s.version = "0.3.6" s.date = "2008-05-10" s.author = "Scott Chacon" s.email = "schacon@gmail.com"Stage this hunk [y,n,a,d,/,j,J,g,e,?]? y

$ git add -pdiff --git a/ticgit.gemspec b/ticgit.gemspecindex 9c32bd4..a44667b 100644--- a/ticgit.gemspec+++ b/ticgit.gemspec@@ -1,7 +1,7 @@ Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.name = "ticgit"- s.version = "0.3.5"+ s.version = "0.3.6" s.date = "2008-05-10" s.author = "Scott Chacon" s.email = "schacon@gmail.com"Stage this hunk [y,n,a,d,/,j,J,g,e,?]? y

$ git add -pdiff --git a/ticgit.gemspec b/ticgit.gemspecindex 9c32bd4..a44667b 100644--- a/ticgit.gemspec+++ b/ticgit.gemspec@@ -1,7 +1,7 @@ Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.name = "ticgit"- s.version = "0.3.5"+ s.version = "0.3.6" s.date = "2008-05-10" s.author = "Scott Chacon" s.email = "schacon@gmail.com"Stage this hunk [y,n,a,d,/,j,J,g,e,?]?

$ git add -pdiff --git a/ticgit.gemspec b/ticgit.gemspecindex 9c32bd4..a44667b 100644--- a/ticgit.gemspec+++ b/ticgit.gemspec@@ -1,7 +1,7 @@ Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.name = "ticgit"- s.version = "0.3.5"+ s.version = "0.3.6" s.date = "2008-05-10" s.author = "Scott Chacon" s.email = "schacon@gmail.com"Stage this hunk [y,n,a,d,/,j,J,g,e,?]? y

@@ -9,9 +9,10 @@ Gem::Specification.new do |s| s.files = ["lib/ticgit/base.rb", "lib/ticgit/cli.rb", "lib/ticgit/comment.rb", "lib/ticgit/ticket.rb", "lib/ticgit.rb", "bin/ti", "bin/ticgitweb"] s.bindir = 'bin'- s.executables << "ti"- s.executables << "ticgitweb"+ s.executables = ["ti", "ticgitweb"]+ s.default_executable = %q{ti} s.homepage = "http://github/schacon/ticgit" s.require_paths = ["lib", "bin"]+ s.specification_version = 2 if s.respond_to? :specification_version= endStage this hunk [y,n,a,d,/,K,g,s,e,?]?

@@ -9,9 +9,10 @@ Gem::Specification.new do |s| s.files = ["lib/ticgit/base.rb", "lib/ticgit/cli.rb", "lib/ticgit/comment.rb", "lib/ticgit/ticket.rb", "lib/ticgit.rb", "bin/ti", "bin/ticgitweb"] s.bindir = 'bin'- s.executables << "ti"- s.executables << "ticgitweb"+ s.executables = ["ti", "ticgitweb"]+ s.default_executable = %q{ti} s.homepage = "http://github/schacon/ticgit" s.require_paths = ["lib", "bin"]+ s.specification_version = 2 if s.respond_to? :specification_version= endStage this hunk [y,n,a,d,/,K,g,s,e,?]?

@@ -9,9 +9,10 @@ Gem::Specification.new do |s| s.files = ["lib/ticgit/base.rb", "lib/ticgit/cli.rb", "lib/ticgit/comment.rb", "lib/ticgit/ticket.rb", "lib/ticgit.rb", "bin/ti", "bin/ticgitweb"] s.bindir = 'bin'- s.executables << "ti"- s.executables << "ticgitweb"+ s.executables = ["ti", "ticgitweb"]+ s.default_executable = %q{ti} s.homepage = "http://github/schacon/ticgit" s.require_paths = ["lib", "bin"]+ s.specification_version = 2 if s.respond_to? :specification_version= endStage this hunk [y,n,a,d,/,K,g,s,e,?]? n

$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: ticgit.gemspec## 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: ticgit.gemspec#

$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: ticgit.gemspec## 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: ticgit.gemspec#

$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: ticgit.gemspec## 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: ticgit.gemspec#

$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: ticgit.gemspec## 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: ticgit.gemspec#

partially stage files

git add -p

Changes

deltastorage

snapshotstorage

deltastorage

snapshotstorage

deltastorage

snapshotstorage

git diff

What is not yet staged?

git diff

git diff

working directory

repository

index

What is staged?

git diff --cached

git diff --cached

working directory

repository

index

git diff --stat

$ git diff --stat kidgloves.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)

Unified Diff

git diff > change.patch

git diff > change.patch

patch -p1 < change.patch

git diff > change.patch

patch -p1 < change.patch

git apply change.patchor

History

git log

Branching and Merging

branches

brancheslightweight, movablepointers to a commit

C1

branch

branching

git branch

git checkout

C1

master

C0

C2 C3

experiment

HEAD

default

C1

master

C0

C2 C3

experimentC1

master

C0

C2 C3

C4

experiment

C5

T1

git branch experiment

HEAD

default

C1

master

C0

C2 C3

experimentC1

master

C0

C2 C3

C4

experiment

C5

T1

git branch experiment

HEAD

default

C1

master

C0

C2 C3

experimentC1

master

C0

C2 C3

C4

experiment

C5

T1

HEAD

$ git branch* default experiment

default

C1

master

C0

C2 C3

experimentC1

master

C0

C2 C3

C4

experiment

C5

T1

HEAD

$ git branch* default experiment

default

C1

master

C0

C2 C3

experimentC1

master

C0

C2 C3

C4

experiment

C5

T1

git checkout experiment

HEAD

default

C1

master

C0

C2 C3

experiment

C1

master

C0

C2 C3

C4

experiment

C5

T1

git commit

HEAD

default

C1

master

C0

C2 C3

experiment

C1

master

C0

C2 C3

C4

experiment

C5

T1

git commit

HEAD

default

C1

master

C0

C2 C3

experiment

C1

master

C0

C2 C3

C4

experiment

C5

T1

git commit

HEAD

default

C1

master

C0

C2 C3

experiment

C1

master

C0

C2 C3

C4

experiment

C5

T1

git commitgit commit

HEAD

default

C1

master

C0

C2 C3

experiment

C1

master

C0

C2 C3

C4

experiment

C5

T1

HEAD

git checkout defaultdefault

C1

master

C0

C2 C3

experiment

C1

master

C0

C2 C3

C4

experiment

C5

T1

HEAD

git checkout defaultdefault

C1

master

C0

C2 C3

C4

experiment

C5

T1

C1

master

C0

C2 C3

C4

experiment

C5

T1git commit

HEAD

default

C1

master

C0

C2 C3

C4

experiment

C5

T1

C1

master

C0

C2 C3

C4

experiment

C5

T1git commit

HEAD

default

C1

master

C0

C2 C3

C4

experiment

C5

T1

C1

master

C0

C2 C3

C4

experiment

C5

T1git commit

HEAD

default

C1

master

C0

C2 C3

C4

experiment

C5

T1

git checkout experimentgit commit

HEAD

default

what is a branch, really?

$ find .git/refs.git/refs.git/refs/heads.git/refs/heads/default.git/refs/heads/experiment

$ find .git/refs.git/refs.git/refs/heads.git/refs/heads/default.git/refs/heads/experiment

$ find .git/refs.git/refs.git/refs/heads.git/refs/heads/default.git/refs/heads/experiment

$ find .git/refs.git/refs.git/refs/heads.git/refs/heads/default.git/refs/heads/experiment

$ cat .git/refs/heads/default6370409dc9e38af91565082bdf93577ff555489e

$ find .git/refs.git/refs.git/refs/heads.git/refs/heads/default.git/refs/heads/experiment

$ cat .git/refs/heads/default6370409dc9e38af91565082bdf93577ff555489e$ cat .git/refs/heads/experiment 33ce13c2f0ed35775956f81191b01a644448dcfc

$ cat .git/HEAD ref: refs/heads/experiment

$ cat .git/HEAD ref: refs/heads/experiment

$ cat .git/HEAD ref: refs/heads/experiment

merging

git merge

C1

master

C0

C2 C3

C4

experiment

C5

T1

HEAD

default

C1

master

C0

C2 C3

C4

experiment

C5

T1

HEAD

git checkout default

default

C1C0

C2 C3

C4

experiment

C5

C6

masterT1

git checkout defaultgit merge experiment

HEAD

default

C1C0

C2 C3

C4

experiment

C5

C6

masterT1

git checkout defaultgit merge experiment

HEAD

default

C1C0

C2 C3

C4

C5

C6

C7

C8

default

experiment

HEADgit checkout experiment

C1C0

C2 C3

C4

C5

C6

C7

C8

default

experiment

HEADgit commit

C1C0

C2 C3

C4

C5

C6

C7

C8

default

experiment

HEAD

git checkout default

C1C0

C2 C3

C4

C5

C6

C7

C8

default

experiment

HEAD

git merge experiment

Why is this cool?

try out an idea

isolate work units

long running topics

visualizing your branches

git log --graph

git log --oneline --graph

gitk

gitk 6d13f..41aba

git log --all

Deleting Branches

git branch -d branch

git branch -D branch

Stashing

when a commit is too much

$ git status# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stashSaved working directory and index state "WIP on iss53: c8208f9... Merge branch 'cupcake'"HEAD is now at c8208f9 Merge branch 'cupcake'(To restore them type "git stash apply")

$ git status# On branch iss53nothing to commit (working directory clean)

$ git status# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stashSaved working directory and index state "WIP on iss53: c8208f9... Merge branch 'cupcake'"HEAD is now at c8208f9 Merge branch 'cupcake'(To restore them type "git stash apply")

$ git status# On branch iss53nothing to commit (working directory clean)

$ git status# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stashSaved working directory and index state "WIP on iss53: c8208f9... Merge branch 'cupcake'"HEAD is now at c8208f9 Merge branch 'cupcake'(To restore them type "git stash apply")

$ git status# On branch iss53nothing to commit (working directory clean)

$ git status# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stashSaved working directory and index state "WIP on iss53: c8208f9... Merge branch 'cupcake'"HEAD is now at c8208f9 Merge branch 'cupcake'(To restore them type "git stash apply")

$ git status# On branch iss53nothing to commit (working directory clean)

$ git status# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stashSaved working directory and index state "WIP on iss53: c8208f9... Merge branch 'cupcake'"HEAD is now at c8208f9 Merge branch 'cupcake'(To restore them type "git stash apply")

$ git status# On branch iss53nothing to commit (working directory clean)

$ git status# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stashSaved working directory and index state "WIP on iss53: c8208f9... Merge branch 'cupcake'"HEAD is now at c8208f9 Merge branch 'cupcake'(To restore them type "git stash apply")

$ git status# On branch iss53nothing to commit (working directory clean)

$ git status# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stashSaved working directory and index state "WIP on iss53: c8208f9... Merge branch 'cupcake'"HEAD is now at c8208f9 Merge branch 'cupcake'(To restore them type "git stash apply")

$ git status# On branch iss53nothing to commit (working directory clean)

$ git status# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stashSaved working directory and index state "WIP on iss53: c8208f9... Merge branch 'cupcake'"HEAD is now at c8208f9 Merge branch 'cupcake'(To restore them type "git stash apply")

$ git status# On branch iss53nothing to commit (working directory clean)

$ git status# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stashSaved working directory and index state "WIP on iss53: c8208f9... Merge branch 'cupcake'"HEAD is now at c8208f9 Merge branch 'cupcake'(To restore them type "git stash apply")

$ git status# On branch iss53nothing to commit (working directory clean)

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash apply# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash drop stash@{0}Dropped stash@{0} (e19b0e94032d0614f450238f91953fe5e7e454a8)

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash apply# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash drop stash@{0}Dropped stash@{0} (e19b0e94032d0614f450238f91953fe5e7e454a8)

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash apply# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash drop stash@{0}Dropped stash@{0} (e19b0e94032d0614f450238f91953fe5e7e454a8)

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash apply# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash drop stash@{0}Dropped stash@{0} (e19b0e94032d0614f450238f91953fe5e7e454a8)

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash apply# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash drop stash@{0}Dropped stash@{0} (e19b0e94032d0614f450238f91953fe5e7e454a8)

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash apply# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash drop stash@{0}Dropped stash@{0} (e19b0e94032d0614f450238f91953fe5e7e454a8)

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash apply# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash drop stash@{0}Dropped stash@{0} (e19b0e94032d0614f450238f91953fe5e7e454a8)

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash apply# On branch iss53# 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: src/com/android/alarmclock/AlarmAlert.java# modified: src/com/android/alarmclock/AlarmAlertWakeLock.java#no changes added to commit (use "git add" and/or "git commit -a")

$ git stash liststash@{0}: WIP on iss53: c8208f9... Merge branch 'cupcake'

$ git stash drop stash@{0}Dropped stash@{0} (e19b0e94032d0614f450238f91953fe5e7e454a8)

git stash branch new_branch stash@{1}

git stashsave

list

drop

pop

apply

branch

Remotes

sharing git

git clone git://github.com/schacon/simplegit2.git

distributed workflow

distributed workflowfetch, pull and push

fetch

pull

pull = fetch + merge

push

git push

git push origin branchA:branchB

a who in the what now?

public repo

local repo

local repo

public repo

internet

A B C

public repo

local repo

local repo

public repo

git push(ssh)

internet

A B C

A B C

public repo

local repo

local repo

public repo

git push(ssh)

git fetch(git)

internet

A B C

A B C

A B C

public repo

local repo

local repo

public repo

git push(ssh)

git fetch(git)

internet

A B C

A B C

A B C

D E F git commit

public repo

local repo

local repo

public repo

git push(ssh)

git fetch(git)

git push(ssh)

internet

A B C

A B C

A B C

D E F

A B C

D E F

public repo

local repo

local repo

public repo

git fetch(http)

git push(ssh)

git fetch(git)

git push(ssh)

internet

A B C

A B C

A B C

D E F

A B C

D E F

D E F

public repo

local repo

local repo

public repo

git fetch(http)

git push(ssh)

git fetch(git)

git push(ssh)

internet

A B C

A B C

A B C

D E F

A B C

D E F

D E FD E F

multiple remotes

developernick

developerjessica

my repo5ec

e4a4a7ce0 master

developernick

developerjessica

my repo5ec

e4a4a7ce0 master

commit

developernick

developerjessica

my repo5ec

e4a4a7ce0 master

tree

developernick

developerjessica

my repo5ec

e4a4a7ce0 master

blobs

schacon/project

developernick

developerjessica

"public"

my repo5ec

e4a4a7ce0 master

git push public

public/master

5ece4a

4a7ce0

schacon/project

developerjessica

"public"

my repo5ec

e4a4a7ce0 master

git clone (url)

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nick

schacon/project

developerjessica

"public"

my repo5ec

e4a4a7ce0 master

git commit

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f git clone (url)

5ece4a

4a7ce0developer

jessica

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09git commit

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09git push

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git remote add nick git://github.com/nickh/project.git

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick"

git remote add nick git://github.com/nickh/project.git

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git remote add nick git://github.com/nickh/project.git

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick"“nick”

git remote add nick git://github.com/nickh/project.git

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git remote add jess git://github.com/jessica/project.git

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

git remote add jess git://github.com/jessica/project.git

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git remote add jess git://github.com/jessica/project.git

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

git remote add jess git://github.com/jessica/project.git

“jess”

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git remote add jess git://github.com/jessica/project.git

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git fetch nick

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

c12ec524f nick/master

git fetch nick

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git fetch nick

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

c12ec524f nick/master

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git remote add jess git://github.com/jessica/project.git

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

git fetch jess

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git fetch jess

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

ec524f nick/master

2fbdf74eaa09

jess/masterc12

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git fetch nick

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

c12ec524f nick/master

schacon/project

"public"

my repo5ec

e4a4a7ce0 master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git fetch jess

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

ec524f nick/master

2fbdf74eaa09

jess/masterc12

schacon/project

"public"

my repo5ec

e4a4a7ce0

master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

ec524f nick/master

2fbdf74eaa09

jess/masterc12

b3bc63

git merge nick jessgit merge nick/master jess/master

schacon/project

"public"

my repo5ec

e4a4a7ce0

master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

git push public

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

ec524f nick/master

2fbdf74eaa09

jess/masterc12

b3bc63

e4aec524f

2fbdf74eaa09

c12

b3bc63

schacon/project

"public"

my repo5ec

e4a4a7ce0

master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

ec524f nick/master

2fbdf74eaa09

jess/masterc12

b3bc63

e4aec524f

2fbdf74eaa09

c12

b3bc63

schacon/project

"public"

my repo5ec

e4a4a7ce0

master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

ec524f nick/master

2fbdf74eaa09

jess/masterc12

b3bc63

e4aec524f

2fbdf74eaa09

c12

b3bc63

schacon/project

"public"

my repo5ec

e4a4a7ce0

master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

ec524f nick/master

2fbdf74eaa09

jess/masterc12

b3bc63

e4aec524f

2fbdf74eaa09

c12

b3bc63

schacon/project

"public"

my repo5ec

e4a4a7ce0

master

public/master

5ece4a

4a7ce0

5ece4a

4a7ce0developer

nickc12ec524f

5ece4a

4a7ce0developer

jessica2fbdf74ea

a09

5ece4a

4a7ce0nickh/project

c12ec524f

5ece4a

4a7ce0jessica/project

2fbdf74eaa09"nick" "jess"

ec524f nick/master

2fbdf74eaa09

jess/masterc12

b3bc63

e4aec524f

2fbdf74eaa09

c12

b3bc63

Remotes Are Branches

C0

default

scott jessica

C1

C0

default

scott jessica

C1

C0

scott/default default

C1

C0

default

scott jessica

C1

C0

scott/default default

C1

git clone

C0

default

scott jessica

C1

C0

scott/default default

C1

C0

default

scott jessica

C1

C0

scott/default default

C1

C0

default

scott jessica

C1 C1

C0

scott/default

default

C2

C3

C4

C0

default

scott jessica

C1 C1

C0

scott/default

default

C2

C3

C4

C0

default

scott jessica

C1 C1

C0

scott/default

default

C2

C3

C4

C0

default

scott

C1

C5

C6

C7

jessica

C1

C0

scott/default

default

C2

C3

C4

C0

default

scott

C1

C5

C6

C7

jessica

C1

C0

scott/default

default

C2

C3

C4

C0

default

scott jessica

C1

C0

scott/default default

C2

C3

C4

C1

C5

C6

C7

C5

C6

C7

C0

default

scott jessica

C1

C0

scott/default default

C2

C3

C4

C1

C5

C6

C7

C5

C6

C7

experiment

C8

C9

C0

default

scott jessica

C1

C0

scott/default default

C2

C3

C4

C1

C5

C6

C7

C5

C6

C7

experiment

C8

C9

C0

default

scott jessica

C1

C0

scott/default default

C2

C3

C4

C1

C5

C6

C7

C5

C6

C7

experiment

C8

C9

git merge experiment

git merge scott/default

C0

default

scott jessica

C1

C0

scott/default default

C2

C3

C4

C1

C5

C6

C7

C5

C6

C7

experiment

C8

C9

C0

default

scott jessica

C1

C0

scott/default default

C2

C3

C4

C1

C5

C6

C7

C5

C6

C7

experiment

C8

C9

a “remote” branch is simply alocal pointer to the last known

state of another repository

Tagging

lightweight tags

Snapshot A Snapshot B Snapshot C

98ca9 34ac2 f30ab

master

HEAD

git tag v1.0

Snapshot A Snapshot B Snapshot C

98ca9 34ac2 f30ab

master

HEAD

v1.0

Snapshot A Snapshot B Snapshot C

98ca9 34ac2 f30ab

master

HEAD

v1.0

Snapshot D

a38d3

annotated tags

git tag -a v1.1 34ac2

tag size

49e11..

object

type

tagger

my tag message that explains

this tag

ae668

commit

Scott

tag v1.3

Snapshot A Snapshot B Snapshot C

98ca9 34ac2 f30ab

master

HEAD

v1.0

Snapshot D

a38d3

tag data

v1.1

tagging objects

git hash-object -w file.txt

$ git hash-object -w ~/README.txt 35a0dd3af166e09ac378dfeb95953923e71ea45b

$ git tag -a my_readme 35a0dd3af166e09ac378dfeb95953923e71ea45b

$ git show my_readmetag my_readmeTagger: Scott Chacon <schacon@gmail.com>Date: Tue Mar 16 08:36:24 2010 -0700

my readmeMy README File by Scott Chacon

This is my READMEThere are many like itBut this one is mine

$ git hash-object -w ~/README.txt 35a0dd3af166e09ac378dfeb95953923e71ea45b

$ git tag -a my_readme 35a0dd3af166e09ac378dfeb95953923e71ea45b

$ git show my_readmetag my_readmeTagger: Scott Chacon <schacon@gmail.com>Date: Tue Mar 16 08:36:24 2010 -0700

my readmeMy README File by Scott Chacon

This is my READMEThere are many like itBut this one is mine

$ git hash-object -w ~/README.txt 35a0dd3af166e09ac378dfeb95953923e71ea45b

$ git tag -a my_readme 35a0dd3af166e09ac378dfeb95953923e71ea45b

$ git show my_readmetag my_readmeTagger: Scott Chacon <schacon@gmail.com>Date: Tue Mar 16 08:36:24 2010 -0700

my readmeMy README File by Scott Chacon

This is my READMEThere are many like itBut this one is mine

sharing tags

git push --tags

Git Inspection

Revision Selection

Revision Selection

alternate ways to refer to objects or ranges of objects

Revision Selectionfull sha-1

partial sha-1

branch or tag name

caret parent

tilde spec

blob spec

relative specs

ranges

Full SHA1

6e453f523fa1da50ecb04431101112b3611c6a4d

Partial SHA16e453f523fa1da50ecb04431101112b3611c6a4d

6e453f523fa1da50

6e453

Branch, Remote or Tag Name

v1.0

default

m/cupcake

Caret Parent

default^2

2nd parent of ‘default’

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

master^

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

master^2

Tilde Spec

default~2

grandparent of ‘default’(parent of the parent)

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

master~2

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

master^^^2master~2^2

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

master^^^2master~2^2

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

master^^^2master~2^2

Blob Spec

default:path/to/file

blob of that file in ‘default’ commit

Relative Specs

master@{yesterday}

the commit ‘master’ was at yesterday

Relative Specs

master@{5}

the 5th prior value of ‘master’ (locally)

Ranges

ce0e4..e4272

every commit reachable by e4272 that is not reachable by ce034

Ranges

[old]..[new]

every commit reachable by [new] that is not reachable by [old]

Ranges

ce0e4..

everything since a commit

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master..master

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master..master

jess/master..master

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master..master

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master..c36ae

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master..c36ae

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master..c36ae

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master..c36ae

Ranges

ce0e4...e4272

every commit reachable by eitherbut not commits reachable by both

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master...c36ae

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master...c36ae

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master...c36ae

ce0e4

master

5ec47 2f45e 4eadf 2fbb3 18cae

b3be1 a09c6 df2fa c36ae

jess/master

jess/master...c36ae

Advanced Log

Log Subsets

git log m/cupcake..

C1

C0

m/cupcake default HEAD

C1

C0

C2

C3

default C4

m/cupcake

HEAD

C1

C0

C2

C3

default C4

m/cupcake

HEAD

git log m/cupcake..

C1

C0

C2

C3

default C4

m/cupcake

HEAD

git log m/cupcake..HEAD

C1

C0

C2

C3

default C4

m/cupcake

HEAD

git log m/cupcake..HEAD

C1

C0

C2

C3

default C4

m/cupcake

HEAD

git log m/cupcake..HEAD

C1

C0

C2

C3

default C4

m/cupcake

HEAD

git log m/cupcake..HEAD

commit 72d404debaa804fca82fd9cf710fbde48c7305c6Author: Shawn O. Pearce <spearce@spearce.org>Date: Sun Oct 12 13:13:59 2008 -0700

test-lib: fix broken printf b8eecafd888d219633f4c29e8b6a90fc21a46dfd introduced usage of printf without a format string. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>

commit 969c877506cf8cc760c7b251fef6c5b6850bfc19Author: Jeff King <peff@peff.net>Date: Sun Oct 12 00:06:11 2008 -0400

git apply --directory broken for new files We carefully verify that the input to git-apply is sane, including cross-checking that the filenames we see in "+++" headers match what was provided on the command line of "diff --git". When --directory is used, however, we ended up comparing the unadorned name to one with the prepended root, causing us to complain about a mismatch. We simply need to prepend the root directory, if any, when pulling the name out of the git header. commit ff74126c03a8dfd04e7533573a5c420f2a7112acAuthor: Johannes Schindelin <Johannes.Schindelin@gmx.de>Date: Fri Oct 10 13:42:12 2008 +0200

rebase -i: do not fail when there is no commit to cherry-pick

commit 72d404debaa804fca82fd9cf710fbde48c7305c6Author: Shawn O. Pearce <spearce@spearce.org>Date: Sun Oct 12 13:13:59 2008 -0700

test-lib: fix broken printf b8eecafd888d219633f4c29e8b6a90fc21a46dfd introduced usage of printf without a format string. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>

commit 969c877506cf8cc760c7b251fef6c5b6850bfc19Author: Jeff King <peff@peff.net>Date: Sun Oct 12 00:06:11 2008 -0400

git apply --directory broken for new files We carefully verify that the input to git-apply is sane, including cross-checking that the filenames we see in "+++" headers match what was provided on the command line of "diff --git". When --directory is used, however, we ended up comparing the unadorned name to one with the prepended root, causing us to complain about a mismatch. We simply need to prepend the root directory, if any, when pulling the name out of the git header. commit ff74126c03a8dfd04e7533573a5c420f2a7112acAuthor: Johannes Schindelin <Johannes.Schindelin@gmx.de>Date: Fri Oct 10 13:42:12 2008 +0200

rebase -i: do not fail when there is no commit to cherry-pick

C2

C3

C4

git log m/cupcake..

git log m/cupcake..HEAD

git log HEAD ^m/cupcake

git log 35ae2 ^9fe42

git log 3e45a ^573eb

git log 3e45a ^573eb

git log 08cb1 ca374 ^c0bf9

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

m/cupcake

git log c5 c7 ^c9

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

m/cupcakem/cupcake

default

git log c5 c7 ^c9

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

m/cupcakem/cupcake

default

git log c5 c7 ^c9

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

m/cupcakem/cupcake

git log c5 c7 ^c9

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git log c5 c7 ^c9

which changes aren’t in experiment?

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git log m/cupcake default ^experiment

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git log m/cupcake default ^experiment

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git log m/cupcake default ^experiment

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git log m/cupcake default ^experiment

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git log m/cupcake default ^experiment

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git log m/cupcake default ^experiment

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git log m/cupcake default ^experiment

Log Formatting

git log -p

git log -p

git log --pretty

git log --left-right

$ git log --pretty=oneline --left-right 5f7f801...77976b<5f7f801227868c7abcce7e58dee3eff855011955 convert file browser to html>77976b24ff839c59c3b20d80cb28351ccb5e59a8 remove cruft>09b76d2966e2370a78ed37a31c2f7c23d08609c3 git-log>7000b24511618a21d40b39ee213d397e1d29497d like i said>c2a6adfcd18c0d95dbed6ea62ac9c9a912d18123 create this on deploy>6ba3609953d5c46a76ca1d0d3d83018be61454e6 i am too meta for you<3dff6074fe205e36fae219f277ef87aab097e236 Merge branch 'master' into html<1cdc8437fa6c621d96c4dfa5f6370c8fdb9cbc3d Merge branch 'master' into html<20125a6d37d5c1614ffe1de94ca064095968e7f0 delete default images

$ git log --pretty=oneline --left-right 5f7f801...77976b<5f7f801227868c7abcce7e58dee3eff855011955 convert file browser to html>77976b24ff839c59c3b20d80cb28351ccb5e59a8 remove cruft>09b76d2966e2370a78ed37a31c2f7c23d08609c3 git-log>7000b24511618a21d40b39ee213d397e1d29497d like i said>c2a6adfcd18c0d95dbed6ea62ac9c9a912d18123 create this on deploy>6ba3609953d5c46a76ca1d0d3d83018be61454e6 i am too meta for you<3dff6074fe205e36fae219f277ef87aab097e236 Merge branch 'master' into html<1cdc8437fa6c621d96c4dfa5f6370c8fdb9cbc3d Merge branch 'master' into html<20125a6d37d5c1614ffe1de94ca064095968e7f0 delete default images

$ git log --pretty=oneline --left-right 5f7f801...77976b<5f7f801227868c7abcce7e58dee3eff855011955 convert file browser to html>77976b24ff839c59c3b20d80cb28351ccb5e59a8 remove cruft>09b76d2966e2370a78ed37a31c2f7c23d08609c3 git-log>7000b24511618a21d40b39ee213d397e1d29497d like i said>c2a6adfcd18c0d95dbed6ea62ac9c9a912d18123 create this on deploy>6ba3609953d5c46a76ca1d0d3d83018be61454e6 i am too meta for you<3dff6074fe205e36fae219f277ef87aab097e236 Merge branch 'master' into html<1cdc8437fa6c621d96c4dfa5f6370c8fdb9cbc3d Merge branch 'master' into html<20125a6d37d5c1614ffe1de94ca064095968e7f0 delete default images

$ git log --pretty=oneline --left-right 5f7f801...77976b<5f7f801227868c7abcce7e58dee3eff855011955 convert file browser to html>77976b24ff839c59c3b20d80cb28351ccb5e59a8 remove cruft>09b76d2966e2370a78ed37a31c2f7c23d08609c3 git-log>7000b24511618a21d40b39ee213d397e1d29497d like i said>c2a6adfcd18c0d95dbed6ea62ac9c9a912d18123 create this on deploy>6ba3609953d5c46a76ca1d0d3d83018be61454e6 i am too meta for you<3dff6074fe205e36fae219f277ef87aab097e236 Merge branch 'master' into html<1cdc8437fa6c621d96c4dfa5f6370c8fdb9cbc3d Merge branch 'master' into html<20125a6d37d5c1614ffe1de94ca064095968e7f0 delete default images

git log --graph

git log --pretty=oneline --graph

gitk

gitk 6d13f..41aba

Merged Branches

git branch --merged

git branch --no-merged

Branch Diffs

git diff branch

diff --git a/Rakefile b/Rakefileindex eb54561..2d2c777 100644--- a/Rakefile+++ b/Rakefile@@ -17,10 +17,6 @@ Rake::GemPackageTask.new(spec) do |pkg| pkg.need_tar = true end -task :default => "pkg/#{spec.name}-#{spec.version}.gem" do- puts "generated latest version"-end- desc "Regenerate Documentation" task :doc do |t| system('rdoc lib/ README --main README --inline-source')diff --git a/TODO b/TODOdeleted file mode 100644index bbe7708..0000000--- a/TODO+++ /dev/null@@ -1,7 +0,0 @@-Git Functions:-* add

git diff --stat

$ git diff --stat branch1 Rakefile | 4 ---- TODO | 7 ------- lib/simple_git.rb | 48 ------------------------------------------------ lib/simplegit.rb | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 59 deletions(-)

git diff --name-only

$ git diff --name-only branchRakefileTODOlib/simple_git.rblib/simplegit.rb

git diff branch

git diff branch HEAD

git diff branch1 branch2

Revision Diffs

git diff revA revB

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git diff c6 c4

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git diff c6 c4

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git diff c6 c4

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

git diff c6 c4this may not be what you want!

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

./file1C1

C2

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

./file1C1

./file1

./file2

C2

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

./file1C1

./file1

./file2C3 ./file1

./file3

C2

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

./file1C1

./file1

./file2C3 ./file1

./file3

C4 ./file1./file3./file4

C2

C1

C0

C2

C6

C7

C3

C4

C8

C9

C5

m/cupcake default

experiment

./file1C1

./file1

./file2C3 ./file1

./file3

C4 ./file1./file3./file4

C6 ./file1./file2./file6

C2

./file1C1

./file1

./file2C3 ./file1

./file3

C4 ./file1./file3./file4

C6 ./file1./file2./file6

git diff c6 c4

+file3+file4

C2

./file1C1

./file1

./file2C3 ./file1

./file3

C4 ./file1./file3./file4

C6 ./file1./file2./file6

git diff c6 c4

+file3+file4

C2

./file1C1

./file1

./file2C3 ./file1

./file3

C4 ./file1./file3./file4

C6 ./file1./file2./file6

git diff c6 c4

+file3+file4-file2-file6

C2

./file1C1

./file1

./file2C3 ./file1

./file3

C4 ./file1./file3./file4

C6 ./file1./file2./file6

git diff c6 c4

+file3+file4-file2-file6

C2

./file1C1

./file1

./file2C3 ./file1

./file3

C4 ./file1./file3./file4

C6 ./file1./file2./file6

git diff c6 c4

+file3+file4-file2-file6

C2

./file1C1

./file1

./file2C3 ./file1

./file3

C4 ./file1./file3./file4

C6 ./file1./file2./file6

git diff c1 c4

+file3+file4

C2

./file1

./file1

./file2C3 ./file1

./file3

C4./file1./file2./file6

git diff c6...c4

+file3+file4

./file1

./file3

./file4

C6

C1

Undo

Single File

git checkout [commit] file

$ git checkout master@{yesterday} netcfg.c

$ git checkout v1.0 netcfg.c

Entire Project

git reset

$ git status# Not currently on any branch.# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: src/com/android/launcher/Workspace.java## 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: src/com/android/launcher/LiveFolder.java#

$ git status# Not currently on any branch.# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: src/com/android/launcher/Workspace.java## 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: src/com/android/launcher/LiveFolder.java#

$ git status# Not currently on any branch.# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: src/com/android/launcher/Workspace.java## 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: src/com/android/launcher/LiveFolder.java#

$ git status# Not currently on any branch.# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: src/com/android/launcher/Workspace.java## 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: src/com/android/launcher/LiveFolder.java#

by default, reset changes the staging area

$ git status# Not currently on any branch.# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: src/com/android/launcher/Workspace.java## 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: src/com/android/launcher/LiveFolder.java#

$ git reset --hard

--hard changes stage and working directory

you’ve made commits, but want to move them

to a topic branch

$ git branch experiment $ git reset --hard origin/master$ git checkout topicname

$ git branch experiment $ git reset --hard origin/master$ git checkout topicname

$ git branch experiment $ git reset --hard origin/master$ git checkout experiment

C0

HEAD

C1origin/master

master

C0

HEAD

C1origin/master

master

C2

C3

C0

HEAD

C1origin/master

master

C2

C3 experiment

git checkout experiment

C0

HEAD

C1origin/master

master C2

C3 experiment

git reset --hard origin/master

C0

HEAD

C1origin/master

master C2

C3

experiment

C4

git commit

Debugging

Annotation

git blame

git blameie: “what dumbass did this? oh, it was me...”

git blame daemon.c979e32fa (Randal L. Schwartz 2005-10-25 16:29:09 -0700 1) #include "cache.h"85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 2) #include "pkt-line.h"77cb17e9 (Michal Ostrowski 2006-01-10 21:12:17 -0500 3) #include "exec_cmd.h"49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 4) #include "interpolate.h"f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 5) 85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 6) #include <syslog.h>85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 7) 695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 8) #ifndef HOST_NAME_MAX695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 9) #define HOST_NAME_MAX 256695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 10) #endif695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 11) 415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 12) #ifndef NI_MAXSERV415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 13) #define NI_MAXSERV 32415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 14) #endif415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 15) 9048fe1c (Petr Baudis 2005-09-24 16:13:01 +0200 16) static int log_syslog;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 17) static int verbose;1955fabf (Mark Wooding 2006-02-03 20:27:04 +0000 18) static int reuseaddr;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 19) 960deccb (H. Peter Anvin 2005-10-19 14:27:01 -0700 20) static const char daemon_usage[] =1b1dd23f (Stephan Beyer 2008-07-13 15:36:15 +0200 21) "git daemon [--verbose] [--syslog] [3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 22) " [--timeout=n] [--init-ti3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 23) " [--strict-paths] [--base73a7a656 (Jens Axboe 2007-07-27 14:00:29 -0700 24) " [--user-path | --user-pa49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 25) " [--interpolated-path=pat678dac6b (Tilman Sauerbeck 2006-08-22 19:37:41 +0200 26) " [--reuseaddr] [--detach]d9edcbd6 (Junio C Hamano 2006-09-07 01:40:04 -0700 27) " [--[enable|disable|allowdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 28) " [--inetd | [--listen=hosdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 29) " [--user=user dd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 30) " [directory...]";4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 31) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 32) /* List of acceptable pathname prefi96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 33) static char **ok_paths;96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 34) static int strict_paths;4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 35) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 36) /* If this is set, git-daemon-export96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 37) static int export_all_trees;

git blame daemon.c979e32fa (Randal L. Schwartz 2005-10-25 16:29:09 -0700 1) #include "cache.h"85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 2) #include "pkt-line.h"77cb17e9 (Michal Ostrowski 2006-01-10 21:12:17 -0500 3) #include "exec_cmd.h"49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 4) #include "interpolate.h"f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 5) 85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 6) #include <syslog.h>85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 7) 695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 8) #ifndef HOST_NAME_MAX695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 9) #define HOST_NAME_MAX 256695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 10) #endif695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 11) 415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 12) #ifndef NI_MAXSERV415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 13) #define NI_MAXSERV 32415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 14) #endif415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 15) 9048fe1c (Petr Baudis 2005-09-24 16:13:01 +0200 16) static int log_syslog;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 17) static int verbose;1955fabf (Mark Wooding 2006-02-03 20:27:04 +0000 18) static int reuseaddr;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 19) 960deccb (H. Peter Anvin 2005-10-19 14:27:01 -0700 20) static const char daemon_usage[] =1b1dd23f (Stephan Beyer 2008-07-13 15:36:15 +0200 21) "git daemon [--verbose] [--syslog] [3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 22) " [--timeout=n] [--init-ti3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 23) " [--strict-paths] [--base73a7a656 (Jens Axboe 2007-07-27 14:00:29 -0700 24) " [--user-path | --user-pa49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 25) " [--interpolated-path=pat678dac6b (Tilman Sauerbeck 2006-08-22 19:37:41 +0200 26) " [--reuseaddr] [--detach]d9edcbd6 (Junio C Hamano 2006-09-07 01:40:04 -0700 27) " [--[enable|disable|allowdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 28) " [--inetd | [--listen=hosdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 29) " [--user=user dd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 30) " [directory...]";4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 31) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 32) /* List of acceptable pathname prefi96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 33) static char **ok_paths;96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 34) static int strict_paths;4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 35) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 36) /* If this is set, git-daemon-export96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 37) static int export_all_trees;

git blame daemon.c979e32fa (Randal L. Schwartz 2005-10-25 16:29:09 -0700 1) #include "cache.h"85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 2) #include "pkt-line.h"77cb17e9 (Michal Ostrowski 2006-01-10 21:12:17 -0500 3) #include "exec_cmd.h"49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 4) #include "interpolate.h"f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 5) 85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 6) #include <syslog.h>85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 7) 695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 8) #ifndef HOST_NAME_MAX695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 9) #define HOST_NAME_MAX 256695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 10) #endif695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 11) 415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 12) #ifndef NI_MAXSERV415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 13) #define NI_MAXSERV 32415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 14) #endif415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 15) 9048fe1c (Petr Baudis 2005-09-24 16:13:01 +0200 16) static int log_syslog;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 17) static int verbose;1955fabf (Mark Wooding 2006-02-03 20:27:04 +0000 18) static int reuseaddr;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 19) 960deccb (H. Peter Anvin 2005-10-19 14:27:01 -0700 20) static const char daemon_usage[] =1b1dd23f (Stephan Beyer 2008-07-13 15:36:15 +0200 21) "git daemon [--verbose] [--syslog] [3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 22) " [--timeout=n] [--init-ti3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 23) " [--strict-paths] [--base73a7a656 (Jens Axboe 2007-07-27 14:00:29 -0700 24) " [--user-path | --user-pa49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 25) " [--interpolated-path=pat678dac6b (Tilman Sauerbeck 2006-08-22 19:37:41 +0200 26) " [--reuseaddr] [--detach]d9edcbd6 (Junio C Hamano 2006-09-07 01:40:04 -0700 27) " [--[enable|disable|allowdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 28) " [--inetd | [--listen=hosdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 29) " [--user=user dd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 30) " [directory...]";4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 31) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 32) /* List of acceptable pathname prefi96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 33) static char **ok_paths;96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 34) static int strict_paths;4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 35) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 36) /* If this is set, git-daemon-export96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 37) static int export_all_trees;

979e32fa (Randal L. Schwartz 2005-10-25 16:29:09 -0700 1) #include "cache.h"85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 2) #include "pkt-line.h"77cb17e9 (Michal Ostrowski 2006-01-10 21:12:17 -0500 3) #include "exec_cmd.h"49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 4) #include "interpolate.h"f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 5) 85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 6) #include <syslog.h>85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 7) 695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 8) #ifndef HOST_NAME_MAX695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 9) #define HOST_NAME_MAX 256695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 10) #endif695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 11) 415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 12) #ifndef NI_MAXSERV415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 13) #define NI_MAXSERV 32415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 14) #endif415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 15) 9048fe1c (Petr Baudis 2005-09-24 16:13:01 +0200 16) static int log_syslog;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 17) static int verbose;1955fabf (Mark Wooding 2006-02-03 20:27:04 +0000 18) static int reuseaddr;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 19) 960deccb (H. Peter Anvin 2005-10-19 14:27:01 -0700 20) static const char daemon_usage[] =1b1dd23f (Stephan Beyer 2008-07-13 15:36:15 +0200 21) "git daemon [--verbose] [--syslog] [3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 22) " [--timeout=n] [--init-ti3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 23) " [--strict-paths] [--base73a7a656 (Jens Axboe 2007-07-27 14:00:29 -0700 24) " [--user-path | --user-pa49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 25) " [--interpolated-path=pat678dac6b (Tilman Sauerbeck 2006-08-22 19:37:41 +0200 26) " [--reuseaddr] [--detach]d9edcbd6 (Junio C Hamano 2006-09-07 01:40:04 -0700 27) " [--[enable|disable|allowdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 28) " [--inetd | [--listen=hosdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 29) " [--user=user dd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 30) " [directory...]";4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 31) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 32) /* List of acceptable pathname prefi96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 33) static char **ok_paths;96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 34) static int strict_paths;4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 35) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 36) /* If this is set, git-daemon-export96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 37) static int export_all_trees;

git blame daemon.c

979e32fa (Randal L. Schwartz 2005-10-25 16:29:09 -0700 1) #include "cache.h"85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 2) #include "pkt-line.h"77cb17e9 (Michal Ostrowski 2006-01-10 21:12:17 -0500 3) #include "exec_cmd.h"49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 4) #include "interpolate.h"f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 5) 85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 6) #include <syslog.h>85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 7) 695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 8) #ifndef HOST_NAME_MAX695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 9) #define HOST_NAME_MAX 256695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 10) #endif695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 11) 415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 12) #ifndef NI_MAXSERV415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 13) #define NI_MAXSERV 32415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 14) #endif415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 15) 9048fe1c (Petr Baudis 2005-09-24 16:13:01 +0200 16) static int log_syslog;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 17) static int verbose;1955fabf (Mark Wooding 2006-02-03 20:27:04 +0000 18) static int reuseaddr;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 19) 960deccb (H. Peter Anvin 2005-10-19 14:27:01 -0700 20) static const char daemon_usage[] =1b1dd23f (Stephan Beyer 2008-07-13 15:36:15 +0200 21) "git daemon [--verbose] [--syslog] [3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 22) " [--timeout=n] [--init-ti3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 23) " [--strict-paths] [--base73a7a656 (Jens Axboe 2007-07-27 14:00:29 -0700 24) " [--user-path | --user-pa49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 25) " [--interpolated-path=pat678dac6b (Tilman Sauerbeck 2006-08-22 19:37:41 +0200 26) " [--reuseaddr] [--detach]d9edcbd6 (Junio C Hamano 2006-09-07 01:40:04 -0700 27) " [--[enable|disable|allowdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 28) " [--inetd | [--listen=hosdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 29) " [--user=user dd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 30) " [directory...]";4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 31) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 32) /* List of acceptable pathname prefi96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 33) static char **ok_paths;96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 34) static int strict_paths;4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 35) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 36) /* If this is set, git-daemon-export96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 37) static int export_all_trees;

git blame daemon.c

979e32fa (Randal L. Schwartz 2005-10-25 16:29:09 -0700 1) #include "cache.h"85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 2) #include "pkt-line.h"77cb17e9 (Michal Ostrowski 2006-01-10 21:12:17 -0500 3) #include "exec_cmd.h"49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 4) #include "interpolate.h"f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 5) 85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 6) #include <syslog.h>85023577 (Junio C Hamano 2006-12-19 14:34:12 -0800 7) 695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 8) #ifndef HOST_NAME_MAX695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 9) #define HOST_NAME_MAX 256695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 10) #endif695dffe2 (Johannes Schindelin 2006-09-28 12:00:35 +0200 11) 415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 12) #ifndef NI_MAXSERV415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 13) #define NI_MAXSERV 32415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 14) #endif415e7b87 (Patrick Welche 2007-10-18 18:17:39 +0100 15) 9048fe1c (Petr Baudis 2005-09-24 16:13:01 +0200 16) static int log_syslog;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 17) static int verbose;1955fabf (Mark Wooding 2006-02-03 20:27:04 +0000 18) static int reuseaddr;f8ff0c06 (Petr Baudis 2005-09-22 11:25:28 +0200 19) 960deccb (H. Peter Anvin 2005-10-19 14:27:01 -0700 20) static const char daemon_usage[] =1b1dd23f (Stephan Beyer 2008-07-13 15:36:15 +0200 21) "git daemon [--verbose] [--syslog] [3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 22) " [--timeout=n] [--init-ti3bd62c21 (Stephen R. van den Berg 2008-08-14 20:02:20 +0200 23) " [--strict-paths] [--base73a7a656 (Jens Axboe 2007-07-27 14:00:29 -0700 24) " [--user-path | --user-pa49ba83fb (Jon Loeliger 2006-09-19 20:31:51 -0500 25) " [--interpolated-path=pat678dac6b (Tilman Sauerbeck 2006-08-22 19:37:41 +0200 26) " [--reuseaddr] [--detach]d9edcbd6 (Junio C Hamano 2006-09-07 01:40:04 -0700 27) " [--[enable|disable|allowdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 28) " [--inetd | [--listen=hosdd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 29) " [--user=user dd467629 (Jon Loeliger 2006-09-26 09:47:43 -0500 30) " [directory...]";4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 31) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 32) /* List of acceptable pathname prefi96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 33) static char **ok_paths;96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 34) static int strict_paths;4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 35) 4ae95682 (H. Peter Anvin 2005-09-26 19:10:55 -0700 36) /* If this is set, git-daemon-export96f1e58f (David Rientjes 2006-08-15 10:23:48 -0700 37) static int export_all_trees;

git blame daemon.c

git blame -C GITPackUpload.m

git blame -C GITPackUpload.mf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 12) f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 13) #define PACK_SIGNf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 14) #define PACK_VERSf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 15) ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 16) @implementation Gad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 17) ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 18) @synthesize gitRead11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 19) @synthesize needRad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 20) @synthesize gitSoad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 21) @synthesize refDiad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 22) a2cbabf5 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-25 22:29:39 +0100 23) - (id) initWithGiad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 24) {a2cbabf5 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-25 22:29:39 +0100 25) gitRepo = ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 26) needRefs =ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 27) gitSocket ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 28) return selad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 29) }ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 30) ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 31) - (bool) uploadPaf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 32) {f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 33) NSLog(@"upf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 34) NSString *f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 35) NSArray *tf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 36) 56ef2caf Source/Network/GITServerHandler.m (Scott Chacon 2009-01-05 21:44:26 -0800 37) refDict = f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 38)

f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 12) f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 13) #define PACK_SIGNf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 14) #define PACK_VERSf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 15) ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 16) @implementation Gad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 17) ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 18) @synthesize gitRead11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 19) @synthesize needRad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 20) @synthesize gitSoad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 21) @synthesize refDiad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 22) a2cbabf5 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-25 22:29:39 +0100 23) - (id) initWithGiad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 24) {a2cbabf5 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-25 22:29:39 +0100 25) gitRepo = ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 26) needRefs =ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 27) gitSocket ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 28) return selad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 29) }ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 30) ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 31) - (bool) uploadPaf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 32) {f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 33) NSLog(@"upf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 34) NSString *f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 35) NSArray *tf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 36) 56ef2caf Source/Network/GITServerHandler.m (Scott Chacon 2009-01-05 21:44:26 -0800 37) refDict = f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 38)

git blame -C GITPackUpload.m

f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 12) f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 13) #define PACK_SIGNf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 14) #define PACK_VERSf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 15) ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 16) @implementation Gad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 17) ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 18) @synthesize gitRead11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 19) @synthesize needRad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 20) @synthesize gitSoad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 21) @synthesize refDiad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 22) a2cbabf5 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-25 22:29:39 +0100 23) - (id) initWithGiad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 24) {a2cbabf5 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-25 22:29:39 +0100 25) gitRepo = ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 26) needRefs =ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 27) gitSocket ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 28) return selad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 29) }ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 30) ad11ac80 Source/Network/GITPackUpload.m (Scott Chacon 2009-03-24 18:32:50 +0100 31) - (bool) uploadPaf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 32) {f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 33) NSLog(@"upf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 34) NSString *f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 35) NSArray *tf344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 36) 56ef2caf Source/Network/GITServerHandler.m (Scott Chacon 2009-01-05 21:44:26 -0800 37) refDict = f344f58d Source/Network/GITServerHandler.m (Scott Chacon 2009-01-04 18:59:04 -0800 38)

git blame -C GITPackUpload.m

Bisecting

binary search for where a bug was introduced

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table and$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table and$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table and$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table and$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table and$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table and$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table and$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect start$ git bisect bad$ git bisect good 3acb4c2c6666ed6cb91cb0b983efe9d50cf8cfbeBisecting: 6 revisions left to test after this[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo$ git bisect goodBisecting: 3 revisions left to test after this[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing$ git bisect badBisecting: 1 revisions left to test after this[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table$ git bisect goodb047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commitcommit b047b02ea83310a70fd603dc8cd7a6cd13d15c04Author: PJ Hyett <pjhyett@gmail.com>Date: Tue Jan 27 14:48:32 2009 -0800

secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config

$ git bisect reset

Rebasing

Rewriting History

Modifying the last commit

git commit --amend

Rebasing

C1

C4

C5

C2

C3

master topic

git merge masterC1

C4

C5

C2

C3

master

topic

C6

C1

C4

C5

C2

C3

master topic

git rebase master

C1

C4

C5

C2

C3

master topic

git rebase master

C1

C4

C5

C2

C3

master topic

git rebase master

C1

C4

C5

C2

C3

master topic

git rebase master

C1

C4

C5

C2

C3

master topic

git rebase master

git diff c2 c3 > 2-3.patch

diff --git a/test b/testindex 2eadcec..bd8c6c9 100644--- a/test+++ b/test@@ -1,2 +1,3 @@ version one version four+version fiveC1

C4

C5

C2

C3

master topic

git rebase master

git diff c2 c3 > 2-3.patch

2-3.patchC1

C4

C5

C2

C3

master topic

2-3.patchC1

C4

C5

C2

C3

master topic

git diff c1 c2 > 1-2.patch

2-3.patchC1

C4

C5

C2

C3

master topic

git diff c1 c2 > 1-2.patch1-2.patch

1-2.patch

2-3.patchC1

C4

C5

C2

C3

master topic

1-2.patch

2-3.patchC1

C4

C5

C2

C3

master topic

git rebase master

2-3.patchC1

C4

C5

C2

C3

master topic

git rebase master

1-2.patch

2-3.patch

git rebase master

C1

C4

C5

C2

C3

master

topic

C2'

2-3.patchgit rebase master

C1

C4

C5

C2

C3

master

topic

C2'

git rebase master

C1

C4

C5

C2

C3

master

topic

C2'

C3'

git rebase master

C1

C4

C5

C2

C3

master

topic

C2'

C3'

git rebase master

C1

C4

C5

C2

C3

master

topic

C2'

C3'

topic

C2'

C3'

C1

C4

C5

master

C1

C4

C5master

topic

C2'

C3'

git rebase master

topic

C2'

C3'

C1

C4

C5master

Fun with Rebasing

rebase --onto

Transplanting Topic Branches

C1 C2

master

C1 C2

master

C1 C2

C3

server

C1 C2

C3

C8 C9

client

C1 C2

master

server

C1 C2

server

C3 C4

C8

C10

C9

client

master

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

move your ‘client’ branch work to your

‘master’ branch

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase master

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase master

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase master

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase master

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase server

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase server

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase server

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase server

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase server --onto master

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase server --onto master

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase server --onto master

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

git rebase server --onto master

C8 C9

C8 C9C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

C8' C9'

client

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

client

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

C8' C9'

client

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

C8' C9'

client

git checkout servergit rebase master

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

C8' C9'

client

git checkout servergit rebase client

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

C8' C9'

client

git checkout servergit rebase client

C1 C2 C5

server

C3

master

C4

C6

C8

C10

C9

C8' C9'

client

git checkout servergit rebase client

C1 C2 C5 C6 C8' C9'

client

C3' C4' C10'

git checkout servergit rebase client

C1 C2 C5 C6 C8' C9'

client

C3' C4' C10'C1 C2 C5 C6 C8' C9'

client server

C3' C4' C10'

master

C1 C2 C5 C6 C8' C9'

client server

C3' C4' C10'

git checkout servergit rebase client

master

transplant some of a topic branch

C1C0 C2

C3

master

topic

C4 C5

C1C0 C2

C3

master

topic

C4 C5

git branch newtopic C3

C1C0 C2

C3

master

topic

C4 C5

git branch newtopic C3

newtopic

C1C0 C2

C3

master

topic

C4 C5

git branch newtopic C3git rebase newtopic --onto master

newtopic

C1C0 C2

C3

master

topic

C4 C5

C1C0 C2

C3

master topic

C4 C5

C4' C5'

git branch newtopic C3git rebase newtopic --onto master

newtopic

Fixing a commit several back

git rebase -igit rebase --interactive

C1

C0

C2

C3

C4

default

C1

C0

C2

C3

C4

default

C1

C0

C2

C3

C4

default

default~2

C1

C0

C2

C3

C4

default

default~2

git rebase -i default~2^

git rebase -i default~2^

git rebase -i default~2^

pick 969c877 git apply --directory broken for new filespick b75271d git diff <tree>{3,}: do not reverse order of argspick 72d404d test-lib: fix broken printf

# Rebase f285a2d..5c283eb onto f285a2d## Commands:# p, pick = use commit# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#~ ~ ~ ~ ~ "~/projects/git/.git/rebase-merge/git-rebase-todo" 14L, 472C

pick 969c877 git apply --directory broken for new filespick b75271d git diff <tree>{3,}: do not reverse order of argspick 72d404d test-lib: fix broken printf

# Rebase f285a2d..5c283eb onto f285a2d## Commands:# p, pick = use commit# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#~ ~ ~ ~ ~ "~/projects/git/.git/rebase-merge/git-rebase-todo" 14L, 472C

C2

C3

C4

pick 969c877 git apply --directory broken for new filespick b75271d git diff <tree>{3,}: do not reverse order of argspick 72d404d test-lib: fix broken printf

# Rebase f285a2d..5c283eb onto f285a2d## Commands:# p, pick = use commit# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#~ ~ ~ ~ ~ "~/projects/git/.git/rebase-merge/git-rebase-todo" 14L, 472C

pick 969c877 git apply --directory broken for new filespick b75271d git diff <tree>{3,}: do not reverse order of argspick 72d404d test-lib: fix broken printf

# Rebase f285a2d..5c283eb onto f285a2d## Commands:# p, pick = use commit# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#~ ~ ~ ~ ~ "~/projects/git/.git/rebase-merge/git-rebase-todo" 14L, 472C

pick 969c877 git apply --directory broken for new filespick b75271d git diff <tree>{3,}: do not reverse order of argspick 72d404d test-lib: fix broken printf

# Rebase f285a2d..5c283eb onto f285a2d## Commands:# p, pick = use commit# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#~ ~ ~ ~ ~ "~/projects/git/.git/rebase-merge/git-rebase-todo" 14L, 472C

pick 969c877 git apply --directory broken for new filespick b75271d git diff <tree>{3,}: do not reverse order of argspick 72d404d test-lib: fix broken printf

# Rebase f285a2d..5c283eb onto f285a2d## Commands:# p, pick = use commit# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#~ ~ ~ ~ ~ "~/projects/git/.git/rebase-merge/git-rebase-todo" 14L, 472C

pick 969c877 git apply --directory broken for new filespick b75271d git diff <tree>{3,}: do not reverse order of argspick 72d404d test-lib: fix broken printf

# Rebase f285a2d..5c283eb onto f285a2d## Commands:# p, pick = use commit# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#~ ~ ~ ~ ~ "~/projects/git/.git/rebase-merge/git-rebase-todo" 14L, 472C

edit 969c877 git apply --directory broken for new filespick b75271d git diff <tree>{3,}: do not reverse order of argspick 72d404d test-lib: fix broken printf

# Rebase f285a2d..5c283eb onto f285a2d## Commands:# p, pick = use commit# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#~ ~ ~ ~ ~ "~/projects/git/.git/rebase-merge/git-rebase-todo" 14L, 472C

$ git rebase -i default~2^Stopped at 969c877... git apply --directory broken for new filesYou can amend the commit now, with

git commit --amend

Once you are satisfied with your changes, run

git rebase --continue

$_

$ git rebase -i default~2^Stopped at 969c877... git apply --directory broken for new filesYou can amend the commit now, with

git commit --amend

Once you are satisfied with your changes, run

git rebase --continue

$_

edit filesgit add

git commit --amendgit rebase --continue

$ git rebase -i default~2^Stopped at 969c877... git apply --directory broken for new filesYou can amend the commit now, with

git commit --amend

Once you are satisfied with your changes, run

git rebase --continue

$_

edit filesgit add

git commit --amendgit rebase --continue

$ git rebase -i default~2^Stopped at 969c877... git apply --directory broken for new filesYou can amend the commit now, with

git commit --amend

Once you are satisfied with your changes, run

git rebase --continue

$_

edit filesgit add

git commit --amendgit rebase --continue

$ git rebase -i default~2^Stopped at 969c877... git apply --directory broken for new filesYou can amend the commit now, with

git commit --amend

Once you are satisfied with your changes, run

git rebase --continue

$_

edit filesgit add

git commit --amendgit rebase --continue

C1

C0

C2

C3

C4

default

C2'

C3'

C4'

C1

C0

C2

C3

C4

default

C2'

C3'

C4'

C1

C0

C2

C3

C4

default

C2'

C3'

C4'

Squashing commits together

pick 969c877 git apply --directory broken for new filespick b75271d git diff <tree>{3,}: do not reverse order of argspick 72d404d test-lib: fix broken printf

# Rebase f285a2d..5c283eb onto f285a2d## Commands:# p, pick = use commit# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#~ ~ ~ ~ ~ "~/projects/git/.git/rebase-merge/git-rebase-todo" 14L, 472C

pick 969c877 git apply --directory broken for new filessquash b75271d git diff <tree>{3,}: do not reverse order of argssquash 72d404d test-lib: fix broken printf

# Rebase f285a2d..5c283eb onto f285a2d## Commands:# p, pick = use commit# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#~ ~ ~ ~ ~ "~/projects/git/.git/rebase-merge/git-rebase-todo" 14L, 472C

# This is a combination of 3 commits.# The first commit's message is:git apply --directory broken for new files

# This is the 2nd commit message:

git diff <tree>{3,}: do not reverse order of args

# This is the 3rd commit message:

test-lib: fix broken printf

# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## Author: Jeff King <peff@peff.net>## Not currently on any branch.# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: builtin-apply.c# modified: builtin-diff.c# modified: t/t4013-diff-various.sh# new file: t/t4013/diff.diff_master_master^_side# modified: t/t4128-apply-root.sh# modified: t/test-lib.sh#~ ~ ".git/COMMIT_EDITMSG" 39L, 1454C

# This is a combination of 3 commits.# The first commit's message is:git apply --directory broken for new files

# This is the 2nd commit message:

git diff <tree>{3,}: do not reverse order of args

# This is the 3rd commit message:

test-lib: fix broken printf

# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## Author: Jeff King <peff@peff.net>## Not currently on any branch.# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: builtin-apply.c# modified: builtin-diff.c# modified: t/t4013-diff-various.sh# new file: t/t4013/diff.diff_master_master^_side# modified: t/t4128-apply-root.sh# modified: t/test-lib.sh#~ ~ ".git/COMMIT_EDITMSG" 39L, 1454C

# This is a combination of 3 commits.# The first commit's message is:git apply --directory broken for new files

# This is the 2nd commit message:

git diff <tree>{3,}: do not reverse order of args

# This is the 3rd commit message:

test-lib: fix broken printf

# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## Author: Jeff King <peff@peff.net>## Not currently on any branch.# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: builtin-apply.c# modified: builtin-diff.c# modified: t/t4013-diff-various.sh# new file: t/t4013/diff.diff_master_master^_side# modified: t/t4128-apply-root.sh# modified: t/test-lib.sh#~ ~ ".git/COMMIT_EDITMSG" 39L, 1454C

# This is a combination of 3 commits.# The first commit's message is:git apply --directory broken for new files

# This is the 2nd commit message:

git diff <tree>{3,}: do not reverse order of args

# This is the 3rd commit message:

test-lib: fix broken printf

# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## Author: Jeff King <peff@peff.net>## Not currently on any branch.# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: builtin-apply.c# modified: builtin-diff.c# modified: t/t4013-diff-various.sh# new file: t/t4013/diff.diff_master_master^_side# modified: t/t4128-apply-root.sh# modified: t/test-lib.sh#~ ~ ".git/COMMIT_EDITMSG" 39L, 1454C

C1

C0

C2

C3

C4

default

C5

The Perils

C1

C0

default

scott jessica

C0

default

scott jessica

C1

C0

scott/default

default

C2

C3

C4

C1

C0

C5

C6

C7

default

scott jessica

C1

C0

scott/default default

C2

C3

C4

C1

C5

C6

C7

C0

C5

C6

C7

default

scott jessica

C1

C0

scott/default

default

C2

C3

C4

C1

C5

C6

C7

C8

C0

C5

C6

C7

default

scott jessica

C1

C0

scott/default

default

C2

C3

C4

C1

C5

C6

C7

C5'

C6'

C7'

C8

C0

C5

C6

C7

default

scott jessica

C1

C0

scott/default

default

C2

C3

C4

C1

C5

C6

C7

C5'

C6'

C7'

C8

C5'

C6'

C7'

C0

C5

C6

C7

default

scott jessica

C1

C0

scott/default

default

C2

C3

C4

C1

C5

C6

C7

C5'

C6'

C7'

C8

C5'

C6'

C7'

C9

Filter BranchHistory Revision on Steroids

remove all instances of a file from every commit

git filter-branch --tree-filter 'rm -f filename'

HEAD

change your email in all commits

git filter-branch --env-filter "export GIT_AUTHOR_EMAIL=you@email.com"

HEAD

git filter-branch --env-filter "export GIT_AUTHOR_EMAIL=you@email.com"

origin/master..HEAD

Cherry Picking

git cherry-pick 3f40a

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake default

experiment

C10

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake default

experiment

C10

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake default

experiment

C10

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake default

experiment

C10

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake default

experiment

C10

git checkout default

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake default

experiment

C10

git cherry-pick c9

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake default

experiment

C10

git cherry-pick c9git cherry-pick experiment^

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake default

experiment

C10

git cherry-pick c9

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake

default experiment

C10C9'

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake

default experiment

C10C9'

git branch -d experiment

C1

C0

C2

C6

C7

C3

C4 C8

C9C5

m/cupcake

default experiment

C10C9'

Customizing

Colors

$ git config --global color.ui true

Custom Merge Tool

perforce visual merge tool

http://www.perforce.com/perforce/products/merge.html

$ cat /usr/local/bin/extMerge #!/bin/sh /Applications/p4merge.app/Contents/MacOS/p4merge $*

$ git config --global merge.tool extMerge

$ git config --global mergetool.extMerge.cmd 'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'

$ git config --global mergetool.trustExitCode = false

[merge] tool = extMerge[mergetool "extMerge"] cmd = extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED" trustExitCode = false

~/.gitconfig

git mergetool

Git Attributes

.gitattributes

Diff Binary Files

Images

diff --git a/image.png b/image.pngindex 88839c4..4afcb7c 100644Binary files a/image.png and b/image.png differ

tell Git how to diff a binary file

exiftool

$ echo '*.png diff=exif' >> .gitattributes$ git config diff.exif.textconv exiftool

$ echo '*.png diff=exif' >> .gitattributes$ git config diff.exif.textconv exiftool

every file that ends in .png

$ echo '*.png diff=exif' >> .gitattributes$ git config diff.exif.textconv exiftool

pre-process them with a strategy called ‘exif ’

$ echo '*.png diff=exif' >> .gitattributes$ git config diff.exif.textconv exiftool

$ echo '*.png diff=exif' >> .gitattributes$ git config diff.exif.textconv exiftool

the ‘exif ’ strategy is to run ‘exiftool’ on it

$ exiftool image.png ExifTool Version Number : 7.74File Name : image.pngDirectory : .File Size : 94 kBFile Modification Date/Time : 2009:04:21 07:02:43-07:00File Type : PNGMIME Type : image/pngImage Width : 1056Image Height : 827Bit Depth : 8Color Type : RGB with AlphaCompression : Deflate/InflateFilter : AdaptiveInterlace : NoninterlacedProfile CMM Type : applProfile Version : 2.0.0Profile Class : Display Device ProfileColor Space Data : RGBProfile Connection Space : XYZProfile Date Time : 2009:04:05 12:26:58Profile File Signature : acspPrimary Platform : Apple Computer Inc.CMM Flags : Not Embedded, IndependentDevice Manufacturer : Device Model : Device Attributes : Reflective, Glossy, Positive, ColorRendering Intent : PerceptualConnection Space Illuminant : 0.9642 1 0.82491Profile Creator : applProfile ID : 0Red Matrix Column : 0.39493 0.22505 0.02957Green Matrix Column : 0.42793 0.69208 0.14424Blue Matrix Column : 0.14134 0.08327 0.65096Media White Point : 0.95047 1 1.0891Chromatic Adaptation : 1.04788 0.02292 -0.0502 0.02957 0.99049 -0.01706 -0.00923 0.01508 0.75165Red Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract)Green Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract)Blue Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract)Video Card Gamma : (Binary data 1554 bytes, use -b option to extract)Native Display Info : (Binary data 1598 bytes, use -b option to extract)Profile Description : Color LCDProfile Description ML : Farge-LCDMake And Model : (Binary data 40 bytes, use -b option to extract)Profile Copyright : Copyright Apple, Inc., 2009Pixels Per Unit X : 5906Pixels Per Unit Y : 5906Pixel Units : MetersImage Size : 1056x827

$ echo '*.png diff=exif' >> .gitattributes$ git config diff.exif.textconv exiftool

diff --git a/image.png b/image.png index 88839c4..4afcb7c 100644 --- a/image.png +++ b/image.png @@ -1,12 +1,12 @@ ExifTool Version Number : 7.74 -File Size : 70 kB -File Modification Date/Time : 2009:04:21 07:02:45-07:00 +File Size : 94 kB +File Modification Date/Time : 2009:04:21 07:02:43-07:00 File Type : PNG MIME Type : image/png -Image Width : 1058 -Image Height : 889 +Image Width : 1056 +Image Height : 827 Bit Depth : 8 Color Type : RGB with Alpha

Documents

$ echo '*.doc diff=doc' >> .gitattributes$ git config diff.doc.textconv strings

$ git diff diff --git a/chapter1.doc b/chapter1.doc index c1c8a0a..b93c9e4 100644 --- a/chapter1.doc +++ b/chapter1.doc @@ -8,7 +8,8 @@ re going to cover Version Control Systems (VCS) and Git basics re going to cover how to get it and set it up for the first time if you don t already have it on your system. In Chapter Two we will go over basic Git usage - how to use Git for the 80% -s going on, modify stuff and contribute changes. If the book spontaneously +s going on, modify stuff and contribute changes. If the book spontaneously +Let's see if this works. Chapter Three is about the branching model in Git, often described as Git

$ git diff diff --git a/chapter1.doc b/chapter1.doc index c1c8a0a..b93c9e4 100644 --- a/chapter1.doc +++ b/chapter1.doc @@ -8,7 +8,8 @@ re going to cover Version Control Systems (VCS) and Git basics re going to cover how to get it and set it up for the first time if you don t already have it on your system. In Chapter Two we will go over basic Git usage - how to use Git for the 80% -s going on, modify stuff and contribute changes. If the book spontaneously +s going on, modify stuff and contribute changes. If the book spontaneously +Let's see if this works. Chapter Three is about the branching model in Git, often described as Git

File Filtering

Staging Area

fileA.txt

fileB.txt

fileC.rb

clean

smudge

*.txt Filter

Staging Area

fileA.txt

fileB.txt

fileC.rb

clean

smudge

*.txt Filter

Staging Area

fileA.txt

fileB.txt

fileC.rb

git checkout

Staging Area Working Directory

fileA.txt

fileB.txt clean

smudge fileA.txt'

fileB.txt'

*.txt Filter

fileC.rb fileC.rb

git checkout

Staging Area Working Directory

fileA.txt

fileB.txt clean

smudge fileA.txt'

fileB.txt'

*.txt Filter

fileC.rb fileC.rb

Staging Area Working Directory

fileA.txt

fileB.txt clean

smudge fileA.txt'

fileB.txt'

*.txt Filter

fileC.rb fileC.rb

git commit

Staging Area Working Directory

fileA.txt

fileB.txt clean

smudge fileA.txt'

fileB.txt'

*.txt Filter

fileC.rb fileC.rb

git commit

expanding a $Date$

#! /usr/bin/env rubydata = STDIN.readdate = `git log --pretty=format:"%ad" -1`puts data.gsub('$Date$', '$Date: ' + date + '$')

/usr/bin/expand_date

git config filter.dater.smudge expand_date

git config filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'

git config filter.dater.smudge expand_date

git config filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'

replace $Date(whatever)$ with $Date$

git config filter.dater.smudge expand_date

git config filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'

replace $Date(whatever)$ with $Date$

test it

$ echo '# $Date$' > date_test.rb $ echo 'date*.rb filter=dater' >> .gitattributes

$ git add date_test.rb .gitattributes$ git commit -m "Testing date expansion in Git"$ rm date_test.rb$ git checkout date_test.rb$ cat date_test.rb# $Date: Tue Apr 21 07:26:52 2009 -0700$

$ echo '# $Date$' > date_test.rb $ echo 'date*.rb filter=dater' >> .gitattributes

$ git add date_test.rb .gitattributes$ git commit -m "Testing date expansion in Git"$ rm date_test.rb$ git checkout date_test.rb$ cat date_test.rb# $Date: Tue Apr 21 07:26:52 2009 -0700$

$ echo '# $Date$' > date_test.rb $ echo 'date*.rb filter=dater' >> .gitattributes

$ git add date_test.rb .gitattributes$ git commit -m "Testing date expansion in Git"$ rm date_test.rb$ git checkout date_test.rb$ cat date_test.rb# $Date: Tue Apr 21 07:26:52 2009 -0700$

use the ‘dater’ filter for any files matching ‘date*.rb’

$ echo '# $Date$' > date_test.rb $ echo 'date*.rb filter=dater' >> .gitattributes

$ git add date_test.rb .gitattributes$ git commit -m "Testing date expansion in Git"$ rm date_test.rb$ git checkout date_test.rb$ cat date_test.rb# $Date: Tue Apr 21 07:26:52 2009 -0700$

$ echo '# $Date$' > date_test.rb $ echo 'date*.rb filter=dater' >> .gitattributes

$ git add date_test.rb .gitattributes$ git commit -m "Testing date expansion in Git"$ rm date_test.rb$ git checkout date_test.rb$ cat date_test.rb# $Date: Tue Apr 21 07:26:52 2009 -0700$

$ echo '# $Date$' > date_test.rb $ echo 'date*.rb filter=dater' >> .gitattributes

$ git add date_test.rb .gitattributes$ git commit -m "Testing date expansion in Git"$ rm date_test.rb$ git checkout date_test.rb

$ cat date_test.rb# $Date: Tue Apr 21 07:26:52 2009 -0700$

$ git add date_test.rb .gitattributes$ git commit -m "Testing date expansion in Git"$ rm date_test.rb$ git checkout date_test.rb

$ cat date_test.rb# $Date: Tue Apr 21 07:26:52 2009 -0700$

$ echo '# $Date$' > date_test.rb $ echo 'date*.rb filter=dater' >> .gitattributes