Smacking Git Around Advanced Git Tricks

50 %
50 %
Information about Smacking Git Around Advanced Git Tricks

Published on May 6, 2009

Author: railsconf

Source: slideshare.net

Smacking Git Around by Scott Chacon

Me

Scott Chacon

github.com/schacon

“Scott Chacon has an understandable but borderline unhealthy obsession with Git” - Ilya Grigorik igvita.com

git-scm.com

book.git-scm.com

schacon@gmail.com

</me>

previously, on Git...

GIT

Git

image by matthew mccullough

Scott Chacon Scott Scott Chacon is a Git v1 v2 v3

98ca9.. 34ac2.. f30ab.. commit commit commit size size size tree tree tree 0de24 184ca 92ec2 author parent parent Scott 98ca9 34ac2 committer author author Scott Scott Scott committer committer initial commit of my project Scott Scott fixed bug #1328 - stack add feature #32 - ability to overflow under certain add new formats to the central snapshot A snapshot B snapshot C

98ca9.. e8455.. commit size blob size 0de24.. 0de24.. tree 0de24 == LICENSE: tree size parent nil (The MIT License) author Scott blob e8455 README Copyright (c) 2007 Tom Preston- committer Scott tree 10af9 lib Permission is hereby granted, f my commit message goes here ree of charge, to any person ob and it is really, really cool bc52a.. 10af9.. blob size tree size require 'grit/index' blob bc52a mylib.rb require 'grit/status' tree b70f8 inc module Grit class << self attr_accessor :debug b70f8.. 0ad1a.. tree size size blob blob 0ad1a tricks.rb require 'grit/git-ruby/reposi require 'grit/git-ruby/file_i module Grit module Tricks

98ca9.. e8455.. commit size blob size 0de24.. 0de24.. tree 0de24 == LICENSE: tree size parent nil (The MIT License) author Scott blob e8455 README Copyright (c) 2007 Tom Preston- committer Scott tree 10af9 lib Permission is hereby granted, f my commit message goes here ree of charge, to any person ob and it is really, really cool bc52a.. 10af9.. blob size tree size require 'grit/index' blob bc52a mylib.rb require 'grit/status' tree b70f8 inc module Grit class << self attr_accessor :debug b70f8.. 0ad1a.. tree size size blob blob 0ad1a tricks.rb require 'grit/git-ruby/reposi require 'grit/git-ruby/file_i module Grit module Tricks

0de24.. 22d8858e8513666bf91b82bd2939ec7b0d1974da

stable master 98ca9 34ac2 f30ab a23fe 3acd1 topic

stable master 98ca9 34ac2 f30ab a23fe 3acd1 topic

stable master 98ca9 34ac2 f30ab a23fe 3acd1 topic

stable master 98ca9 34ac2 f30ab a23fe 3acd1 topic

$ time git checkout -b newbranch Switched to a new branch quot;newbranchquot; real 0m0.040s user 0m0.003s sys 0m0.008s

$ time git checkout -b newbranch Switched to a new branch quot;newbranchquot; real 0m0.040s user 0m0.003s sys 0m0.008s

master develop topic

distributed development image by matthew mccullough

ccf03da00eca1b60a489354c1278c27f1fbc55dc a640106f173c5be59ed5757cf33f568b3e10994f c51a137df64b8ed2f8d84ad62df7b49b1c409906 7e06f7f8d471d5ccbe958fcfaef0fc48ff1a3def dafe95908f7b9cbd2697f04544b68904a6c59aac 2934b685f5dfd2b12c5d7d35d07c6058640f0581 d3b47a90ef9bf2d7bbc5a7cf2b2f27eef4a08f04 dbfeee0f5717d9978788da17cd6853316c92744a 864734938d4044fc5e713e4818f60ecb4f460525 3793a0108438a539f958236dbb9f4ea98b6b70ea 00a60fa1439f082128c1ec03ec3c73acab074d31 6ba82b4879f04de35ffe2ef02d50df0adf184fad 861020b6afeeec245afa2f864c72f5c2588295be 505f3128a573bfe1d23aec2acef83c34c3cbd8be 213e6f8761df038ab0b7c34a9fc4c2c3ce6c8b43 798a8088bcc7cf47fdb33a9d79e398220b660f88

