how to git - cmu computer clubajo/disseminate/2015-08-03-how-to-git.pdf · git is a version control...

61
How to git http://longair.net/blog/2009/04/16/git-fetch-and-merge/

Upload: trinhkhanh

Post on 01-Sep-2018

231 views

Category:

Documents


0 download

TRANSCRIPT

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 non-linear and mutable

History is non-linear and mutable

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

Navigating by real identities sucks

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

master

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

master

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'