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.

index.md 48KB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. title: Git Branch Rename
  2. url: https://github.com/chancancode/branch-rename/blob/main/README.md
  3. hash_url: 240b647e699da81b505d43af39257996
  4. <p>So, you want to rename a branch on Git/GitHub. The most common case of this is
  5. to rename the default "master" branch to something else, such as "main". We are
  6. going to use this as our example, but you may have a different use case in
  7. mind. If that's the case, just replace "master" and "main" to the source and
  8. target branches you have in mind.</p>
  9. <h2><a id="user-content-table-of-contents" class="anchor" aria-hidden="true" href="#table-of-contents"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Table of Contents</h2>
  10. <h2><a id="user-content-new-project" class="anchor" aria-hidden="true" href="#new-project"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>New Project</h2>
  11. <p>If you are starting a brand new project, you can follow these steps:</p>
  12. <ol>
  13. <li>
  14. <p><a href="https://github.com/new">Create a new repository on GitHub</a> to host your
  15. project with the following settings:</p>
  16. <ul>
  17. <li><strong>Repository template</strong>: No template</li>
  18. <li><strong>Initialize this repository with a README</strong>: Leave unchecked</li>
  19. <li><strong>Add .gitignore</strong>: None</li>
  20. <li><strong>Add a license</strong>: None</li>
  21. </ul>
  22. <p>If you wish to use any of these features (i.e. with settings different than
  23. the above), that is not a problem. However, GitHub will create the default
  24. "master" branch for you. In that case, clone the repository locally and
  25. follow the steps in the <a href="#simple-migration"><strong>Simple Migration</strong></a> section
  26. instead.</p>
  27. </li>
  28. <li>
  29. <p>Initialize an empty Git repository:</p>
  30. <div class="highlight highlight-source-shell"><pre>$ mkdir my-git-project
  31. $ <span class="pl-c1">cd</span> my-git-project
  32. $ git init <span class="pl-c1">.</span></pre></div>
  33. </li>
  34. <li>
  35. <p>Create the "main" branch:</p>
  36. </li>
  37. <li>
  38. <p>Work on your project and commit some changes. For example, add a README:</p>
  39. <div class="highlight highlight-source-shell"><pre>$ <span class="pl-c1">echo</span> <span class="pl-s"><span class="pl-pds">"</span># My Git Project<span class="pl-pds">"</span></span> <span class="pl-k">&gt;&gt;</span> README.md
  40. $ git add README.md
  41. $ git commit -m <span class="pl-s"><span class="pl-pds">"</span>Initial commit<span class="pl-pds">"</span></span></pre></div>
  42. </li>
  43. <li>
  44. <p>Push your commits to GitHub:</p>
  45. <div class="highlight highlight-source-shell"><pre>$ git remote add origin https://github.com/your-username/my-git-project.git
  46. $ git push -u origin main</pre></div>
  47. </li>
  48. </ol>
  49. <p>That's all! Since "main" was the first branch you pushed to GitHub, it will be
  50. set correctly as the default branch. We also never committed any changes to the
  51. "master" branch locally, it effectively never existed so there is nothing left
  52. to clean up. Enjoy your new project!</p>
  53. <h2><a id="user-content-simple-migration" class="anchor" aria-hidden="true" href="#simple-migration"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Simple Migration</h2>
  54. <p>If you have a small personal project and you are comfortable with just doing
  55. the rename right away, here are the steps you can take.</p>
  56. <p>Note that if this is a <a href="https://pages.github.com">GitHub Pages</a> repository and
  57. the content is stored on the "master" branch, then you cannot perform the
  58. migration at this time since GitHub Pages does not seem to support alternative
  59. default branch names yet. If you want, you may follow the steps in the <a href="#local-migration"><strong>Local
  60. Migration</strong></a> or <a href="#gradual-migration"><strong>Gradual Migration</strong></a>
  61. section partially to get your project ready.</p>
  62. <ol>
  63. <li>
  64. <p>Pull the latest commits from the "master" branch into your local repository:</p>
  65. <div class="highlight highlight-source-shell"><pre>$ <span class="pl-c1">cd</span> my-git-project
  66. $ git checkout master
  67. $ git pull origin master</pre></div>
  68. </li>
  69. <li>
  70. <p>Rename the local "master" branch to "main":</p>
  71. </li>
  72. <li>
  73. <p>Push the "main" branch to GitHub:</p>
  74. <div class="highlight highlight-source-shell"><pre>$ git push -u origin main</pre></div>
  75. </li>
  76. <li>
  77. <p><a href="https://help.github.com/en/github/administering-a-repository/setting-the-default-branch">Change the default branch on GitHub</a> to "main".</p>
  78. </li>
  79. <li>
  80. <p>If there are existing pull requests open against the "master" branch that
  81. you would like to keep, <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-base-branch-of-a-pull-request">update their base branch</a> to
  82. the "main" branch. Otherwise, they will be closed automatically when we
  83. delete the remote "master" branch on GitHub.</p>
  84. </li>
  85. <li>
  86. <p>Delete your local "master" branch:</p>
  87. </li>
  88. <li>
  89. <p>Delete the remote "master" branch:</p>
  90. <div class="highlight highlight-source-shell"><pre>$ git push origin :master</pre></div>
  91. </li>
  92. </ol>
  93. <p>At this point, the migration is complete. However, as you work on the project,
  94. you may discover additional settings that you need to tweak to account for the
  95. rename. For example, you may have update the branch names in your CI config.</p>
  96. <h2><a id="user-content-gradual-migration" class="anchor" aria-hidden="true" href="#gradual-migration"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Gradual Migration</h2>
  97. <p>If you have a work or open-source repository with multiple contributors and
  98. forks, you may prefer to perform the migration gradually.</p>
  99. <p>These steps are for you if you find yourself in a similar scenario, where it is
  100. important to give everyone ample of time to prepare for the migration, changing
  101. local configs, adapting workflows, scripts and other automation to ensure a
  102. seamless migration.</p>
  103. <p>This gradual migration plan is intended to be spread out over a long period of
  104. time – weeks, or months. It uses all available tools on GitHub to provide as
  105. much advance notice as possible.</p>
  106. <p>For most organizations, this plan may be overly cautious and some of the steps
  107. may not be necessary. On the other hand, for a popular open-source project, it
  108. may not be feasible to get to the end and fully deprecate and remove the legacy
  109. "master" branch at all, due to compatibility requirements. Treat this plan as a
  110. template and adapt it for your own needs.</p>
  111. <p>Unlike the other sections, the steps here are a bit less exact and is intended
  112. for someone with a some prior experience with Git and GitHub. In practice, you
  113. will probably run into situations that causes deviations from the plan which
  114. would require some manual repair and adjustments. For example, pushes during a
  115. partial GitHub outage may cause the two branches to diverge and requires you
  116. to determine how to best reconcile the differences.</p>
  117. <h3><a id="user-content-phase-1-mirror-master-and-main" class="anchor" aria-hidden="true" href="#phase-1-mirror-master-and-main"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Phase 1: Mirror "master" and "main"</h3>
  118. <p>The goal of this phase is to make it <em>possible</em> to use the "main" branch name
  119. as an alternative. This allows some early adopters to start testing the new
  120. setup.</p>
  121. <ol>
  122. <li>
  123. <p>As always, make sure your local "master" branch is up-to-date.</p>
  124. </li>
  125. <li>
  126. <p>Create the new "main" branch:</p>
  127. </li>
  128. <li>
  129. <p>Add a <a href="https://github.com/features/actions">GitHub Actions</a> workflow file at
  130. <strong>.github/workflows/mirror-master-and-main.yml</strong> with the following:</p>
  131. <div class="highlight highlight-source-yaml"><pre><span class="pl-ent">name</span>: <span class="pl-s">Mirror "master" and "main" branches</span>
  132. <span class="pl-ent">on</span>:
  133. <span class="pl-ent">push</span>:
  134. <span class="pl-ent">branches</span>:
  135. - <span class="pl-s">master</span>
  136. - <span class="pl-s">main</span>
  137. <span class="pl-ent">jobs</span>:
  138. <span class="pl-ent">mirror</span>:
  139. <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
  140. <span class="pl-ent">steps</span>:
  141. - <span class="pl-ent">name</span>: <span class="pl-s">Mirror to "master"</span>
  142. <span class="pl-ent">uses</span>: <span class="pl-s">zofrex/mirror-branch@v1</span>
  143. <span class="pl-ent">with</span>:
  144. <span class="pl-ent">target-branch</span>: <span class="pl-s">master</span>
  145. <span class="pl-ent">force</span>: <span class="pl-c1">false</span>
  146. - <span class="pl-ent">name</span>: <span class="pl-s">Mirror to "main"</span>
  147. <span class="pl-ent">uses</span>: <span class="pl-s">zofrex/mirror-branch@v1</span>
  148. <span class="pl-ent">with</span>:
  149. <span class="pl-ent">target-branch</span>: <span class="pl-s">main</span>
  150. <span class="pl-ent">force</span>: <span class="pl-c1">false</span></pre></div>
  151. </li>
  152. <li>
  153. <p>Commit and your changes to the local "main" branch.</p>
  154. </li>
  155. <li>
  156. <p>Push your changes to the remote "main" branch:</p>
  157. <div class="highlight highlight-source-shell"><pre>$ git push -u origin main</pre></div>
  158. </li>
  159. </ol>
  160. <p>If things are working correctly, you should see the same commit pushed to the
  161. "master" branch shortly. You can monitor the progress and unexpected errors in
  162. the "Actions" tab in your repository.</p>
  163. <h4><a id="user-content-about-github-actions" class="anchor" aria-hidden="true" href="#about-github-actions"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>About GitHub Actions</h4>
  164. <p>You do not have to be already using GitHub Actions for this to work. You do not
  165. need to activate or enable the feature for your repository, simply pushing the
  166. workflow file to the is sufficient. All open-source repositories have unlimited
  167. GitHub Actions minutes, and all personal and team accounts comes with 2000-3000
  168. free GitHub Actions minutes for private repositories.</p>
  169. <p>If you already regularly uses up your free minutes, this may slightly increase
  170. your GitHub bills, but in practice, the workflow we added runs very quickly so
  171. the impact is very minimal. For reference, GitHub Actions are billed at $0.008
  172. USD per minute for private repositories, after the free quota is exhausted.</p>
  173. <p>This workflow will be triggered when commits are pushed to either the "master"
  174. or "main" branch. It uses the <a href="https://github.com/marketplace/actions/mirror-branch">Mirror Branch action</a> to
  175. update the branches using GitHub's API.</p>
  176. <h4><a id="user-content-interaction-with-branch-protection" class="anchor" aria-hidden="true" href="#interaction-with-branch-protection"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Interaction with Branch Protection</h4>
  177. <p>Unfortunately, if you have enabled <a href="https://help.github.com/en/github/administering-a-repository/configuring-protected-branches">branch protection</a> on
  178. the "master" branch, the push from the mirroring action may be rejected. For
  179. example, if you had enabled "Require pull request reviews before merging", then
  180. this would not work as the changes are expected to be submitted via a pull
  181. request with reviews.</p>
  182. <p>A possible workaround is to disable the "Include administrators" checkbox in
  183. the branch protection settings for the "master" branch and configure the script
  184. to push the commits as an administrator:</p>
  185. <ol>
  186. <li>
  187. <p>Login as an administrator on GitHub. You may also want to consider creating
  188. a new account specifically for this purpose.</p>
  189. </li>
  190. <li>
  191. <p>Generate a <a href="https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line">personal access token</a> with the "repo"
  192. scope (and the "public_repo" scope, if needed).</p>
  193. </li>
  194. <li>
  195. <p><a href="https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository">Add it as a secret</a> to the repository.</p>
  196. </li>
  197. <li>
  198. <p>Change the "Checkout" step in the mirror workflow to use the new deploy key:</p>
  199. <div class="highlight highlight-source-yaml"><pre>- <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span>
  200. <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v2</span>
  201. <span class="pl-ent">with</span>:
  202. <span class="pl-ent">token</span>: <span class="pl-s">${{ secrets.DEPLOY_TOKEN }}</span></pre></div>
  203. <p>Here, <code>DEPLOY_TOKEN</code> is the name you picked from step 3.</p>
  204. </li>
  205. </ol>
  206. <p>Alternatively, an SSH key for the administrator can be used instead of a
  207. personal access token, via the <code>ssh-key</code> argument. See the documentation for
  208. the <a href="https://github.com/actions/checkout">checkout action</a> for more details.</p>
  209. <h4><a id="user-content-interaction-with-other-github-action-workflows" class="anchor" aria-hidden="true" href="#interaction-with-other-github-action-workflows"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Interaction with Other GitHub Action Workflows</h4>
  210. <p>By default, when pushing commits from within the GitHub Actions job, it does
  211. not trigger additional GitHub Actions workflow to run. For example, when a
  212. contributor pushes to the "main" branch, it will trigger any GitHub Actions
  213. that normally runs on the "main" branch's push events, including the one we
  214. added here. However, when our mirror workflow pushes the same commit to the
  215. "master" branch, it will not trigger any workflow that normally runs on the
  216. "master" branch's push events.</p>
  217. <p>For this reason, you may want to update existing workflows that runs on the
  218. "master" branch to also run on the "main" branch, as we did in our mirror
  219. workflow file (the <code>on.push.branches</code> config key). This is the recommended
  220. approach as it ensures only a single build per push.</p>
  221. <p>Alternatively, if it is important to you that workflows are triggered by pushes
  222. from the mirror workflow, you can accomplish this by supplying an alternative
  223. SSH key to the <a href="https://github.com/actions/checkout">checkout action</a>:</p>
  224. <ol>
  225. <li>
  226. <p><a href="https://help.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent">Generate a new SSH key</a> locally. Don't worry about adding
  227. it to the ssh-agent.</p>
  228. </li>
  229. <li>
  230. <p>Find the generated <em>public key</em> and <a href="https://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys">add it as a deploy key</a>
  231. to the repository. Be sure to select "Allow write access".</p>
  232. </li>
  233. <li>
  234. <p>Find the generated <em>private key</em> and <a href="https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository">add it as a secret</a> to the
  235. repository.</p>
  236. </li>
  237. <li>
  238. <p>Change the "Checkout" step in the mirror workflow to use the new deploy key:</p>
  239. <div class="highlight highlight-source-yaml"><pre>- <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span>
  240. <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v2</span>
  241. <span class="pl-ent">with</span>:
  242. <span class="pl-ent">ssh-key</span>: <span class="pl-s">${{ secrets.DEPLOY_KEY }}</span></pre></div>
  243. <p>Here, <code>DEPLOY_KEY</code> is the name you picked from step 3.</p>
  244. </li>
  245. </ol>
  246. <p>With this, the mirror workflow will authenticate with GitHub using the deploy
  247. key instead of the default token when pushing commits, triggering any workflows
  248. as if a regular user had pushed those commits. This does not change the author
  249. or committer on the commits.</p>
  250. <h4><a id="user-content-real-world-example" class="anchor" aria-hidden="true" href="#real-world-example"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Real World Example</h4>
  251. <p>See <a href="https://github.com/chancancode/ember-concurrency-async/commit/afbacf7088e473dd056138109e00d8749b95b2d0">this commit</a> and <a href="https://github.com/chancancode/ember-concurrency-async/runs/788797792?check_suite_focus=true">the resulting workflow run</a>
  252. for an example of this working in action. Note that the code in the commit may
  253. be outdated by the time you read this – refer to the above for the latest
  254. instructions.</p>
  255. <h4><a id="user-content-next-steps" class="anchor" aria-hidden="true" href="#next-steps"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Next Steps</h4>
  256. <p>After verifying that everything is working as intended, you can start inviting
  257. the early adopters to start pushing to the "main" branch. The easiest way to do
  258. this is to rename the local "master" branch:</p>
  259. <div class="highlight highlight-source-shell"><pre>$ <span class="pl-c1">cd</span> my-git-project
  260. $ git checkout master
  261. $ git branch -m main
  262. $ git branch -u origin/main</pre></div>
  263. <p>This would also be a good time to start changing any automation or external
  264. services to the "main" branch to ensure that everything is working as expected.</p>
  265. <h3><a id="user-content-phase-2-change-the-default-branch-to-main-deprecate-master" class="anchor" aria-hidden="true" href="#phase-2-change-the-default-branch-to-main-deprecate-master"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Phase 2: Change the default branch to "main", deprecate "master"</h3>
  266. <p>After verifying the viability of the rename during the previous phase, the goal
  267. of this phase is to set "main" as the default branch and start issuing
  268. deprecation warnings when the legacy "master" branch is used.</p>
  269. <ol>
  270. <li>
  271. <p><a href="https://help.github.com/en/github/administering-a-repository/setting-the-default-branch">Change the default branch on GitHub</a> to "main".</p>
  272. </li>
  273. <li>
  274. <p>Add a <a href="https://github.com/features/actions">GitHub Actions</a> workflow file at
  275. <strong>.github/workflows/deprecate-master-branch.yml</strong> with the following:</p>
  276. <div class="highlight highlight-source-yaml"><pre><span class="pl-ent">name</span>: <span class="pl-s">Deprecate "master" branch</span>
  277. <span class="pl-ent">on</span>:
  278. <span class="pl-ent">push</span>:
  279. <span class="pl-ent">branches</span>:
  280. - <span class="pl-s">master</span>
  281. <span class="pl-ent">pull_request</span>:
  282. <span class="pl-ent">branches</span>:
  283. - <span class="pl-s">master</span>
  284. <span class="pl-ent">jobs</span>:
  285. <span class="pl-ent">on-push</span>:
  286. <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
  287. <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event_name == 'push' }}</span>
  288. <span class="pl-ent">steps</span>:
  289. - <span class="pl-ent">name</span>: <span class="pl-s">Deprecation</span>
  290. <span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/commit-comment@v1</span>
  291. <span class="pl-ent">with</span>:
  292. <span class="pl-ent">body</span>: <span class="pl-s">|</span>
  293. <span class="pl-s"> Hello @${{ github.event.sender.login }}!</span>
  294. <span class="pl-s"/>
  295. <span class="pl-s"> I see that you have pushed some commits to the "master" branch. We are in the process of renaming the "master" branch to "main" in this repository.</span>
  296. <span class="pl-s"/>
  297. <span class="pl-s"> :warning: **The "master" branch is deprecated and will be removed from this repository in the future.**</span>
  298. <span class="pl-s"/>
  299. <span class="pl-s"> Please migrate your local repository by renaming the "master" branch to "main":</span>
  300. <span class="pl-s"/>
  301. <span class="pl-s"> ```bash</span>
  302. <span class="pl-s"> $ cd my-git-project</span>
  303. <span class="pl-s"> $ git checkout master</span>
  304. <span class="pl-s"> $ git branch -m main</span>
  305. <span class="pl-s"> $ git branch -u origin/main</span>
  306. <span class="pl-s"> ```</span>
  307. <span class="pl-s"/>
  308. <span class="pl-s"> Before merging pull requests, ensure their base branch is set to "main" instead of "master". For more information on how to do this, refer to [this GitHub support article][1].</span>
  309. <span class="pl-s"/>
  310. <span class="pl-s"> [1]: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-base-branch-of-a-pull-request</span>
  311. <span class="pl-s"/>
  312. <span class="pl-s"/> <span class="pl-ent">on-pull-request</span>:
  313. <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
  314. <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event_name == 'pull_request' }}</span>
  315. <span class="pl-ent">env</span>:
  316. <span class="pl-ent">DEPRECATION_MESSAGE</span>: <span class="pl-s">|</span>
  317. <span class="pl-s"> Hello @${{ github.event.sender.login }}!</span>
  318. <span class="pl-s"/>
  319. <span class="pl-s"> I see that you have opened a pull request against the "master" branch. We are in the process of renaming the "master" branch to "main" in this repository.</span>
  320. <span class="pl-s"/>
  321. <span class="pl-s"> :warning: **The "master" branch is deprecated and will be removed from this repository in the future.**</span>
  322. <span class="pl-s"/>
  323. <span class="pl-s"> Please migrate your local repository by renaming the "master" branch to "main":</span>
  324. <span class="pl-s"/>
  325. <span class="pl-s"> ```bash</span>
  326. <span class="pl-s"> $ cd my-git-project</span>
  327. <span class="pl-s"> $ git checkout master</span>
  328. <span class="pl-s"> $ git branch -m main</span>
  329. <span class="pl-s"> $ git branch -u origin/main</span>
  330. <span class="pl-s"> ```</span>
  331. <span class="pl-s"/>
  332. <span class="pl-s"> Please also set the base branch for this pull request to "main" instead of "master". For more information on how to do this, refer to [this GitHub support article][1].</span>
  333. <span class="pl-s"/>
  334. <span class="pl-s"> [1]: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-base-branch-of-a-pull-request</span>
  335. <span class="pl-s"/> <span class="pl-ent">steps</span>:
  336. - <span class="pl-ent">name</span>: <span class="pl-s">Deprecation</span>
  337. <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.pull_request.head.repo.fork == false }}</span>
  338. <span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/create-or-update-comment@v1</span>
  339. <span class="pl-ent">with</span>:
  340. <span class="pl-ent">issue-number</span>: <span class="pl-s">${{ github.event.number }}</span>
  341. <span class="pl-ent">body</span>: <span class="pl-s">${{ env.DEPRECATION_MESSAGE }}</span>
  342. - <span class="pl-ent">name</span>: <span class="pl-s">Deprecation</span>
  343. <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.pull_request.head.repo.fork == true }}</span>
  344. <span class="pl-ent">run</span>: <span class="pl-s">|</span>
  345. <span class="pl-s"> echo "$DEPRECATION_MESSAGE"</span>
  346. <span class="pl-s"> echo '::error::Please set the base branch for this pull request to "main" instead of "master".'</span>
  347. <span class="pl-s"> exit 1</span></pre></div>
  348. </li>
  349. <li>
  350. <p>Commit and push your changes to the "main" branch.</p>
  351. </li>
  352. </ol>
  353. <p>We added a workflow file that triggers whenever a contributor pushes to or
  354. opens a pull request against the "master" branch.</p>
  355. <p>The workflow adds a comment to the commit or pull request, notifying the
  356. contributor that the "master" branch has been deprecated, along with the steps
  357. they need to take to migrate their local repository and changes they need to
  358. make it to the pull request.</p>
  359. <p>It is recommended that you customize the messages with additional information
  360. relevant for your organization. For example, you may want to include a link to
  361. a tracking issue for additional context, or ways for the contributor to ask for
  362. additional assistance if needed.</p>
  363. <h4><a id="user-content-limitations-of-github-actions-in-forks" class="anchor" aria-hidden="true" href="#limitations-of-github-actions-in-forks"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Limitations of GitHub Actions in Forks</h4>
  364. <p>Unfortunately, due to limitations of GitHub Actions, it is not possible to add
  365. a pull request comment from the workflow when the pull request originated from
  366. a fork, which is very common in open-source repositories. As a workaround, the
  367. workflow prints the deprecation message to the logs and fails the build.</p>
  368. <h4><a id="user-content-real-world-example-1" class="anchor" aria-hidden="true" href="#real-world-example-1"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Real World Example</h4>
  369. <p>See <a href="https://github.com/chancancode/ember-concurrency-async/commit/7f3509b4363f3fcdb3275ec136c4b5766f39c192">this commit</a> and <a href="https://github.com/chancancode/ember-concurrency-async/pull/5">this pull request</a> for an
  370. example of this working in action. Note that the code in the commit may be
  371. outdated by the time you read this – refer to the above for the latest
  372. instructions.</p>
  373. <h4><a id="user-content-next-steps-1" class="anchor" aria-hidden="true" href="#next-steps-1"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Next Steps</h4>
  374. <p>This would be a good time to start updating any internal and external links to
  375. the "master" branch. A common example would be automatically generated links to
  376. source code from the API documentation.</p>
  377. <h3><a id="user-content-phase-3-complete-the-migration" class="anchor" aria-hidden="true" href="#phase-3-complete-the-migration"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Phase 3: Complete the migration</h3>
  378. <p>After a successful phase 2 rollout, it is time to plan for completing the
  379. migration. However, what completion means is going to be different depending on
  380. your situation.</p>
  381. <p>For private work repositories, the legacy "master" branch can likely be removed
  382. from the repository after giving team members a few weeks to migrate. Don't
  383. forget to remove the workflow files as well.</p>
  384. <p>For open-source repositories with lots of contributors, you may want to move a
  385. lot slower. Monitor the Actions tab of the repository to see how often the
  386. deprecation workflow is triggered. When the activity diminishes, it may be good
  387. indication that the legacy "master" branch is no longer needed.</p>
  388. <h4><a id="user-content-soft-removal" class="anchor" aria-hidden="true" href="#soft-removal"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Soft Removal</h4>
  389. <p>As an alternative to removing the branch right away, you may want to consider
  390. pushing a final commit to the branch, removing all files but leave behind a
  391. README file explaining that branch has been moved, along with the steps they
  392. need to take in order to migrate their local repository.</p>
  393. <h4><a id="user-content-url-considerations" class="anchor" aria-hidden="true" href="#url-considerations"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>URL Considerations</h4>
  394. <p>It is also important to consider URL breakages, as links that points to the
  395. files on the "master" branch will stop working once the branch is removed,
  396. including with the soft-removal method described above.</p>
  397. <p>The impact of this has to be evaluated contextually, but it is important to
  398. note that the scope of the breakage is fairly limited, as this only directly
  399. impacts URLs that links to the "master" branch directly. Links pointing to the
  400. active development branch of repository is quite fragile (especially with line
  401. numbers) and often breaks for other reasons.</p>
  402. <p>For example, a refactor that moves around files or switching from JavaScript to
  403. TypeScript would invalidate these URLs. This sort of activity is fairly common
  404. on an active code repository and is usually performed without taking the URL
  405. consideration in mind. For this reason, it is considered a best practice to use
  406. SHA-based <a href="https://help.github.com/en/github/managing-files-in-a-repository/getting-permanent-links-to-files">permanent links</a> in most situations. These links
  407. are unaffected by the branch rename.</p>
  408. <h4><a id="user-content-packages-considerations" class="anchor" aria-hidden="true" href="#packages-considerations"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Packages Considerations</h4>
  409. <p>For repositories containing <em>installable packages</em>, there are some additional
  410. considerations. Many package managers allow for installing packages from a Git
  411. repository. For example, in npm and yarn, dependencies can be a string like
  412. "username/repo" or "username/repo#branch" in lieu of version range. Likewise,
  413. GitHub Actions are installed using repository and branch references, and it is
  414. a relatively common practice to point an action at the "master" branch.</p>
  415. <p>In these cases, the decision on whether to remove the legacy "master" branch
  416. has to be made carefully. Here are some examples of things to investigate
  417. and consider:</p>
  418. <ul>
  419. <li>
  420. <p>When the branch is omitted from the specifier (e.g. "username/repo"), does
  421. the package manager in your ecosystem hard-code the default to "master" on
  422. the client, or does it respect the remote HEAD ref?</p>
  423. </li>
  424. <li>
  425. <p>Does the package manager use a lockfile, and if so, does it serialize the
  426. branch name (as opposed to the resolved SHA) into the lockfile?</p>
  427. </li>
  428. <li>
  429. <p>Does the package manager maintain a cache of cloned repositories, and if so
  430. do they recover gracefully to a remote branch disappearing?</p>
  431. </li>
  432. </ul>
  433. <p>The answer to these questions affects the potential impact to your end-users
  434. if the legacy "master" branch is removed from the repository. For some, the
  435. end-state of the migration may be to keep the "master" branch permanently as a
  436. read-only mirror, or it may be sufficient to freeze the branch's content and
  437. stop providing updates there. For others, the potential breakage maybe small
  438. enough that it is can be easily justified.</p>
  439. <p>While the workflows added in phase 2 are effective for deprecating <em>writes</em> to
  440. the legacy "master" branch. Unfortunately, Git and GitHub do not offer the
  441. ability to do the same for <em>reads</em> to the branch.</p>
  442. <p>However, you may be able to use features from the package manager to accomplish
  443. a similar result. For example, instead of mirroring the "main" branch to the
  444. "master" branch exactly, you could add a post-install hook to the version on
  445. "master" to issue the deprecation message for any potential consumers.</p>
  446. <h4><a id="user-content-a-concrete-example" class="anchor" aria-hidden="true" href="#a-concrete-example"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>A Concrete Example</h4>
  447. <p>Using the Node.js ecosystem as an example, we can put these considerations into
  448. context, based on preliminary testing with npm and yarn classic (v1). If you
  449. found different results in your own testing, or with other package managers
  450. (pnpm, yarn v2, etc), please file an issue here.</p>
  451. <ul>
  452. <li>
  453. <p>The popular package managers in the ecosystem support installing packages
  454. from git, by specifying "username/repo" or "username/repo#branch" in the
  455. dependencies section of package.json.</p>
  456. </li>
  457. <li>
  458. <p>When a branch name is not specified, the popular package managers defaults to
  459. the remote HEAD ref, which is set by the default branch on GitHub, instead of
  460. hardcoding to the "master" branch in the client.</p>
  461. </li>
  462. <li>
  463. <p>The popular package managers uses a lockfile by default. They serialize the
  464. resolved SHA into the lockfiles, as long as the commits referred to by these
  465. SHAs remain reachable on the remote repository, they will install just fine
  466. when using a lockfile. In the case of a branch rename, this is not an issue,
  467. as the history and commits will remain intact.</p>
  468. </li>
  469. <li>
  470. <p>When installing without a lockfile, the popular package managers will fetch
  471. the latest commit from the repository. Renaming the remote branch did not
  472. appear to cause any issues, either because the repositories are not cached,
  473. or the clients are able to recover gracefully from a "missing" remote branch.</p>
  474. </li>
  475. <li>
  476. <p>Post-install hooks are supported. However, yarn classic <a href="https://github.com/yarnpkg/yarn/issues/5476">hides the output
  477. produced by these scripts</a> if
  478. they are successful (exit cleanly with exit code 0). However, when they fail,
  479. they output <em>is</em> shown to the user.</p>
  480. </li>
  481. <li>
  482. <p>Generally speaking, the ecosystem has strong norms and expectations around
  483. adhering to <a href="https://semver.org" rel="nofollow">semantic versioning</a>. Usually, breaking changes are only
  484. expected on major version bumps.</p>
  485. </li>
  486. <li>
  487. <p>By using a Git dependency instead of specifying a semver range, they are
  488. explicitly opting out of the normal semver guarantee, and breakages are to be
  489. expected. No one could reasonably expect that pointing a dependency to the
  490. active development branch without using a lockfile will result in a stable
  491. system.</p>
  492. </li>
  493. </ul>
  494. <p>Given these findings, here is a concrete proposal for a maximally graceful
  495. completion plan:</p>
  496. <ol>
  497. <li>
  498. <p>Stop providing updates to the "master" branch by removing the mirroring
  499. workflow added in phase 1.</p>
  500. </li>
  501. <li>
  502. <p>Push a commit the "master" branch, updating the README as well as adding a
  503. deprecation message to the runtime code (the <code>main</code> entry point):</p>
  504. <div class="highlight highlight-source-js"><pre><span class="pl-c">// index.js</span>
  505. <span class="pl-k">let</span> <span class="pl-s1">command</span> <span class="pl-c1">=</span> <span class="pl-s">'npm update my-git-project'</span><span class="pl-kos">;</span>
  506. <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">process</span><span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">npm_execpath</span> <span class="pl-c1">&amp;&amp;</span> <span class="pl-s1">process</span><span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">npm_execpath</span><span class="pl-kos">.</span><span class="pl-en">indexOf</span><span class="pl-kos">(</span><span class="pl-s">'yarn'</span><span class="pl-kos">)</span> !== <span class="pl-c1">-</span><span class="pl-c1">1</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  507. <span class="pl-s1">command</span> <span class="pl-c1">=</span> <span class="pl-s">'yarn upgrade my-git-project'</span><span class="pl-kos">;</span>
  508. <span class="pl-kos">}</span>
  509. <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">warn</span><span class="pl-kos">(</span>
  510. <span class="pl-s">`You are running a deprecated copy of the "my-git-project" installed `</span> <span class="pl-c1">+</span>
  511. <span class="pl-s">`from the "master" branch of our repository. The "master" branch is `</span> <span class="pl-c1">+</span>
  512. <span class="pl-s">`deprecated and no longer receives any updates. The branch will soon `</span> <span class="pl-c1">+</span>
  513. <span class="pl-s">`be removed from our repository, at which point the package will fail `</span> <span class="pl-c1">+</span>
  514. <span class="pl-s">`to install.\n\n`</span> <span class="pl-c1">+</span>
  515. <span class="pl-s">`To fix this issue, please modify your package.json and change the `</span> <span class="pl-c1">+</span>
  516. <span class="pl-s">`"my-git-project" dependency from "my-repo/my-git-project#master" to `</span> <span class="pl-c1">+</span>
  517. <span class="pl-s">`"my-repo/my-git-project" or a valid semver range. After making the `</span> <span class="pl-c1">+</span>
  518. <span class="pl-s">`change, run "<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">command</span><span class="pl-kos">}</span></span>" to update the package.`</span>
  519. <span class="pl-kos">)</span><span class="pl-kos">;</span>
  520. <span class="pl-c">// ...rest of index.js</span></pre></div>
  521. </li>
  522. <li>
  523. <p>When releasing the next major version of the package, push another commit to
  524. the "master" branch, remove all files from the branch, leaving behind only a
  525. minimal README file, package.json and index.js:</p>
  526. <div class="highlight highlight-source-js"><pre><span class="pl-c">// package.json</span>
  527. <span class="pl-kos">{</span>
  528. <span class="pl-s">"name"</span>: <span class="pl-s">"my-git-project"</span><span class="pl-kos">,</span>
  529. <span class="pl-s">"scripts"</span>: <span class="pl-kos">{</span>
  530. <span class="pl-s">"postinstall"</span>: <span class="pl-s">"node index.js"</span>
  531. <span class="pl-kos">}</span>
  532. <span class="pl-kos">}</span></pre></div>
  533. <div class="highlight highlight-source-js"><pre><span class="pl-c">// index.js</span>
  534. <span class="pl-k">let</span> <span class="pl-s1">command</span> <span class="pl-c1">=</span> <span class="pl-s">'npm update my-git-project'</span><span class="pl-kos">;</span>
  535. <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">process</span><span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">npm_execpath</span> <span class="pl-c1">&amp;&amp;</span> <span class="pl-s1">process</span><span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">npm_execpath</span><span class="pl-kos">.</span><span class="pl-en">indexOf</span><span class="pl-kos">(</span><span class="pl-s">'yarn'</span><span class="pl-kos">)</span> !== <span class="pl-c1">-</span><span class="pl-c1">1</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  536. <span class="pl-s1">command</span> <span class="pl-c1">=</span> <span class="pl-s">'yarn upgrade my-git-project'</span><span class="pl-kos">;</span>
  537. <span class="pl-kos">}</span>
  538. <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">error</span><span class="pl-kos">(</span>
  539. <span class="pl-s">`You have installed "my-git-project" from the "master" branch of our `</span> <span class="pl-c1">+</span>
  540. <span class="pl-s">`repository. The "master" branch has been official retired.\n\n`</span> <span class="pl-c1">+</span>
  541. <span class="pl-s">`To fix this issue, please modify your package.json and change the `</span> <span class="pl-c1">+</span>
  542. <span class="pl-s">`"my-git-project" dependency from "my-repo/my-git-project#master" to `</span> <span class="pl-c1">+</span>
  543. <span class="pl-s">`"my-repo/my-git-project" or a valid semver range. After making the `</span> <span class="pl-c1">+</span>
  544. <span class="pl-s">`change, run "<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">command</span><span class="pl-kos">}</span></span>" to update the package.`</span>
  545. <span class="pl-kos">)</span><span class="pl-kos">;</span>
  546. <span class="pl-s1">process</span><span class="pl-kos">.</span><span class="pl-en">exit</span><span class="pl-kos">(</span><span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
  547. </li>
  548. <li>
  549. <p>After some time, the master branch can be removed from the repository. This
  550. does not constitute a breaking change, as the package already ceased to
  551. function as of the previous commit. It was just a courteous message to ease
  552. confusion and provide actionable instructions for fixing the issue.</p>
  553. </li>
  554. </ol>
  555. <p>For most projects and organizations, this amount of notice is probably not
  556. necessary or warranted, but it showcases the available tools and techniques,
  557. and demonstrates that there can be a good migration path even under very strict
  558. compatibility requirements. As always, use these steps as a template and tailor
  559. them to your own needs.</p>
  560. <h2><a id="user-content-local-migration" class="anchor" aria-hidden="true" href="#local-migration"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>Local Migration</h2>
  561. <p>Finally, if you are working on a repository you don't control, and you would
  562. like to refer to your local branch with a different name without making any
  563. changes to the upstream project, you can rename your local "master" branch to
  564. "main" with these steps:</p>
  565. <div class="highlight highlight-source-shell"><pre>$ <span class="pl-c1">cd</span> my-git-project
  566. $ git checkout master
  567. $ git branch -m main
  568. $ git branch -u origin/master</pre></div>
  569. <p>This renames the local branch to "main" but sets the remote tracking branch to
  570. "master".</p>
  571. <h2><a id="user-content-license" class="anchor" aria-hidden="true" href="#license"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"/></svg></a>License</h2>
  572. <p>This content in this repository, including this documentation and code examples
  573. are licensed under the <a href="https://creativecommons.org/share-your-work/public-domain/cc0/" rel="nofollow">CC0 "No Rights Reserved"</a> public domain
  574. license. Feel free to reproduce and adapt this work into your own proposals,
  575. documentation, etc.</p>
  576. <p>Attribution is not necessary. However, this guide receives constant updates to
  577. reflect current best-practice and solutions based implementation feedback, so
  578. a reference to this repository may be helpful.</p>