C

fast

efficient

100k repos

80k users

</git-recap>

Git Tips and Tricks

Tips and Tricks Selection and Ranges Data Munging Debugging Customizing

Selection and Ranges

Revision Selection

Revision Selection alternate ways to refer to objects or ranges of objects

Revision Selection full sha-1 partial sha-1 branch or tag name caret parent tilde spec blob spec relative specs ranges

Full SHA1 6e453f523fa1da50ecb04431101112b3611c6a4d

Partial SHA1 6e453f523fa1da50ecb04431101112b3611c6a4d 6e453f523fa1da50 6e453

Branch, Remote or Tag Name v1.0 default m/cupcake

Caret Parent default^2 2nd parent of ‘default’

b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

master^ b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

master^2 b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

Tilde Spec default~2 grandparent of ‘default’ (parent of the parent)

master~2 b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

master^^^2 master~2^2 b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

master^^^2 master~2^2 b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

master^^^2 master~2^2 b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

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

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

“Reachability”

jess/master..master b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..master b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..master b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..master b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..master b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..master b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..master b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..master b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..c36ae b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..c36ae b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..c36ae b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

jess/master..c36ae b3be1 a09c6 df2fa c36ae 5ec47 ce0e4 2f45e 4eadf 2fbb3 18cae jess/master master

Advanced Log

Log Subsets

what am I going to push?

git log origin/master..

C1 origin/master master HEAD C0

C4 master HEAD C3 C2 C1 origin/master C0

C7 C4 origin/master master HEAD C6 C3 C5 C2 C1 git fetch origin C0

C7 C4 origin/master master HEAD C6 C3 C5 C2 C1 git log origin/master.. C0

C7 C4 origin/master master HEAD C6 C3 C5 C2 C1 git log origin/master..HEAD C0

C7 C4 origin/master master HEAD C6 C3 C5 C2 C1 git log origin/master..HEAD C0

C7 C4 origin/master master HEAD C6 C3 C5 C2 C1 git log origin/master..HEAD C0

C7 C4 origin/master master HEAD C6 C3 C5 C2 C1 git log origin/master..HEAD C0

commit 72d404debaa804fca82fd9cf710fbde48c7305c6 Author: 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 969c877506cf8cc760c7b251fef6c5b6850bfc19 Author: 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 quot;+++quot; headers match what was provided on the command line of quot;diff --gitquot;. 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 ff74126c03a8dfd04e7533573a5c420f2a7112ac Author: 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 72d404debaa804fca82fd9cf710fbde48c7305c6 C4 Author: 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 969c877506cf8cc760c7b251fef6c5b6850bfc19 C3 Author: 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 quot;+++quot; headers match what was provided on the command line of quot;diff --gitquot;. 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 ff74126c03a8dfd04e7533573a5c420f2a7112ac C2 Author: 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

C7 C4 origin/master master HEAD C6 C3 C5 C2 C1 git log origin/master .. HEAD C0

C7 C4 origin/master master HEAD C6 C3 C5 C2 C1 git log HEAD .. origin/master C0

C7 C4 origin/master master HEAD C6 C3 C5 C2 C1 git log HEAD .. origin/master C0 “commits in origin/master not in HEAD”

git log origin/master.. git log origin/master..HEAD git log origin/master..master git log master ^origin/master git log master --not origin/master

git log HEAD ^origin/master

git log HEAD ^origin/master

git log master topic1 ^origin/master

origin/master C1 C0

master C3 origin/master C1 C0

experiment C10 C9 C8 master C3 origin/master C1 C0

experiment C10 master origin/master C9 C7 C5 C6 C4 C8 C2 C3 C1 C0

which changes aren’t in experiment?

git log origin/master master ^experiment experiment C10 master origin/master C9 C7 C5 C6 C4 C8 C2 C3 C1 C0

git log origin/master master ^experiment experiment C10 master origin/master C9 C7 C5 C6 C4 C8 C2 C3 C1 C0

