85
git, from the beginning Or, how not cut ourselves on all the shiny options

Git, from the beginning

Embed Size (px)

Citation preview

Page 1: Git, from the beginning

git, from the beginningOr, how not cut ourselves on all the shiny options

Page 2: Git, from the beginning

What we'll cover

• What git is

• Core concepts in git

• Github flow: collaboration (1)

• The core set of git operations

• Github flow: collaboration (2)

Page 3: Git, from the beginning

What git is

• A development tool

• A history tool

• A collaboration tool

Page 4: Git, from the beginning

A development tool

Keep known good states as you work on a feature

C1 C2

def unlock():global.unlock()

def unlock():global.unlock()if global.errors:

raise Invalid

def unlock():if global.errors:

raise Invalidglobal.unlock()

Page 5: Git, from the beginning

A history tool

Find why code is the way it is, and how it changed

C1 C2

def unlock():try:

sem.unlock()except:

passif global.errors:

raise Invalidglobal.unlock()

C3

Page 6: Git, from the beginning

A collaboration tool

Work with others, build stuff together!

C1

C2

C3

Well, I'm stuck. I

need a function to

read from the

Wubstore.

Page 7: Git, from the beginning

A collaboration tool

Work with others, build stuff together!

C1

C2

C3

It's okay, I've got you.

I've just finished

exactly what you

need. C4

C5

Page 8: Git, from the beginning

A collaboration tool

Work with others, build stuff together!

C1

C2

C3C4

C5

C6

Page 9: Git, from the beginning

Core concepts in git

• Repository and working tree

• Commits

• The index

• Branches

• Collaborating across repositories

Page 10: Git, from the beginning

Repository and working tree

Working tree is your files; repository is the history (in .git)

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

Page 11: Git, from the beginning

A git commit

A commit has an id (c1 here), some metadata, and a snapshot of the working tree

C1

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

Metadata:

author(s)

date

message

And some other boring stuff.

Page 12: Git, from the beginning

Commits build a history graph

Each commit has a parent

C1 C2 C3 C4 C5

Page 13: Git, from the beginning

Commits build a history graph

Multiple commits can have the same parent

C1 C2

C3

C4 C5

Page 14: Git, from the beginning

C1 C2

C3

C4 C5

C6

Commits build a history graph

And we can merge these back together again

Page 15: Git, from the beginning

The index

The index is a staging area for your next commit

C1

my_module/

__init__.py

database.py

transform.py

my_module/

__init__.py

database.py

transform.py

utils.py

Working tree

Page 16: Git, from the beginning

The index

Put changes from your working tree into the index

C1

my_module/

__init__.py

database.py

transform.py

my_module/

__init__.py

database.py

transform.py

utils.py

Working tree

my_module/

__init__.py

database.py

transform.py

utils.py

Index

(no changes)

Page 17: Git, from the beginning

The index

And turn the index into your next commit

C1

my_module/

__init__.py

database.py

transform.py

my_module/

__init__.py

database.py

transform.py

utils.py

Working tree

my_module/

__init__.py

database.py

transform.py

utils.py

C2 Index

(now contains no changes) (no changes)

Page 18: Git, from the beginning

Branches point to commits

This is not a branch!

C1 C2

C3

C4 C5

Page 19: Git, from the beginning

C1 C2

C3

C4 C5

master

first branch

second branch

Branches point to commits

Branches allow you to keep track of the state of multiple different pieces of work.

Page 20: Git, from the beginning

Branches point to commits

The current branch is whatever you're working on. You can also just call this HEAD.

C1 C2

C3

C4 C5

master

first branch

second branch

HEAD

Page 21: Git, from the beginning

Collaborating across repositories

As well as your (local) repository, each developer will have one too

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

My repository Alice's repository

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

my_module/

__init__.py

database.py

transform.py

utils.py

setup.py

Bob's repository

Page 22: Git, from the beginning

Collaborating across repositories

And like our local repository, they contain commits

My repository Alice's repository

Bob's repository

C1 C2 C1 C2 C4

C1 C2

C3

