PageRenderTime 27ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/post/2019-06-17-avoid-rebase-hell-squashing-wi/index.html

https://github.com/larsks/blog.oddbit.com
HTML | 282 lines | 205 code | 76 blank | 1 comment | 0 complexity | e636e173ca43eeb76e436e0bf08ae878 MD5 | raw file
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <title>Avoid rebase hell: squashing without rebasing &middot; The Odd Bit</title>
  7. <meta name="description" content="You&rsquo;re working on a pull request. You&rsquo;ve been working on a pull request for a while, and due to lack of sleep or inebriation you&rsquo;ve been merging changes into your feature branch rather than rebasing. You now have a pull request that looks like this (I&rsquo;ve marked merge commits with the text [merge]):
  8. 7e181479 Adds methods for widget sales 0487162 [merge] Merge remote-tracking branch &#39;origin/master&#39; into my_feature 76ee81c [merge] Merge branch &#39;my_feature&#39; of https://github.">
  9. <meta name="HandheldFriendly" content="True">
  10. <meta name="MobileOptimized" content="320">
  11. <meta name="generator" content="Hugo 0.88.0" />
  12. <meta name="robots" content="index,follow">
  13. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  14. <link rel="stylesheet" href="https://blog.oddbit.com/dist/style.min.81747fa30e7c939c160ea84909a818dc1b99d7e662edf55326bd32a4510c9eb5.css">
  15. <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,400,600,700,300&subset=latin,cyrillic-ext,latin-ext,cyrillic">
  16. <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
  17. <!-- alternate output formats -->
  18. <link rel="stylesheet" href="/css/oddbit.css">
  19. <link rel="stylesheet" href="/css/sx.css">
  20. <link rel="stylesheet" href="/css/pull-request.css">
  21. <link rel="stylesheet" href="/css/archive.css">
  22. <link rel="stylesheet" href="/css/syntax.css">
  23. </head>
  24. <body>
  25. <div id="wrapper">
  26. <header class="site-header">
  27. <div class="container">
  28. <div class="site-title-wrapper">
  29. <h1 class="site-title">
  30. <a title="The Odd Bit" href="https://blog.oddbit.com/">The Odd Bit</a>
  31. </h1>
  32. <a class="button-square" href="https://blog.oddbit.com/rss.xml"><i class="fa fa-rss"></i></a>
  33. <a class="button-square button-social hint--top" data-hint="Twitter" title="Twitter" href="https://twitter.com/larsks" rel="me">
  34. <i class="fa fa-twitter"></i>
  35. </a>
  36. <a class="button-square button-social hint--top" data-hint="Github" title="Github" href="https://github.com/larsks" rel="me">
  37. <i class="fa fa-github-alt"></i>
  38. </a>
  39. <a class="button-square button-social hint--top" data-hint="Stack Overflow" title="Stack Overflow" href="https://stackoverflow.com/users/147356/larsks" rel="me">
  40. <i class="fa fa-stack-overflow"></i>
  41. </a>
  42. </div>
  43. <div class="donate">
  44. If you find something here useful or interesting, you can
  45. <a href="https://www.buymeacoffee.com/oddbit">buy me a coffee</a>!
  46. </div>
  47. <ul class="site-nav">
  48. <li class="site-nav-item">
  49. <a title="Home" href="/">Home</a>
  50. </li>
  51. <li class="site-nav-item">
  52. <a title="Categories" href="/categories">Categories</a>
  53. </li>
  54. <li class="site-nav-item">
  55. <a title="Tags" href="/tags">Tags</a>
  56. </li>
  57. <li class="site-nav-item">
  58. <a title="Archives" href="/archives">Archives</a>
  59. </li>
  60. <li class="site-nav-item">
  61. <a title="Answers" href="/about/stackoverflow/">Answers</a>
  62. </li>
  63. <li class="site-nav-item">
  64. <a title="GPG Key" href="/about/gpg/">GPG Key</a>
  65. </li>
  66. </ul>
  67. </div>
  68. </header>
  69. <div id="container">
  70. <div class="container">
  71. <article class="post-container" itemscope="" itemtype="http://schema.org/BlogPosting">
  72. <header class="post-header">
  73. <h1 class="post-title" itemprop="name headline">Avoid rebase hell: squashing without rebasing</h1>
  74. <p class="post-date post-line">
  75. <span>Published <time datetime="2019-06-17" itemprop="datePublished">Mon, Jun 17, 2019</time></span>
  76. <span>by</span>
  77. <span itemscope="" itemprop="author" itemtype="https://schema.org/Person">
  78. <span itemprop="name">
  79. <a href="/about/" itemprop="url" rel="author">Lars Kellogg-Stedman</a>
  80. </span>
  81. </span>
  82. </p>
  83. </header>
  84. <div class="post-content clearfix" itemprop="articleBody">
  85. <p>You&rsquo;re working on a pull request. You&rsquo;ve been working on a pull request for a while, and due to lack of sleep or inebriation you&rsquo;ve been merging changes into your feature branch rather than rebasing. You now have a pull request that looks like this (I&rsquo;ve marked merge commits with the text <code>[merge]</code>):</p>
  86. <pre tabindex="0"><code>7e181479 Adds methods for widget sales
  87. 0487162 [merge] Merge remote-tracking branch 'origin/master' into my_feature
  88. 76ee81c [merge] Merge branch 'my_feature' of https://github.com/my_user_name/widgets into my_feature
  89. 981aab4 Adds api for the widget service.
  90. b048836 Includes fixes suggested by reviewer.
  91. 3dd0c22 adds changes requested by reviewer
  92. 5891db2 [merge] fixing merge conflicts
  93. 2e226e4 fixes suggestions given by the reviewer
  94. da1e85c Adds gadget related API spec
  95. c555cc1 Adds doodad related API spec
  96. e5beb3e Adds api for update and delete of widgets
  97. c43bade Adds api for creating widgets
  98. deaa962 Adds all get methods for listing widgets
  99. 9de79ab Adds api for showing a widget and simple data model
  100. 8288ab1 Adds api framework for widget service
  101. </code></pre><p>You know that&rsquo;s a mess, so you try to fix it by running <code>git rebase -i master</code> and squashing everything together&hellip;and you find yourself stuck in an endless maze of merge conflicts. There has to be a better way!</p>
  102. <p><em>(voiceover: there is a better way&hellip;)</em></p>
  103. <h2 id="option-1-merge---squash">Option 1: merge &ndash;squash</h2>
  104. <p>In this method, you will create a temporary branch and use <code>git merge --squash</code> to squash together the changes in your pull request.</p>
  105. <ol>
  106. <li>
  107. <p>Check out a new branch based on <code>master</code> (or the appropriate base branch if your feature branch isn&rsquo;t based on <code>master</code>):</p>
  108. <pre tabindex="0"><code>git checkout -b work master
  109. </code></pre><p>(This creates a new branch called <code>work</code> and makes that your current branch.)</p>
  110. </li>
  111. <li>
  112. <p>Bring in the changes from your messy pull request using <code>git merge --squash</code>:</p>
  113. <pre tabindex="0"><code>git merge --squash my_feature
  114. </code></pre><p>This brings in all the changes from your <code>my_feature</code> branch and stages them, but does not create <em>any</em> commits.</p>
  115. </li>
  116. <li>
  117. <p>Commit the changes with an appropriate commit message:</p>
  118. <pre tabindex="0"><code>git commit
  119. </code></pre><p>At this point, your <code>work</code> branch should be identical to the original <code>my_feature</code> branch (running <code>git diff my_feature_branch</code> should not show any changes), but it will have only a single commit after <code>master</code>.</p>
  120. </li>
  121. <li>
  122. <p>Return to your feature branch and <code>reset</code> it to the squashed version:</p>
  123. <pre tabindex="0"><code>git checkout my_feature
  124. git reset --hard work
  125. </code></pre></li>
  126. <li>
  127. <p>Update your pull request:</p>
  128. <pre tabindex="0"><code>git push -f
  129. </code></pre></li>
  130. <li>
  131. <p>Optionally clean up your work branch:</p>
  132. <pre tabindex="0"><code>git branch -D work
  133. </code></pre></li>
  134. </ol>
  135. <h2 id="option-2-using-git-commit-tree">Option 2: Using <code>git commit-tree</code></h2>
  136. <p>In this method, you will use <code>git commit-tree</code> to create a new commit without requiring a temporary branch.</p>
  137. <ol>
  138. <li>
  139. <p>Use <code>git commit-tree</code> to create new commit that reproduces the current state of your <code>my_feature</code> branch but</p>
  140. <pre tabindex="0"><code>git commit-tree -p master -m 'this implements my_feature' my_feature^{tree}
  141. </code></pre><p>This uses the current state of the <code>my_feature</code> branch as the source of a new commit whose parent is <code>master</code>. This will print out a commit hash:</p>
  142. <pre tabindex="0"><code>1d3917a3b7c43f4585084e626303c9eeee59c6d6
  143. </code></pre></li>
  144. <li>
  145. <p>Reset your <code>my_feature</code> branch to this new commit hash:</p>
  146. <pre tabindex="0"><code>git reset --hard 1d3917a3b7c43f4585084e626303c9eeee59c6d6
  147. </code></pre></li>
  148. <li>
  149. <p>Consider editing your commit message to meet <a href="https://blog.oddbit.com/post/2019-06-14-git-etiquette-commit-messages/">best practices</a>.</p>
  150. </li>
  151. <li>
  152. <p>Update your pull request:</p>
  153. <pre tabindex="0"><code>git push -f
  154. </code></pre></li>
  155. </ol>
  156. </div>
  157. <footer class="post-footer clearfix">
  158. <p class="post-tags">
  159. <span>Tagged:</span>
  160. <a href="https://blog.oddbit.com/tag/git/">git</a>
  161. </p>
  162. <div class="share">
  163. <a class="icon-twitter" href="https://twitter.com/share?text=Avoid%20rebase%20hell%3a%20squashing%20without%20rebasing&url=https%3a%2f%2fblog.oddbit.com%2fpost%2f2019-06-17-avoid-rebase-hell-squashing-wi%2f"
  164. onclick="window.open(this.href, 'twitter-share', 'width=550,height=235');return false;">
  165. <i class="fa fa-twitter"></i>
  166. <span class="hidden">Twitter</span>
  167. </a>
  168. </div>
  169. </footer>
  170. <script src="https://utteranc.es/client.js"
  171. repo="larsks/blog.oddbit.com"
  172. issue-term="pathname"
  173. label="comment"
  174. theme="github-light"
  175. crossorigin="anonymous"
  176. async>
  177. </script>
  178. </article>
  179. </div>
  180. </div>
  181. </div>
  182. <footer class="footer">
  183. <div class="container">
  184. <div class="site-title-wrapper">
  185. <h1 class="site-title">
  186. <a title="The Odd Bit" href="https://blog.oddbit.com/">The Odd Bit</a>
  187. </h1>
  188. <a class="button-square button-jump-top js-jump-top" href="#">
  189. <i class="fa fa-angle-up"></i>
  190. </a>
  191. </div>
  192. <p class="footer-copyright">
  193. <span>&copy; 2022 / Powered by <a href="https://gohugo.io/">Hugo</a></span>
  194. </p>
  195. <p class="footer-copyright">
  196. <span><a href="https://github.com/roryg/ghostwriter">Ghostwriter theme</a> By <a href="http://jollygoodthemes.com">JollyGoodThemes</a></span>
  197. <span>/ <a href="https://github.com/jbub/ghostwriter">Ported</a> to Hugo By <a href="https://github.com/jbub">jbub</a></span>
  198. </p>
  199. </div>
  200. </footer>
  201. <script src="https://blog.oddbit.com/js/jquery-1.11.3.min.js"></script>
  202. <script src="https://blog.oddbit.com/js/jquery.fitvids.js"></script>
  203. <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
  204. <script src="https://blog.oddbit.com/js/scripts.js"></script>
  205. </body>
  206. </html>