Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You

Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You

Popular Git workflows (e.g., rebase-before-merge) have a side effect of destroying important aspects of the history of the branch being merged. Similarly, inexperienced or lazy developers that don't take the time to properly structure commits before pushing or merging can obscure important aspects of the history of the code being developed. Learn what these problems are, and how to avoid them.

As presented at LinuxFest Northwest, 07 May 2017

D07c1f81d10a1d147d6b5cb80fa1c654?s=128

John SJ Anderson

May 07, 2017
Tweet

Transcript

  1. photo: https://cdn.pixabay.com/photo/2014/10/01/17/59/ my-little-pony-468916960720.jpg logs are magic! john sj anderson |

    @genehack | lfnw 2017 | 7 may 2017 1 — LFNW 2017 – 7 May 2017 – @genehack
  2. photo: https://cdn.pixabay.com/photo/2014/10/01/17/59/ my-little-pony-468916960720.jpg why git workflows & commit structure should

    matter to you john sj anderson | @genehack | lfnw 2017 | 7 may 2017 2 — LFNW 2017 – 7 May 2017 – @genehack
  3. hi, i'm john. a/k/a @genehack 3 — LFNW 2017 –

    7 May 2017 – @genehack
  4. In my day job, I'm the VP of Technology for

    Infinity, a small IT consultancy. vp, tech infinity interactive 4 — LFNW 2017 – 7 May 2017 – @genehack
  5. I wanted to give this talk because I love revision

    control. I've kept my home directory under revision control for over a decade, I maintain a Perl git wrapper module, and I wrote this thing called GitGot to automate batch ops across multiple Git repos (but that's a different talk) i ❤ revision control 5 — LFNW 2017 – 7 May 2017 – @genehack
  6. I liked CVS... cvs 6 — LFNW 2017 – 7

    May 2017 – @genehack
  7. I liked SVN a bit more... svn 7 — LFNW

    2017 – 7 May 2017 – @genehack
  8. Hell, I even liked RCS rcs 8 — LFNW 2017

    – 7 May 2017 – @genehack
  9. Actually, that's a lie -- I don't think anybody liked

    RCS. Anybody here remember RCS? Anybody still using RCS? rcs 9 — LFNW 2017 – 7 May 2017 – @genehack
  10. And now we have git git 10 — LFNW 2017

    – 7 May 2017 – @genehack
  11. I love git. Git makes me happy i ❤ git

    11 — LFNW 2017 – 7 May 2017 – @genehack
  12. How many people have used git at least once? How

    many people feel comfortable in git? How many people would call themselves git "experts"? quick poll! 12 — LFNW 2017 – 7 May 2017 – @genehack
  13. So, if you're not at least a little familiar with

    git, this talk is probably not going to that interesting -- most of the stuff I'm going to talk about does apply to all revision control systems, but my examples and recommendations are all git-based what this talk isn't 13 — LFNW 2017 – 7 May 2017 – @genehack
  14. I'm also not going to be claiming to dispense any

    universal truths in this talk... no universal truths 14 — LFNW 2017 – 7 May 2017 – @genehack
  15. I'm not even going to try to convince you that

    anything I'm telling you is a "best practice". Pretty much anything I advocate in here, I'm sure people will be able to come up with an example where I'd say, "yeah, for that, don't do it" not even "best practices" 15 — LFNW 2017 – 7 May 2017 – @genehack
  16. So what is this talk about then? what this talk

    is 16 — LFNW 2017 – 7 May 2017 – @genehack
  17. Opinionated commentary on some aspects of using revision control systems...

    some opinions 17 — LFNW 2017 – 7 May 2017 – @genehack
  18. ...based on things I've seen over the past mumble years

    making extensive use of revision control on personal, open source, and commercial software projects photo modified from http://i2.kym-cdn.com/photos/images/original/ 001/044/247/297.png backed up with experience 18 — LFNW 2017 – 7 May 2017 – @genehack
  19. Some of this stuff may be more important for larger

    projects with multi-person teams ... maybe more important for larger projects 19 — LFNW 2017 – 7 May 2017 – @genehack
  20. ...but it's also important if you've just started a project

    that you're thinking might grow into something bigger. Having a solid project history from the get-go can make it a lot easier for contributors to come on board and start pitching in but also good for projects that aspire to be bigger 20 — LFNW 2017 – 7 May 2017 – @genehack
  21. maybe more relevant for coding projects 21 — LFNW 2017

    – 7 May 2017 – @genehack
  22. but also applicable for doc or config repos 22 —

    LFNW 2017 – 7 May 2017 – @genehack
  23. Eventually we're going to talk about how to make better

    use of the history in your repos ... making better use of history 23 — LFNW 2017 – 7 May 2017 – @genehack
  24. ...but first, we're going to talk about ways to make

    better history making better history 24 — LFNW 2017 – 7 May 2017 – @genehack
  25. For all these things, there are a few common elements

    prerequisites 25 — LFNW 2017 – 7 May 2017 – @genehack
  26. For maximum value, you're going to want to apply them

    consistently consistency 26 — LFNW 2017 – 7 May 2017 – @genehack
  27. Make them into habits habits 27 — LFNW 2017 –

    7 May 2017 – @genehack
  28. They're pretty much all the type of thing that if

    you do them all the time... do it all the time 28 — LFNW 2017 – 7 May 2017 – @genehack
  29. ...you eventually will just do them without thinking too much

    about it then you don't have to think about it 29 — LFNW 2017 – 7 May 2017 – @genehack
  30. or even better, if you're the right kind of twisted...

    even better 30 — LFNW 2017 – 7 May 2017 – @genehack
  31. ...you'll automate things. for example, i periodically run some scripts

    to find repos in a "dirty" state, or that have local commits that haven't been pushed to a remote, and then clean them up automate it 31 — LFNW 2017 – 7 May 2017 – @genehack
  32. so, moving on to how to make better history how

    to make better history 32 — LFNW 2017 – 7 May 2017 – @genehack
  33. if you're going to talk about git, you almost have

    to talk about workflows. potentially one of the more contentious aspects of starting a new project is deciding what your workflow is going to be workflows 33 — LFNW 2017 – 7 May 2017 – @genehack
  34. workflows can range from the very simple -- just a

    single branch in a local-only repo, just adding commits onto the HEAD of that branch photo credit: modified by https://www.flickr.com/photos/appleboy/ 5488984566/in/photostream/ no remote no branches master only 34 — LFNW 2017 – 7 May 2017 – @genehack
  35. or you can have that basic setup, but with a

    remote that you push things to every so often. this is basically the simplest possible branching workflow -- when you have local commits you haven't pushed to the remote yet, that's (if you squint, a bit) a branch photo credit: modified from https://www.flickr.com/photos/appleboy/5488387469/in/ photostream/ local master no branches & periodic pushes 35 — LFNW 2017 – 7 May 2017 – @genehack
  36. all the way up to fairly complicated workflows like git

    flow, where you have multiple branches in flight at any given point. anybody using git flow, or anything equivalent? photo credit: https://www.flickr.com/photos/appleboy/ 5488984404/in/photostream/ git flow 36 — LFNW 2017 – 7 May 2017 – @genehack
  37. some notable antipatterns 37 — LFNW 2017 – 7 May

    2017 – @genehack
  38. squashed branches 38 — LFNW 2017 – 7 May 2017

    – @genehack
  39. fast forward merges 39 — LFNW 2017 – 7 May

    2017 – @genehack
  40. this is basically doing extra work to mimic what a

    fast forward merge probably would have done rebase before merge 40 — LFNW 2017 – 7 May 2017 – @genehack
  41. all destroy history 41 — LFNW 2017 – 7 May

    2017 – @genehack
  42. all destroy history needlessly 42 — LFNW 2017 – 7

    May 2017 – @genehack
  43. a linear commit history is a lie 43 — LFNW

    2017 – 7 May 2017 – @genehack
  44. a linear commit history is a lie (probably) 44 —

    LFNW 2017 – 7 May 2017 – @genehack
  45. instead 45 — LFNW 2017 – 7 May 2017 –

    @genehack
  46. some good patterns 46 — LFNW 2017 – 7 May

    2017 – @genehack
  47. branch 47 — LFNW 2017 – 7 May 2017 –

    @genehack
  48. branch for errythang 48 — LFNW 2017 – 7 May

    2017 – @genehack
  49. (specifics will vary) 49 — LFNW 2017 – 7 May

    2017 – @genehack
  50. have a release branch 50 — LFNW 2017 – 7

    May 2017 – @genehack
  51. release may be master release may be another branch 51

    — LFNW 2017 – 7 May 2017 – @genehack
  52. (again, specifics will vary) 52 — LFNW 2017 – 7

    May 2017 – @genehack
  53. merging to the release branch is a release 53 —

    LFNW 2017 – 7 May 2017 – @genehack
  54. (ideally, automatically) 54 — LFNW 2017 – 7 May 2017

    – @genehack
  55. make all merges non-FF 55 — LFNW 2017 – 7

    May 2017 – @genehack
  56. an aside 56 — LFNW 2017 – 7 May 2017

    – @genehack
  57. ~/.gitconfig 57 — LFNW 2017 – 7 May 2017 –

    @genehack
  58. git config --global merge.ff false git config --global pull.ff only

    58 — LFNW 2017 – 7 May 2017 – @genehack
  59. [merge] ff = false [pull] ff = only 59 —

    LFNW 2017 – 7 May 2017 – @genehack
  60. maximal historical information 60 — LFNW 2017 – 7 May

    2017 – @genehack
  61. keep it clean 61 — LFNW 2017 – 7 May

    2017 – @genehack
  62. ~/.gitconfig aliases 62 — LFNW 2017 – 7 May 2017

    – @genehack
  63. [alias] br = branch ci = commit -v co =

    checkout st = status 63 — LFNW 2017 – 7 May 2017 – @genehack
  64. clean up remote branches 64 — LFNW 2017 – 7

    May 2017 – @genehack
  65. git push origin --delete <branch> 65 — LFNW 2017 –

    7 May 2017 – @genehack
  66. nuke = push origin --delete 66 — LFNW 2017 –

    7 May 2017 – @genehack
  67. clean up orphaned remote-tracking branches 67 — LFNW 2017 –

    7 May 2017 – @genehack
  68. git remote prune origin 68 — LFNW 2017 – 7

    May 2017 – @genehack
  69. prune = remote prune origin 69 — LFNW 2017 –

    7 May 2017 – @genehack
  70. find unmerged branches 70 — LFNW 2017 – 7 May

    2017 – @genehack
  71. git branch --no-merged master 71 — LFNW 2017 – 7

    May 2017 – @genehack
  72. git branch --no-merged --remote master 72 — LFNW 2017 –

    7 May 2017 – @genehack
  73. unmerged = branch --no-merged unmerged-remote = branch --no-merged --remote 73

    — LFNW 2017 – 7 May 2017 – @genehack
  74. keep it clean 74 — LFNW 2017 – 7 May

    2017 – @genehack
  75. one final note on branches 75 — LFNW 2017 –

    7 May 2017 – @genehack
  76. branch names 76 — LFNW 2017 – 7 May 2017

    – @genehack
  77. a branch equals a ticket 77 — LFNW 2017 –

    7 May 2017 – @genehack
  78. the ticket id should be in the branch name 78

    — LFNW 2017 – 7 May 2017 – @genehack
  79. along with something for the humans 79 — LFNW 2017

    – 7 May 2017 – @genehack
  80. put the number at the end of the branch name

    80 — LFNW 2017 – 7 May 2017 – @genehack
  81. good: fix-login-864 81 — LFNW 2017 – 7 May 2017

    – @genehack
  82. meh: fix-864 82 — LFNW 2017 – 7 May 2017

    – @genehack
  83. bad: 864-crap 83 — LFNW 2017 – 7 May 2017

    – @genehack
  84. !!!: foobar 84 — LFNW 2017 – 7 May 2017

    – @genehack
  85. just. don't. 85 — LFNW 2017 – 7 May 2017

    – @genehack
  86. when merging include the branch name 86 — LFNW 2017

    – 7 May 2017 – @genehack
  87. default message works nicely 87 — LFNW 2017 – 7

    May 2017 – @genehack
  88. Merge branch <name> 88 — LFNW 2017 – 7 May

    2017 – @genehack
  89. maximal historical information 89 — LFNW 2017 – 7 May

    2017 – @genehack
  90. to review 90 — LFNW 2017 – 7 May 2017

    – @genehack
  91. don't squash 91 — LFNW 2017 – 7 May 2017

    – @genehack
  92. don't fast forward 92 — LFNW 2017 – 7 May

    2017 – @genehack
  93. don't rebase before merge 93 — LFNW 2017 – 7

    May 2017 – @genehack
  94. don't destroy your history 94 — LFNW 2017 – 7

    May 2017 – @genehack
  95. use branches 95 — LFNW 2017 – 7 May 2017

    – @genehack
  96. use a release branch 96 — LFNW 2017 – 7

    May 2017 – @genehack
  97. use no-ff to make merge commits 97 — LFNW 2017

    – 7 May 2017 – @genehack
  98. keep your repo clean 98 — LFNW 2017 – 7

    May 2017 – @genehack
  99. let's get more granular 99 — LFNW 2017 – 7

    May 2017 – @genehack
  100. structuring individual commits 100 — LFNW 2017 – 7 May

    2017 – @genehack
  101. a commit equals one "change" 101 — LFNW 2017 –

    7 May 2017 – @genehack
  102. important: at each commit the software must work 102 —

    LFNW 2017 – 7 May 2017 – @genehack
  103. git bisect 103 — LFNW 2017 – 7 May 2017

    – @genehack
  104. smaller >> bigger 104 — LFNW 2017 – 7 May

    2017 – @genehack
  105. whitespace & formatting 105 — LFNW 2017 – 7 May

    2017 – @genehack
  106. always go in distinct commits 106 — LFNW 2017 –

    7 May 2017 – @genehack
  107. remember! 107 — LFNW 2017 – 7 May 2017 –

    @genehack
  108. revision is also a thing 108 — LFNW 2017 –

    7 May 2017 – @genehack
  109. what you eventually push 109 — LFNW 2017 – 7

    May 2017 – @genehack
  110. != 110 — LFNW 2017 – 7 May 2017 –

    @genehack
  111. your commits while working 111 — LFNW 2017 – 7

    May 2017 – @genehack
  112. develop a habit of using checkpoint commits instead of the

    stash savepoints 112 — LFNW 2017 – 7 May 2017 – @genehack
  113. every working micro step 113 — LFNW 2017 – 7

    May 2017 – @genehack
  114. single "change" 10-15 commits 114 — LFNW 2017 – 7

    May 2017 – @genehack
  115. git add --patch 115 — LFNW 2017 – 7 May

    2017 – @genehack
  116. git add -p 116 — LFNW 2017 – 7 May

    2017 – @genehack
  117. editor support 117 — LFNW 2017 – 7 May 2017

    – @genehack
  118. magit fugitive 118 — LFNW 2017 – 7 May 2017

    – @genehack
  119. magit 119 — LFNW 2017 – 7 May 2017 –

    @genehack
  120. don't push first drafts 120 — LFNW 2017 – 7

    May 2017 – @genehack
  121. tell a story 121 — LFNW 2017 – 7 May

    2017 – @genehack
  122. git rebase -i 122 — LFNW 2017 – 7 May

    2017 – @genehack
  123. may be useful to preserve dead ends 123 — LFNW

    2017 – 7 May 2017 – @genehack
  124. photo credit https://pbs.twimg.com/media/ CPlr0tQWcAAZPjf.jpg ...as a warning for others 124

    — LFNW 2017 – 7 May 2017 – @genehack
  125. commit messages 125 — LFNW 2017 – 7 May 2017

    – @genehack
  126. ticket numbers in the subject 126 — LFNW 2017 –

    7 May 2017 – @genehack
  127. (at the end) 127 — LFNW 2017 – 7 May

    2017 – @genehack
  128. you can customize the template for the commit message 128

    — LFNW 2017 – 7 May 2017 – @genehack
  129. if you get to this point, you're also going to

    want to script the repo setup process git config --local commit.template ./.template # edit .template to add whatever you want... 129 — LFNW 2017 – 7 May 2017 – @genehack
  130. examples 130 — LFNW 2017 – 7 May 2017 –

    @genehack
  131. good: make login form use POST instead of GET [#864]

    131 — LFNW 2017 – 7 May 2017 – @genehack
  132. meh: fixed form [#864] 132 — LFNW 2017 – 7

    May 2017 – @genehack
  133. bad: #846 fix 133 — LFNW 2017 – 7 May

    2017 – @genehack
  134. !!!: foo 134 — LFNW 2017 – 7 May 2017

    – @genehack
  135. (˽°□°҂˽Ɨ ˍʓˍ 135 — LFNW 2017 – 7 May 2017

    – @genehack
  136. this is why daddy drinks 136 — LFNW 2017 –

    7 May 2017 – @genehack
  137. to review 137 — LFNW 2017 – 7 May 2017

    – @genehack
  138. 1 commit == 1 change 138 — LFNW 2017 –

    7 May 2017 – @genehack
  139. photo credit https://imgs.xkcd.com/comics/git_commit.png and https://xkcd.com/1296/ commit messages matter! 139 —

    LFNW 2017 – 7 May 2017 – @genehack
  140. when in doubt make it smaller 140 — LFNW 2017

    – 7 May 2017 – @genehack
  141. segregate formatting changes 141 — LFNW 2017 – 7 May

    2017 – @genehack
  142. use checkpoint commits as savepoints 142 — LFNW 2017 –

    7 May 2017 – @genehack
  143. don't push first drafts 143 — LFNW 2017 – 7

    May 2017 – @genehack
  144. revise to tell a story 144 — LFNW 2017 –

    7 May 2017 – @genehack
  145. or at least make yourself look smart 145 — LFNW

    2017 – 7 May 2017 – @genehack
  146. using history better 146 — LFNW 2017 – 7 May

    2017 – @genehack
  147. jfri 147 — LFNW 2017 – 7 May 2017 –

    @genehack
  148. just friggin' read it 148 — LFNW 2017 – 7

    May 2017 – @genehack
  149. ~/.gitconfig (again) 149 — LFNW 2017 – 7 May 2017

    – @genehack
  150. color support 150 — LFNW 2017 – 7 May 2017

    – @genehack
  151. [color] branch = auto diff = auto grep = auto

    interactive = auto showbranch = auto status = auto ui = auto 151 — LFNW 2017 – 7 May 2017 – @genehack
  152. [color "status"] added = green bold changed = red bold

    untracked = cyan bold 152 — LFNW 2017 – 7 May 2017 – @genehack
  153. git blame 153 — LFNW 2017 – 7 May 2017

    – @genehack
  154. git blame -w -M 154 — LFNW 2017 – 7

    May 2017 – @genehack
  155. [alias] praise = blame 155 — LFNW 2017 – 7

    May 2017 – @genehack
  156. editor integration 156 — LFNW 2017 – 7 May 2017

    – @genehack
  157. git blame -L <line>,<line> <file> git log -L <line>,<line>:<file> 157

    — LFNW 2017 – 7 May 2017 – @genehack
  158. git blame -L 1,1 index.html 158 — LFNW 2017 –

    7 May 2017 – @genehack
  159. git blame -L 10,50 index.html 159 — LFNW 2017 –

    7 May 2017 – @genehack
  160. git blame -L 20,+10 index.html 160 — LFNW 2017 –

    7 May 2017 – @genehack
  161. git log -L 1,1:index.html 161 — LFNW 2017 – 7

    May 2017 – @genehack
  162. git log -L 10,50:index.html 162 — LFNW 2017 – 7

    May 2017 – @genehack
  163. git log -L 20,+10:index.html 163 — LFNW 2017 – 7

    May 2017 – @genehack
  164. git log -S <string> 164 — LFNW 2017 – 7

    May 2017 – @genehack
  165. git log --follow 165 — LFNW 2017 – 7 May

    2017 – @genehack
  166. git lg 166 — LFNW 2017 – 7 May 2017

    – @genehack
  167. log --graph --abbrev-commit --date=relative --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'

    167 — LFNW 2017 – 7 May 2017 – @genehack
  168. 168 — LFNW 2017 – 7 May 2017 – @genehack

  169. --graph 169 — LFNW 2017 – 7 May 2017 –

    @genehack
  170. --abbrev-commit 170 — LFNW 2017 – 7 May 2017 –

    @genehack
  171. --date=relative 171 — LFNW 2017 – 7 May 2017 –

    @genehack
  172. SHA in red, branch name (if any) in yellow, commit

    subject, date, author `--pretty=format: '%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'` 172 — LFNW 2017 – 7 May 2017 – @genehack
  173. 173 — LFNW 2017 – 7 May 2017 – @genehack

  174. takeaways! 174 — LFNW 2017 – 7 May 2017 –

    @genehack
  175. history is important 175 — LFNW 2017 – 7 May

    2017 – @genehack
  176. it's probably worth more of your time 176 — LFNW

    2017 – 7 May 2017 – @genehack
  177. both creating it and using it 177 — LFNW 2017

    – 7 May 2017 – @genehack
  178. don't just stop when the software works 178 — LFNW

    2017 – 7 May 2017 – @genehack
  179. software development is hard 179 — LFNW 2017 – 7

    May 2017 – @genehack
  180. be kind to others 180 — LFNW 2017 – 7

    May 2017 – @genehack
  181. be kind to your future self 181 — LFNW 2017

    – 7 May 2017 – @genehack
  182. thanks! lfnw organizers & volunteers linus & others for git

    YOU! 182 — LFNW 2017 – 7 May 2017 – @genehack
  183. 183 — LFNW 2017 – 7 May 2017 – @genehack

  184. questions? (ps: please fill out the talk eval form!) 184

    — LFNW 2017 – 7 May 2017 – @genehack