Page 23: Git, from the beginning

Collaborating across repositories

And they also contain branches

My repository Alice's repository

Bob's repository

C1 C2 C1 C2 C4

C1 C2

C3

master master

master

bobwork

alicework

Page 24: Git, from the beginning

Remotes

A local repository can keep track of "remote" repositories

My repository Alice's repository

C1

C2master

C5 my_work

C1

C2master

C3

alice_work C4

Page 25: Git, from the beginning

Remote tracking branches

Which means it keeps track of the commits and branches from those remotes

My repository Alice's repository

C1

C2master

C5 my_work

C1

C2master

C3

alice_work C4

C3

alice/alice_work C4

Page 26: Git, from the beginning

Local branches and upstreams

A remote tracking branch is "upstream" of the local equivalent

My repository

C1

C2master

C5 my_work C3

alice/alice_work C4 alice_work

Alice's repository

C1

C2master

C3

alice_work C4

Upstream

Page 27: Git, from the beginning

Collaboration via bitbucket

Every developer keeps track of the branches in a central repository

My repository Alice's repository

C1

C2master

C5 my_work

C1

C2master

C3

alice_work C4

C3

bitbucket/alice_work C4

Bob's repository

C1

C2master

C3

bitbucket/alice_work C4

Lots of branches!

Bitbucket repository

C5

bitbucket/my_work

C5

bitbucket/my_work

Page 28: Git, from the beginning

Github flow: collaboration (1)

Run tests

Push your local to remote Create a pull request

Make changes in response

Make your commits

Create fixup commitsPR approvalCollapse fixup commits with the things they fixed

Force push branch Merge into master

Run tests

Review comments

Page 29: Git, from the beginning

The core set of git operations

• Working with remotes

• Working with branches

• Managing the index (and working tree)

• Working with commits

• Remotes and branches

• Rebasing: working on the history graph

Page 30: Git, from the beginning

Working with remotes

• git clone -o remote-name remote-url makes a new local repository out of a remote, giving it a name locally My repository github repository

C1 C2 C1 C2 C4

master master alicework

Page 31: Git, from the beginning

git clone in action

$ git clone -o github https://github.com/jaylett/lists-of-living-things.git Cloning into 'lists-of-living-things'... remote: Counting objects: 34, done. remote: Compressing objects: 100% (22/22), done. remote: Total 34 (delta 12), reused 33 (delta 11), pack-reused 0 Unpacking objects: 100% (34/34), done. $ cd lists-of-living-things $ ls README.md firs.md flowers.md

Page 32: Git, from the beginning

Working with remotes

