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.html 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Setting Up Git Identities (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f0f0ea">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f0f0ea">
  26. <!-- Documented, feel free to shoot an email. -->
  27. <link rel="stylesheet" href="/static/david/css/style_2020-06-19.css">
  28. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  29. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <script type="text/javascript">
  36. function toggleTheme(themeName) {
  37. document.documentElement.classList.toggle(
  38. 'forced-dark',
  39. themeName === 'dark'
  40. )
  41. document.documentElement.classList.toggle(
  42. 'forced-light',
  43. themeName === 'light'
  44. )
  45. }
  46. const selectedTheme = localStorage.getItem('theme')
  47. if (selectedTheme !== 'undefined') {
  48. toggleTheme(selectedTheme)
  49. }
  50. </script>
  51. <meta name="robots" content="noindex, nofollow">
  52. <meta content="origin-when-cross-origin" name="referrer">
  53. <!-- Canonical URL for SEO purposes -->
  54. <link rel="canonical" href="https://www.micah.soy/posts/setting-up-git-identities/">
  55. <body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick">
  56. <article>
  57. <header>
  58. <h1>Setting Up Git Identities</h1>
  59. </header>
  60. <nav>
  61. <p class="center">
  62. <a href="/david/" title="Aller à l’accueil">🏠</a> •
  63. <a href="https://www.micah.soy/posts/setting-up-git-identities/" title="Lien vers le contenu original">Source originale</a>
  64. </p>
  65. </nav>
  66. <hr>
  67. <main>
  68. <p>Working on many projects across multiple identities can be difficult to manage. This is a procedure for leveraging git aliases to set an identity at the project level for any project with support for GPG-based commit signing.</p>
  69. <h3 id="first-remove-any-existing-global-identity">First, remove any existing global identity</h3>
  70. <div class="highlight"><pre><code class="language-shell" data-lang="shell">git config --global --unset user.name
  71. git config --global --unset user.email
  72. git config --global --unset user.signingkey
  73. </code></pre></div>
  74. <h3 id="require-config-to-exist-in-order-to-make-commits">Require config to exist in order to make commits</h3>
  75. <p>Without the global user name and user email, git would use the system’s hostname and username to make commits. Tell git to throw an error instead, requiring you to specify an identity for every new project.</p>
  76. <div class="highlight"><pre><code class="language-shell" data-lang="shell">git config --global user.useConfigOnly true
  77. </code></pre></div>
  78. <h3 id="for-each-identity-generate-gpg-keys">For each identity, generate GPG keys</h3>
  79. <p><img src="https://www.micah.soy/posts/setting-up-git-identities/keygen.png" alt="GPG key generation output"/></p>
  80. <p>Generate a GPG public/private key pair:</p>
  81. <p>Choose (1) RSA and RSA (default) key type. Choose key size of 4096 bits. Set the key to not expire (0) unless you want to repeat this step periodically. Finally, set your name and email address. Comment can be left blank.</p>
  82. <p>Once the key pair is generated we need to export the public key.</p>
  83. <h3 id="export-the-public-keys">Export the public keys</h3>
  84. <p><img src="https://www.micah.soy/posts/setting-up-git-identities/key-export.png" alt="GPG key export"/></p>
  85. <p><em>For each identity</em>, export the public key:</p>
  86. <div class="highlight"><pre><code class="language-shell" data-lang="shell">gpg --list-secret-keys --keyid-format LONG user@example.com
  87. </code></pre></div>
  88. <p>where <code>user@example.com</code> is the email address of the identity you just created.</p>
  89. <p>This will output a <code>sec</code> ID in the format of <code>rsa4096/[serial]</code>. Copy the serial number, then run this command to output the public key:</p>
  90. <div class="highlight"><pre><code class="language-shell" data-lang="shell">gpg --armor --export <span>[</span>serial<span>]</span>
  91. </code></pre></div>
  92. <p>Copy the public key block and add it to your Github or Gitlab settings. With the public key, Github and Gitlab can cryptographically verify your commits, placing a “Verified” label next to each.</p>
  93. <h3 id="set-global-git-config-identities">Set global git config identities</h3>
  94. <p>Now we need to create the identities in git’s global config. For example:</p>
  95. <div class="highlight"><pre><code class="language-shell" data-lang="shell">git config --global user.gitlab.name <span>"Your Name"</span>
  96. git config --global user.gitlab.email <span>"gitlab@example.com"</span>
  97. git config --global user.gitlab.signingkey 543166183AE7043A
  98. git config --global user.github.name <span>"Your Name"</span>
  99. git config --global user.github.email <span>"github@example.com"</span>
  100. git config --global user.github.signingkey BCF8B7A8C138D16B
  101. git config --global user.identity3.name <span>"Your Name"</span>
  102. git config --global user.identity3.email <span>"identity3@example.com"</span>
  103. git config --global user.identity3.signingkey 4F3FFC37B1A027BD
  104. git config --global user.identity4.name <span>"Your Name"</span>
  105. git config --global user.identity4.email <span>"identity4@example.com"</span>
  106. git config --global user.identity4.signingkey D921F8BA473CF1FC
  107. </code></pre></div>
  108. <h3 id="create-git-alias">Create git alias</h3>
  109. <p>Setting a git alias will give us a new git command to use to set the identity at a project level. This really is just a script that sets a particular global identity to the local config.</p>
  110. <div class="highlight"><pre><code class="language-shell" data-lang="shell">git config --global alias.identity <span>'! git config user.name "$(git config user.$1.name)"; git config user.email "$(git config user.$1.email)"; git config user.signingkey "$(git config user.$1.signingkey)"; :'</span>
  111. </code></pre></div>
  112. <h3 id="specify-git-identity">Specify git identity</h3>
  113. <p>For each project, specify the git identity to use:</p>
  114. <div class="highlight"><pre><code class="language-shell" data-lang="shell">$ cd /path/to/git/repo
  115. $ git config user.email <span># should be no response</span>
  116. $ git config user.github.email
  117. github@example.com
  118. $ git identity github
  119. $ git config user.email
  120. github@example.com
  121. </code></pre></div>
  122. <p>That’s it! Now whenever you start a new project or work on an existing project, you can be confident that the correct name, email address, and GPG signing key are being used.</p>
  123. </main>
  124. </article>
  125. <hr>
  126. <footer>
  127. <p>
  128. <a href="/david/" title="Aller à l’accueil">🏠</a> •
  129. <a href="/david/log/" title="Accès au flux RSS">🤖</a> •
  130. <a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> •
  131. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> •
  132. <abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr>
  133. </p>
  134. <template id="theme-selector">
  135. <form>
  136. <fieldset>
  137. <legend>Thème</legend>
  138. <label>
  139. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  140. </label>
  141. <label>
  142. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  143. </label>
  144. <label>
  145. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  146. </label>
  147. </fieldset>
  148. </form>
  149. </template>
  150. </footer>
  151. <script type="text/javascript">
  152. function loadThemeForm(templateName) {
  153. const themeSelectorTemplate = document.querySelector(templateName)
  154. const form = themeSelectorTemplate.content.firstElementChild
  155. themeSelectorTemplate.replaceWith(form)
  156. form.addEventListener('change', (e) => {
  157. const chosenColorScheme = e.target.value
  158. localStorage.setItem('theme', chosenColorScheme)
  159. toggleTheme(chosenColorScheme)
  160. })
  161. const selectedTheme = localStorage.getItem('theme')
  162. if (selectedTheme && selectedTheme !== 'undefined') {
  163. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  164. }
  165. }
  166. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  167. window.addEventListener('load', () => {
  168. let hasDarkRules = false
  169. for (const styleSheet of Array.from(document.styleSheets)) {
  170. let mediaRules = []
  171. for (const cssRule of styleSheet.cssRules) {
  172. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  173. continue
  174. }
  175. // WARNING: Safari does not have/supports `conditionText`.
  176. if (cssRule.conditionText) {
  177. if (cssRule.conditionText !== prefersColorSchemeDark) {
  178. continue
  179. }
  180. } else {
  181. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  182. continue
  183. }
  184. }
  185. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  186. }
  187. // WARNING: do not try to insert a Rule to a styleSheet you are
  188. // currently iterating on, otherwise the browser will be stuck
  189. // in a infinite loop…
  190. for (const mediaRule of mediaRules) {
  191. styleSheet.insertRule(mediaRule.cssText)
  192. hasDarkRules = true
  193. }
  194. }
  195. if (hasDarkRules) {
  196. loadThemeForm('#theme-selector')
  197. }
  198. })
  199. </script>
  200. </body>
  201. </html>