git log origin/master master ^experiment experiment C10 master origin/master C9 C7 C5 C6 C4 C8 C2 C3 C1 C0

git log origin/master master ^experiment experiment C10 master origin/master C9 C7 C5 C6 C4 C8 C2 C3 C1 C0

git log origin/master master ^experiment experiment C10 master origin/master C9 C7 C5 C6 C4 C8 C2 C3 C1 C0

git log origin/master master ^experiment experiment C10 master origin/master C9 C7 C5 C6 C4 C8 C2 C3 C1 C0

git log origin/master master ^experiment experiment C10 master origin/master C9 C7 C5 C6 C4 C8 C2 C3 C1 C0

git log --graph

git log --pretty=oneline --graph

gitk

gitk 6d13f..41aba

Revision Diffs

git diff revA revB

$ echo ‘version one’ > test $ git add test $ git commit -m ‘C1’ master C1

$ git checkout -b topic $ echo ‘version two’ >> test $ git commit -m ‘C2’ topic C2 master C1

$ echo ‘version three’ >> test $ git commit -m ‘C3’ topic C3 C2 master C1

$ git checkout master $ echo ‘version four’ >> test $ git commit -m ‘C4’ topic C3 master C4 C2 C1

$ echo ‘version five’ >> test $ git commit -m ‘C5’ master topic C5 C3 C4 C2 C1

master topic $ git diff topic C5 C3 C4 C2 C1

master topic what does topic have $ git diff topic C5 C3 that I don’t have? C4 C2 C1

master topic what would happen if I $ git diff topic C5 C3 merged in topic? C4 C2 C1

master topic how do I make topic $ git diff topic C5 C3 look like HEAD? C4 C2 C1

$ git diff topic diff --git a/test b/test master topic index 304313d..bd8c6c9 100644 --- a/test +++ b/test C5 C3 @@ -1,3 +1,3 @@ version one -version two -version three C4 C2 +version four +version five C1

$ git diff topic diff --git a/test b/test master topic index 304313d..bd8c6c9 100644 --- a/test +++ b/test C5 C3 @@ -1,3 +1,3 @@ version one -version two -version three C4 C2 +version four +version five C1

$ git diff HEAD topic diff --git a/test b/test master topic index bd8c6c9..304313d 100644 --- a/test +++ b/test C5 C3 @@ -1,3 +1,3 @@ version one -version four -version five C4 C2 +version two +version three C1

$ git diff HEAD topic diff --git a/test b/test master topic index bd8c6c9..304313d 100644 --- a/test +++ b/test C5 C3 @@ -1,3 +1,3 @@ version one -version four -version five C4 C2 +version two +version three C1

git diff HEAD topic

git diff HEAD...topic

git diff HEAD...topic

$ git diff HEAD topic master topic C5 C3 C4 C2 C1

$ git diff HEAD topic master topic C5 C3 C4 C2 C1

$ git diff HEAD...topic master topic C5 C3 C4 C2 C1

$ git diff HEAD...topic diff --git a/test b/test master topic index 9bc69cf..304313d 100644 --- a/test +++ b/test @@ -1 +1,3 @@ C5 C3 version one +version two +version three C4 C2 C1

$ git diff HEAD...topic diff --git a/test b/test master topic index 9bc69cf..304313d 100644 --- a/test what would happen if I +++ b/test @@ -1 +1,3 @@ C5 C3 merged in topic? version one +version two +version three C4 C2 C1

Data Munging

Rewriting History

Modifying the last commit

git commit --amend

Rebasing

master topic C5 C3 C4 C2 C1

topic C6 master C5 C3 C4 C2 C1 git merge master

master topic C5 C3 C4 C2 C1 git rebase master

master topic C5 C3 C4 C2 C1 git rebase master

master topic C5 C3 C4 C2 C1 git rebase master

master topic C5 C3 C4 C2 C1 git rebase master

master topic git diff c2 c3 > 2-3.patch C5 C3 C4 C2 C1 git rebase master

master topic git diff c2 c3 > 2-3.patch C5 C3 diff --git a/test b/test index 2eadcec..bd8c6c9 100644 --- a/test C4 C2 +++ b/test @@ -1,2 +1,3 @@ version one version four C1 +version five git rebase master

