Slide 1

Slide 1 text

Advanced Git let talk

Slide 2

Slide 2 text

@skalnik i’m

Slide 3

Slide 3 text

a few of my favorite things Raindrops on roses and whiskers on kittens… Just kidding, I love git.

Slide 4

Slide 4 text

merge conflicts

Slide 5

Slide 5 text

# Merge a branch $ git merge conflict you can do this after you run `merge-conflict.sh`: https://gist.github.com/skalnik/4951428

Slide 6

Slide 6 text

Auto-merging greeting.txt CONFLICT (content): Merge Automatic merge failed; fi Oh god wtf just happened. Lets check out greeting.txt

Slide 7

Slide 7 text

<<<<<<< HEAD Yay! DevconTLV! ======= DevconTLV Woo! >>>>>>> conflict WHAT IS GOING ON HERE?! Top is what was on HEAD (for us, master) Bottom is what was on the conflict branch Lets get rid of the extra stuff and commit!

Slide 8

Slide 8 text

rerere

Slide 9

Slide 9 text

remembers merge conflicts

Slide 10

Slide 10 text

# It’s gotta be enabled $ git config --global \ rerere.enabled 1 Resets our HEAD, working copy, & index --soft does only HEAD --mixed (default) resets the index, but not working copy

Slide 11

Slide 11 text

a32 2e2 8b3 fe1 2bd topic master Lets say you have a topic branch, and you’ve modified some of the same lines as master

Slide 12

Slide 12 text

a32 2e2 8b3 fe1 2bd topic master af3 when you merge master in, you’ll have to resolve the conflict

Slide 13

Slide 13 text

a32 2e2 8b3 fe1 2bd topic master af3 e69 d19 f4a 3a1 However, a long lived topic branch may do this many times. If any of you read the Linux kernel mailing list, you may remember Linus complaining about these “useless merges” when a subsystem maintainer asked him to pull a branch. So if we got rid of these as we made them

Slide 14

Slide 14 text

a32 2e2 8b3 fe1 2bd topic master f3c e69 d19 f4a 3a1 So if we get rid of these, great! But once we merge master back in… rerere to the rescue!

Slide 15

Slide 15 text

rebase

Slide 16

Slide 16 text

rebase is not a merge

Slide 17

Slide 17 text

rebase is preparation for a merge

Slide 18

Slide 18 text

merge makes a multi-parent commit

Slide 19

Slide 19 text

rebase reorders commits before your branch

Slide 20

Slide 20 text

rebase simulates people taking turns working

Slide 21

Slide 21 text

# Rebase interactively over # last 5 commits $ git rebase --interactive \ HEAD~5

Slide 22

Slide 22 text

a32 2e2 8b3 e69 d19 You can delete commits

Slide 23

Slide 23 text

a32 2e2 e69 d19 Changing any parent changes the children

Slide 24

Slide 24 text

a32 2e2 73e 1d9 Or pull them out

Slide 25

Slide 25 text

a32 2e2 e69 d19 And reorder them

Slide 26

Slide 26 text

a32 d19 e69 2e2 Normally these SHAs would change, but so you can see that they swap, I’ll leave them

Slide 27

Slide 27 text

a32 d19 41a 2e2 Or even take the last 2 commits, and squash ‘em together

Slide 28

Slide 28 text

a32 d19 e69 2e2 + a3f =

Slide 29

Slide 29 text

a32 d19 a3f Or even amend them

Slide 30

Slide 30 text

a32 fa1 df4 Or even completely edit them Talk about git commit --amend

Slide 31

Slide 31 text

# Rebase interactively and # autosquash last 5 commits $ git rebase -i --autosquash \ HEAD~5 fixup! squash! These are automatically set to fixup/squash when rebasing interactively then

Slide 32

Slide 32 text

stash

Slide 33

Slide 33 text

a super quick branch

Slide 34

Slide 34 text

local only

Slide 35

Slide 35 text

stack based push pop peek

Slide 36

Slide 36 text

