DevconTLV Git Workshop

011f777dae520e762d715840b903dc67?s=47 Mike Skalnik
February 14, 2013

DevconTLV Git Workshop

011f777dae520e762d715840b903dc67?s=128

Mike Skalnik

February 14, 2013
Tweet

Transcript

  1. Advanced Git let talk

  2. @skalnik i’m

  3. a few of my favorite things Raindrops on roses and

    whiskers on kittens… Just kidding, I love git.
  4. merge conflicts

  5. # Merge a branch $ git merge conflict you can

    do this after you run `merge-conflict.sh`: https://gist.github.com/skalnik/4951428
  6. Auto-merging greeting.txt CONFLICT (content): Merge Automatic merge failed; fi Oh

    god wtf just happened. Lets check out greeting.txt
  7. <<<<<<< 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!
  8. rerere

  9. remembers merge conflicts

  10. # 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
  11. 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
  12. a32 2e2 8b3 fe1 2bd topic master af3 when you

    merge master in, you’ll have to resolve the conflict
  13. 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
  14. 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!
  15. rebase

  16. rebase is not a merge

  17. rebase is preparation for a merge

  18. merge makes a multi-parent commit

  19. rebase reorders commits before your branch

  20. rebase simulates people taking turns working

  21. # Rebase interactively over # last 5 commits $ git

    rebase --interactive \ HEAD~5
  22. a32 2e2 8b3 e69 d19 You can delete commits

  23. a32 2e2 e69 d19 Changing any parent changes the children

  24. a32 2e2 73e 1d9 Or pull them out

  25. a32 2e2 e69 d19 And reorder them

  26. a32 d19 e69 2e2 Normally these SHAs would change, but

    so you can see that they swap, I’ll leave them
  27. a32 d19 41a 2e2 Or even take the last 2

    commits, and squash ‘em together
  28. a32 d19 e69 2e2 + a3f =

  29. a32 d19 a3f Or even amend them

  30. a32 fa1 df4 Or even completely edit them Talk about

    git commit --amend
  31. # Rebase interactively and # autosquash last 5 commits $

    git rebase -i --autosquash \ HEAD~5 fixup! <another commit message> squash! <another commit message> These are automatically set to fixup/squash when rebasing interactively then
  32. stash

  33. a super quick branch

  34. local only

  35. stack based push pop peek

  36. # stash your changes $ git stash

  37. # save ‘em $ git stash save ‘message’

  38. # list ‘em $ git stash list

  39. # use ‘em $ git stash pop

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

  41. # or if you want to keep it $ git

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

    stash apply
  43. # too good to just stash? $ git stash branch

  44. cherry-pick

  45. “cherry picking” a commit into your branch

  46. # All you need is the SHA $ git cherry-pick

    <SHA> Or multiple! This creates a brand new commit, but with the same diff It’s much like a manual rebase
  47. # What if you don’t want # the commit? $

    git cherry-pick <SHA> --no-commit Or multiple! This creates a brand new commit, but with the same diff It’s much like a manual rebase
  48. ref log

  49. a journal of your local actions

  50. 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
  51. # 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
  52. hunks

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

    add --patch
  54. 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
  55. 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
  56. # But that’s not all! $ git reset -p

  57. # Checkouts too! $ git checkout -p

  58. hub

  59. hub introduces git to GitHub

  60. # Install via Homebrew $ brew install hub # or

    with curl $ curl \ http://defunkt.io/hub/standalone \ -sLo ~/bin/hub && \ chmod +x ~/bin/hub
  61. # Clone a GitHub repo $ git clone user/repo #

    vs $ git clone \ git://github.com/user/repo
  62. # Private repo? $ git clone -p github/github

  63. # Fork current repo $ git fork

  64. # Then after some changes $ git pull-request

  65. plumbing

  66. git is a key-value store

  67. # 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
  68. # Look at a git object $ git cat-file $

    git cat-file -p 053a0094e47bd27c88ee17e205f42beb974791aa Yay DevconTLV $ git cat-file -t 053a0094e47bd27c88ee17e205f42beb974791aa blob
  69. 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?
  70. # 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)
  71. # Ignore a file $ git update-index \ --assume-unchanged \

    <file> Cool aside,
  72. # 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
  73. # 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
  74. # Lets update the master ref $ echo “SHA” >

    \ .git/objects/refs/heads/master $ echo “2b63f9dffeb0b40e34a491890ae35241b34e360e” > .git/objects/refs/heads/master $ git log --stat
  75. fin

  76. any questions?