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.

Git-ing out of your git messes

2,249 views

Published on

Avoiding & Fixing your messes in git - by Katie Sylor-Miller of ohshitgit.com. Part of #vBrownBag #commitmas 2016

Published in: Engineering
  • Be the first to comment

Git-ing out of your git messes

  1. 1. Git-ing out of your Git messes Katie Sylor-Miller Senior Software Engineer, Etsy ohshitgit.com
  2. 2. DON’T GIT INTO A MESS IN THE FIRST PLACE
  3. 3. Fundamentals commits, branches, HEAD & environments
  4. 4. Fundamentals: Commits
  5. 5. Each commit contains a few pieces of information: ● A snapshot of the entire repo ● Who made this change ● When this change was made ● A message describing the commit ● A pointer to the previous commit (This is a bit of an over simplification, for a more detailed explanation, see: http://blog.thoughtram.io/git/2014/11/18/the-anatomy-of-a-git-commit.html) What’s in a commit
  6. 6. Each commit contains a few pieces of information: ● A snapshot of the entire repo ● Who made this change ● When this change was made ● A message describing the commit ● A pointer to the previous commit (This is a bit of an over-simplification, for a more detailed explanation, see: http://blog.thoughtram.io/git/2014/11/18/the-anatomy-of-a-git-commit.html) What’s in a commit SHA-1 Unique 40- char Hash
  7. 7. Commit hashes a4df41a8045877d50396d00113598e47f6ad10ef aec561108fd86412c2a9083d7d95ed1668d2f4e4 6dab6a712177cf2dd2cf8b79a2cee24351be60eb 1a3531222242241153ac8a76b752d5f525a99d2c 912bde5d4e5e962269ddff87da83cc5ce55e75d0
  8. 8. Fun fact: commit hash abbreviations a4df41a aec5611 6dab6a7 1a35312 912bde5
  9. 9. Fundamentals: Branches
  10. 10. ● Each git repository starts out with a single branch, called master. ● There can be multiple branches of each repo. ● Each branch is essentially a copy of the master branch and all of it’s history ● Branches are cheap and easy (unlike TFS or SVN), so use them as much as you want! Branches: the connection between commits
  11. 11. Mental model: a linked list of commits a4df41aaec56116dab6a71a35312 912bde5
  12. 12. Each commit contains a few pieces of information: ● A snapshot of the entire repository ● Who made this change ● When this change was made ● A message describing the commit ● A pointer to the previous commit Mental model: a linked list of commits a4df41aaec56116dab6a71a35312 912bde5
  13. 13. Mental model: a linked list of commits a4df41aaec56116dab6a71a35312 912bde5 parent child
  14. 14. Mental model: a linked list of commits a4df41aaec56116dab6a71a35312 912bde5
  15. 15. Branches are a reference to a commit master a4df41aaec56116dab6a71a35312 912bde5
  16. 16. git branch new-branch Create a new branch
  17. 17. Branches are a reference to a commit master a4df41aaec56116dab6a71a35312 912bde5 new-branch
  18. 18. Fundamentals: HEAD
  19. 19. HEAD points to currently checked-out branch master new-branch a4df41aaec5611 912bde56dab6a7 HEAD
  20. 20. Check out a branch git checkout new-branch
  21. 21. HEAD points to currently checked-out branch master new-branch a4df41aaec5611 912bde56dab6a7 HEAD
  22. 22. A new commit’s parent is the HEAD master new-branch a4df41aaec5611 912bde5 1668d2f6dab6a7 HEAD
  23. 23. master new-branch a4df41aaec5611 912bde5 1668d2f ca53f4f 6aac7b2 Branches are a linked list tree HEAD
  24. 24. Branches are a linked list tree directed acyclic graph https://en.wikipedia.org/wiki/Directed_acyclic_graph
  25. 25. Fundamentals: Remote vs. Local
  26. 26. Remote/Origin Local Staging/Index Workspace Stash Your machinegithub Central server where shared git repositories are stored -- Remotes typically are “bare” - you can’t directly modify them
  27. 27. Your local copy of the remote git repository -- Contains the entire history and all branches of a remote repo Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  28. 28. Snapshot of changes to the current branch that you want to commit -- Is a copy of all of the files in the repo, not just the changed files Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  29. 29. Where changes to files are made -- Analogous to the physical directory where files are stored on disk Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  30. 30. A place to store changes to files that you aren’t ready to commit yet -- Aka “shelving” changes for later Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  31. 31. History Viewing and changing history
  32. 32. Viewing history
  33. 33. See the history of a branch git log
  34. 34. See the history of a branch git log git log
  35. 35. See the history of the HEAD git reflog
  36. 36. See the history of the HEAD git reflog git reflog
  37. 37. Moving backwards in history
  38. 38. Checkout Go back to a specific point in time git checkout <commit hash>
  39. 39. Aside: Detached HEAD Detached HEAD means that HEAD is not a symbolic reference anymore, therefore new commits will not be part of history. Happens when you: ● Checkout a commit that is not the tip of a branch, or ● Checkout a remote tracking branch Fix it by: ● Checking out a branch, or ● Create a new branch from this state
  40. 40. Fixing messes Reset & revert
  41. 41. git reset HEAD@{x} # or git reset HEAD~x # or git reset <commit hash> Reset Go back to a previous point in time
  42. 42. git reset --soft HEAD~ git reset --mixed HEAD~ git reset --hard HEAD~ Three types of resetting
  43. 43. soft Takes you back in history, and leaves your changes in staging Takes you back in history, and discards those changes hardmixed (default) takes you back in history, and leaves your changes in the workspace
  44. 44. git reset --hardPro tip Clear out your staging area and workspace
  45. 45. git revert <commit hash> # or git revert HEAD~X Revert Undo a public commit
  46. 46. ● Pass in the identifier(s) of specific commits ● Git creates a new commit that undoes the work of the specified commit. ● You can revert a commit in the middle of other commits, but if a later commit modifies the same file, you will need to resolve that conflict. Reverting commits
  47. 47. Revert multiple commits You can use either HEAD~ references, or commit hashes # range git revert HEAD~3..HEAD # or list newest->oldest git revert HEAD~2 HEAD~3 HEAD~4
  48. 48. Revert without auto-commit In case you want to double-check the revert git revert --no-commit <commit or range or list> # leaves changes staged # for manual commit
  49. 49. Workflow Committing & branching
  50. 50. A simple workflow
  51. 51. master master baz.php foo.php bar.php Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  52. 52. master master baz.php git add foo.php bar.php baz.php foo.php bar.php Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  53. 53. master HEAD master git commit baz.php foo.php bar.php Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  54. 54. master master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  55. 55. git push Send changes to remote
  56. 56. master git push master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  57. 57. master master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  58. 58. But… it’s usually not that simple
  59. 59. master master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  60. 60. Avoiding messes Stay up-to-date
  61. 61. master master origin/ master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  62. 62. git fetch origin Update local tracking branch
  63. 63. master master git fetch Remote/Origin Local Staging/Index Workspace Stash Your machinegithub origin/ master
  64. 64. git merge origin/masterMerge
  65. 65. master master origin/ master New merge commit Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  66. 66. master master origin/ master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  67. 67. git pull # git fetch && git merge Pull Do a fetch & merge at the same time
  68. 68. master master origin/ master git pull Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  69. 69. git push Sync changes to remote
  70. 70. master git push master origin/ master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  71. 71. mastermaster origin/ master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  72. 72. Avoiding messes Rebase all the things
  73. 73. master master origin/ master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  74. 74. git rebase origin/masterRebase
  75. 75. master origin/ master master Our commit Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  76. 76. master origin/ master master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  77. 77. git pull --rebase # git fetch && git rebase Pull with Rebase
  78. 78. git config --global alias.rpull ‘pull -- rebase’Pro tip Add rpull as an alias for git pull --rebase
  79. 79. master origin/ master master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  80. 80. git push Sync changes to remote
  81. 81. master origin/ master master git push Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  82. 82. master origin/ master master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  83. 83. Avoiding Messes Always Be Committing
  84. 84. Why lots of commits are better ● Commits are cheap and easy ● Save progress over time - easier to go back ● Smaller diffs are easier to reason about ● Less chance of committing the wrong thing when you are reviewing small changelists
  85. 85. Problem: Committing the wrong thing
  86. 86. Avoid the problem: Committing the wrong thing ● Set up your command line to show you what branch you are on (https://github.com/jimeh/git-aware-prompt) ● Be careful about what files you edit - use .gitignore to your advantage ● git status is your BFF ● Understand how staging works (subsequent changes to a file are not reflected)
  87. 87. Fix the problem Entering the wrong commit message # make sure nothing is in staging git commit -amend # follow prompts to change # the commit message
  88. 88. Fix the problem Forgetting to commit a file git add filename git commit -amend # follow prompts to change # the commit message
  89. 89. Fix the problem Committing the wrong file # undo your last commit # but leave the changes in staging git reset HEAD~ # unstage the file git reset HEAD filename # re-do commit git commit -m “Commit message”
  90. 90. Fix the problem Committing to the wrong branch (version one) # undo the last commit, but leave the changes available git reset HEAD~ --soft git stash # move to the correct # branch git checkout name-of-the-correct- branch git stash pop git add . # or add individual files git commit -m "your message here" # now your changes are on the correct branch
  91. 91. Fix the problem Committing to the wrong branch (version two) git checkout name-of-the-correct- branch # grab the last commit to master git cherry-pick master # delete it from master git checkout master git reset HEAD~ --hard
  92. 92. Avoiding messes Always Be Branching
  93. 93. Why a feature branch workflow is better ● Create a new branch of master, do your work on that branch. When you are ready, merge your changes back into master ● Safety net: you aren’t changing master directly until your feature is ready for prime time ● Allows you to switch between tasks/manage unrelated changes ● Preserve the history of larger features or long-term work and share with a team
  94. 94. Problem: Staying up to date
  95. 95. MERGE REBASE ● Adds a new commit to your feature branch. ● You are resolving potential conflicts created by other people’s code. ● Replays your commits on top of the latest of master. ● You are resolving potential conflicts created by your own code. Avoid the problem: rebase vs. merge
  96. 96. Rebasing gotchas & caveats ● Each commit is applied as a separate patch, so you might need to resolve conflicts for each commit :( :( :( ● Don’t change the public history of a branch or you’re gonna have a bad time. ● Some people like to keep commit history of branches. Discuss with your team which is preferred!
  97. 97. git rebase -i HEAD~x Avoid the problem Combine commits so you have fewer conflicts to deal with when rebasing
  98. 98. master feature-branch origin/ master git rebase -i HEAD~2 Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  99. 99. DON’T PANIC
  100. 100. master feature-branch origin/ master Remote/Origin Local Staging/Index Workspace Stash Your machinegithub
  101. 101. git checkout master && git merge --squash feature- branch Merging back to master *controversial opinion*
  102. 102. Remote (Origin) Local Staging/Index Workspace Stash master Your VMgithub.etsycorp.com Etsyweb Etsyweb feature-branch master
  103. 103. ● Combines all of the commits in your feature branch into a single changeset ● Leaves you in a state where the changes are not committed, you need to make the final commit ● Lose historical connection to the feature branch Squash merging
  104. 104. Avoiding messes Resolving conflicts
  105. 105. ● Communication with teammates ● Update your local master and origin/master all.the.time. ● Periodically squash commits to reduce the number of commit conflicts to resolve (esp. When rebasing) Avoid conflicts in the first place
  106. 106. DO DON’T ● Merge feature-branch into master ● Rebase feature- branch against master ● Merge master into feature-branch ● Rebase master against feature-branch Avoid conflicts: merge & rebase in the right direction
  107. 107. The problem: conflict markers
  108. 108. Fix the problem Check for remaining conflict markers before committing git diff --check
  109. 109. Pro tip Use git mergetool command to open a GUI to help resolve conflicts. HIGHLY RECOMMEND any Jetbrains IDE, also meld looks good git config merge.tool <toolname>
  110. 110. If all else fails Abort! abort! git merge --abort # or git rebase --abort
  111. 111. That’s it! Easy, right?
  112. 112. Recap: Avoiding messes ● Understand the fundamentals (commits, branches, history, environments, workflow) ● Use tools to help you work smarter (cmd line formatting mergetool, etc.) ● Always be committing & branching ● Rebase & merge in the right direction ● DON’T PANIC! Everything is fixable (one way or another)
  113. 113. ● Visual git cheatsheet http://ndpsoftware.com/git-cheatsheet.html ● Oh shit, git! http://ohshitgit.com ● Atlassian git tutorial (esp. the advanced tutorials) https://www.atlassian.com/git/ ● Git for Humans book https://abookapart.com/products/git-for-humans Useful links
  114. 114. Thank you! @ksylor && @ohshitgit

×