# stash your changes $ git stash

Slide 37

Slide 37 text

# save ‘em $ git stash save ‘message’

Slide 38

Slide 38 text

# list ‘em $ git stash list

Slide 39

Slide 39 text

# use ‘em $ git stash pop

Slide 40

Slide 40 text

# use a specific one $ git stash pop stash@{1}

Slide 41

Slide 41 text

# or if you want to keep it $ git stash apply

Slide 42

Slide 42 text

# or if you want to keep it $ git stash apply

Slide 43

Slide 43 text

# too good to just stash? $ git stash branch

Slide 44

Slide 44 text

cherry-pick

Slide 45

Slide 45 text

“cherry picking” a commit into your branch

Slide 46

Slide 46 text

# All you need is the SHA $ git cherry-pick Or multiple! This creates a brand new commit, but with the same diff It’s much like a manual rebase

Slide 47

Slide 47 text

# What if you don’t want # the commit? $ git cherry-pick --no-commit Or multiple! This creates a brand new commit, but with the same diff It’s much like a manual rebase

Slide 48

Slide 48 text

ref log

Slide 49

Slide 49 text

a journal of your local actions

Slide 50

Slide 50 text

2a52e96 HEAD@{0}: commit (merge): Merge branches 'feature_division_ 369adba HEAD@{1}: checkout: moving from feature_subtraction_polishe 818f033 HEAD@{2}: checkout: moving from feature_division_polished t 57d0bf6 HEAD@{3}: commit: Removing subtraction from the division li cb2d322 HEAD@{4}: checkout: moving from feature_division to feature e650f37 HEAD@{5}: checkout: moving from master to feature_division 369adba HEAD@{6}: checkout: moving from feature_division to master e650f37 HEAD@{7}: rebase -i (continue): Fixed a typo in a tested va 3c9306f HEAD@{8}: cherry-pick 09b08e4 HEAD@{9}: checkout: moving from feature_division to 09b08e4 9fc18b5 HEAD@{10}: checkout: moving from feature_division to 9fc18b 9fc18b5 HEAD@{11}: commit: Fixed a typo in a tested value of divisi d5ef5f0 HEAD@{12}: checkout: moving from feature_division_polished cb2d322 HEAD@{13}: commit (amend): Added subtract feature 6a795b8 HEAD@{14}: rebase: Added subtract feture 369adba HEAD@{15}: checkout: moving from feature_division_polished d5ef5f0 HEAD@{16}: checkout: moving from master to feature_division 369adba HEAD@{17}: checkout: moving from feature_division_polished d5ef5f0 HEAD@{18}: checkout: moving from feature_division to featur d5ef5f0 HEAD@{19}: checkout: moving from feature_division_polished d5ef5f0 HEAD@{20}: checkout: moving from d5ef5f0e74c56bd678ea1d504c d5ef5f0 HEAD@{21}: checkout: moving from 818f033c4ae7f26b2b29e90494

Slide 51

Slide 51 text

# We messed up good $ git reset --hard HEAD@{3} Resets our HEAD, working copy, & index --soft does only HEAD --mixed (default) resets the index, but not working copy

Slide 52

Slide 52 text

hunks

Slide 53

Slide 53 text

# Hunk level adding, i.e. # patch mode $ git add --patch

Slide 54

Slide 54 text

diff --git a/app.coffee b/app.coffee index c99027a..b1e7e9b 100755 --- a/app.coffee +++ b/app.coffee @@ -10,11 +10,7 @@ app.configure -> app.use express.methodOverride() app.use app.router -app.configure 'development', -> - app.use express.errorHandler({ dumpExceptions: true, showStack: true }) - -app.configure 'production', -> - app.use express.errorHandler() +app.use express.errorHandler() port = process.env.PORT || 3000 Stage this hunk [y,n,q,a,d,/,e,?]? y - yes n - no s - split e - open in $EDITOR

Slide 55

