A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 4 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang=fr>
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset=utf-8>
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name=viewport content="width=device-width,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Telling stories through your commits (archive) — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <meta name="robots" content="noindex, nofollow">
  28. <meta content="origin-when-cross-origin" name="referrer">
  29. <!-- Canonical URL for SEO purposes -->
  30. <link rel="canonical" href="https://blog.mocoso.co.uk/talks/2015/01/12/telling-stories-through-your-commits/">
  31. <style>
  32. /* http://meyerweb.com/eric/tools/css/reset/ */
  33. html, body, div, span,
  34. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  35. a, abbr, address, big, cite, code,
  36. del, dfn, em, img, ins,
  37. small, strike, strong, tt, var,
  38. dl, dt, dd, ol, ul, li,
  39. fieldset, form, label, legend,
  40. table, caption, tbody, tfoot, thead, tr, th, td,
  41. article, aside, canvas, details, embed,
  42. figure, figcaption, footer, header, hgroup,
  43. menu, nav, output, ruby, section, summary,
  44. time, mark, audio, video {
  45. margin: 0;
  46. padding: 0;
  47. border: 0;
  48. font-size: 100%;
  49. font: inherit;
  50. vertical-align: baseline;
  51. }
  52. /* HTML5 display-role reset for older browsers */
  53. article, aside, details, figcaption, figure,
  54. footer, header, hgroup, menu, nav, section { display: block; }
  55. body { line-height: 1; }
  56. blockquote, q { quotes: none; }
  57. blockquote:before, blockquote:after,
  58. q:before, q:after {
  59. content: '';
  60. content: none;
  61. }
  62. table {
  63. border-collapse: collapse;
  64. border-spacing: 0;
  65. }
  66. /* http://practicaltypography.com/equity.html */
  67. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  68. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  69. @font-face {
  70. font-family: 'EquityTextB';
  71. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  72. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  73. font-weight: 300;
  74. font-style: normal;
  75. font-display: swap;
  76. }
  77. @font-face {
  78. font-family: 'EquityTextB';
  79. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  80. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  81. font-weight: 300;
  82. font-style: italic;
  83. font-display: swap;
  84. }
  85. @font-face {
  86. font-family: 'EquityTextB';
  87. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  88. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  89. font-weight: 700;
  90. font-style: normal;
  91. font-display: swap;
  92. }
  93. @font-face {
  94. font-family: 'ConcourseT3';
  95. src: url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff2') format('woff2'),
  96. url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff') format('woff');
  97. font-weight: 300;
  98. font-style: normal;
  99. font-display: swap;
  100. }
  101. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  102. body {
  103. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  104. font-family: "EquityTextB", Palatino, serif;
  105. background-color: #f0f0ea;
  106. color: #07486c;
  107. font-kerning: normal;
  108. -moz-osx-font-smoothing: grayscale;
  109. -webkit-font-smoothing: subpixel-antialiased;
  110. text-rendering: optimizeLegibility;
  111. font-variant-ligatures: common-ligatures contextual;
  112. font-feature-settings: "kern", "liga", "clig", "calt";
  113. }
  114. pre, code, kbd, samp, var, tt {
  115. font-family: 'TriplicateT4c', monospace;
  116. }
  117. em {
  118. font-style: italic;
  119. color: #323a45;
  120. }
  121. strong {
  122. font-weight: bold;
  123. color: black;
  124. }
  125. nav {
  126. background-color: #323a45;
  127. color: #f0f0ea;
  128. display: flex;
  129. justify-content: space-around;
  130. padding: 1rem .5rem;
  131. }
  132. nav:last-child {
  133. border-bottom: 1vh solid #2d7474;
  134. }
  135. nav a {
  136. color: #f0f0ea;
  137. }
  138. nav abbr {
  139. border-bottom: 1px dotted white;
  140. }
  141. h1 {
  142. border-top: 1vh solid #2d7474;
  143. border-bottom: .2vh dotted #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 5rem 0 4rem 0;
  148. width: 100%;
  149. font-family: 'ConcourseT3';
  150. display: flex;
  151. flex-direction: column;
  152. }
  153. h1.single {
  154. padding-bottom: 10rem;
  155. }
  156. h1 span {
  157. position: absolute;
  158. top: 1vh;
  159. left: 20%;
  160. line-height: 0;
  161. }
  162. h1 span a {
  163. line-height: 1.7;
  164. padding: 1rem 1.2rem .6rem 1.2rem;
  165. border-radius: 0 0 6% 6%;
  166. background: #2d7474;
  167. font-size: 1.3rem;
  168. color: white;
  169. text-decoration: none;
  170. }
  171. h2 {
  172. margin: 4rem 0 1rem;
  173. border-top: .2vh solid #2d7474;
  174. padding-top: 1vh;
  175. }
  176. h3 {
  177. text-align: center;
  178. margin: 3rem 0 .75em;
  179. }
  180. hr {
  181. height: .4rem;
  182. width: .4rem;
  183. border-radius: .4rem;
  184. background: #07486c;
  185. margin: 2.5rem auto;
  186. }
  187. time {
  188. display: bloc;
  189. margin-left: 0 !important;
  190. }
  191. ul, ol {
  192. margin: 2rem;
  193. }
  194. ul {
  195. list-style-type: square;
  196. }
  197. a {
  198. text-decoration-skip-ink: auto;
  199. text-decoration-thickness: 0.05em;
  200. text-underline-offset: 0.09em;
  201. }
  202. article {
  203. max-width: 50rem;
  204. display: flex;
  205. flex-direction: column;
  206. margin: 2rem auto;
  207. }
  208. article.single {
  209. border-top: .2vh dotted #2d7474;
  210. margin: -6rem auto 1rem auto;
  211. background: #f0f0ea;
  212. padding: 2rem;
  213. }
  214. article p:last-child {
  215. margin-bottom: 1rem;
  216. }
  217. p {
  218. padding: 0 .5rem;
  219. margin-left: 3rem;
  220. }
  221. p + p,
  222. figure + p {
  223. margin-top: 2rem;
  224. }
  225. blockquote {
  226. background-color: #e3e1e1;
  227. border-left: .5vw solid #2d7474;
  228. display: flex;
  229. flex-direction: column;
  230. align-items: center;
  231. padding: 1rem;
  232. margin: 1.5rem;
  233. }
  234. blockquote cite {
  235. font-style: italic;
  236. }
  237. blockquote p {
  238. margin-left: 0;
  239. }
  240. figure {
  241. border-top: .2vh solid #2d7474;
  242. background-color: #e3e1e1;
  243. text-align: center;
  244. padding: 1.5rem 0;
  245. margin: 1rem 0 0;
  246. font-size: 1.5rem;
  247. width: 100%;
  248. }
  249. figure img {
  250. max-width: 250px;
  251. max-height: 250px;
  252. border: .5vw solid #323a45;
  253. padding: 1px;
  254. }
  255. figcaption {
  256. padding: 1rem;
  257. line-height: 1.4;
  258. }
  259. aside {
  260. display: flex;
  261. flex-direction: column;
  262. background-color: #e3e1e1;
  263. padding: 1rem 0;
  264. border-bottom: .2vh solid #07486c;
  265. }
  266. aside p {
  267. max-width: 50rem;
  268. margin: 0 auto;
  269. }
  270. /* https://fvsch.com/code/css-locks/ */
  271. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  272. font-size: 1rem;
  273. line-height: calc( 1.5em + 0.2 * 1rem );
  274. }
  275. h1 {
  276. font-size: 1.9rem;
  277. line-height: calc( 1.2em + 0.2 * 1rem );
  278. }
  279. h2 {
  280. font-size: 1.6rem;
  281. line-height: calc( 1.3em + 0.2 * 1rem );
  282. }
  283. h3 {
  284. font-size: 1.35rem;
  285. line-height: calc( 1.4em + 0.2 * 1rem );
  286. }
  287. @media (min-width: 20em) {
  288. /* The (100vw - 20rem) / (50 - 20) part
  289. resolves to 0-1rem, depending on the
  290. viewport width (between 20em and 50em). */
  291. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  292. font-size: calc( 1rem + .6 * (100vw - 20rem) / (50 - 20) );
  293. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  294. margin-left: 0;
  295. }
  296. h1 {
  297. font-size: calc( 1.9rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  298. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  299. }
  300. h2 {
  301. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  302. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  303. }
  304. h3 {
  305. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  306. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  307. }
  308. }
  309. @media (min-width: 50em) {
  310. /* The right part of the addition *must* be a
  311. rem value. In this example we *could* change
  312. the whole declaration to font-size:2.5rem,
  313. but if our baseline value was not expressed
  314. in rem we would have to use calc. */
  315. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  316. font-size: calc( 1rem + .6 * 1rem );
  317. line-height: 1.5em;
  318. }
  319. p, li, pre, details {
  320. margin-left: 3rem;
  321. }
  322. h1 {
  323. font-size: calc( 1.9rem + 1.5 * 1rem );
  324. line-height: 1.2em;
  325. }
  326. h2 {
  327. font-size: calc( 1.5rem + 1.5 * 1rem );
  328. line-height: 1.3em;
  329. }
  330. h3 {
  331. font-size: calc( 1.35rem + 1.5 * 1rem );
  332. line-height: 1.4em;
  333. }
  334. figure img {
  335. max-width: 500px;
  336. max-height: 500px;
  337. }
  338. }
  339. figure.unsquared {
  340. margin-bottom: 1.5rem;
  341. }
  342. figure.unsquared img {
  343. height: inherit;
  344. }
  345. @media print {
  346. body { font-size: 100%; }
  347. a:after { content: " (" attr(href) ")"; }
  348. a, a:link, a:visited, a:after {
  349. text-decoration: underline;
  350. text-shadow: none !important;
  351. background-image: none !important;
  352. background: white;
  353. color: black;
  354. }
  355. abbr[title] { border-bottom: 0; }
  356. abbr[title]:after { content: " (" attr(title) ")"; }
  357. img { page-break-inside: avoid; }
  358. @page { margin: 2cm .5cm; }
  359. h1, h2, h3 { page-break-after: avoid; }
  360. p3 { orphans: 3; widows: 3; }
  361. img {
  362. max-width: 250px !important;
  363. max-height: 250px !important;
  364. }
  365. nav, aside { display: none; }
  366. }
  367. ul.with_columns {
  368. column-count: 1;
  369. }
  370. @media (min-width: 20em) {
  371. ul.with_columns {
  372. column-count: 2;
  373. }
  374. }
  375. @media (min-width: 50em) {
  376. ul.with_columns {
  377. column-count: 3;
  378. }
  379. }
  380. ul.with_two_columns {
  381. column-count: 1;
  382. }
  383. @media (min-width: 20em) {
  384. ul.with_two_columns {
  385. column-count: 1;
  386. }
  387. }
  388. @media (min-width: 50em) {
  389. ul.with_two_columns {
  390. column-count: 2;
  391. }
  392. }
  393. .gallery {
  394. display: flex;
  395. flex-wrap: wrap;
  396. justify-content: space-around;
  397. }
  398. .gallery figure img {
  399. margin-left: 1rem;
  400. margin-right: 1rem;
  401. }
  402. .gallery figure figcaption {
  403. font-family: 'ConcourseT3'
  404. }
  405. footer {
  406. font-family: 'ConcourseT3';
  407. display: flex;
  408. flex-direction: column;
  409. border-top: 3px solid white;
  410. padding: 4rem 0;
  411. background-color: #07486c;
  412. color: white;
  413. }
  414. footer > * {
  415. max-width: 50rem;
  416. margin: 0 auto;
  417. }
  418. footer a {
  419. color: #f1c40f;
  420. }
  421. footer .avatar {
  422. width: 200px;
  423. height: 200px;
  424. border-radius: 50%;
  425. float: left;
  426. -webkit-shape-outside: circle();
  427. shape-outside: circle();
  428. margin-right: 2rem;
  429. padding: 2px 5px 5px 2px;
  430. background: white;
  431. border-left: 1px solid #f1c40f;
  432. border-top: 1px solid #f1c40f;
  433. border-right: 5px solid #f1c40f;
  434. border-bottom: 5px solid #f1c40f;
  435. }
  436. </style>
  437. <h1>
  438. <span><a id="jumper" href="#jumpto" title="Un peu perdu ?">?</a></span>
  439. Telling stories through your commits (archive)
  440. <time>Pour la pérennité des contenus liés. Non-indexé, retrait sur simple email.</time>
  441. </h1>
  442. <section>
  443. <article>
  444. <h3><a href="https://blog.mocoso.co.uk/talks/2015/01/12/telling-stories-through-your-commits/">Source originale du contenu</a></h3>
  445. <p>This is a short talk that I have given on a variety of occasions about
  446. how you can use your source control commit messages to keep track of the
  447. intent of your code changes and make it easier to keep changing your
  448. project in future.</p>
  449. <p>The transcript below is from the version of the talk that I gave at the
  450. <a href="http://2016.theleaddeveloper.com/talks#joel-chippindale">Lead Developer
  451. Conference</a> in
  452. London in June 2016.</p>
  453. <h2 id="transcript">Transcript</h2>
  454. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.001.png" alt="opening slide"/></p>
  455. <p class="transcript">I am Joel Chippindale and I have been the CTO at FutureLearn for the
  456. last few years and I am here to talk to you about telling stories
  457. through your commits.</p>
  458. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.002.png" alt="opening slide"/></p>
  459. <p class="transcript">If we have a successful software development project then our key
  460. challenge, as lead developers, is to manage complexity because projects
  461. can get very complex very quickly even within quite small teams.</p>
  462. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.003.png" alt="opening slide"/></p>
  463. <p class="transcript">As lead developers we, and our teams, spend a lot of time thinking about
  464. this. We think about the naming of methods and functions and variables
  465. and…</p>
  466. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.004.png" alt="opening slide"/></p>
  467. <p class="transcript">we think about our code design.</p>
  468. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.005.png" alt="opening slide"/></p>
  469. <p class="transcript">We probably spend a lot of time refactoring code. Taking code that works
  470. and making it simpler to understand.</p>
  471. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.006.png" alt="opening slide"/></p>
  472. <p class="transcript">And probably most of your teams are spending a good proportion of their
  473. time writing automated tests and that allows your teams to have the
  474. confidence to keep changing the software but also helps to document what
  475. the code is supposed to do.</p>
  476. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.007.png" alt="opening slide"/></p>
  477. <p class="transcript">All these tools and techniques help communicate the intent of our
  478. software and if we want to keep changing it we need to understand this
  479. intent.</p>
  480. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.008.png" alt="opening slide"/></p>
  481. <p class="transcript">There is one tool that we under utilise in our communities for
  482. communicating our intent and that is our version control system. All the
  483. examples in this talk use git but the principles apply to whatever
  484. system you are using.</p>
  485. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.009.png" alt="opening slide"/></p>
  486. <p class="transcript">Our commit history has some very special properties which make it
  487. particularly useful for documenting intent.</p>
  488. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.010.png" alt="opening slide"/></p>
  489. <p class="transcript">It is kept forever.</p>
  490. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.011.png" alt="opening slide"/></p>
  491. <p class="transcript">It is always up to date and this almost certainly not true of most of
  492. the documentation you have, perhaps in a wiki or even in code comments.</p>
  493. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.012.png" alt="opening slide"/></p>
  494. <p class="transcript">And, this may come as a surprise to some of you, it is searchable. Git
  495. doesn’t make this obvious so here are some commands that you may find
  496. useful.</p>
  497. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.013.png" alt="opening slide"/></p>
  498. <p class="transcript">You can search all the contents of all your commit messages.</p>
  499. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.014.png" alt="opening slide"/></p>
  500. <p class="transcript">You can search all the contents of all the code changes in your commits.</p>
  501. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.015.png" alt="opening slide"/></p>
  502. <p class="transcript">And you can find out where each line of code was last changed…</p>
  503. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.016.png" alt="opening slide"/></p>
  504. <p class="transcript">…giving you output like this.</p>
  505. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.017.png" alt="opening slide"/></p>
  506. <p class="transcript">It is these properties that allow Mislav Marahonić to say that, “Every
  507. line of code is always documented”. If every line of code is documented
  508. how do we make sure that this documentation tells a useful story to us
  509. and our teams about that line of code?</p>
  510. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.018.png" alt="opening slide"/></p>
  511. <p class="transcript">I will share 3 principles with that will help you with this.</p>
  512. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.019.png" alt="opening slide"/></p>
  513. <p class="transcript">Firstly and most importantly make atomic commits. Make your commits
  514. about a single change to your code base.</p>
  515. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.020.png" alt="opening slide"/></p>
  516. <p class="transcript">To illustrate why this is important I am going to share a git horror
  517. story with you. This is from a project which I am responsible for. Bug
  518. fixes? Which ones? How many? We have no idea. And a Wordpress update.
  519. Those of you who are laughing are probably doing so because there are
  520. 175 thousand lines of code changes in this commit. Reverse engineering
  521. this commit to find out what happened is very hard.</p>
  522. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.021.png" alt="opening slide"/></p>
  523. <p class="transcript">Let us imagine an alternate history where this commit had been split
  524. into atomic commits.</p>
  525. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.022.png" alt="opening slide"/></p>
  526. <p class="transcript">Here we might have a Wordpress update commit containing the vast
  527. majority of those 175k lines of changes and then 8 separate commits each
  528. one about a single bug which is easy to understand.</p>
  529. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.023.png" alt="opening slide"/></p>
  530. <p class="transcript">When I talk about this, I am often asked how big an atomic commit should
  531. be? In our industry we generally make our commits too big so it is worth
  532. thinking about a minimum viable commit. What’s the smallest useful
  533. change that you can make to your codebase?</p>
  534. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.024.png" alt="opening slide"/></p>
  535. <p class="transcript">Another useful rule of thumb is to avoid needing ‘and’ in your commit
  536. messages. If you did ‘A’ and ‘B’ maybe they are two separate changes.</p>
  537. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.025.png" alt="opening slide"/></p>
  538. <p class="transcript">Second principle: write good commit messages.</p>
  539. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.026.png" alt="opening slide"/></p>
  540. <p class="transcript">That’s very easy for me to say so I will take you through a template to
  541. give you more of an idea of what I mean.</p>
  542. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.027.png" alt="opening slide"/></p>
  543. <p class="transcript">Short one line title because you view your commits in lists and a longer
  544. description if you need it.</p>
  545. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.028.png" alt="opening slide"/></p>
  546. <p class="transcript">An explanation of why the change is being made. If people want to know
  547. how they can change this in future then they need to know what the
  548. intention of this change was.</p>
  549. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.029.png" alt="opening slide"/></p>
  550. <p class="transcript">Lastly, when you make this commit, you know more about why you are
  551. making this change and how you are fixing or improving this thing than
  552. anyone else ever will and so it can be useful to outline some of the
  553. context and alternative approaches considered.</p>
  554. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.030.png" alt="opening slide"/></p>
  555. <p class="transcript">To make this more concrete, here is an example of a commit message from
  556. one of the other projects I am responsible for. You can see the one line
  557. title, you can see a link to our bug tracking system, you can see an
  558. explanation of the quirks of Outlook and why we are making this
  559. particular change and a link to a blog post which explains more about
  560. the problem. This is gold dust for people going back and trying to work
  561. out why the CSS in our project is in the particular state it is in.</p>
  562. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.031.png" alt="opening slide"/></p>
  563. <p class="transcript">Third principle: revise your development history before sharing. We all
  564. know that once commits are on master, or once they are deployed, you
  565. don’t want to change them out from underneath people. But, in your
  566. development branches, it can be much more useful if they tell a story
  567. about what you intended to do instead of a blow by blow account of all
  568. the missteps you took along the way.</p>
  569. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.032.png" alt="opening slide"/></p>
  570. <p class="transcript">There’s a tool for this, git rebase interactive…</p>
  571. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.033.png" alt="opening slide"/></p>
  572. <p class="transcript">…and this allows you to remove, reorder, edit, merge and split
  573. commits. Essentially with this tool your development branches are
  574. infinitely malleable.</p>
  575. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.034.png" alt="opening slide"/></p>
  576. <p class="transcript">To give you a quick example. Imagine I have added Foo and made a commit,
  577. removed Bar and made a commit and then I have spotted a typo in the
  578. first commit so I make a new commit to fix the typo. That’s just noise
  579. for other people. No one cares about the fact that I didn’t get the
  580. first commit right first time.</p>
  581. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.035.png" alt="opening slide"/></p>
  582. <p class="transcript">We can use git rebase interactive to merge the first and third commits
  583. and tell a simpler story about what we are trying to do.</p>
  584. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.036.png" alt="opening slide"/></p>
  585. <p class="transcript">So three principles. 1. Make atomic commits. 2. Write good commit
  586. messages and 3. Revise your development history before sharing</p>
  587. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.037.png" alt="opening slide"/></p>
  588. <p class="transcript">This is a quote from someone who joined our team recently which I hope
  589. will help persuade you of the benefits of taking this approach.</p>
  590. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.038.png" alt="opening slide"/></p>
  591. <p class="transcript">Perhaps you are sitting here, as lead developers, thinking this sounds
  592. like a really good idea. How am I going to take this back to my team on
  593. Monday? How am I going to persuade them to adopt these practices that
  594. seem like they have pay off months or even years down the line perhaps
  595. for other developers on the team?</p>
  596. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.039.png" alt="opening slide"/></p>
  597. <p class="transcript">Won’t it take a huge amount of discipline?</p>
  598. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.040.png" alt="opening slide"/></p>
  599. <p class="transcript">I think the key is that all these practices make things simpler for
  600. individual developers in your team right now.</p>
  601. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.041.png" alt="opening slide"/></p>
  602. <div class="transcript">
  603. <p>Let’s go back over the principles.</p>
  604. <p><strong>Make atomic commits</strong></p>
  605. <p>This is about making sure that you are making one change at a time to
  606. your code. This makes it simpler to work on.</p>
  607. <p><strong>Write good commit messages</strong></p>
  608. <p>If you can write down what you are trying to do in the particular change
  609. that you are making then you are half way there already and it is a
  610. really valuable discipline for you and your teams to get into.</p>
  611. <p><strong>Revise your history before sharing</strong></p>
  612. <p>If your development branch tells a good story about what you did then it
  613. is easier for you to understand what you did and whether it solves the
  614. problem you had and also it is easier to share with others, perhaps in a
  615. pull request, to get feedback. All these practices making things easier
  616. now for your teams.</p>
  617. </div>
  618. <p class="slide"><img src="https://blog.mocoso.co.uk/assets/telling-stories-through-your-commits/slides.042.png" alt="opening slide"/></p>
  619. <p class="transcript">Thank you for your time.</p>
  620. </article>
  621. </section>
  622. <nav id="jumpto">
  623. <p>
  624. <a href="/david/blog/">Accueil du blog</a> |
  625. <a href="https://blog.mocoso.co.uk/talks/2015/01/12/telling-stories-through-your-commits/">Source originale</a> |
  626. <a href="/david/stream/2019/">Accueil du flux</a>
  627. </p>
  628. </nav>
  629. <footer>
  630. <div>
  631. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  632. <p>
  633. Bonjour/Hi!
  634. Je suis <a href="/david/" title="Profil public">David&nbsp;Larlet</a>, je vis actuellement à Montréal et j’alimente cet espace depuis 15 ans. <br>
  635. Si tu as apprécié cette lecture, n’hésite pas à poursuivre ton exploration. Par exemple via les <a href="/david/blog/" title="Expériences bienveillantes">réflexions bimestrielles</a>, la <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a> ou en t’abonnant au <a href="/david/log/" title="S’abonner aux publications via RSS">flux RSS</a> (<a href="/david/blog/2019/flux-rss/" title="Tiens c’est quoi un flux RSS ?">so 2005</a>).
  636. </p>
  637. <p>
  638. Je m’intéresse à la place que je peux avoir dans ce monde. En tant qu’humain, en tant que membre d’une famille et en tant qu’associé d’une coopérative. De temps en temps, je fais aussi des <a href="https://github.com/davidbgk" title="Principalement sur Github mais aussi ailleurs">trucs techniques</a>. Et encore plus rarement, <a href="/david/talks/" title="En ce moment je laisse plutôt la place aux autres">j’en parle</a>.
  639. </p>
  640. <p>
  641. Voici quelques articles choisis :
  642. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  643. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  644. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  645. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  646. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  647. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  648. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  649. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  650. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  651. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  652. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  653. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  654. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  655. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  656. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  657. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  658. </p>
  659. <p>
  660. On peut <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">échanger par courriel</a>. Si éventuellement tu souhaites que l’on travaille ensemble, tu devrais commencer par consulter le <a href="http://larlet.com">profil dédié à mon activité professionnelle</a> et/ou contacter directement <a href="http://scopyleft.fr/">scopyleft</a>, la <abbr title="Société coopérative et participative">SCOP</abbr> dont je fais partie depuis six ans. Je recommande au préalable de lire <a href="/david/blog/2018/cout-site/" title="Attention ce qui va suivre peut vous choquer">combien coûte un site</a> et pourquoi je suis plutôt favorable à une <a href="/david/pro/devis/" title="Discutons-en !">non-demande de devis</a>.
  661. </p>
  662. <p>
  663. Je ne traque pas ta navigation mais mon
  664. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  665. conserve des logs d’accès.
  666. </p>
  667. </div>
  668. </footer>
  669. <script type="text/javascript">
  670. ;(_ => {
  671. const jumper = document.getElementById('jumper')
  672. jumper.addEventListener('click', e => {
  673. e.preventDefault()
  674. const anchor = e.target.getAttribute('href')
  675. const targetEl = document.getElementById(anchor.substring(1))
  676. targetEl.scrollIntoView({behavior: 'smooth'})
  677. })
  678. })()
  679. </script>