master topic C5 C3 C4 C2 C1 2-3.patch

master topic C5 C3 C4 C2 git diff c1 c2 > 1-2.patch C1 2-3.patch

master topic C5 C3 C4 C2 git diff c1 c2 > 1-2.patch 1-2.patch C1 2-3.patch

master topic C5 C3 C4 C2 1-2.patch C1 2-3.patch

git rebase master master topic C5 C3 C4 C2 1-2.patch C1 2-3.patch

git rebase master 1-2.patch master topic C5 C3 C4 C2 C1 2-3.patch

git rebase master topic master C2' C5 C3 C4 C2 C1 2-3.patch

git rebase master 2-3.patch topic master C2' C5 C3 C4 C2 C1

topic git rebase master C3' master C2' C5 C3 C4 C2 C1

topic C3' master C2' git rebase master C5 C3 C4 C2 C1

topic C3' master C2' git rebase master C5 C3 C4 C2 C1

topic C3' C2' git rebase master C5 master C4 C1

Fun with Rebasing

rebase --onto

Transplanting Topic Branches

master C1 C2

master C1 C2 C3 server

master C1 C2 C3 server C8 C9 client

master C1 C2 C3 C4 C10 server C8 C9 client

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client

move your ‘client’ branch work to your ‘master’ branch

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase master

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase master

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase master

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase master

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase server

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase server

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase server

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase server

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase --onto master server

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase --onto master server

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase --onto master server

master C1 C2 C5 C6 C3 C4 C10 server C8 C9 client git rebase --onto master server

master client master C1 C5 C6 C8' C9' C1 C2 C6 C8 C9 C3 C4 C10 C4 C10 server server C8 C9 C8 C9 client

master client C1 C2 C5 C6 C8' C9' C3 C4 C10 server C8 C9

master client C1 C2 C5 C6 C8' C9' C3 C4 C10 server C8 C9 git checkout server git rebase master

master client C1 C2 C5 C6 C8' C9' C3 C4 C10 server C8 C9 git checkout server git rebase client

master client C1 C2 C5 C6 C8' C9' C3 C4 C10 server C8 C9 git checkout server git rebase client

master client client C1 C2 C5 C6 C8' C9' C6 C3' C4' C10' C3 C4 C10 server C8 C9 git checkout server git rebase client

client client server master C3' C10' C1 C1 C2 C2 C5 C5 C6 C6 C8' C8' C9' C9' C3' C4' git checkout server git rebase client

client server master C1 C2 C5 C6 C8' C9' C3' C4' C10' git checkout server git rebase client

transplant some of a topic branch

master C0 C1 C2 C3 C4 C5 topic

master C0 C1 C2 C3 C4 C5 topic

master C0 C1 C2 C3 C4 C5 topic git branch newtopic C3

master C0 C1 C2 C3 C4 C5 newtopic topic git branch newtopic C3

master C0 C1 C2 C3 C4 C5 newtopic topic git branch newtopic C3 git rebase --onto master newtopic

master topic C4' C5' C0 C1 C2 C3 C4 C5 newtopic git branch newtopic C3 git rebase --onto master newtopic

Fixing a commit several back

git rebase -i git rebase --interactive

default C4 C3 C2 C1 C0

default C4 C3 C2 C1 C0

default C4 C3 default~2 C2 C1 C0

default C4 C3 default~2 C2 C1 C0

git rebase -i default~2^

git rebase -i default~2^

git rebase -i default~2^

pick 969c877 git apply --directory broken for new files pick b75271d git diff <tree>{3,}: do not reverse order of args pick 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. # ~ ~ ~ ~ ~ quot;~/projects/git/.git/rebase-merge/git-rebase-todoquot; 14L, 472C

C2 pick 969c877 git apply --directory broken for new files pick b75271d git diff <tree>{3,}: do not reverse order of args C3 pick 72d404d test-lib: fix broken printf C4 # 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. # ~ ~ ~ ~ ~ quot;~/projects/git/.git/rebase-merge/git-rebase-todoquot; 14L, 472C