Slide 55 text

Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? y - stage this hunk n - do not stage this hunk a - stage this and all the remaining hunks in the file d - do not stage this hunk nor any of the remaining hunks in the file g - select a hunk to go to / - search for a hunk matching the given regex j - leave this hunk undecided, see next undecided hunk J - leave this hunk undecided, see next hunk k - leave this hunk undecided, see previous undecided hunk K - leave this hunk undecided, see previous hunk s - split the current hunk into smaller hunks e - manually edit the current hunk ? - print help

Slide 56

Slide 56 text

# But that’s not all! $ git reset -p

Slide 57

Slide 57 text

# Checkouts too! $ git checkout -p

Slide 58

Slide 58 text

hub

Slide 59

Slide 59 text

hub introduces git to GitHub

Slide 60

Slide 60 text

# Install via Homebrew $ brew install hub # or with curl $ curl \ http://defunkt.io/hub/standalone \ -sLo ~/bin/hub && \ chmod +x ~/bin/hub

Slide 61

Slide 61 text

# Clone a GitHub repo $ git clone user/repo # vs $ git clone \ git://github.com/user/repo

Slide 62

Slide 62 text

# Private repo? $ git clone -p github/github

Slide 63

Slide 63 text

# Fork current repo $ git fork

Slide 64

Slide 64 text

# Then after some changes $ git pull-request

Slide 65

Slide 65 text

plumbing

Slide 66

Slide 66 text

git is a key-value store

Slide 67

Slide 67 text

# Get the object ID $ git hash-object $ echo “Yay DevconTLV” | git hash-object -w --stdin 053a0094e47bd27c88ee17e205f42beb974791aa $ find .git/objects -type f .git/objects/05/3a0094e47bd27c88ee17e205f42beb974791aa

Slide 68

Slide 68 text

# Look at a git object $ git cat-file $ git cat-file -p 053a0094e47bd27c88ee17e205f42beb974791aa Yay DevconTLV $ git cat-file -t 053a0094e47bd27c88ee17e205f42beb974791aa blob

Slide 69

Slide 69 text

Lets talk trees! hash-object makes blobs for us. But those are just content. How does git keep track of multiple files? And file names?

Slide 70

Slide 70 text

# Update the staging area $ git update-index To write a tree, we must first create the index, or staging area. $ git update-index --add --cacheinfo 100644 \ 053a0094e47bd27c88ee17e205f42beb974791aa greeting.txt $ git status (shows greeting.txt)

Slide 71

Slide 71 text

# Ignore a file $ git update-index \ --assume-unchanged \ Cool aside,

Slide 72

Slide 72 text

# Write the index tree $ git write-tree This simply takes the current index and writes it as a tree, and gives back the ID $ git write-tree 202ad037ef5d9a7b369eb4a56fb5fcb3a4c74228

Slide 73

Slide 73 text

# Commit an existing tree $ git commit-tree Now that we have a tree, we can commit it! $ echo “Initial commit!” | git commit-tree 202ad037ef5d9a7b369eb4a56fb5fcb3a4c74228 7847536f3db84e7b21ef79427f8ec7ddb4abdc99 Pass it -p for a parent $ echo 'Woo! DevconTLV!' > greeting.txt $ git hash-object -w greeting.txt 989932c6ebee1b4a284e8a47a1eb9095e971a599 $ git update-index --add --cacheinfo 100644 989932c6ebee1b4a284e8a47a1eb9095e971a599 greeting.txt $ git write-tree 54e49d1aaff28b88c6639b1b4634f6bde673b39d $ echo "Commit #2" | git commit-tree 54e49d -p 784753 2b63f9dffeb0b40e34a491890ae35241b34e360e

Slide 74

Slide 74 text

# Lets update the master ref $ echo “SHA” > \ .git/objects/refs/heads/master $ echo “2b63f9dffeb0b40e34a491890ae35241b34e360e” > .git/objects/refs/heads/master $ git log --stat

Slide 75

Slide 75 text

fin

Slide 76

Slide 76 text

any questions?