How to githttp://longair.net/blog/2009/04/16/git-fetch-and-merge/
git is a version control systema.k.a. “Source Control Management”a.k.a. “Source Code Management”
It manages your source code.backend
arb
libquery
engage
git is a version control systema.k.a. “Source Control Management”a.k.a. “Source Code Management”
It manages your source code and its history.backend
arb
engage
backend
arb
libquery
engage
backend
arb
libquery
git is a version control systema.k.a. “Source Control Management”a.k.a. “Source Code Management”
It manages your source code and its history.backend
arb
engage
backend
arb
libquery
engage
backend
arb
libquery
History is shared (i.e. replicated)
Everybody has their own history books.Some history books might not agree with others.They might be missing pieces, or they might tell an outright different story.As far as git is concerned, this is okay.
We navigate history by landmarksEvery git commit — every node in this graph — has a unique identifier: its SHA hash.
A node’s SHA hash depends on the SHA hashes of all its ancestors, plus its actual diff, plus its commit message, committer, and timestamp. Changing any of those will change the SHA hash.
The SHA hash is in a very real sense the real identity of the node.
A SHA hash (a.k.a. revision, a.k.a. commit) identifies a specific version of the codebase.
0e73048 eff08db 83b3845
21605de 72b4aa3
We navigate history by landmarksgit allows us to set signposts along the way, in the form of branch names and tag names.
A tag is basically just a symbolic synonym for a SHA hash.
0e73048 eff08db 83b3845
21605de 72b4aa3
shipped-v2 ≡ eff08db
We navigate history by landmarksgit allows us to set signposts along the way, in the form of branch names and tag names.
A tag is basically just a symbolic synonym for a SHA hash.I won't talk about them any more.
The interesting kind of signpostis called a branch.
0e73048 eff08db 83b3845
21605de 72b4aa3
shipped-v2 ≡ eff08db
We navigate history by landmarks
0e73048 eff08db 83b3845
21605de 72b4aa3
shipped-v2 ≡ eff08db
Tags
master
kamp-new-feature
kamp-crystal-lake
Branches
HEAD
We navigate history by landmarks
0e73048 eff08db 83b3845
21605de
master
HEAD
72b4aa3
kamp-cl
git checkout master
72b4aa3
We navigate history by landmarks
0e73048 eff08db 83b3845
21605de
HEAD
kamp-cl
02115d7
master
git checkout mastergit commit
72b4aa3
“Detached HEAD” state
0e73048 eff08db 83b3845
21605de
kamp-cl
02115d7
master
git checkout 83b3845 HEAD
72b4aa3
“Detached HEAD” state
0e73048 eff08db 83b3845
21605de
kamp-cl
02115d7
master
git checkout 02115d7 HEAD
72b4aa3
“Detached HEAD” state
0e73048 eff08db 83b3845
21605de
kamp-cl
02115d7
master
git checkout 02115d7git commit
07aeca8
HEAD
72b4aa3
git checkout -B: “Accio signpost”
0e73048 eff08db 83b3845
21605de
kamp-cl
02115d7
git checkout 02115d7git commitgit checkout -B master
07aeca8
HEAD
master
72b4aa3
Nothing is ever really lost*
0e73048 eff08db 83b3845
21605de
kamp-cl
02115d7
git checkout HEAD~2git checkout -B master
07aeca8
HEAD
master
72b4aa3
Nothing is ever really lost*
0e73048 eff08db 83b3845
21605de
kamp-cl
git checkout HEAD~2git checkout -B mastergit gc
HEAD
master
72b4aa3
git reflog: sift through the trash
0e73048 eff08db 83b3845
21605de
kamp-cl
02115d7
git checkout HEAD~2git checkout -B mastergit reflog
83b3845 HEAD@{0}: checkout: moving from 83b38458a4140 to master83b3845 HEAD@{1}: checkout: moving from master to HEAD~207aeca8 HEAD@{2}: commit (amend): Dogs don't moo...
07aeca8
HEAD
master
72b4aa3
git log: look backward
0e73048 eff08db 83b3845
21605de
kamp-cl
02115d7 07aeca8
HEAD
master
git log
commit 83b38458a4... Author: Arthur O'Dwyer Date: Sat Jan 26 20:28:03 2013
Dogs (first commit)
commit eff08db287859e8f8f Author: Arthur O'Dwyer Date: Sat Jan 26 20:00:10 2013
Cats, sadly no dogs yet ...
72b4aa3
git branch -v: list all signposts
0e73048 eff08db 83b3845
21605de
kamp-cl
02115d7
git branch -v
* master 83b3845 Dogs (first commit) kamp-cl 72b4aa3 Added some cabins
07aeca8
HEAD
master
Stretch break #1 of 2
We’ve now learned all about● SHA hashes● navigating around with git checkout● moving signposts with git checkout -B● git branch -v, git log, and git reflogUp next:● Rewriting history (locally)
Let’s merge kamp-cl into master!
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
git checkout master
master
Let’s merge kamp-cl into master!
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
git checkout mastergit merge kamp-cl
217ad0a
master
git diff 83b3845 217ad0a ≡ git diff eff08db 72b4aa3
Let’s rebase kamp-cl onto master!
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
git checkout kamp-cl
master
Let’s rebase kamp-cl onto master!
0e73048 eff08db 83b3845
21605de 72b4aa3
git checkout kamp-clgit rebase master
master
298711a 11b6bba
kamp-cl
git diff 298711a~ 298711a ≡ git diff 21605de~ 21605degit diff 11b6bba~ 11b6bba ≡ git diff 72b4aa3~ 72b4aa3
Let’s rebase kamp-cl onto master!
0e73048 eff08db 83b3845
21605de 72b4aa3
git checkout kamp-clgit rebase mastergit checkout -B master
master
298711a 11b6bba
kamp-cl
Orphaned revisions, ripe for git gc
Rebasing gives you a linear history
0e73048 eff08db 83b3845
21605de 72b4aa3
master
298711a 11b6bba
kamp-cl
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
217ad0a
masterMerging doesn’t
Rebase and squash
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
git checkout kamp-clgit rebase -i master
master
pick 21605de Add cabins
pick 72b4aa3 Add dirt path
# Rebase eff08db..72b4aa3 onto 83b3845
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the com...
# e, edit = use commit, but stop for amend...
# s, squash = use commit, but meld into pr...
# f, fixup = like "squash", but discard th...
# x, exec = run command (the rest of the l...
Rebase and squash
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
git checkout kamp-clgit rebase -i master
master
pick 21605de Add cabins
s 72b4aa3 Add dirt path
# Rebase eff08db..72b4aa3 onto 83b3845
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the com...
# e, edit = use commit, but stop for amend...
# s, squash = use commit, but meld into pr...
# f, fixup = like "squash", but discard th...
# x, exec = run command (the rest of the l...
Rebase and squash
0e73048 eff08db 83b3845
21605de 72b4aa3
git checkout kamp-clgit rebase -i master
master
8662abc
kamp-cl
git diff 8662abc~ 8662abc ≡ git diff eff08db 72b4aa3
pick 21605de Add cabins
s 72b4aa3 Add dirt path
Protip: fixup = squash a typo-fix
In git rebase –i, the action fixup (or f) is equivalent to squash, except that it doesn’t prompt you for a new commit message.It just takes your first commit message and throws away your second one.
Oh no! There are merge conflicts!
git rebase ––abort
This will cancel the entire rebase operation and drop you safely back where you were before starting the rebase.
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
master
0e73048 eff08db 83b3845
21605de 72b4aa3
master
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
master
1234567
git rebase ––abort
Change the order of two patchespick 21605de Add cabins
pick 72b4aa3 Add dirt path
# Rebase eff08db..72b4aa3 onto 83b3845
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
Mess with the codebase directly
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
git checkout master
master
Mess with the codebase directly
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
git checkout mastergit checkout kamp-cl --
master
At this point it’sas if you’ve edited yourlocal filesystem tolook just like 72b4aa3;but HEAD has not moved!
Mess with the codebase directly
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
git checkout mastergit checkout kamp-cl --git checkout master -- libquery/
master
Mess with the codebase directly
0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
git checkout mastergit checkout kamp-cl --git checkout master -- libquery/git commit -a
289747a
master
Stretch break #2 of 2
We’ve now learned all about● rebasing (versus merging)● all the actions you can do with git rebase -i● aborting a rebase with git rebase --abort● making the filesystem match a given revision
with git checkout revision -- pathUp next: Pulling and pushing
git fetch0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
master
0e73048 eff08db 83b3845
21605de 72b4aa3
origin/kamp-cl
origin/mastermastergit fetch
The purple signposts denote tracking branches: they’re not quite like normal branches, but not quite like tags either.
git fetch0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
master
0e73048 eff08db 83b3845
21605de 72b4aa3
origin/kamp-cl
origin/mastermastergit fetchgit checkout origin/master
83b3845
git fetch0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
master
0e73048 eff08db
21605de 72b4aa3
origin/kamp-cl
origin/mastergit fetchgit checkout origin/mastergit checkout -B master
master
83b3845
git fetch0e73048 eff08db 83b3845
21605de 72b4aa3
kamp-cl
master
0e73048 eff08db
21605de 72b4aa3
origin/kamp-cl
origin/mastergit fetchgit checkout origin/mastergit checkout -B mastergit checkout origin/kamp-clgit checkout -B kamp-cl
master
kamp-cl
Case 20e73048 eff08db 83b3845
master
0e73048 eff08db
21605de
master
Suppose I’ve done some work in my own master, accidentally...
Case 20e73048 eff08db 83b3845
kamp-cl
0e73048 eff08db
21605de
kamp-cl
Suppose I’ve done some work in my own master, accidentally...
Or replace master with kamp-cl here and suppose that Fez and I are collaborating on the same feature branch.
Case 20e73048 eff08db 83b3845
kamp-cl
0e73048 eff08db 83b3845
21605de
origin/kamp-cl
kamp-cl
git fetch
Oh no! How do we resolve this problem?
Case 20e73048 eff08db 83b3845
kamp-cl
0e73048 eff08db 83b3845
21605de
kamp-cl
git fetch
Oh no! How do we resolve this problem?
git merge origin/kamp-cl orgit rebase -i origin/kamp-cl
origin/kamp-cl
Use git pull, but know how not to
git pull is basically git fetch plus git merge.
(But git merge is evil!)
git pull will do the right thing (almost) all the time. It tends to get confused by rewritten history. Fall back on git fetch if necessary.
merge0e73048 eff08db 83b3845
kamp-cl
0e73048 eff08db 83b3845
21605de
git fetchgit checkout kamp-clgit merge origin/kamp-cl
origin/kamp-cl
239872f
kamp-cl
merge0e73048 eff08db 83b3845
0e73048 eff08db 83b3845
21605de
git fetchgit checkout kamp-clgit merge origin/kamp-clgit push origin kamp-cl
Merging works nicely for collaboration on a feature branch.
origin/kamp-cl
239872f
kamp-cl
21605de
239872f
kamp-cl
rebase0e73048 eff08db 83b3845
kamp-cl
0e73048 eff08db 83b3845
21605de
git fetchgit checkout kamp-clgit rebase origin/kamp-cl
origin/kamp-cl
9823687
kamp-cl
rebase0e73048 eff08db 83b3845
0e73048 eff08db 83b3845
21605de
git fetchgit checkout kamp-clgit rebase origin/kamp-clgit push origin kamp-cl
origin/kamp-cl
9823687
kamp-cl
9823687
kamp-cl
Can I push rewritten history?
0e73048 eff08db 83b3845
0e73048 eff08db 7282387
kamp-cl
9823687
kamp-cl
git fetchgit checkout kamp-clgit rebase origin/kamp-clgit push origin kamp-cl
git rebase -i HEAD~2git push origin kamp-cl????????
Can I push rewritten history?
0e73048 eff08db 83b3845
0e73048 eff08db 7282387
kamp-cl
9823687
kamp-cl
git push origin kamp-cl
To [email protected]:Quuxplusone/magic
! [rejected] kamp-cl -> kamp-cl
(non-fast-forward)
error: failed to push some refs to
'[email protected]:Quuxplusone/magic'
hint: Updates were rejected because
the tip of your current branch is
behind its remote counterpart.
Integrate the remote changes (e.g.
git pull ...) before pushing again.
See the Note about fast-forwards in
git push --help for details.
Basically, our guy Fez doesn’t know whether to merge or rebase (nor how to resolve merge conflicts).
Can I push rewritten history? Yes.
0e73048 eff08db
0e73048 eff08db 7282387
kamp-clgit fetchgit checkout kamp-clgit rebase origin/kamp-clgit push origin kamp-cl
git rebase -i HEAD~2git push -f origin kamp-cl
7282387
kamp-cl
Collaborating? Merge.Working on your own? Rebase.● In a feature branch that’s all my own, I prefer
periodically: git rebase -i origin/master and squash periodically: git push -f origin kamp-my-branch
● To merge kamp-my-branch into master, I prefer git checkout kamp-my-branch git fetch; git rebase -i origin/master git checkout -B master; git push origin master
● To collaborate in a feature branch, I use the same workflow as for merging into master; but during slow periods I ask if it’s okay to rebase-and-squash.
Please don’t try this at home(env)ajo@arthur:~/analytics$ git push -f origin master
Counting objects: 1, done.
Writing objects: 100% (1/1), 220 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
remote: error: GH003: Sorry, force-pushing to master is not allowed.
To [email protected]:mixpanel/analytics.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to '[email protected]:mixpanel/analytics.git'