pick 969c877 git apply --directory broken for new files pick b75271d git diff <tree>{3,}: do not reverse order of args pick 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. # ~ ~ ~ ~ ~ quot;~/projects/git/.git/rebase-merge/git-rebase-todoquot; 14L, 472C

pick 969c877 git apply --directory broken for new files pick b75271d git diff <tree>{3,}: do not reverse order of args pick 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. # ~ ~ ~ ~ ~ quot;~/projects/git/.git/rebase-merge/git-rebase-todoquot; 14L, 472C

pick 969c877 git apply --directory broken for new files pick b75271d git diff <tree>{3,}: do not reverse order of args pick 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. # ~ ~ ~ ~ ~ quot;~/projects/git/.git/rebase-merge/git-rebase-todoquot; 14L, 472C

pick 969c877 git apply --directory broken for new files pick b75271d git diff <tree>{3,}: do not reverse order of args pick 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. # ~ ~ ~ ~ ~ quot;~/projects/git/.git/rebase-merge/git-rebase-todoquot; 14L, 472C

pick 969c877 git apply --directory broken for new files pick b75271d git diff <tree>{3,}: do not reverse order of args pick 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. # ~ ~ ~ ~ ~ quot;~/projects/git/.git/rebase-merge/git-rebase-todoquot; 14L, 472C

edit 969c877 git apply --directory broken for new files pick b75271d git diff <tree>{3,}: do not reverse order of args pick 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. # ~ ~ ~ ~ ~ quot;~/projects/git/.git/rebase-merge/git-rebase-todoquot; 14L, 472C

$ git rebase -i default~2^ Stopped at 969c877... git apply --directory broken for new files You 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 files You can amend the commit now, with git commit --amend Once you are satisfied with your changes, run git rebase --continue $_ edit files git add git commit --amend git rebase --continue

$ git rebase -i default~2^ Stopped at 969c877... git apply --directory broken for new files You can amend the commit now, with git commit --amend Once you are satisfied with your changes, run git rebase --continue $_ edit files git add git commit --amend git rebase --continue

$ git rebase -i default~2^ Stopped at 969c877... git apply --directory broken for new files You can amend the commit now, with git commit --amend Once you are satisfied with your changes, run git rebase --continue $_ edit files git add git commit --amend git rebase --continue

$ git rebase -i default~2^ Stopped at 969c877... git apply --directory broken for new files You can amend the commit now, with git commit --amend Once you are satisfied with your changes, run git rebase --continue $_ edit files git add git commit --amend git rebase --continue

default C4 C4' C3 C3' C2 C2' C1 C0

default C4 C4' C3 C3' C2 C2' C1 C0

default C4 C4' C3 C3' C2 C2' C1 C0

Squashing commits together

pick 969c877 git apply --directory broken for new files pick b75271d git diff <tree>{3,}: do not reverse order of args pick 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. # ~ ~ ~ ~ ~ quot;~/projects/git/.git/rebase-merge/git-rebase-todoquot; 14L, 472C

pick 969c877 git apply --directory broken for new files squash b75271d git diff <tree>{3,}: do not reverse order of args squash 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. # ~ ~ ~ ~ ~ quot;~/projects/git/.git/rebase-merge/git-rebase-todoquot; 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 quot;git reset HEAD <file>...quot; 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 # ~ ~ quot;.git/COMMIT_EDITMSGquot; 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 quot;git reset HEAD <file>...quot; 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 # ~ ~ quot;.git/COMMIT_EDITMSGquot; 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 quot;git reset HEAD <file>...quot; 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 # ~ ~ quot;.git/COMMIT_EDITMSGquot; 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 quot;git reset HEAD <file>...quot; 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 # ~ ~ quot;.git/COMMIT_EDITMSGquot; 39L, 1454C

C4 C3 default C2 C5 C1 C0

The Perils

scott jessica default C1 C0

scott jessica default C4 C3 C2 default scott/default C1 C1 C0 C0

scott jessica default scott/default default C7 C7 C4 C6 C6 C3 C5 C5 C2 C1 C1 C0 C0