• git fetch -p remote-name updates your view of a remote (fetching commits you don't have, and updating remote tracking branches)

My repository Alice's repository

C1

C2master

C5 my_work

C1

C2master

C3

alice_work C4

C3

alice/alice_work C4

Page 33: Git, from the beginning

git fetch in boring action

$ git fetch -p github

Page 34: Git, from the beginning

Working with branches

• git branch tells you what local branches there are

• git branch -r tells you about remote tracking branches

Page 35: Git, from the beginning

git branch in action

$ git branch * master $ git branch -r github/HEAD -> github/master github/flowers github/foxes github/master

Page 36: Git, from the beginning

Working with branches

• git checkout branch-name updates the index and the files in your working tree to match the branch. HEAD will now point at branch-name, which is now your current branch.

C1 C2

C3

C4 C5

branch-name

master

HEAD

C1 C2

C3

C4 C5

branch-name

master

HEAD

Page 37: Git, from the beginning

Working with branches

• If the branch doesn't exist, but it does exist as a remote tracking branch (as remote-name/branch-name) then a local branch is created with the remote tracking branch as its upstream My repository

C1

C2master

C5 my_work C3

alice/alice_work C4 alice_work

Alice's repository

C1

C2master

C3

alice_work C4

Page 38: Git, from the beginning

git checkout in action

$ git checkout master Already on 'master' Your branch is up-to-date with 'github/master'. $ ls README.md firs.md flowers.md $ git checkout foxes Branch foxes set up to track remote branch foxes from github. Switched to a new branch 'foxes' $ ls README.md firs.md flowers.md foxes.md

Page 39: Git, from the beginning

Working with branches

• git checkout -b branch-name will make a new branch pointing at the same commit the current branch pointed at. HEAD will now point at branch-name, which is now your current branch.

C2 C4 C5

branch-name

master

HEAD

Page 40: Git, from the beginning

git checkout -b in action

$ git checkout master Switched to branch 'master' Your branch is up-to-date with 'github/master'. $ ls README.md firs.md flowers.md $ git checkout -b fungi Switched to a new branch 'fungi' $ ls README.md firs.md flowers.md $ git status On branch fungi nothing to commit, working tree clean

Page 41: Git, from the beginning

Working with branches

• git show-branch branch1 branch2 will give an overview of which commits are in the branches you specify. A lot of IDEs and graphical tools (eg gitx on macOS) will provide a similar view.

C1 C2 C3

C4 C5 C6 C7

foxes

master

Page 42: Git, from the beginning

git show-branch in action

$ git show-branch master foxes * [master] Flesh out our list of firs. ! [foxes] fixup! Add a list of foxes. -- + [foxes] fixup! Add a list of foxes. + [foxes^] fixup! Add a list of foxes. + [foxes~2] Add two foxes missing from our list. + [foxes~3] Add a list of foxes. * [master] Flesh out our list of firs. *+ [foxes~4] Add some more firs.

Page 43: Git, from the beginning

Working with branches

• git merge --ff-only branch-name will move your current branch forward so it points at the same commit as branch-name. If it cannot (because there's no forward route through the commit graph) it will give an error.

C1 C2 C3 C4 C5

master bitbucket/master

Page 44: Git, from the beginning

git merge --ff-only in action (1)

$ git checkout master Switched to branch 'master' Your branch is up-to-date with 'github/master'. $ git remote add james https://github.com/jaylett/lists-of-living-things-2.git $ git fetch -p james remote: Counting objects: 3, done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 1), reused 2 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From https://github.com/jaylett/lists-of-living-things-2 * [new branch] flowers -> james/flowers * [new branch] foxes -> james/foxes * [new branch] master -> james/master

Page 45: Git, from the beginning

git merge --ff-only in action (2)

$ git merge --ff-only james/master Updating c64f496..7b774eb Fast-forward firs.md | 4 ++++ 1 file changed, 4 insertions(+) $ git diff github/master diff --git a/firs.md b/firs.md index ed982db..4ee5697 100644 --- a/firs.md +++ b/firs.md @@ -29,3 +29,7 @@ * Noble fir * Red fir + +## Bracteata + + * Bristlecone fir

Page 46: Git, from the beginning

Working with branches

• git merge branch-name will create a merge commit so that your current branch contains all the changes on branch-name, back to their common parent.

C1 C2 C3

C4

branch-name

master

Page 47: Git, from the beginning

Working with branches

• This will update your current branch pointer, and hence also move HEAD.

• If it can, it will simply move your current branch and HEAD to point at branch-name, as with git merge --ff-only.

C1 C2 C3

C4

github/flowers

master

C4

Page 48: Git, from the beginning

git merge in action

$ git checkout master Already on 'master' Your branch is ahead of 'github/master' by 1 commit. (use "git push" to publish your local commits) $ git merge github/flowers Merge made by the 'recursive' strategy. flowers.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) $ git show -s HEAD commit 89f4241540a9479c2f9687becef69583dae0729e Merge: 7b774eb 8a34f24 Author: James Aylett <[email protected]> Date: Sun May 14 18:59:35 2017 +0100

Merge branch 'github/flowers'

Page 49: Git, from the beginning

Managing the index (and working tree)

• git diff shows the differences between the working tree and the index

• git diff --cached shows the differences between the index and the last commit

• You can include a list of filenames to restrict to just those

• You can include a commit or branch name (before the filenames, if any) to show the difference between that commit and either the working tree or the index

• git status will summarise what's going on with the index and working tree

Page 50: Git, from the beginning

git diff in action

$ git checkout fungi Switched to branch 'fungi' $ sed -i~ -e 's/flora/living things/' README.md $ git diff diff --git a/README.md b/README.md index 184968c..9163ba0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# Lists of flora +# Lists of living things -Each file in this repository will be a list of some type of flora. +Each file in this repository will be a list of some type of living things.

Page 51: Git, from the beginning

Managing the index (and working tree)

• git add -p allows you to add changes into the index; it will prompt for each change in the working tree

• git reset -p allows you to remove changes from the index again

• git checkout -p allows you to discard changes in the working tree (once gone, lost forever!)

Page 52: Git, from the beginning

git add -p in action

$ git add -p diff --git a/README.md b/README.md index 184968c..9163ba0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# Lists of flora +# Lists of living things -Each file in this repository will be a list of some type of flora. +Each file in this repository will be a list of some type of living things. Stage this hunk [y,n,q,a,d,/,s,e,?]? y

Page 53: Git, from the beginning

git status & diff --cached in action

$ git status On branch fungi Changes to be committed: (use "git reset HEAD <file>..." to unstage)

modified: README.md $ git diff --cached diff --git a/README.md b/README.md index 184968c..9163ba0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# Lists of flora +# Lists of living things -Each file in this repository will be a list of some type of flora. +Each file in this repository will be a list of some type of living things.

Page 54: Git, from the beginning

git reset -p in action

$ git reset -p diff --git a/README.md b/README.md index 184968c..9163ba0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# Lists of flora +# Lists of living things -Each file in this repository will be a list of some type of flora. +Each file in this repository will be a list of some type of living things. Unstage this hunk [y,n,q,a,d,/,s,e,?]? y $ git status On branch fungi Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory)

modified: README.md

no changes added to commit (use "git add" and/or "git commit -a")

Page 55: Git, from the beginning

git checkout -p in action

$ git checkout -p diff --git a/README.md b/README.md index 184968c..9163ba0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# Lists of flora +# Lists of living things -Each file in this repository will be a list of some type of flora. +Each file in this repository will be a list of some type of living things. Discard this hunk from worktree [y,n,q,a,d,/,s,e,?]? y

$ git status On branch fungi nothing to commit, working tree clean

Page 56: Git, from the beginning

Managing the index (and working tree)

• If you have a new file, git add -N filename will tell git that it exists; you can then use git add -p to add the changes from the file. (You can use git add filename to do both in one go, but as you learn more about git this will become limiting, and it's worth getting into good practices early.)

• git mv filename new-filename will move a file from one place to another in the working tree and tells git to track that move in the index

• git rm filename removes a file from the working tree and tells git to add that removal to the index

Page 57: Git, from the beginning

git add -N in action

$ echo -e "# List of fungi\n\n * mushroom" > fungi.md $ git add -N fungi.md $ git add -p diff --git a/fungi.md b/fungi.md index e69de29..f47e8b0 100644 --- a/fungi.md +++ b/fungi.md @@ -0,0 +1,3 @@ +# List of fungi + + * mushroom Stage this hunk [y,n,q,a,d,/,e,?]? y

Page 58: Git, from the beginning

Working with commits: looking

• git diff commit-ref1 commit-ref2 will show the differences between two different commits

• git diff -w commit-ref1 commit-ref2 ignores whitespace changes

• git show commit-ref will show a summary of the commit, including its metadata and changes to previous

Page 59: Git, from the beginning

git diff in action

$ git diff HEAD^ HEAD diff --git a/firs.md b/firs.md index de0db27..ed982db 100644 --- a/firs.md +++ b/firs.md @@ -1,7 +1,31 @@ # Firs - * Balsam fir +## Abies + + * Silver fir + * Sicilian fir

[…]

Page 60: Git, from the beginning

git show in action

$ git show HEAD commit c64f496f779ac1d5f079e824aa5d66dbbb94fdaf Author: James Aylett <[email protected]> Date: Sun May 14 17:44:43 2017 +0100

Flesh out our list of firs. Apparently firs come in different types! I probably haven't found all of them, but this is a better list.

diff --git a/firs.md b/firs.md index de0db27..ed982db 100644 --- a/firs.md +++ b/firs.md @@ -1,7 +1,31 @@ # Firs

[…]

Page 61: Git, from the beginning

Working with commits: making

• Make a commit from the index (it will open an editor for the commit message): git commit -v

• Do not use git commit -m ever. Various online tutorials tell you to. Ignore them: it will prevent you writing good commit messages.

Page 62: Git, from the beginning

git commit -v in action (1)

$ sed -i~ -e 's/flora/living things/' README.md $ git add -p diff --git a/README.md b/README.md index 184968c..9163ba0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# Lists of flora +# Lists of living things -Each file in this repository will be a list of some type of flora. +Each file in this repository will be a list of some type of living things. Stage this hunk [y,n,q,a,d,/,s,e,?]? y

Page 63: Git, from the beginning

git commit -v in action (2)

# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch fungi # Changes to be committed: # modified: README.md # new file: fungi.md # # ------------------------ >8 ------------------------ # Do not touch the line above. # Everything below will be removed. diff --git a/README.md b/README.md index 184968c..9163ba0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# Lists of flora +# Lists of living things

[…]

Page 64: Git, from the beginning

git commit -v in action (3)

$ git commit -v

Here, git waits for you to edit the commit message and save it

[fungi cfcd7f5] Add mushrooms. 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 fungi.md $ git show -s commit cfcd7f5b02ea6008faf7235f1c3b2561ed50180f Author: James Aylett <[email protected]> Date: Sun May 14 19:27:43 2017 +0100

Add mushrooms.

Page 65: Git, from the beginning

Working with commits: unmaking

• git reset --soft HEAD^ will undo a commit you just made, returning those changes to the index

C1

my_module/

__init__.py

database.py

transform.py

my_module/

__init__.py

database.py

transform.py

utils.py

Working tree

my_module/

__init__.py

database.py

transform.py

utils.py

C2 Index

(no changes)

my_module/

__init__.py

database.py

transform.py

* utils.py

Page 66: Git, from the beginning

git reset --soft in action

$ git show --oneline -s HEAD cfcd7f5 Add mushrooms. $ git reset --soft HEAD^ $ git status On branch fungi Changes to be committed: (use "git reset HEAD <file>..." to unstage)

modified: README.md new file: fungi.md $ git show --oneline -s HEAD c64f496 Flesh out our list of firs.

Page 67: Git, from the beginning

Working with commits: unmaking

• git reset --mixed commit-ref will undo all commits back to the given commit or branch, leaving the changes in the working tree.

C1

my_module/

__init__.py

database.py

transform.py

my_module/

__init__.py

database.py

transform.py

* utils.py

Working tree

my_module/

__init__.py

database.py

transform.py

utils.py

C2 Index

(no changes from C1)

Page 68: Git, from the beginning

Working with commits: unmaking

• git reset --hard commit-ref will undo all changes back to the given commit or branch. This is how you throw away changes.

C1

my_module/

__init__.py

database.py

transform.py

my_module/

__init__.py

database.py

transform.py

Working tree

my_module/

__init__.py

database.py

transform.py

utils.py

C2 Index

(no changes from C1) (no changes from C1)

Page 69: Git, from the beginning

Remotes and branches

• Push your commits up to a remote for the first time: git push -u remote-name branch-name

• After that, you can just do git push

My repository github repository

C1 C2 C1 C2 C3C3

master master mywork

mywork

Page 70: Git, from the beginning

git push -u in action

$ git commit -v [fungi 283cf75] Add mushrooms. 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 fungi.md $ git push -u james fungi Counting objects: 4, done. Delta compression using up to 24 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (4/4), 451 bytes | 0 bytes/s, done. Total 4 (delta 0), reused 0 (delta 0) To github.com:jaylett/lists-of-living-things-2.git * [new branch] fungi -> fungi Branch fungi set up to track remote branch fungi from james

Page 71: Git, from the beginning

git push in (boring) action

$ git push Everything up-to-date

Page 72: Git, from the beginning

Rebasing: working on the history graph

Rebasing is crazy powerful. We'll just look at some very simple uses.

• reword messages

• reorder commits

• collapse commits

Page 73: Git, from the beginning

Rebase recreates commits

• Rebase works by recreating commits from one part of the history to another (or to the same place)

C1 C2 C3 C4 C5

branch-point your-branch

C2’ C3’ C4’ C5’

your-branch

(before rebase)

(after rebase)

(the commit thatrebase starts from)

Page 74: Git, from the beginning

Interactive rebase can be controlled

C1 C2 C3 C4 C5

branch-point your-branch

C2’ C5’ C34

your-branch

(before rebase)

(after rebase)

(the commit thatrebase starts from)

Interactive rebase todo list:

1. Pick C2.2. Pick C5.3. Squash C3 and C4 together.

Page 75: Git, from the beginning

Interactive rebase

You start an interactive rebase session with:

git rebase -i commit-ref

which will drop into an editor with a list of every commit between commit-ref and HEAD. You can re-order the commits, and also change the action to be taken for each.

Page 76: Git, from the beginning

Interactive rebase actions

• pick will just recreate the commit • reword lets you edit the commit message first • fixup collapses the changes into the previous commit • squash is like fixup, but allows you to edit the commit

message afters

Page 77: Git, from the beginning

git rebase -i in action (1)

$ git checkout foxes Switched to branch 'foxes' Your branch is up-to-date with 'github/foxes'. $ git log --oneline HEAD~4..HEAD bb3f285 fixup! Add a list of foxes. 74ee814 fixup! Add a list of foxes. 8ec86e7 Add two foxes missing from our list. f1923f9 Add a list of foxes. $ git rebase -i HEAD~4

git now opens an editor with the commit & action list

Page 78: Git, from the beginning

git rebase -i in action (2)

pick f1923f9 Add a list of foxes. pick 8ec86e7 Add two foxes missing from our list. pick 74ee814 fixup! Add a list of foxes. pick bb3f285 fixup! Add a list of foxes.

# Rebase 9e096f3..bb3f285 onto 9e096f3 (4 commands) # # 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

[…]

Page 79: Git, from the beginning

git rebase -i in action (3)

pick f1923f9 Add a list of foxes. fixup 74ee814 fixup! Add a list of foxes. fixup bb3f285 fixup! Add a list of foxes. pick 8ec86e7 Add two foxes missing from our list.

# Rebase 9e096f3..bb3f285 onto 9e096f3 (4 commands) # # 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

[…]

Page 80: Git, from the beginning

git rebase -i in action (4)

$ git rebase -i HEAD~4 Successfully rebased and updated refs/heads/foxes. $ git log --oneline HEAD~2..HEAD 9ae7b9e Add two foxes missing from our list. 049c4ee Add a list of foxes.

Page 81: Git, from the beginning

Fixups and squashes

• If you spot that a previous commit isn't quite right, you can make a "fixup" commit: git commit --fixup commit-ref

• git rebase -i --autosquash will then automatically move those commits into the right place and mark them as fixup (rather than pick)

• to make a "squash" commit instead of fixup, use git commit --squash commit-ref

Page 82: Git, from the beginning

Github flow: collaboration (2)

Run tests

Push your local to remote Create a pull request

Make changes in response

Make your commits

Create fixup commitsPR approvalInteractive rebase to collapse fixup commits

Force push branch Merge into master

Run tests

Review comments

Page 83: Git, from the beginning

What is a pull request?

• A set of proposed commits, with a narrative

• An opportunity for review ahead of merging to master

• A way to actively collaborate rather than just using each others' work

Page 84: Git, from the beginning

The commands for github flow

• make commits: add -p, commit -v

• push your branch: push -u

• create fixup commits: commit --fixup

• collapse fixup commits: rebase -i --autosquash $(git merge-base HEAD master)

• force push branch: push -f

Page 85: Git, from the beginning

Questions?

• http://www.slideshare.net/jaylett/git-from-the-beginning

• @jaylett