Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Understanding Github PR Merge Options (1up-ing your git skills part 2)

91 views

Published on

In this talk, Ben Limmer helps to improve your understanding of common git and github concepts. Topics of discussion include:
- the two schools of thought surrounding history in github
- the three options for integrating GitHub PRs (create a merge commit, squash and merge, rebase and merge)
- some gotchas with rewriting history in git, and how to avoid and correct issues
- helpful git commands (add by patch, git revert and git bisect)

A talk for the Ibotta Technology Lunch and Learn Series in August 2017.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Understanding Github PR Merge Options (1up-ing your git skills part 2)

  1. 1. your git skills Ben Limmer August 28, 2017 @blimmer
  2. 2. Desired Takeaways understand the two main schools of thought on commit history understand the three github PR merge options understand common gotchas with rewriting history master a new git command or two
  3. 3. Plumbing vs. Porcelain We’ll stick mostly to using porcelain commands, but reading the is highly recommended once you’re familiar with these concepts. plumbing docs
  4. 4. A Tale of Two Histories
  5. 5. Two main schools of thought on commit history
  6. 6. School 0: “It’s a record of what actually happened” source: It’s a historical document, valuable in its own right, and shouldn’t be tampered with. From this angle, changing the commit history is almost blasphemous; you’re lying about what actually transpired. So what if there was a messy series of merge commits? That’s how it happened, and the repository should preserve that for posterity. git book
  7. 7. Who could forget such classics as…
  8. 8. or my personal favorite…
  9. 9. Some of these are, of course, shown in jest and the commit messages could be improved. This really is a record of exactly what happened. However, the historical record can be difficult to traverse.
  10. 10. School 1: “It’s the story of how your project was made” source: You wouldn’t publish the first draft of a book, and the manual for how to maintain your software deserves careful editing. This is the camp that uses tools like rebase and filter-branch to tell the story in the way that’s best for future readers. git book
  11. 11. Which gives you commits like these…
  12. 12. School 0 vs. School 1
  13. 13. School 0 “It’s a record of what actually happened” Pros Easy Low-Risk / Barrier to Entry History records what “really happened” Cons Lots of micro-commits, with varying levels of meaning More commits === more time traversing the logs
  14. 14. School 1 “It’s the story of how your project was made” Pros Clean, meaningful history No “WIP”, “Initial”, etc. commits Cons Must be careful with rewriting history Can create very “macro” commits containing a lot of code
  15. 15. on the two schools ?
  16. 16. The Three Github PR Options source: github help docs
  17. 17. Create a Merge Commit
  18. 18. Merge A merge occurs when you want to integrate two branches together.
  19. 19. When you merge feature/add-behavior into develop, it performs a three-way merge between the two latest branch snapshots (C4 and C5) and the most recent common ancestor of the two (C1), creating a new snapshot (and commit - C6).
  20. 20. This is fine, but we’ve produced another commit which might not have value. Additionally, we have feature branch commits intermixed within the history of develop.
  21. 21. on merging ?
  22. 22. Rebase and Merge
  23. 23. A rebase takes one or more commits and reapplies it on top of new commits on the destination branch.
  24. 24. When you rebase feature/add-behavior off of develop, it works by going to the common ancestor of the two branches (C1), generating diffs for each subsequent commit (C2/C3/C5), and replays each commit.
  25. 25. Then, the merge can occur as a “fast-forward” merge, creating no merge commit.
  26. 26. The result of the merge and the rebase are functionally the same, except the rebase history looks more linear.
  27. 27. Create a Merge Commit
  28. 28. Rebase and Merge
  29. 29. on rebase and merge ?
  30. 30. Squash and Merge
  31. 31. A “squash” takes one or more commits, creates a single commit from those commits and applies it to the destination branch.
  32. 32. When you squash feature/add-behavior, it conceptually rebases the branch as before. But then, it "squashes" the commits (C6/C7/C8) into one commit.
  33. 33. All the commits from the branch are now contained in one commit (C9).
  34. 34. Then, the merge can occur as a “fast-forward” merge, creating no merge commit. Just like a rebase and merge.
  35. 35. You should also update the commit messages as you squash and merge. By default it is just a “starred” list of all your commit messages:
  36. 36. Take the few extra minutes to add some thought about what the code does. It may prove helpful to a future dev who finds your code.
  37. 37. on squash and merge ?
  38. 38. Recap on GitHub Merge Options
  39. 39. Create a Merge Commit
  40. 40. Rebase and Merge
  41. 41. Squash and Merge
  42. 42. Patterns at Ibotta We enforce “squash and merge” on most repositories.
  43. 43. It produces history like this:
  44. 44. A developer that finds this commit years down the road would have lots of context and information on why we changed the code in this way.
  45. 45. The individual commits are still also viewable within the PR, and the branch can be restored in its original state, if needed.
  46. 46. Gotchas with Rewriting History
  47. 47. Remember our squash and merge from before?
  48. 48. What would happen if someone branched off of our branch before we squashed and merged? Their branch would still know about commits C2/C3/C5, but those commits don't exist anymore...
  49. 49. Charlie’s branch has commits C2/C3/C5 from when he originally branched from Bob’s branch.
  50. 50. When Bob merges, he creates C9 and “rewrites history” so that C2/C3/C5 don’t end up on develop. But Charlie’s branch still knows about Bob’s original commits.
  51. 51. To fix this, we need to help git understand what’s going on. or replay the last two commits only (ours): git rebase --onto develop feature/add-behavior feature/add-more-behavior git rebase --onto develop HEAD~2
  52. 52. This will result in a nice clean graph:
  53. 53. However, when you try to push, git might tell you that you can’t… > git push origin feature/add-more-behavior To github.com:blimmer/example-repo.git ! [rejected] add-more-behavior -> add-more-behavior (non-fast-forward) error: failed to push some refs to 'git@github.com:blimmer/example-repo.git' hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Integrate the remote changes (e.g. hint: 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
  54. 54. git is warning us that history has changed in a way that it doesn’t understand. it’s suggesting a git pull, but that’s not what we want to do (that will re-integrate C2/C3/C5 from origin!)
  55. 55. we need to tell git that we know what we’re doing and that we just rebased. origin will now happily accept our newly rebased version of our branch. > git push --force-with-lease origin feature/add-more-behavior
  56. 56. --force-with-lease ???
  57. 57. --force-with-lease Checks to make sure that no-one pushed an additional commit to your branch before you rebased.
  58. 58. TLDR; use --force-with-lease and if you get a warning that looks like this: Check out who else is working on your branch. > git push --force-with-lease origin feature/add-more-behavior [rejected] add-more-behavior -> add-more-behavior (stale info) error: failed to push some refs to 'git@github.com:blimmer/example-repo.git'
  59. 59. Also, an alias is really handy here. Add this to ~/.gitconfig. Then you can do this instead [alias] pushf = push --force-with-lease git pushf origin feature/add-more-behavior
  60. 60. on rewriting history gotchas?
  61. 61. PSA you (almost) never need to merge the same branch into itself
  62. 62. commit history on the develop branch
  63. 63. what happened?
  64. 64. > git push origin develop To github.com:blimmer/example-repo.git ! [rejected] develop -> develop (non-fast-forward) error: failed to push some refs to 'git@github.com:blimmer/example-repo.git' hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Integrate the remote changes (e.g. hint: 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
  65. 65. we never want to force push develop like with our other branches. we want to integrate the missed commit and replay our commit.
  66. 66. this will replay our commit after the missed upstream commit git pull origin develop --rebase
  67. 67. now git will happily accept the branch without any force push because the histories match upstream and locally. git push origin develop
  68. 68. on why you almost never need to merge your own branch into itself?
  69. 69. Other git tricks git add -p git revert git bisect
  70. 70. git add -p
  71. 71. another tool to use instead of git add .
  72. 72. steps through each file patch by patch, staging as you go.
  73. 73. Imagine a change at the top and bottom of a file, but they’re not related to the same change. diff --git a/README.md b/README.md index 8cb1ada..81f96b0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # 1-Up Your Git Skills +A change up top. + A talk given at the Ibotta Engineering Lunch and Learn series on August 29, 2017. This presentation was created with [reveal-ck](https://github.com/jedcn/reveal-ck). @@ -16,3 +18,5 @@ If you want to run this project locally: 3. Run `bundle exec reveal-ck generate` 4. Run `bundle exec reveal-ck serve` 5. Visit http://localhost:10000 + +A change at the bottom.
  74. 74. diff --git a/README.md b/README.md index 8cb1ada..81f96b0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # 1-Up Your Git Skills +A change up top. + A talk given at the Ibotta Engineering Lunch and Learn series on August 29, 2017. This presentation was created with [reveal-ck](https://github.com/jedcn/reveal-ck). Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? n @@ -16,3 +18,5 @@ If you want to run this project locally: 3. Run `bundle exec reveal-ck generate` 4. Run `bundle exec reveal-ck serve` 5. Visit http://localhost:10000 + +A change at the bottom. Stage this hunk [y,n,q,a,d,/,K,g,e,?]? y
  75. 75. On branch update-talk Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: README.md 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
  76. 76. git revert
  77. 77. with squash and merge this is easy!
  78. 78. git revert 1e736b8 git push origin develop
  79. 79. then, checkout a new branch, revert the revert and fix it up. git checkout -b feature/revert-revert-filtering-rps git revert 43baa57
  80. 80. git bisect
  81. 81. git bisect use binary search to find the commit that introduced a bug
  82. 82. Steps: 1. Tell git that we want to bisect. 2. Mark a good commit (where the problem doesn’t exist). 3. Mark a bad commit (where the problem does exist). 4. Find where the bug was introduced.
  83. 83. git bisect example source
  84. 84. > cat test.txt row row row your car gently down the stream
  85. 85. > git log commit d6c3e9b9cc226db47b96c926e35c3ca8733a618b (HEAD -> master) Author: Ben Limmer <ben@benlimmer.com> Date: Mon Aug 28 18:00:31 2017 -0600 Adding the word 'stream' commit 06ecaeb65e34c2a1999e0df388d6740d827700cd Author: Ben Limmer <ben@benlimmer.com> Date: Mon Aug 28 18:00:31 2017 -0600 Adding the word 'the' commit 8483a605ca3a0ee2114217d85bfd350dbe32c6c4 Author: Ben Limmer <ben@benlimmer.com> Date: Mon Aug 28 18:00:31 2017 -0600 Adding the word 'down' commit a01f608a342d01f6e0f190575e505119de23b64d Author: Ben Limmer <ben@benlimmer.com> Date: Mon Aug 28 18:00:31 2017 -0600 Changing the word 'boat' to 'car' commit 025c6896d02fbad81ad7425542ec58e762a84d79 Author: Ben Limmer <ben@benlimmer.com> Date: Mon Aug 28 18:00:31 2017 -0600
  86. 86. git bisect to the rescue! first, tell git that we want to bisect. git bisect start
  87. 87. mark the commit where we knew things were OK. commit cdc7bf7a1d671343e27fba67a94ce462b8ee009b Author: Ben Limmer <ben@benlimmer.com> Date: Mon Aug 28 18:00:31 2017 -0600 Adding the word 'boat' git bisect good cdc7bf7a1d671343e27fba67a94ce462b8ee009b
  88. 88. and mark where we know it’s bad. commit d6c3e9b9cc226db47b96c926e35c3ca8733a618b (HEAD -> master) Author: Ben Limmer <ben@benlimmer.com> Date: Mon Aug 28 18:00:31 2017 -0600 Adding the word 'stream' git bisect bad d6c3e9b9cc226db47b96c926e35c3ca8733a618b
  89. 89. now step through and check it out at each step in the binary search. Bisecting: 2 revisions left to test after this (roughly 1 step) [a01f608a342d01f6e0f190575e505119de23b64d] Changing the word 'boat' to 'car' > cat test.txt row row row your car gently git bisect bad
  90. 90. Bisecting: 0 revisions left to test after this (roughly 0 steps) [025c6896d02fbad81ad7425542ec58e762a84d79] Adding the word 'gently' > cat test.txt row row row your boat gently git bisect good
  91. 91. a01f608a342d01f6e0f190575e505119de23b64d is the first bad commit commit a01f608a342d01f6e0f190575e505119de23b64d Author: Ben Limmer <ben@benlimmer.com> Date: Mon Aug 28 18:00:31 2017 -0600 Changing the word 'boat' to 'car' :100644 100644 9eb95934daee636eba60587a2aef592cd5edacc1 34802b80cf929a42035c7b02dae715c864e :000000 100644 0000000000000000000000000000000000000000 9eb95934daee636eba60587a2aef592cd5e
  92. 92. on anything else
  93. 93. Resources git book rypress git plumbing git help <command-name>
  94. 94. Thanks! Ben Limmer hello@benlimmer.com @blimmer
  95. 95. Legal Stuff I was heavily influenced by the , which is licensed under the , thus this presentation is also subject to the same license. You need to attribute it if you use it, indicate if changes were made and distribute any remix of this work under the same license. I cribbed the “two schools of thought” from that book and added my opinions. Git Book Creative Commons Attribution Non Commercial Share Alike 3.0 license

×