scott jessica default C8 scott/default default C7 C7 C4 C6 C6 C3 C5 C5 C2 C1 C1 C0 C0

scott jessica default C8 scott/default default C7 C7 C7' C4 C6 C6 C6' C3 C5 C5 C5' C2 C1 C1 C0 C0

scott jessica default C8 scott/default default C7' C7 C7 C7' C4 C6' C6 C6 C6' C3 C5' C5 C5 C5' C2 C1 C1 C0 C0

scott jessica default C9 C8 scott/default default C7' C7 C7 C7' C4 C6' C6 C6 C6' C3 C5' C5 C5 C5' C2 C1 C1 C0 C0

Filter Branch History 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 quot;export GIT_AUTHOR_EMAIL=you@email.comquot; HEAD

git filter-branch --env-filter quot;export GIT_AUTHOR_EMAIL=you@email.comquot; origin/master..HEAD

Subtree Merging

Alternative to Submodules

$ ls README rack_app.rb $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote warning: no common commits remote: Counting objects: 3184, done. remote: Compressing objects: 100% (1465/1465), done. remote: Total 3184 (delta 1952), reused 2770 (delta 1675) Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, do Resolving deltas: 100% (1952/1952), done. From git@github.com:schacon/rack * [new branch] master -> rack_remote/master $ git checkout -b rack_branch rack_remote/master Branch rack_branch set up to track remote branch refs/remotes Switched to a new branch quot;rack_branchquot; $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

master C3 C2 C1 C0

$ ls README rack_app.rb $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote warning: no common commits remote: Counting objects: 3184, done. remote: Compressing objects: 100% (1465/1465), done. remote: Total 3184 (delta 1952), reused 2770 (delta 1675) Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, do Resolving deltas: 100% (1952/1952), done. From git@github.com:schacon/rack * [new branch] master -> rack_remote/master $ git checkout -b rack_branch rack_remote/master Branch rack_branch set up to track remote branch refs/remotes Switched to a new branch quot;rack_branchquot; $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

$ ls README rack_app.rb $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote warning: no common commits remote: Counting objects: 3184, done. remote: Compressing objects: 100% (1465/1465), done. remote: Total 3184 (delta 1952), reused 2770 (delta 1675) Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, do Resolving deltas: 100% (1952/1952), done. From git@github.com:schacon/rack * [new branch] master -> rack_remote/master $ git checkout -b rack_branch rack_remote/master Branch rack_branch set up to track remote branch refs/remotes Switched to a new branch quot;rack_branchquot; $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

$ ls README rack_app.rb $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote warning: no common commits remote: Counting objects: 3184, done. remote: Compressing objects: 100% (1465/1465), done. remote: Total 3184 (delta 1952), reused 2770 (delta 1675) Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, do Resolving deltas: 100% (1952/1952), done. From git@github.com:schacon/rack * [new branch] master -> rack_remote/master $ git checkout -b rack_branch rack_remote/master Branch rack_branch set up to track remote branch refs/remotes Switched to a new branch quot;rack_branchquot; $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

$ ls README rack_app.rb $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote warning: no common commits remote: Counting objects: 3184, done. remote: Compressing objects: 100% (1465/1465), done. remote: Total 3184 (delta 1952), reused 2770 (delta 1675) Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, do Resolving deltas: 100% (1952/1952), done. From git@github.com:schacon/rack * [new branch] master -> rack_remote/master $ git checkout -b rack_branch rack_remote/master Branch rack_branch set up to track remote branch refs/remotes Switched to a new branch quot;rack_branchquot; $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

$ ls README rack_app.rb $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote warning: no common commits remote: Counting objects: 3184, done. remote: Compressing objects: 100% (1465/1465), done. remote: Total 3184 (delta 1952), reused 2770 (delta 1675) Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, do Resolving deltas: 100% (1952/1952), done. From git@github.com:schacon/rack * [new branch] master -> rack_remote/master $ git checkout -b rack_branch rack_remote/master Branch rack_branch set up to track remote branch refs/remotes Switched to a new branch quot;rack_branchquot; $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

