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.

пре 5 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  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>GitHub Flow Like a Pro with these 13 Git Aliases (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="http://haacked.com/archive/2014/07/28/github-flow-aliases/">
  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. GitHub Flow Like a Pro with these 13 Git Aliases (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="http://haacked.com/archive/2014/07/28/github-flow-aliases/">Source originale du contenu</a></h3>
  445. <p><a href="http://scottchacon.com/2011/08/31/github-flow.html">GitHub Flow</a> is a Git work flow with a simple branching model. The following diagram of this flow is from Zach Holman's talk on <a href="http://zachholman.com/talk/how-github-uses-github-to-build-github/">How GitHub uses GitHub to build GitHub</a>.</p>
  446. <p><img src="https://cloud.githubusercontent.com/assets/19977/3638839/8343b14c-1063-11e4-8369-537f7d62be06.png" alt="github-branching"/></p>
  447. <p>You are now a master of GitHub flow. Drop the mic and go release some software!</p>
  448. <p>Ok, there's probably a few more details than that diagram to understand. The basic idea is that new work (such as a bug fix or new feature) is done in a "topic" branch off of the <code>master</code> branch. At any time, you should feel free to push the topic branch and create a pull request (PR). A Pull Request is a discussion around some code and not <a href="https://github.com/blog/1124-how-we-use-pull-requests-to-build-github">necessarily the completed work</a>.</p>
  449. <p>At some point, the PR is complete and ready for review. After a few rounds of review (as needed), either the PR gets closed or someone merges the branch into master and the cycle continues. If the reviews have been respectful, you may even still continue to like your colleagues.</p>
  450. <p>It's simple, but powerful.</p>
  451. <p>Over time, my laziness spurred me to write a set of Git aliases that streamline this flow for me. In this post, I share these aliases and some tips on writing your own. These aliases start off simple, but they get more advanced near the end. The advanced ones demonstrate some techniques for building your own very useful aliases.</p>
  452. <h2>Intro to Git Aliases</h2>
  453. <p>An alias is simply a way to add a shorthand for a common Git command or set of Git commands. Some are quite simple. For example, here's a common one:</p>
  454. <div class="highlight"><pre><code class="language-bash" data-lang="bash">git config --global alias.co checkout
  455. </code></pre></div>
  456. <p>This sets <code>co</code> as an alias for <code>checkout</code>. If you open up your <code>.gitconfig</code> file, you can see this in a section named <code>alias</code>.</p>
  457. <p>With this alias, you can checkout a branch by using <code>git co some-branch</code> instead of <code>git checkout some-branch</code>. Since I often edit aliases by hand, I have one that opens the <code>gitconfig</code> file with my default editor.</p>
  458. <p>These sort of simple aliases only begin to scratch the surface.</p>
  459. <h2>GitHub Flow Aliases</h2>
  460. <h3>Get my working directory up to date.</h3>
  461. <p>When I'm ready to start some work, I always do the work in a new branch. But first, I make sure that my working directory is up to date with the origin before I create that branch. Typically, I'll want to run the following commands:</p>
  462. <div class="highlight"><pre><code class="language-bash" data-lang="bash">git pull --rebase --prune
  463. git submodule update --init --recursive
  464. </code></pre></div>
  465. <p>The first command pulls changes from the remote. If I have any local commits, it'll rebase them to come after the commits I pulled down. The <code>--prune</code> option removes remote-tracking branches that no longer exist on the remote.</p>
  466. <p>This combination is so common, I've created an alias <code>up</code> for this.</p>
  467. <div class="highlight"><pre><code class="language-ini" data-lang="ini"> <span class="na">up</span> <span class="o">=</span> <span class="s">!git pull --rebase --prune $@ &amp;&amp; git submodule update --init --recursive</span>
  468. </code></pre></div>
  469. <p>Note that I'm combining two git commands together. I can use the <code>!</code> prefix to execute everything after it in the shell. This is why I needed to use the full git commands. Using the <code>!</code> prefix allows me to use <em>any</em> command and not just git commands in the alias.</p>
  470. <h3>Starting new work</h3>
  471. <p>At this point, I can start some new work. All new work starts in a branch so I would typically use <code>git checkout -b new-branch</code>. However I alias this to <code>cob</code> to build upon <code>co</code>.</p>
  472. <p>Note that this simple alias is expanded in place. So to create a branch named "emoji-completion" I simply type <code>git cob emoji-completion</code> which expands to <code>git checkout -b emoji-completion</code>.</p>
  473. <p>With this new branch, I can start writing the crazy codes. As I go along, I try and commit regularly with my <code>cm</code> alias.</p>
  474. <div class="highlight"><pre><code class="language-ini" data-lang="ini"> <span class="na">cm</span> <span class="o">=</span> <span class="s">!git add -A &amp;&amp; git commit -m</span>
  475. </code></pre></div>
  476. <p>For example, <code>git cm "Making stuff work"</code>. This adds all changes including untracked files to the index and then creates a commit with the message "Making Stuff Work".</p>
  477. <p>Sometimes, I just want to save my work in a commit without having to think of a commit message. I could stash it, but I prefer to write a proper commit which I will change later.</p>
  478. <p><code>git save</code> or <code>git wip</code>. The first one adds all changes including untracked files and creates a commit. The second one only commits tracked changes. I generally use the first one.</p>
  479. <div class="highlight"><pre><code class="language-ini" data-lang="ini"> <span class="na">save</span> <span class="o">=</span> <span class="s">!git add -A &amp;&amp; git commit -m 'SAVEPOINT'</span>
  480. <span class="s"> wip = commit -am "WIP" </span>
  481. </code></pre></div>
  482. <p>When I return to work, I'll just use <code>git undo</code> which resets the previous commit, but keeps all the changes from that commit in the working directory.</p>
  483. <div class="highlight"><pre><code class="language-ini" data-lang="ini"> <span class="na">undo</span> <span class="o">=</span> <span class="s">reset HEAD~1 --mixed</span>
  484. </code></pre></div>
  485. <p>Or, if I merely need to modify the previous commit, I'll use <code>git amend</code></p>
  486. <div class="highlight"><pre><code class="language-ini" data-lang="ini"> <span class="na">amend</span> <span class="o">=</span> <span class="s">commit -a --amend</span>
  487. </code></pre></div>
  488. <p>The <code>-a</code> adds any modifications and deletions of existing files to the commit but ignores brand new files. The <code>--amend</code> launches your default commit editor (Notepad in my case) and lets you change the commit message of the most recent commit.</p>
  489. <h3>A proper reset</h3>
  490. <p>There will be times when you explore a promising idea in code and it turns out to be crap. You just want to throw your hands up in disgust and burn all the work in your working directory to the ground and start over.</p>
  491. <p>In an attempt to be helpful, people might recommend: <code>git reset HEAD --hard</code>.</p>
  492. <p>Slap those people in the face. It's a bad idea. Don't do it!</p>
  493. <p>That's basically a delete of your current changes without any undo. As soon as you run that command, Murphy's law dictates you'll suddenly remember there was that one gem among the refuse you don't want to rewrite.</p>
  494. <p>Too bad. If you reset work that you <em>never committed</em> it is gone for good. Hence, the <code>wipe</code> alias.</p>
  495. <div class="highlight"><pre><code class="language-ini" data-lang="ini"> <span class="na">wipe</span> <span class="o">=</span> <span class="s">!git add -A &amp;&amp; git commit -qm 'WIPE SAVEPOINT' &amp;&amp; git reset HEAD~1 --hard</span>
  496. </code></pre></div>
  497. <p>This commits everything in my working directory and then does a hard reset to remove that commit. The nice thing is, the commit is still there, but it's just unreachable. Unreachable commits are a bit inconvenient to restore, but at least they are still there. You can run the <code>git reflog</code> command and find the SHA of the commit if you realize later that you made a mistake with the reset. The commit message will be "WIPE SAVEPOINT" in this case.</p>
  498. <h3>Completing the pull request</h3>
  499. <p>While working on a branch, I regularly push my changes to GitHub. At some point, I'll go to github.com and create a pull request, people will review it, and then it'll get merged. Once it's merged, I like to <a href="https://github.com/blog/1335-tidying-up-after-pull-requests">tidy up and delete the branch via the Web UI</a>. At this point, I'm done with this topic branch and I want to clean everything up on my local machine. Here's where I use one of my more powerful aliases, <code>git bdone</code>.</p>
  500. <p>This alias does the following.</p>
  501. <ol>
  502. <li>Switches to master (though you can specify a different default branch)</li>
  503. <li>Runs <code>git up</code> to bring master up to speed with the origin</li>
  504. <li>Deletes all branches already merged into master using another alias, <code>git bclean</code></li>
  505. </ol>
  506. <p>It's quite powerful and useful and demonstrates some advanced concepts of git aliases. But first, let me show <code>git bclean</code>. This alias is meant to be run from your master (or default) branch and does the cleanup of merged branches.</p>
  507. <div class="highlight"><pre><code class="language-ini" data-lang="ini"><span class="na">bclean</span> <span class="o">=</span> <span class="s">"!f() { git branch --merged ${1-master} | grep -v " ${1-master}$" | xargs -r git branch -d; }; f"</span>
  508. </code></pre></div>
  509. <p>If you're not used to shell scripts, this looks a bit odd. What it's doing is defining a function and then calling that function. The general format is <code>!f() { /* git operations */; }; f</code> We define a function named <code>f</code> that encapsulates some git operations, and then we invoke the function at the very end.</p>
  510. <p>What's cool about this is we can take advantage of arguments to this alias. In fact, we can have optional parameters. For example, the first argument to this alias can be accessed via <code>$1</code>. But suppose you want a default value for this argument if none is provided. That's where the curly braces come in. Inside the braces you specify the argument index (<code>$0</code> returns the whole script) followed by a dash and then the default value.</p>
  511. <p>Thus when you type <code>git bclean</code> the expression <code>${1-master}</code> evaluates to <code>master</code> because no argument was provided. But if you're working on a GitHub pages repository, you'll probably want to call <code>git bclean gh-pages</code> in which case the expression <code>${1-master}</code> evaluates to <code>gh-pages</code> as that's the first argument to the the alias.</p>
  512. <p>Let's break down this alias into pieces to understand it.</p>
  513. <p><code>git branch --merged ${1-master}</code> lists all the branches that have been merged into the specify branch (or master if none is specified). This list is then piped into the <code>grep -v "${1-master}"</code> command. <a href="http://www.gnu.org/software/grep/manual/grep.html">Grep</a> prints out lines matching the pattern. The <code>-v</code> flag inverts the match. So this will list all merged branches that are not <code>master</code> itself. Finally this gets piped into <code>xargs</code> which takes the standard input and executes the <code>git branch -d</code> line for each line in the standard input which is piped in from the previous command.</p>
  514. <p>In other words, it deletes every branch that's been merged into <code>master</code> except <code>master</code>. I love how we can compose these commands together.</p>
  515. <p>With <code>bclean</code> in place, I can compose my git aliases together and write <code>git bdone</code>.</p>
  516. <div class="highlight"><pre><code class="language-ini" data-lang="ini"> <span class="na">bdone</span> <span class="o">=</span> <span class="s">"!f() { git checkout ${1-master} &amp;&amp; git up &amp;&amp; git bclean ${1-master}; }; f"</span>
  517. </code></pre></div>
  518. <p>I use this one all the time when I'm deep in the GitHub flow. And now, you too can be a GitHub flow master.</p>
  519. <h2>The List</h2>
  520. <p>Here's a list of all the aliases together for your convenience.</p>
  521. <div class="highlight"><pre><code class="language-ini" data-lang="ini"><span class="k">[alias]</span>
  522. <span class="na">co</span> <span class="o">=</span> <span class="s">checkout</span>
  523. <span class="s"> ec = config --global -e</span>
  524. <span class="s"> up = !git pull --rebase --prune $@ &amp;&amp; git submodule update --init --recursive</span>
  525. <span class="s"> cob = checkout -b</span>
  526. <span class="s"> cm = !git add -A &amp;&amp; git commit -m</span>
  527. <span class="s"> save = !git add -A &amp;&amp; git commit -m 'SAVEPOINT'</span>
  528. <span class="s"> wip = !git add -u &amp;&amp; git commit -m "WIP" </span>
  529. <span class="s"> undo = reset HEAD~1 --mixed</span>
  530. <span class="s"> amend = commit -a --amend</span>
  531. <span class="s"> wipe = !git add -A &amp;&amp; git commit -qm 'WIPE SAVEPOINT' &amp;&amp; git reset HEAD~1 --hard</span>
  532. <span class="s"> bclean = "!f() { git branch --merged ${1-master} | grep -v " ${1-master}$" | xargs -r git branch -d; }; f"</span>
  533. <span class="s"> bdone = "!f() { git checkout ${1-master} &amp;&amp; git up &amp;&amp; git bclean ${1-master}; }; f"</span>
  534. </code></pre></div>
  535. <h2>Credits and more reading</h2>
  536. <p>It would be impossible to source every git alias I use as many of these are pretty common and I've adapted them for my own needs. However, here are a few blog posts that provided helpful information about git aliases that served as my inspiration. I also added a couple posts about how GitHub uses pull requests.</p>
  537. <p><em>PS: If you liked this post <a href="https://twitter.com/haacked">follow me on Twitter</a> for interesting links and my wild observations about pointless drivel</em></p>
  538. <p><em>PPS</em>: For Windows users, these aliases don't require using Git Bash. They work in PowerShell and CMD when msysgit is in your path. For example, if you install <a href="https://windows.github.com/">GitHub for Windows</a> and use the GitHub Shell, these all work fine.</p>
  539. </article>
  540. </section>
  541. <nav id="jumpto">
  542. <p>
  543. <a href="/david/blog/">Accueil du blog</a> |
  544. <a href="http://haacked.com/archive/2014/07/28/github-flow-aliases/">Source originale</a> |
  545. <a href="/david/stream/2019/">Accueil du flux</a>
  546. </p>
  547. </nav>
  548. <footer>
  549. <div>
  550. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  551. <p>
  552. Bonjour/Hi!
  553. 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>
  554. 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>).
  555. </p>
  556. <p>
  557. 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>.
  558. </p>
  559. <p>
  560. Voici quelques articles choisis :
  561. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  562. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  563. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  564. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  565. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  566. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  567. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  568. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  569. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  570. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  571. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  572. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  573. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  574. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  575. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  576. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  577. </p>
  578. <p>
  579. 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>.
  580. </p>
  581. <p>
  582. Je ne traque pas ta navigation mais mon
  583. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  584. conserve des logs d’accès.
  585. </p>
  586. </div>
  587. </footer>
  588. <script type="text/javascript">
  589. ;(_ => {
  590. const jumper = document.getElementById('jumper')
  591. jumper.addEventListener('click', e => {
  592. e.preventDefault()
  593. const anchor = e.target.getAttribute('href')
  594. const targetEl = document.getElementById(anchor.substring(1))
  595. targetEl.scrollIntoView({behavior: 'smooth'})
  596. })
  597. })()
  598. </script>