$ ls README rack_app.rb $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote warning: no common commits remote: Counting objects: 3184, done. remote: Compressing objects: 100% (1465/1465), done. remote: Total 3184 (delta 1952), reused 2770 (delta 1675) Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, do Resolving deltas: 100% (1952/1952), done. From git@github.com:schacon/rack * [new branch] master -> rack_remote/master $ git checkout -b rack_branch rack_remote/master Branch rack_branch set up to track remote branch refs/remotes Switched to a new branch quot;rack_branchquot; $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

$ ls README rack_app.rb $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote warning: no common commits remote: Counting objects: 3184, done. remote: Compressing objects: 100% (1465/1465), done. remote: Total 3184 (delta 1952), reused 2770 (delta 1675) Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, do Resolving deltas: 100% (1952/1952), done. From git@github.com:schacon/rack * [new branch] master -> rack_remote/master $ git checkout -b rack_branch rack_remote/master Branch rack_branch set up to track remote branch refs/remotes Switched to a new branch quot;rack_branchquot; $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

$ ls README rack_app.rb $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote warning: no common commits remote: Counting objects: 3184, done. remote: Compressing objects: 100% (1465/1465), done. remote: Total 3184 (delta 1952), reused 2770 (delta 1675) Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, do Resolving deltas: 100% (1952/1952), done. From git@github.com:schacon/rack * [new branch] master -> rack_remote/master $ git checkout -b rack_branch rack_remote/master Branch rack_branch set up to track remote branch refs/remotes Switched to a new branch quot;rack_branchquot; $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

master C3 rack_branch C6 rack_remote/master C2 C5 C1 C0 C4

$ git checkout master $ ls README rack_app.rb $ git checkout rack_branch $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

$ git checkout master $ ls README rack_app.rb $ git checkout rack_branch $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

$ git checkout master $ ls README rack_app.rb $ git checkout rack_branch $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

$ git checkout master $ ls README rack_app.rb $ git checkout rack_branch $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test

checkout ‘rack’ into my project

$ git read-tree --prefix=rack/ -u rack_branch $ ls README rack rack_app.rb $ ls rack AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test $ git add rack $ git commit -m 'added rack code' [master 0839fd8] added rack code 108 files changed, 10334 insertions(+), 0 dele create mode 100644 rack/AUTHORS create mode 100644 rack/COPYING ... create mode 100644 rack/test/testrequest.rb

$ git read-tree --prefix=rack/ -u rack_branch $ ls README rack rack_app.rb $ ls rack AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test $ git add rack $ git commit -m 'added rack code' [master 0839fd8] added rack code 108 files changed, 10334 insertions(+), 0 dele create mode 100644 rack/AUTHORS create mode 100644 rack/COPYING ... create mode 100644 rack/test/testrequest.rb

$ git read-tree --prefix=rack/ -u rack_branch $ ls README rack rack_app.rb $ ls rack AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test $ git add rack $ git commit -m 'added rack code' [master 0839fd8] added rack code 108 files changed, 10334 insertions(+), 0 dele create mode 100644 rack/AUTHORS create mode 100644 rack/COPYING ... create mode 100644 rack/test/testrequest.rb

$ git read-tree --prefix=rack/ -u rack_branch $ ls README rack rack_app.rb $ ls rack AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test $ git add rack $ git commit -m 'added rack code' [master 0839fd8] added rack code 108 files changed, 10334 insertions(+), 0 dele create mode 100644 rack/AUTHORS create mode 100644 rack/COPYING ... create mode 100644 rack/test/testrequest.rb

$ git read-tree --prefix=rack/ -u rack_branch $ ls README rack rack_app.rb $ ls rack AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test $ git add rack $ git commit -m 'added rack code' [master 0839fd8] added rack code 108 files changed, 10334 insertions(+), 0 dele create mode 100644 rack/AUTHORS create mode 100644 rack/COPYING ... create mode 100644 rack/test/testrequest.rb

$ git read-tree --prefix=rack/ -u rack_branch $ ls README rack rack_app.rb $ ls rack AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test $ git add rack $ git commit -m 'added rack code' [master 0839fd8] added rack code 108 files changed, 10334 insertions(+), 0 dele create mode 100644 rack/AUTHORS create mode 100644 rack/COPYING ... create mode 100644 rack/test/testrequest.rb

edit a file in rack

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge --squash -s subtree --no-commit master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $ git status # On branch rack_branch # Changes to be committed: # (use quot;git reset HEAD <file>...quot; to unstage) # # modified: lib/rack.rb #

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge --squash -s subtree --no-commit master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $ git status # On branch rack_branch # Changes to be committed: # (use quot;git reset HEAD <file>...quot; to unstage) # # modified: lib/rack.rb #

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge --squash -s subtree --no-commit master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $ git status # On branch rack_branch # Changes to be committed: # (use quot;git reset HEAD <file>...quot; to unstage) # # modified: lib/rack.rb #

submit the change back to rack

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge --squash -s subtree --no-commit master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $ git status # On branch rack_branch # Changes to be committed: # (use quot;git reset HEAD <file>...quot; to unstage) # # modified: lib/rack.rb #

git merge -s subtree

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge -s subtree --no-commit --squash master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $ git status # On branch rack_branch # Changes to be committed: # (use quot;git reset HEAD <file>...quot; to unstage) # # modified: lib/rack.rb #

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge -s subtree --no-commit --squash master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $ git status # On branch rack_branch # Changes to be committed: # (use quot;git reset HEAD <file>...quot; to unstage) # # modified: lib/rack.rb #

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge -s subtree --no-commit --squash master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $ git status # On branch rack_branch # Changes to be committed: # (use quot;git reset HEAD <file>...quot; to unstage) # # modified: lib/rack.rb #

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge -s subtree --no-commit --squash master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $ git status # On branch rack_branch # Changes to be committed: # (use quot;git reset HEAD <file>...quot; to unstage) # # modified: lib/rack.rb #

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge -s subtree --no-commit --squash master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $ git status # On branch rack_branch # Changes to be committed: # (use quot;git reset HEAD <file>...quot; to unstage) # # modified: lib/rack.rb #

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge -s subtree --no-commit --squash master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $ git status # On branch rack_branch # Changes to be committed: # (use quot;git reset HEAD <file>...quot; to unstage) # # modified: lib/rack.rb #

$ vim rack/lib/rack.rb $ git commit -am 'added awesome to rack' [master b1b77ee] added awesome to rack 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout rack_branch $ git merge -s subtree --no-commit --squash master Squash commit -- not updating HEAD Automatic merge went well; stopped before committin $

Add a comment

Related pages

Smacking Git Around - Advanced Git Tricks - RailsConf ...

This session will cover intermediate to advanced Git commands and usage that will save you time and money. You will not understand how you lived life with ...
Read more

Smacking Git Around - Advanced Git Tricks: RailsConf 2009 ...

This session will cover intermediate to advanced Git commands and usage that will save you time and money. You will not understand how you lived life with ...
Read more

Railsconf: Smacking Git Around – Advanced Git Tricks Scott ...

Glad You're Ready. Let's Get Started! Let us know how we can contact you. Thank you!
Read more

Smacking Git Around - Advanced Git Tricks - Documents

Much of the Ruby and Rails community is now using Git, ... Smacking Git Around - Advanced Git Tricks ...
Read more

Smacking Git Around - O'Reilly Media

Smacking Git Around by Scott Chacon. Me. ... unhealthy obsession with Git ... module Tricks 0de24.. blob size e8455.. commit size
Read more

Smacking Git Around - Advanced Git Tricks | SpeakerRate

This session will cover intermediate to advanced Git commands and usage that will save you time and money. You will not understand how you lived life with ...
Read more

Git timeline | World History Project

Smacking Git Around - Advanced Git Tricks - RailsConf. This session will cover intermediate to advanced Git commands and usage that will save you time and ...
Read more

Codingdomain.com: Getting up speed with Git

Smacking Git Around - Scott Chacon Advanced Git Tricks: Revision selection, rewriting history, ... followed by advanced topics. Smacking Git Around ...
Read more