@@ -0,0 +1,823 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="fr"> | |||
<!-- Has to be within the first 1024 bytes, hence before the <title> | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>Git Branch Rename (archive) — David Larlet</title> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f0f0ea"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f0f0ea"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2020-06-19.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script type="text/javascript"> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="https://github.com/chancancode/branch-rename/blob/main/README.md"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick"> | |||
<article> | |||
<h1>Git Branch Rename</h1> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil" tabindex="1">🏠</a> | |||
</p> | |||
</nav> | |||
<hr> | |||
<h2><a href="https://github.com/chancancode/branch-rename/blob/main/README.md">Source originale du contenu</a></h2> | |||
<p>So, you want to rename a branch on Git/GitHub. The most common case of this is | |||
to rename the default "master" branch to something else, such as "main". We are | |||
going to use this as our example, but you may have a different use case in | |||
mind. If that's the case, just replace "master" and "main" to the source and | |||
target branches you have in mind.</p> | |||
<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> | |||
<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> | |||
<p>If you are starting a brand new project, you can follow these steps:</p> | |||
<ol> | |||
<li> | |||
<p><a href="https://github.com/new">Create a new repository on GitHub</a> to host your | |||
project with the following settings:</p> | |||
<ul> | |||
<li><strong>Repository template</strong>: No template</li> | |||
<li><strong>Initialize this repository with a README</strong>: Leave unchecked</li> | |||
<li><strong>Add .gitignore</strong>: None</li> | |||
<li><strong>Add a license</strong>: None</li> | |||
</ul> | |||
<p>If you wish to use any of these features (i.e. with settings different than | |||
the above), that is not a problem. However, GitHub will create the default | |||
"master" branch for you. In that case, clone the repository locally and | |||
follow the steps in the <a href="#simple-migration"><strong>Simple Migration</strong></a> section | |||
instead.</p> | |||
</li> | |||
<li> | |||
<p>Initialize an empty Git repository:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ mkdir my-git-project | |||
$ <span class="pl-c1">cd</span> my-git-project | |||
$ git init <span class="pl-c1">.</span></pre></div> | |||
</li> | |||
<li> | |||
<p>Create the "main" branch:</p> | |||
</li> | |||
<li> | |||
<p>Work on your project and commit some changes. For example, add a README:</p> | |||
<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">>></span> README.md | |||
$ git add README.md | |||
$ git commit -m <span class="pl-s"><span class="pl-pds">"</span>Initial commit<span class="pl-pds">"</span></span></pre></div> | |||
</li> | |||
<li> | |||
<p>Push your commits to GitHub:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ git remote add origin https://github.com/your-username/my-git-project.git | |||
$ git push -u origin main</pre></div> | |||
</li> | |||
</ol> | |||
<p>That's all! Since "main" was the first branch you pushed to GitHub, it will be | |||
set correctly as the default branch. We also never committed any changes to the | |||
"master" branch locally, it effectively never existed so there is nothing left | |||
to clean up. Enjoy your new project!</p> | |||
<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> | |||
<p>If you have a small personal project and you are comfortable with just doing | |||
the rename right away, here are the steps you can take.</p> | |||
<p>Note that if this is a <a href="https://pages.github.com">GitHub Pages</a> repository and | |||
the content is stored on the "master" branch, then you cannot perform the | |||
migration at this time since GitHub Pages does not seem to support alternative | |||
default branch names yet. If you want, you may follow the steps in the <a href="#local-migration"><strong>Local | |||
Migration</strong></a> or <a href="#gradual-migration"><strong>Gradual Migration</strong></a> | |||
section partially to get your project ready.</p> | |||
<ol> | |||
<li> | |||
<p>Pull the latest commits from the "master" branch into your local repository:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ <span class="pl-c1">cd</span> my-git-project | |||
$ git checkout master | |||
$ git pull origin master</pre></div> | |||
</li> | |||
<li> | |||
<p>Rename the local "master" branch to "main":</p> | |||
</li> | |||
<li> | |||
<p>Push the "main" branch to GitHub:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ git push -u origin main</pre></div> | |||
</li> | |||
<li> | |||
<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> | |||
</li> | |||
<li> | |||
<p>If there are existing pull requests open against the "master" branch that | |||
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 | |||
the "main" branch. Otherwise, they will be closed automatically when we | |||
delete the remote "master" branch on GitHub.</p> | |||
</li> | |||
<li> | |||
<p>Delete your local "master" branch:</p> | |||
</li> | |||
<li> | |||
<p>Delete the remote "master" branch:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ git push origin :master</pre></div> | |||
</li> | |||
</ol> | |||
<p>At this point, the migration is complete. However, as you work on the project, | |||
you may discover additional settings that you need to tweak to account for the | |||
rename. For example, you may have update the branch names in your CI config.</p> | |||
<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> | |||
<p>If you have a work or open-source repository with multiple contributors and | |||
forks, you may prefer to perform the migration gradually.</p> | |||
<p>These steps are for you if you find yourself in a similar scenario, where it is | |||
important to give everyone ample of time to prepare for the migration, changing | |||
local configs, adapting workflows, scripts and other automation to ensure a | |||
seamless migration.</p> | |||
<p>This gradual migration plan is intended to be spread out over a long period of | |||
time – weeks, or months. It uses all available tools on GitHub to provide as | |||
much advance notice as possible.</p> | |||
<p>For most organizations, this plan may be overly cautious and some of the steps | |||
may not be necessary. On the other hand, for a popular open-source project, it | |||
may not be feasible to get to the end and fully deprecate and remove the legacy | |||
"master" branch at all, due to compatibility requirements. Treat this plan as a | |||
template and adapt it for your own needs.</p> | |||
<p>Unlike the other sections, the steps here are a bit less exact and is intended | |||
for someone with a some prior experience with Git and GitHub. In practice, you | |||
will probably run into situations that causes deviations from the plan which | |||
would require some manual repair and adjustments. For example, pushes during a | |||
partial GitHub outage may cause the two branches to diverge and requires you | |||
to determine how to best reconcile the differences.</p> | |||
<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> | |||
<p>The goal of this phase is to make it <em>possible</em> to use the "main" branch name | |||
as an alternative. This allows some early adopters to start testing the new | |||
setup.</p> | |||
<ol> | |||
<li> | |||
<p>As always, make sure your local "master" branch is up-to-date.</p> | |||
</li> | |||
<li> | |||
<p>Create the new "main" branch:</p> | |||
</li> | |||
<li> | |||
<p>Add a <a href="https://github.com/features/actions">GitHub Actions</a> workflow file at | |||
<strong>.github/workflows/mirror-master-and-main.yml</strong> with the following:</p> | |||
<div class="highlight highlight-source-yaml"><pre><span class="pl-ent">name</span>: <span class="pl-s">Mirror "master" and "main" branches</span> | |||
<span class="pl-ent">on</span>: | |||
<span class="pl-ent">push</span>: | |||
<span class="pl-ent">branches</span>: | |||
- <span class="pl-s">master</span> | |||
- <span class="pl-s">main</span> | |||
<span class="pl-ent">jobs</span>: | |||
<span class="pl-ent">mirror</span>: | |||
<span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span> | |||
<span class="pl-ent">steps</span>: | |||
- <span class="pl-ent">name</span>: <span class="pl-s">Mirror to "master"</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">zofrex/mirror-branch@v1</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">target-branch</span>: <span class="pl-s">master</span> | |||
<span class="pl-ent">force</span>: <span class="pl-c1">false</span> | |||
- <span class="pl-ent">name</span>: <span class="pl-s">Mirror to "main"</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">zofrex/mirror-branch@v1</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">target-branch</span>: <span class="pl-s">main</span> | |||
<span class="pl-ent">force</span>: <span class="pl-c1">false</span></pre></div> | |||
</li> | |||
<li> | |||
<p>Commit and your changes to the local "main" branch.</p> | |||
</li> | |||
<li> | |||
<p>Push your changes to the remote "main" branch:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ git push -u origin main</pre></div> | |||
</li> | |||
</ol> | |||
<p>If things are working correctly, you should see the same commit pushed to the | |||
"master" branch shortly. You can monitor the progress and unexpected errors in | |||
the "Actions" tab in your repository.</p> | |||
<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> | |||
<p>You do not have to be already using GitHub Actions for this to work. You do not | |||
need to activate or enable the feature for your repository, simply pushing the | |||
workflow file to the is sufficient. All open-source repositories have unlimited | |||
GitHub Actions minutes, and all personal and team accounts comes with 2000-3000 | |||
free GitHub Actions minutes for private repositories.</p> | |||
<p>If you already regularly uses up your free minutes, this may slightly increase | |||
your GitHub bills, but in practice, the workflow we added runs very quickly so | |||
the impact is very minimal. For reference, GitHub Actions are billed at $0.008 | |||
USD per minute for private repositories, after the free quota is exhausted.</p> | |||
<p>This workflow will be triggered when commits are pushed to either the "master" | |||
or "main" branch. It uses the <a href="https://github.com/marketplace/actions/mirror-branch">Mirror Branch action</a> to | |||
update the branches using GitHub's API.</p> | |||
<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> | |||
<p>Unfortunately, if you have enabled <a href="https://help.github.com/en/github/administering-a-repository/configuring-protected-branches">branch protection</a> on | |||
the "master" branch, the push from the mirroring action may be rejected. For | |||
example, if you had enabled "Require pull request reviews before merging", then | |||
this would not work as the changes are expected to be submitted via a pull | |||
request with reviews.</p> | |||
<p>A possible workaround is to disable the "Include administrators" checkbox in | |||
the branch protection settings for the "master" branch and configure the script | |||
to push the commits as an administrator:</p> | |||
<ol> | |||
<li> | |||
<p>Login as an administrator on GitHub. You may also want to consider creating | |||
a new account specifically for this purpose.</p> | |||
</li> | |||
<li> | |||
<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" | |||
scope (and the "public_repo" scope, if needed).</p> | |||
</li> | |||
<li> | |||
<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> | |||
</li> | |||
<li> | |||
<p>Change the "Checkout" step in the mirror workflow to use the new deploy key:</p> | |||
<div class="highlight highlight-source-yaml"><pre>- <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v2</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">token</span>: <span class="pl-s">${{ secrets.DEPLOY_TOKEN }}</span></pre></div> | |||
<p>Here, <code>DEPLOY_TOKEN</code> is the name you picked from step 3.</p> | |||
</li> | |||
</ol> | |||
<p>Alternatively, an SSH key for the administrator can be used instead of a | |||
personal access token, via the <code>ssh-key</code> argument. See the documentation for | |||
the <a href="https://github.com/actions/checkout">checkout action</a> for more details.</p> | |||
<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> | |||
<p>By default, when pushing commits from within the GitHub Actions job, it does | |||
not trigger additional GitHub Actions workflow to run. For example, when a | |||
contributor pushes to the "main" branch, it will trigger any GitHub Actions | |||
that normally runs on the "main" branch's push events, including the one we | |||
added here. However, when our mirror workflow pushes the same commit to the | |||
"master" branch, it will not trigger any workflow that normally runs on the | |||
"master" branch's push events.</p> | |||
<p>For this reason, you may want to update existing workflows that runs on the | |||
"master" branch to also run on the "main" branch, as we did in our mirror | |||
workflow file (the <code>on.push.branches</code> config key). This is the recommended | |||
approach as it ensures only a single build per push.</p> | |||
<p>Alternatively, if it is important to you that workflows are triggered by pushes | |||
from the mirror workflow, you can accomplish this by supplying an alternative | |||
SSH key to the <a href="https://github.com/actions/checkout">checkout action</a>:</p> | |||
<ol> | |||
<li> | |||
<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 | |||
it to the ssh-agent.</p> | |||
</li> | |||
<li> | |||
<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> | |||
to the repository. Be sure to select "Allow write access".</p> | |||
</li> | |||
<li> | |||
<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 | |||
repository.</p> | |||
</li> | |||
<li> | |||
<p>Change the "Checkout" step in the mirror workflow to use the new deploy key:</p> | |||
<div class="highlight highlight-source-yaml"><pre>- <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v2</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">ssh-key</span>: <span class="pl-s">${{ secrets.DEPLOY_KEY }}</span></pre></div> | |||
<p>Here, <code>DEPLOY_KEY</code> is the name you picked from step 3.</p> | |||
</li> | |||
</ol> | |||
<p>With this, the mirror workflow will authenticate with GitHub using the deploy | |||
key instead of the default token when pushing commits, triggering any workflows | |||
as if a regular user had pushed those commits. This does not change the author | |||
or committer on the commits.</p> | |||
<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> | |||
<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> | |||
for an example of this working in action. Note that the code in the commit may | |||
be outdated by the time you read this – refer to the above for the latest | |||
instructions.</p> | |||
<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> | |||
<p>After verifying that everything is working as intended, you can start inviting | |||
the early adopters to start pushing to the "main" branch. The easiest way to do | |||
this is to rename the local "master" branch:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ <span class="pl-c1">cd</span> my-git-project | |||
$ git checkout master | |||
$ git branch -m main | |||
$ git branch -u origin/main</pre></div> | |||
<p>This would also be a good time to start changing any automation or external | |||
services to the "main" branch to ensure that everything is working as expected.</p> | |||
<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> | |||
<p>After verifying the viability of the rename during the previous phase, the goal | |||
of this phase is to set "main" as the default branch and start issuing | |||
deprecation warnings when the legacy "master" branch is used.</p> | |||
<ol> | |||
<li> | |||
<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> | |||
</li> | |||
<li> | |||
<p>Add a <a href="https://github.com/features/actions">GitHub Actions</a> workflow file at | |||
<strong>.github/workflows/deprecate-master-branch.yml</strong> with the following:</p> | |||
<div class="highlight highlight-source-yaml"><pre><span class="pl-ent">name</span>: <span class="pl-s">Deprecate "master" branch</span> | |||
<span class="pl-ent">on</span>: | |||
<span class="pl-ent">push</span>: | |||
<span class="pl-ent">branches</span>: | |||
- <span class="pl-s">master</span> | |||
<span class="pl-ent">pull_request</span>: | |||
<span class="pl-ent">branches</span>: | |||
- <span class="pl-s">master</span> | |||
<span class="pl-ent">jobs</span>: | |||
<span class="pl-ent">on-push</span>: | |||
<span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span> | |||
<span class="pl-ent">if</span>: <span class="pl-s">${{ github.event_name == 'push' }}</span> | |||
<span class="pl-ent">steps</span>: | |||
- <span class="pl-ent">name</span>: <span class="pl-s">Deprecation</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/commit-comment@v1</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">body</span>: <span class="pl-s">|</span> | |||
<span class="pl-s"> Hello @${{ github.event.sender.login }}!</span> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> :warning: **The "master" branch is deprecated and will be removed from this repository in the future.**</span> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> Please migrate your local repository by renaming the "master" branch to "main":</span> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> ```bash</span> | |||
<span class="pl-s"> $ cd my-git-project</span> | |||
<span class="pl-s"> $ git checkout master</span> | |||
<span class="pl-s"> $ git branch -m main</span> | |||
<span class="pl-s"> $ git branch -u origin/main</span> | |||
<span class="pl-s"> ```</span> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> | |||
<span class="pl-s"/> <span class="pl-ent">on-pull-request</span>: | |||
<span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span> | |||
<span class="pl-ent">if</span>: <span class="pl-s">${{ github.event_name == 'pull_request' }}</span> | |||
<span class="pl-ent">env</span>: | |||
<span class="pl-ent">DEPRECATION_MESSAGE</span>: <span class="pl-s">|</span> | |||
<span class="pl-s"> Hello @${{ github.event.sender.login }}!</span> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> :warning: **The "master" branch is deprecated and will be removed from this repository in the future.**</span> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> Please migrate your local repository by renaming the "master" branch to "main":</span> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> ```bash</span> | |||
<span class="pl-s"> $ cd my-git-project</span> | |||
<span class="pl-s"> $ git checkout master</span> | |||
<span class="pl-s"> $ git branch -m main</span> | |||
<span class="pl-s"> $ git branch -u origin/main</span> | |||
<span class="pl-s"> ```</span> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> <span class="pl-ent">steps</span>: | |||
- <span class="pl-ent">name</span>: <span class="pl-s">Deprecation</span> | |||
<span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.pull_request.head.repo.fork == false }}</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/create-or-update-comment@v1</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">issue-number</span>: <span class="pl-s">${{ github.event.number }}</span> | |||
<span class="pl-ent">body</span>: <span class="pl-s">${{ env.DEPRECATION_MESSAGE }}</span> | |||
- <span class="pl-ent">name</span>: <span class="pl-s">Deprecation</span> | |||
<span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.pull_request.head.repo.fork == true }}</span> | |||
<span class="pl-ent">run</span>: <span class="pl-s">|</span> | |||
<span class="pl-s"> echo "$DEPRECATION_MESSAGE"</span> | |||
<span class="pl-s"> echo '::error::Please set the base branch for this pull request to "main" instead of "master".'</span> | |||
<span class="pl-s"> exit 1</span></pre></div> | |||
</li> | |||
<li> | |||
<p>Commit and push your changes to the "main" branch.</p> | |||
</li> | |||
</ol> | |||
<p>We added a workflow file that triggers whenever a contributor pushes to or | |||
opens a pull request against the "master" branch.</p> | |||
<p>The workflow adds a comment to the commit or pull request, notifying the | |||
contributor that the "master" branch has been deprecated, along with the steps | |||
they need to take to migrate their local repository and changes they need to | |||
make it to the pull request.</p> | |||
<p>It is recommended that you customize the messages with additional information | |||
relevant for your organization. For example, you may want to include a link to | |||
a tracking issue for additional context, or ways for the contributor to ask for | |||
additional assistance if needed.</p> | |||
<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> | |||
<p>Unfortunately, due to limitations of GitHub Actions, it is not possible to add | |||
a pull request comment from the workflow when the pull request originated from | |||
a fork, which is very common in open-source repositories. As a workaround, the | |||
workflow prints the deprecation message to the logs and fails the build.</p> | |||
<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> | |||
<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 | |||
example of this working in action. Note that the code in the commit may be | |||
outdated by the time you read this – refer to the above for the latest | |||
instructions.</p> | |||
<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> | |||
<p>This would be a good time to start updating any internal and external links to | |||
the "master" branch. A common example would be automatically generated links to | |||
source code from the API documentation.</p> | |||
<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> | |||
<p>After a successful phase 2 rollout, it is time to plan for completing the | |||
migration. However, what completion means is going to be different depending on | |||
your situation.</p> | |||
<p>For private work repositories, the legacy "master" branch can likely be removed | |||
from the repository after giving team members a few weeks to migrate. Don't | |||
forget to remove the workflow files as well.</p> | |||
<p>For open-source repositories with lots of contributors, you may want to move a | |||
lot slower. Monitor the Actions tab of the repository to see how often the | |||
deprecation workflow is triggered. When the activity diminishes, it may be good | |||
indication that the legacy "master" branch is no longer needed.</p> | |||
<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> | |||
<p>As an alternative to removing the branch right away, you may want to consider | |||
pushing a final commit to the branch, removing all files but leave behind a | |||
README file explaining that branch has been moved, along with the steps they | |||
need to take in order to migrate their local repository.</p> | |||
<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> | |||
<p>It is also important to consider URL breakages, as links that points to the | |||
files on the "master" branch will stop working once the branch is removed, | |||
including with the soft-removal method described above.</p> | |||
<p>The impact of this has to be evaluated contextually, but it is important to | |||
note that the scope of the breakage is fairly limited, as this only directly | |||
impacts URLs that links to the "master" branch directly. Links pointing to the | |||
active development branch of repository is quite fragile (especially with line | |||
numbers) and often breaks for other reasons.</p> | |||
<p>For example, a refactor that moves around files or switching from JavaScript to | |||
TypeScript would invalidate these URLs. This sort of activity is fairly common | |||
on an active code repository and is usually performed without taking the URL | |||
consideration in mind. For this reason, it is considered a best practice to use | |||
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 | |||
are unaffected by the branch rename.</p> | |||
<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> | |||
<p>For repositories containing <em>installable packages</em>, there are some additional | |||
considerations. Many package managers allow for installing packages from a Git | |||
repository. For example, in npm and yarn, dependencies can be a string like | |||
"username/repo" or "username/repo#branch" in lieu of version range. Likewise, | |||
GitHub Actions are installed using repository and branch references, and it is | |||
a relatively common practice to point an action at the "master" branch.</p> | |||
<p>In these cases, the decision on whether to remove the legacy "master" branch | |||
has to be made carefully. Here are some examples of things to investigate | |||
and consider:</p> | |||
<ul> | |||
<li> | |||
<p>When the branch is omitted from the specifier (e.g. "username/repo"), does | |||
the package manager in your ecosystem hard-code the default to "master" on | |||
the client, or does it respect the remote HEAD ref?</p> | |||
</li> | |||
<li> | |||
<p>Does the package manager use a lockfile, and if so, does it serialize the | |||
branch name (as opposed to the resolved SHA) into the lockfile?</p> | |||
</li> | |||
<li> | |||
<p>Does the package manager maintain a cache of cloned repositories, and if so | |||
do they recover gracefully to a remote branch disappearing?</p> | |||
</li> | |||
</ul> | |||
<p>The answer to these questions affects the potential impact to your end-users | |||
if the legacy "master" branch is removed from the repository. For some, the | |||
end-state of the migration may be to keep the "master" branch permanently as a | |||
read-only mirror, or it may be sufficient to freeze the branch's content and | |||
stop providing updates there. For others, the potential breakage maybe small | |||
enough that it is can be easily justified.</p> | |||
<p>While the workflows added in phase 2 are effective for deprecating <em>writes</em> to | |||
the legacy "master" branch. Unfortunately, Git and GitHub do not offer the | |||
ability to do the same for <em>reads</em> to the branch.</p> | |||
<p>However, you may be able to use features from the package manager to accomplish | |||
a similar result. For example, instead of mirroring the "main" branch to the | |||
"master" branch exactly, you could add a post-install hook to the version on | |||
"master" to issue the deprecation message for any potential consumers.</p> | |||
<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> | |||
<p>Using the Node.js ecosystem as an example, we can put these considerations into | |||
context, based on preliminary testing with npm and yarn classic (v1). If you | |||
found different results in your own testing, or with other package managers | |||
(pnpm, yarn v2, etc), please file an issue here.</p> | |||
<ul> | |||
<li> | |||
<p>The popular package managers in the ecosystem support installing packages | |||
from git, by specifying "username/repo" or "username/repo#branch" in the | |||
dependencies section of package.json.</p> | |||
</li> | |||
<li> | |||
<p>When a branch name is not specified, the popular package managers defaults to | |||
the remote HEAD ref, which is set by the default branch on GitHub, instead of | |||
hardcoding to the "master" branch in the client.</p> | |||
</li> | |||
<li> | |||
<p>The popular package managers uses a lockfile by default. They serialize the | |||
resolved SHA into the lockfiles, as long as the commits referred to by these | |||
SHAs remain reachable on the remote repository, they will install just fine | |||
when using a lockfile. In the case of a branch rename, this is not an issue, | |||
as the history and commits will remain intact.</p> | |||
</li> | |||
<li> | |||
<p>When installing without a lockfile, the popular package managers will fetch | |||
the latest commit from the repository. Renaming the remote branch did not | |||
appear to cause any issues, either because the repositories are not cached, | |||
or the clients are able to recover gracefully from a "missing" remote branch.</p> | |||
</li> | |||
<li> | |||
<p>Post-install hooks are supported. However, yarn classic <a href="https://github.com/yarnpkg/yarn/issues/5476">hides the output | |||
produced by these scripts</a> if | |||
they are successful (exit cleanly with exit code 0). However, when they fail, | |||
they output <em>is</em> shown to the user.</p> | |||
</li> | |||
<li> | |||
<p>Generally speaking, the ecosystem has strong norms and expectations around | |||
adhering to <a href="https://semver.org" rel="nofollow">semantic versioning</a>. Usually, breaking changes are only | |||
expected on major version bumps.</p> | |||
</li> | |||
<li> | |||
<p>By using a Git dependency instead of specifying a semver range, they are | |||
explicitly opting out of the normal semver guarantee, and breakages are to be | |||
expected. No one could reasonably expect that pointing a dependency to the | |||
active development branch without using a lockfile will result in a stable | |||
system.</p> | |||
</li> | |||
</ul> | |||
<p>Given these findings, here is a concrete proposal for a maximally graceful | |||
completion plan:</p> | |||
<ol> | |||
<li> | |||
<p>Stop providing updates to the "master" branch by removing the mirroring | |||
workflow added in phase 1.</p> | |||
</li> | |||
<li> | |||
<p>Push a commit the "master" branch, updating the README as well as adding a | |||
deprecation message to the runtime code (the <code>main</code> entry point):</p> | |||
<div class="highlight highlight-source-js"><pre><span class="pl-c">// index.js</span> | |||
<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> | |||
<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">&&</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> | |||
<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> | |||
<span class="pl-kos">}</span> | |||
<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">warn</span><span class="pl-kos">(</span> | |||
<span class="pl-s">`You are running a deprecated copy of the "my-git-project" installed `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`from the "master" branch of our repository. The "master" branch is `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`deprecated and no longer receives any updates. The branch will soon `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`be removed from our repository, at which point the package will fail `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`to install.\n\n`</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`To fix this issue, please modify your package.json and change the `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`"my-git-project" dependency from "my-repo/my-git-project#master" to `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`"my-repo/my-git-project" or a valid semver range. After making the `</span> <span class="pl-c1">+</span> | |||
<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> | |||
<span class="pl-kos">)</span><span class="pl-kos">;</span> | |||
<span class="pl-c">// ...rest of index.js</span></pre></div> | |||
</li> | |||
<li> | |||
<p>When releasing the next major version of the package, push another commit to | |||
the "master" branch, remove all files from the branch, leaving behind only a | |||
minimal README file, package.json and index.js:</p> | |||
<div class="highlight highlight-source-js"><pre><span class="pl-c">// package.json</span> | |||
<span class="pl-kos">{</span> | |||
<span class="pl-s">"name"</span>: <span class="pl-s">"my-git-project"</span><span class="pl-kos">,</span> | |||
<span class="pl-s">"scripts"</span>: <span class="pl-kos">{</span> | |||
<span class="pl-s">"postinstall"</span>: <span class="pl-s">"node index.js"</span> | |||
<span class="pl-kos">}</span> | |||
<span class="pl-kos">}</span></pre></div> | |||
<div class="highlight highlight-source-js"><pre><span class="pl-c">// index.js</span> | |||
<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> | |||
<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">&&</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> | |||
<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> | |||
<span class="pl-kos">}</span> | |||
<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">error</span><span class="pl-kos">(</span> | |||
<span class="pl-s">`You have installed "my-git-project" from the "master" branch of our `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`repository. The "master" branch has been official retired.\n\n`</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`To fix this issue, please modify your package.json and change the `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`"my-git-project" dependency from "my-repo/my-git-project#master" to `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`"my-repo/my-git-project" or a valid semver range. After making the `</span> <span class="pl-c1">+</span> | |||
<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> | |||
<span class="pl-kos">)</span><span class="pl-kos">;</span> | |||
<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> | |||
</li> | |||
<li> | |||
<p>After some time, the master branch can be removed from the repository. This | |||
does not constitute a breaking change, as the package already ceased to | |||
function as of the previous commit. It was just a courteous message to ease | |||
confusion and provide actionable instructions for fixing the issue.</p> | |||
</li> | |||
</ol> | |||
<p>For most projects and organizations, this amount of notice is probably not | |||
necessary or warranted, but it showcases the available tools and techniques, | |||
and demonstrates that there can be a good migration path even under very strict | |||
compatibility requirements. As always, use these steps as a template and tailor | |||
them to your own needs.</p> | |||
<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> | |||
<p>Finally, if you are working on a repository you don't control, and you would | |||
like to refer to your local branch with a different name without making any | |||
changes to the upstream project, you can rename your local "master" branch to | |||
"main" with these steps:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ <span class="pl-c1">cd</span> my-git-project | |||
$ git checkout master | |||
$ git branch -m main | |||
$ git branch -u origin/master</pre></div> | |||
<p>This renames the local branch to "main" but sets the remote tracking branch to | |||
"master".</p> | |||
<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> | |||
<p>This content in this repository, including this documentation and code examples | |||
are licensed under the <a href="https://creativecommons.org/share-your-work/public-domain/cc0/" rel="nofollow">CC0 "No Rights Reserved"</a> public domain | |||
license. Feel free to reproduce and adapt this work into your own proposals, | |||
documentation, etc.</p> | |||
<p>Attribution is not necessary. However, this guide receives constant updates to | |||
reflect current best-practice and solutions based implementation feedback, so | |||
a reference to this repository may be helpful.</p> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil">🏠</a> • | |||
<a href="/david/log/" title="Accès au flux RSS">🤖</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> • | |||
<abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script type="text/javascript"> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,594 @@ | |||
title: Git Branch Rename | |||
url: https://github.com/chancancode/branch-rename/blob/main/README.md | |||
hash_url: 240b647e699da81b505d43af39257996 | |||
<p>So, you want to rename a branch on Git/GitHub. The most common case of this is | |||
to rename the default "master" branch to something else, such as "main". We are | |||
going to use this as our example, but you may have a different use case in | |||
mind. If that's the case, just replace "master" and "main" to the source and | |||
target branches you have in mind.</p> | |||
<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> | |||
<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> | |||
<p>If you are starting a brand new project, you can follow these steps:</p> | |||
<ol> | |||
<li> | |||
<p><a href="https://github.com/new">Create a new repository on GitHub</a> to host your | |||
project with the following settings:</p> | |||
<ul> | |||
<li><strong>Repository template</strong>: No template</li> | |||
<li><strong>Initialize this repository with a README</strong>: Leave unchecked</li> | |||
<li><strong>Add .gitignore</strong>: None</li> | |||
<li><strong>Add a license</strong>: None</li> | |||
</ul> | |||
<p>If you wish to use any of these features (i.e. with settings different than | |||
the above), that is not a problem. However, GitHub will create the default | |||
"master" branch for you. In that case, clone the repository locally and | |||
follow the steps in the <a href="#simple-migration"><strong>Simple Migration</strong></a> section | |||
instead.</p> | |||
</li> | |||
<li> | |||
<p>Initialize an empty Git repository:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ mkdir my-git-project | |||
$ <span class="pl-c1">cd</span> my-git-project | |||
$ git init <span class="pl-c1">.</span></pre></div> | |||
</li> | |||
<li> | |||
<p>Create the "main" branch:</p> | |||
</li> | |||
<li> | |||
<p>Work on your project and commit some changes. For example, add a README:</p> | |||
<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">>></span> README.md | |||
$ git add README.md | |||
$ git commit -m <span class="pl-s"><span class="pl-pds">"</span>Initial commit<span class="pl-pds">"</span></span></pre></div> | |||
</li> | |||
<li> | |||
<p>Push your commits to GitHub:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ git remote add origin https://github.com/your-username/my-git-project.git | |||
$ git push -u origin main</pre></div> | |||
</li> | |||
</ol> | |||
<p>That's all! Since "main" was the first branch you pushed to GitHub, it will be | |||
set correctly as the default branch. We also never committed any changes to the | |||
"master" branch locally, it effectively never existed so there is nothing left | |||
to clean up. Enjoy your new project!</p> | |||
<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> | |||
<p>If you have a small personal project and you are comfortable with just doing | |||
the rename right away, here are the steps you can take.</p> | |||
<p>Note that if this is a <a href="https://pages.github.com">GitHub Pages</a> repository and | |||
the content is stored on the "master" branch, then you cannot perform the | |||
migration at this time since GitHub Pages does not seem to support alternative | |||
default branch names yet. If you want, you may follow the steps in the <a href="#local-migration"><strong>Local | |||
Migration</strong></a> or <a href="#gradual-migration"><strong>Gradual Migration</strong></a> | |||
section partially to get your project ready.</p> | |||
<ol> | |||
<li> | |||
<p>Pull the latest commits from the "master" branch into your local repository:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ <span class="pl-c1">cd</span> my-git-project | |||
$ git checkout master | |||
$ git pull origin master</pre></div> | |||
</li> | |||
<li> | |||
<p>Rename the local "master" branch to "main":</p> | |||
</li> | |||
<li> | |||
<p>Push the "main" branch to GitHub:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ git push -u origin main</pre></div> | |||
</li> | |||
<li> | |||
<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> | |||
</li> | |||
<li> | |||
<p>If there are existing pull requests open against the "master" branch that | |||
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 | |||
the "main" branch. Otherwise, they will be closed automatically when we | |||
delete the remote "master" branch on GitHub.</p> | |||
</li> | |||
<li> | |||
<p>Delete your local "master" branch:</p> | |||
</li> | |||
<li> | |||
<p>Delete the remote "master" branch:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ git push origin :master</pre></div> | |||
</li> | |||
</ol> | |||
<p>At this point, the migration is complete. However, as you work on the project, | |||
you may discover additional settings that you need to tweak to account for the | |||
rename. For example, you may have update the branch names in your CI config.</p> | |||
<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> | |||
<p>If you have a work or open-source repository with multiple contributors and | |||
forks, you may prefer to perform the migration gradually.</p> | |||
<p>These steps are for you if you find yourself in a similar scenario, where it is | |||
important to give everyone ample of time to prepare for the migration, changing | |||
local configs, adapting workflows, scripts and other automation to ensure a | |||
seamless migration.</p> | |||
<p>This gradual migration plan is intended to be spread out over a long period of | |||
time – weeks, or months. It uses all available tools on GitHub to provide as | |||
much advance notice as possible.</p> | |||
<p>For most organizations, this plan may be overly cautious and some of the steps | |||
may not be necessary. On the other hand, for a popular open-source project, it | |||
may not be feasible to get to the end and fully deprecate and remove the legacy | |||
"master" branch at all, due to compatibility requirements. Treat this plan as a | |||
template and adapt it for your own needs.</p> | |||
<p>Unlike the other sections, the steps here are a bit less exact and is intended | |||
for someone with a some prior experience with Git and GitHub. In practice, you | |||
will probably run into situations that causes deviations from the plan which | |||
would require some manual repair and adjustments. For example, pushes during a | |||
partial GitHub outage may cause the two branches to diverge and requires you | |||
to determine how to best reconcile the differences.</p> | |||
<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> | |||
<p>The goal of this phase is to make it <em>possible</em> to use the "main" branch name | |||
as an alternative. This allows some early adopters to start testing the new | |||
setup.</p> | |||
<ol> | |||
<li> | |||
<p>As always, make sure your local "master" branch is up-to-date.</p> | |||
</li> | |||
<li> | |||
<p>Create the new "main" branch:</p> | |||
</li> | |||
<li> | |||
<p>Add a <a href="https://github.com/features/actions">GitHub Actions</a> workflow file at | |||
<strong>.github/workflows/mirror-master-and-main.yml</strong> with the following:</p> | |||
<div class="highlight highlight-source-yaml"><pre><span class="pl-ent">name</span>: <span class="pl-s">Mirror "master" and "main" branches</span> | |||
<span class="pl-ent">on</span>: | |||
<span class="pl-ent">push</span>: | |||
<span class="pl-ent">branches</span>: | |||
- <span class="pl-s">master</span> | |||
- <span class="pl-s">main</span> | |||
<span class="pl-ent">jobs</span>: | |||
<span class="pl-ent">mirror</span>: | |||
<span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span> | |||
<span class="pl-ent">steps</span>: | |||
- <span class="pl-ent">name</span>: <span class="pl-s">Mirror to "master"</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">zofrex/mirror-branch@v1</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">target-branch</span>: <span class="pl-s">master</span> | |||
<span class="pl-ent">force</span>: <span class="pl-c1">false</span> | |||
- <span class="pl-ent">name</span>: <span class="pl-s">Mirror to "main"</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">zofrex/mirror-branch@v1</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">target-branch</span>: <span class="pl-s">main</span> | |||
<span class="pl-ent">force</span>: <span class="pl-c1">false</span></pre></div> | |||
</li> | |||
<li> | |||
<p>Commit and your changes to the local "main" branch.</p> | |||
</li> | |||
<li> | |||
<p>Push your changes to the remote "main" branch:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ git push -u origin main</pre></div> | |||
</li> | |||
</ol> | |||
<p>If things are working correctly, you should see the same commit pushed to the | |||
"master" branch shortly. You can monitor the progress and unexpected errors in | |||
the "Actions" tab in your repository.</p> | |||
<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> | |||
<p>You do not have to be already using GitHub Actions for this to work. You do not | |||
need to activate or enable the feature for your repository, simply pushing the | |||
workflow file to the is sufficient. All open-source repositories have unlimited | |||
GitHub Actions minutes, and all personal and team accounts comes with 2000-3000 | |||
free GitHub Actions minutes for private repositories.</p> | |||
<p>If you already regularly uses up your free minutes, this may slightly increase | |||
your GitHub bills, but in practice, the workflow we added runs very quickly so | |||
the impact is very minimal. For reference, GitHub Actions are billed at $0.008 | |||
USD per minute for private repositories, after the free quota is exhausted.</p> | |||
<p>This workflow will be triggered when commits are pushed to either the "master" | |||
or "main" branch. It uses the <a href="https://github.com/marketplace/actions/mirror-branch">Mirror Branch action</a> to | |||
update the branches using GitHub's API.</p> | |||
<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> | |||
<p>Unfortunately, if you have enabled <a href="https://help.github.com/en/github/administering-a-repository/configuring-protected-branches">branch protection</a> on | |||
the "master" branch, the push from the mirroring action may be rejected. For | |||
example, if you had enabled "Require pull request reviews before merging", then | |||
this would not work as the changes are expected to be submitted via a pull | |||
request with reviews.</p> | |||
<p>A possible workaround is to disable the "Include administrators" checkbox in | |||
the branch protection settings for the "master" branch and configure the script | |||
to push the commits as an administrator:</p> | |||
<ol> | |||
<li> | |||
<p>Login as an administrator on GitHub. You may also want to consider creating | |||
a new account specifically for this purpose.</p> | |||
</li> | |||
<li> | |||
<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" | |||
scope (and the "public_repo" scope, if needed).</p> | |||
</li> | |||
<li> | |||
<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> | |||
</li> | |||
<li> | |||
<p>Change the "Checkout" step in the mirror workflow to use the new deploy key:</p> | |||
<div class="highlight highlight-source-yaml"><pre>- <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v2</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">token</span>: <span class="pl-s">${{ secrets.DEPLOY_TOKEN }}</span></pre></div> | |||
<p>Here, <code>DEPLOY_TOKEN</code> is the name you picked from step 3.</p> | |||
</li> | |||
</ol> | |||
<p>Alternatively, an SSH key for the administrator can be used instead of a | |||
personal access token, via the <code>ssh-key</code> argument. See the documentation for | |||
the <a href="https://github.com/actions/checkout">checkout action</a> for more details.</p> | |||
<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> | |||
<p>By default, when pushing commits from within the GitHub Actions job, it does | |||
not trigger additional GitHub Actions workflow to run. For example, when a | |||
contributor pushes to the "main" branch, it will trigger any GitHub Actions | |||
that normally runs on the "main" branch's push events, including the one we | |||
added here. However, when our mirror workflow pushes the same commit to the | |||
"master" branch, it will not trigger any workflow that normally runs on the | |||
"master" branch's push events.</p> | |||
<p>For this reason, you may want to update existing workflows that runs on the | |||
"master" branch to also run on the "main" branch, as we did in our mirror | |||
workflow file (the <code>on.push.branches</code> config key). This is the recommended | |||
approach as it ensures only a single build per push.</p> | |||
<p>Alternatively, if it is important to you that workflows are triggered by pushes | |||
from the mirror workflow, you can accomplish this by supplying an alternative | |||
SSH key to the <a href="https://github.com/actions/checkout">checkout action</a>:</p> | |||
<ol> | |||
<li> | |||
<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 | |||
it to the ssh-agent.</p> | |||
</li> | |||
<li> | |||
<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> | |||
to the repository. Be sure to select "Allow write access".</p> | |||
</li> | |||
<li> | |||
<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 | |||
repository.</p> | |||
</li> | |||
<li> | |||
<p>Change the "Checkout" step in the mirror workflow to use the new deploy key:</p> | |||
<div class="highlight highlight-source-yaml"><pre>- <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v2</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">ssh-key</span>: <span class="pl-s">${{ secrets.DEPLOY_KEY }}</span></pre></div> | |||
<p>Here, <code>DEPLOY_KEY</code> is the name you picked from step 3.</p> | |||
</li> | |||
</ol> | |||
<p>With this, the mirror workflow will authenticate with GitHub using the deploy | |||
key instead of the default token when pushing commits, triggering any workflows | |||
as if a regular user had pushed those commits. This does not change the author | |||
or committer on the commits.</p> | |||
<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> | |||
<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> | |||
for an example of this working in action. Note that the code in the commit may | |||
be outdated by the time you read this – refer to the above for the latest | |||
instructions.</p> | |||
<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> | |||
<p>After verifying that everything is working as intended, you can start inviting | |||
the early adopters to start pushing to the "main" branch. The easiest way to do | |||
this is to rename the local "master" branch:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ <span class="pl-c1">cd</span> my-git-project | |||
$ git checkout master | |||
$ git branch -m main | |||
$ git branch -u origin/main</pre></div> | |||
<p>This would also be a good time to start changing any automation or external | |||
services to the "main" branch to ensure that everything is working as expected.</p> | |||
<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> | |||
<p>After verifying the viability of the rename during the previous phase, the goal | |||
of this phase is to set "main" as the default branch and start issuing | |||
deprecation warnings when the legacy "master" branch is used.</p> | |||
<ol> | |||
<li> | |||
<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> | |||
</li> | |||
<li> | |||
<p>Add a <a href="https://github.com/features/actions">GitHub Actions</a> workflow file at | |||
<strong>.github/workflows/deprecate-master-branch.yml</strong> with the following:</p> | |||
<div class="highlight highlight-source-yaml"><pre><span class="pl-ent">name</span>: <span class="pl-s">Deprecate "master" branch</span> | |||
<span class="pl-ent">on</span>: | |||
<span class="pl-ent">push</span>: | |||
<span class="pl-ent">branches</span>: | |||
- <span class="pl-s">master</span> | |||
<span class="pl-ent">pull_request</span>: | |||
<span class="pl-ent">branches</span>: | |||
- <span class="pl-s">master</span> | |||
<span class="pl-ent">jobs</span>: | |||
<span class="pl-ent">on-push</span>: | |||
<span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span> | |||
<span class="pl-ent">if</span>: <span class="pl-s">${{ github.event_name == 'push' }}</span> | |||
<span class="pl-ent">steps</span>: | |||
- <span class="pl-ent">name</span>: <span class="pl-s">Deprecation</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/commit-comment@v1</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">body</span>: <span class="pl-s">|</span> | |||
<span class="pl-s"> Hello @${{ github.event.sender.login }}!</span> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> :warning: **The "master" branch is deprecated and will be removed from this repository in the future.**</span> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> Please migrate your local repository by renaming the "master" branch to "main":</span> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> ```bash</span> | |||
<span class="pl-s"> $ cd my-git-project</span> | |||
<span class="pl-s"> $ git checkout master</span> | |||
<span class="pl-s"> $ git branch -m main</span> | |||
<span class="pl-s"> $ git branch -u origin/main</span> | |||
<span class="pl-s"> ```</span> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> | |||
<span class="pl-s"/> <span class="pl-ent">on-pull-request</span>: | |||
<span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span> | |||
<span class="pl-ent">if</span>: <span class="pl-s">${{ github.event_name == 'pull_request' }}</span> | |||
<span class="pl-ent">env</span>: | |||
<span class="pl-ent">DEPRECATION_MESSAGE</span>: <span class="pl-s">|</span> | |||
<span class="pl-s"> Hello @${{ github.event.sender.login }}!</span> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> :warning: **The "master" branch is deprecated and will be removed from this repository in the future.**</span> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> Please migrate your local repository by renaming the "master" branch to "main":</span> | |||
<span class="pl-s"/> | |||
<span class="pl-s"> ```bash</span> | |||
<span class="pl-s"> $ cd my-git-project</span> | |||
<span class="pl-s"> $ git checkout master</span> | |||
<span class="pl-s"> $ git branch -m main</span> | |||
<span class="pl-s"> $ git branch -u origin/main</span> | |||
<span class="pl-s"> ```</span> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> | |||
<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> | |||
<span class="pl-s"/> <span class="pl-ent">steps</span>: | |||
- <span class="pl-ent">name</span>: <span class="pl-s">Deprecation</span> | |||
<span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.pull_request.head.repo.fork == false }}</span> | |||
<span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/create-or-update-comment@v1</span> | |||
<span class="pl-ent">with</span>: | |||
<span class="pl-ent">issue-number</span>: <span class="pl-s">${{ github.event.number }}</span> | |||
<span class="pl-ent">body</span>: <span class="pl-s">${{ env.DEPRECATION_MESSAGE }}</span> | |||
- <span class="pl-ent">name</span>: <span class="pl-s">Deprecation</span> | |||
<span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.pull_request.head.repo.fork == true }}</span> | |||
<span class="pl-ent">run</span>: <span class="pl-s">|</span> | |||
<span class="pl-s"> echo "$DEPRECATION_MESSAGE"</span> | |||
<span class="pl-s"> echo '::error::Please set the base branch for this pull request to "main" instead of "master".'</span> | |||
<span class="pl-s"> exit 1</span></pre></div> | |||
</li> | |||
<li> | |||
<p>Commit and push your changes to the "main" branch.</p> | |||
</li> | |||
</ol> | |||
<p>We added a workflow file that triggers whenever a contributor pushes to or | |||
opens a pull request against the "master" branch.</p> | |||
<p>The workflow adds a comment to the commit or pull request, notifying the | |||
contributor that the "master" branch has been deprecated, along with the steps | |||
they need to take to migrate their local repository and changes they need to | |||
make it to the pull request.</p> | |||
<p>It is recommended that you customize the messages with additional information | |||
relevant for your organization. For example, you may want to include a link to | |||
a tracking issue for additional context, or ways for the contributor to ask for | |||
additional assistance if needed.</p> | |||
<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> | |||
<p>Unfortunately, due to limitations of GitHub Actions, it is not possible to add | |||
a pull request comment from the workflow when the pull request originated from | |||
a fork, which is very common in open-source repositories. As a workaround, the | |||
workflow prints the deprecation message to the logs and fails the build.</p> | |||
<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> | |||
<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 | |||
example of this working in action. Note that the code in the commit may be | |||
outdated by the time you read this – refer to the above for the latest | |||
instructions.</p> | |||
<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> | |||
<p>This would be a good time to start updating any internal and external links to | |||
the "master" branch. A common example would be automatically generated links to | |||
source code from the API documentation.</p> | |||
<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> | |||
<p>After a successful phase 2 rollout, it is time to plan for completing the | |||
migration. However, what completion means is going to be different depending on | |||
your situation.</p> | |||
<p>For private work repositories, the legacy "master" branch can likely be removed | |||
from the repository after giving team members a few weeks to migrate. Don't | |||
forget to remove the workflow files as well.</p> | |||
<p>For open-source repositories with lots of contributors, you may want to move a | |||
lot slower. Monitor the Actions tab of the repository to see how often the | |||
deprecation workflow is triggered. When the activity diminishes, it may be good | |||
indication that the legacy "master" branch is no longer needed.</p> | |||
<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> | |||
<p>As an alternative to removing the branch right away, you may want to consider | |||
pushing a final commit to the branch, removing all files but leave behind a | |||
README file explaining that branch has been moved, along with the steps they | |||
need to take in order to migrate their local repository.</p> | |||
<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> | |||
<p>It is also important to consider URL breakages, as links that points to the | |||
files on the "master" branch will stop working once the branch is removed, | |||
including with the soft-removal method described above.</p> | |||
<p>The impact of this has to be evaluated contextually, but it is important to | |||
note that the scope of the breakage is fairly limited, as this only directly | |||
impacts URLs that links to the "master" branch directly. Links pointing to the | |||
active development branch of repository is quite fragile (especially with line | |||
numbers) and often breaks for other reasons.</p> | |||
<p>For example, a refactor that moves around files or switching from JavaScript to | |||
TypeScript would invalidate these URLs. This sort of activity is fairly common | |||
on an active code repository and is usually performed without taking the URL | |||
consideration in mind. For this reason, it is considered a best practice to use | |||
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 | |||
are unaffected by the branch rename.</p> | |||
<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> | |||
<p>For repositories containing <em>installable packages</em>, there are some additional | |||
considerations. Many package managers allow for installing packages from a Git | |||
repository. For example, in npm and yarn, dependencies can be a string like | |||
"username/repo" or "username/repo#branch" in lieu of version range. Likewise, | |||
GitHub Actions are installed using repository and branch references, and it is | |||
a relatively common practice to point an action at the "master" branch.</p> | |||
<p>In these cases, the decision on whether to remove the legacy "master" branch | |||
has to be made carefully. Here are some examples of things to investigate | |||
and consider:</p> | |||
<ul> | |||
<li> | |||
<p>When the branch is omitted from the specifier (e.g. "username/repo"), does | |||
the package manager in your ecosystem hard-code the default to "master" on | |||
the client, or does it respect the remote HEAD ref?</p> | |||
</li> | |||
<li> | |||
<p>Does the package manager use a lockfile, and if so, does it serialize the | |||
branch name (as opposed to the resolved SHA) into the lockfile?</p> | |||
</li> | |||
<li> | |||
<p>Does the package manager maintain a cache of cloned repositories, and if so | |||
do they recover gracefully to a remote branch disappearing?</p> | |||
</li> | |||
</ul> | |||
<p>The answer to these questions affects the potential impact to your end-users | |||
if the legacy "master" branch is removed from the repository. For some, the | |||
end-state of the migration may be to keep the "master" branch permanently as a | |||
read-only mirror, or it may be sufficient to freeze the branch's content and | |||
stop providing updates there. For others, the potential breakage maybe small | |||
enough that it is can be easily justified.</p> | |||
<p>While the workflows added in phase 2 are effective for deprecating <em>writes</em> to | |||
the legacy "master" branch. Unfortunately, Git and GitHub do not offer the | |||
ability to do the same for <em>reads</em> to the branch.</p> | |||
<p>However, you may be able to use features from the package manager to accomplish | |||
a similar result. For example, instead of mirroring the "main" branch to the | |||
"master" branch exactly, you could add a post-install hook to the version on | |||
"master" to issue the deprecation message for any potential consumers.</p> | |||
<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> | |||
<p>Using the Node.js ecosystem as an example, we can put these considerations into | |||
context, based on preliminary testing with npm and yarn classic (v1). If you | |||
found different results in your own testing, or with other package managers | |||
(pnpm, yarn v2, etc), please file an issue here.</p> | |||
<ul> | |||
<li> | |||
<p>The popular package managers in the ecosystem support installing packages | |||
from git, by specifying "username/repo" or "username/repo#branch" in the | |||
dependencies section of package.json.</p> | |||
</li> | |||
<li> | |||
<p>When a branch name is not specified, the popular package managers defaults to | |||
the remote HEAD ref, which is set by the default branch on GitHub, instead of | |||
hardcoding to the "master" branch in the client.</p> | |||
</li> | |||
<li> | |||
<p>The popular package managers uses a lockfile by default. They serialize the | |||
resolved SHA into the lockfiles, as long as the commits referred to by these | |||
SHAs remain reachable on the remote repository, they will install just fine | |||
when using a lockfile. In the case of a branch rename, this is not an issue, | |||
as the history and commits will remain intact.</p> | |||
</li> | |||
<li> | |||
<p>When installing without a lockfile, the popular package managers will fetch | |||
the latest commit from the repository. Renaming the remote branch did not | |||
appear to cause any issues, either because the repositories are not cached, | |||
or the clients are able to recover gracefully from a "missing" remote branch.</p> | |||
</li> | |||
<li> | |||
<p>Post-install hooks are supported. However, yarn classic <a href="https://github.com/yarnpkg/yarn/issues/5476">hides the output | |||
produced by these scripts</a> if | |||
they are successful (exit cleanly with exit code 0). However, when they fail, | |||
they output <em>is</em> shown to the user.</p> | |||
</li> | |||
<li> | |||
<p>Generally speaking, the ecosystem has strong norms and expectations around | |||
adhering to <a href="https://semver.org" rel="nofollow">semantic versioning</a>. Usually, breaking changes are only | |||
expected on major version bumps.</p> | |||
</li> | |||
<li> | |||
<p>By using a Git dependency instead of specifying a semver range, they are | |||
explicitly opting out of the normal semver guarantee, and breakages are to be | |||
expected. No one could reasonably expect that pointing a dependency to the | |||
active development branch without using a lockfile will result in a stable | |||
system.</p> | |||
</li> | |||
</ul> | |||
<p>Given these findings, here is a concrete proposal for a maximally graceful | |||
completion plan:</p> | |||
<ol> | |||
<li> | |||
<p>Stop providing updates to the "master" branch by removing the mirroring | |||
workflow added in phase 1.</p> | |||
</li> | |||
<li> | |||
<p>Push a commit the "master" branch, updating the README as well as adding a | |||
deprecation message to the runtime code (the <code>main</code> entry point):</p> | |||
<div class="highlight highlight-source-js"><pre><span class="pl-c">// index.js</span> | |||
<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> | |||
<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">&&</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> | |||
<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> | |||
<span class="pl-kos">}</span> | |||
<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">warn</span><span class="pl-kos">(</span> | |||
<span class="pl-s">`You are running a deprecated copy of the "my-git-project" installed `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`from the "master" branch of our repository. The "master" branch is `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`deprecated and no longer receives any updates. The branch will soon `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`be removed from our repository, at which point the package will fail `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`to install.\n\n`</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`To fix this issue, please modify your package.json and change the `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`"my-git-project" dependency from "my-repo/my-git-project#master" to `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`"my-repo/my-git-project" or a valid semver range. After making the `</span> <span class="pl-c1">+</span> | |||
<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> | |||
<span class="pl-kos">)</span><span class="pl-kos">;</span> | |||
<span class="pl-c">// ...rest of index.js</span></pre></div> | |||
</li> | |||
<li> | |||
<p>When releasing the next major version of the package, push another commit to | |||
the "master" branch, remove all files from the branch, leaving behind only a | |||
minimal README file, package.json and index.js:</p> | |||
<div class="highlight highlight-source-js"><pre><span class="pl-c">// package.json</span> | |||
<span class="pl-kos">{</span> | |||
<span class="pl-s">"name"</span>: <span class="pl-s">"my-git-project"</span><span class="pl-kos">,</span> | |||
<span class="pl-s">"scripts"</span>: <span class="pl-kos">{</span> | |||
<span class="pl-s">"postinstall"</span>: <span class="pl-s">"node index.js"</span> | |||
<span class="pl-kos">}</span> | |||
<span class="pl-kos">}</span></pre></div> | |||
<div class="highlight highlight-source-js"><pre><span class="pl-c">// index.js</span> | |||
<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> | |||
<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">&&</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> | |||
<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> | |||
<span class="pl-kos">}</span> | |||
<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">error</span><span class="pl-kos">(</span> | |||
<span class="pl-s">`You have installed "my-git-project" from the "master" branch of our `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`repository. The "master" branch has been official retired.\n\n`</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`To fix this issue, please modify your package.json and change the `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`"my-git-project" dependency from "my-repo/my-git-project#master" to `</span> <span class="pl-c1">+</span> | |||
<span class="pl-s">`"my-repo/my-git-project" or a valid semver range. After making the `</span> <span class="pl-c1">+</span> | |||
<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> | |||
<span class="pl-kos">)</span><span class="pl-kos">;</span> | |||
<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> | |||
</li> | |||
<li> | |||
<p>After some time, the master branch can be removed from the repository. This | |||
does not constitute a breaking change, as the package already ceased to | |||
function as of the previous commit. It was just a courteous message to ease | |||
confusion and provide actionable instructions for fixing the issue.</p> | |||
</li> | |||
</ol> | |||
<p>For most projects and organizations, this amount of notice is probably not | |||
necessary or warranted, but it showcases the available tools and techniques, | |||
and demonstrates that there can be a good migration path even under very strict | |||
compatibility requirements. As always, use these steps as a template and tailor | |||
them to your own needs.</p> | |||
<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> | |||
<p>Finally, if you are working on a repository you don't control, and you would | |||
like to refer to your local branch with a different name without making any | |||
changes to the upstream project, you can rename your local "master" branch to | |||
"main" with these steps:</p> | |||
<div class="highlight highlight-source-shell"><pre>$ <span class="pl-c1">cd</span> my-git-project | |||
$ git checkout master | |||
$ git branch -m main | |||
$ git branch -u origin/master</pre></div> | |||
<p>This renames the local branch to "main" but sets the remote tracking branch to | |||
"master".</p> | |||
<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> | |||
<p>This content in this repository, including this documentation and code examples | |||
are licensed under the <a href="https://creativecommons.org/share-your-work/public-domain/cc0/" rel="nofollow">CC0 "No Rights Reserved"</a> public domain | |||
license. Feel free to reproduce and adapt this work into your own proposals, | |||
documentation, etc.</p> | |||
<p>Attribution is not necessary. However, this guide receives constant updates to | |||
reflect current best-practice and solutions based implementation feedback, so | |||
a reference to this repository may be helpful.</p> |
@@ -0,0 +1,159 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="fr"> | |||
<!-- Has to be within the first 1024 bytes, hence before the <title> | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>The end of the Redis adventure (archive) — David Larlet</title> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f0f0ea"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f0f0ea"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2020-06-19.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script type="text/javascript"> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="http://antirez.com/news/133"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick"> | |||
<article> | |||
<h1>The end of the Redis adventure</h1> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil" tabindex="1">🏠</a> | |||
</p> | |||
</nav> | |||
<hr> | |||
<h2><a href="http://antirez.com/news/133">Source originale du contenu</a></h2> | |||
<p>When I started the Redis project more than ten years ago I was in one of the most exciting moments of my career. My co-founder and I had successfully launched two of the major web 2.0 services of the Italian web. In order to make them scalable we had to invent many new concepts, that were already known in the field most of the times, but we didn’t know, nor we cared to check. Problem? Let’s figure out a solution. We wanted to solve problems but we wanted, even more, to have fun. This was the playful environment where Redis was born.</p> | |||
<p>But now Redis is, incredibly, one of the main parts of so many things. And year after year my work changed from building this thing to making sure that it was also as useful as possible, as reliable as possible. And in recent years, what I do every day changed so much that most of my attention is spent in checking what other developers tell me about the Redis code, how to improve it, the changes it requires to be more correct or faster or more secure. However I never wanted to be a software maintainer.</p> | |||
<p>I write code in order to express myself, and I consider what I code an artifact, rather than just something useful to get things done. I would say that what I write is useful just as a side effect, but my first goal is to make something that is, in some way, beautiful. In essence, I would rather be remembered as a bad artist than a good programmer. Now I’m asked more and more, by the circumstances created by a project that became so important, to express myself less and to maintain the project more. And this is indeed exactly what Redis needs right now. But this is not what I want to do, and I stretched myself enough during the past years.</p> | |||
<p>So, dear Redis community, today I’m stepping back as the Redis maintainer. My new position will be, on one side, an “ideas” person at Redis Labs, in order to provide inputs for new Redis possibilities: I’ll continue to be part of the Redis Labs advisory board. On the other hand however my hands will be free, and I’ll do something else, that could be writing code or not, who knows, I don’t want to make plans for now. However I’m very skeptical about me not writing more code in the future. It’s just too much fun :D</p> | |||
<p>I leave Redis in the hands of the Redis community. I asked my colleagues Yossi Gottlieb and Oran Agra to continue to maintain the project starting from today: these are the people that helped me the most in recent years, and that tried hard, even when it was not “linear” to follow me in my very subjective point of views, to understand what my vision on Redis was. Since I don’t want to be part of how the new Redis development setup will be shaped (that is the most meta of the maintenance tasks, exactly what I want to avoid), I’ll just leave Yossi and Oran the task of understanding how to interface with the rest of the Redis developers to find a sustainable development model, you can hear directly from Yossi and Oran in this blog post: <a rel="nofollow" href="https://redislabs.com/blog/new-governance-for-redis/">https://redislabs.com/blog/new-governance-for-redis/</a></p> | |||
<p>I believe I’m not just leaving Redis in the hands of a community of expert programmers, but also in the hands of people who care about the legacy of the community spirit of Redis. In eleven years I hope I was able to provide a point of view that certain persons understood, about an alternative way to write software. I hope that such point of view will be taken into consideration in the evolution of Redis.</p> | |||
<p>Redis was the most stressful thing I did in my career, and probably also the most important. I don’t like much what the underground programming world became in recent years, but even if it was not an easy journey, I had the privilege to work and interact with many great individuals. Thank you for your humanity and your help, and for what you taught me. You know who you are! I want to also say thank you to the companies and individuals inside such companies that allowed me to write open source every day for so many years, with the freedom to do what I believed to be correct for the user base. Redis Labs, VMware and Pivotal, thank you for your great help and generosity.</p> | |||
<p>As I said, I don’t really know what there is for me in my future, other than the involvement with the Redis advisory board. I guess that for some time, just look around is a good idea, without doing too many things. I would like to explore more a few hobbies of mine. Writing blog posts is also a major thing that I wanted to do but did less and less because of time concerns. Recently I published videos in Italian language explaining technological concepts to the general public, I had fun doing that and received good feedbacks, maybe I’ll do more of that as well. Anyway I guess some of you know that I’m active on Twitter as @antirez. If you are interested in what an old, strange programmer will do next, see you there.</p> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil">🏠</a> • | |||
<a href="/david/log/" title="Accès au flux RSS">🤖</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> • | |||
<abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script type="text/javascript"> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,19 @@ | |||
title: The end of the Redis adventure | |||
url: http://antirez.com/news/133 | |||
hash_url: 5e366e8fe10507c713ca8d581daeb17c | |||
When I started the Redis project more than ten years ago I was in one of the most exciting moments of my career. My co-founder and I had successfully launched two of the major web 2.0 services of the Italian web. In order to make them scalable we had to invent many new concepts, that were already known in the field most of the times, but we didn’t know, nor we cared to check. Problem? Let’s figure out a solution. We wanted to solve problems but we wanted, even more, to have fun. This was the playful environment where Redis was born. | |||
But now Redis is, incredibly, one of the main parts of so many things. And year after year my work changed from building this thing to making sure that it was also as useful as possible, as reliable as possible. And in recent years, what I do every day changed so much that most of my attention is spent in checking what other developers tell me about the Redis code, how to improve it, the changes it requires to be more correct or faster or more secure. However I never wanted to be a software maintainer. | |||
I write code in order to express myself, and I consider what I code an artifact, rather than just something useful to get things done. I would say that what I write is useful just as a side effect, but my first goal is to make something that is, in some way, beautiful. In essence, I would rather be remembered as a bad artist than a good programmer. Now I’m asked more and more, by the circumstances created by a project that became so important, to express myself less and to maintain the project more. And this is indeed exactly what Redis needs right now. But this is not what I want to do, and I stretched myself enough during the past years. | |||
So, dear Redis community, today I’m stepping back as the Redis maintainer. My new position will be, on one side, an “ideas” person at Redis Labs, in order to provide inputs for new Redis possibilities: I’ll continue to be part of the Redis Labs advisory board. On the other hand however my hands will be free, and I’ll do something else, that could be writing code or not, who knows, I don’t want to make plans for now. However I’m very skeptical about me not writing more code in the future. It’s just too much fun :D | |||
I leave Redis in the hands of the Redis community. I asked my colleagues Yossi Gottlieb and Oran Agra to continue to maintain the project starting from today: these are the people that helped me the most in recent years, and that tried hard, even when it was not “linear” to follow me in my very subjective point of views, to understand what my vision on Redis was. Since I don’t want to be part of how the new Redis development setup will be shaped (that is the most meta of the maintenance tasks, exactly what I want to avoid), I’ll just leave Yossi and Oran the task of understanding how to interface with the rest of the Redis developers to find a sustainable development model, you can hear directly from Yossi and Oran in this blog post: <a rel="nofollow" href="https://redislabs.com/blog/new-governance-for-redis/">https://redislabs.com/blog/new-governance-for-redis/</a> | |||
I believe I’m not just leaving Redis in the hands of a community of expert programmers, but also in the hands of people who care about the legacy of the community spirit of Redis. In eleven years I hope I was able to provide a point of view that certain persons understood, about an alternative way to write software. I hope that such point of view will be taken into consideration in the evolution of Redis. | |||
Redis was the most stressful thing I did in my career, and probably also the most important. I don’t like much what the underground programming world became in recent years, but even if it was not an easy journey, I had the privilege to work and interact with many great individuals. Thank you for your humanity and your help, and for what you taught me. You know who you are! I want to also say thank you to the companies and individuals inside such companies that allowed me to write open source every day for so many years, with the freedom to do what I believed to be correct for the user base. Redis Labs, VMware and Pivotal, thank you for your great help and generosity. | |||
As I said, I don’t really know what there is for me in my future, other than the involvement with the Redis advisory board. I guess that for some time, just look around is a good idea, without doing too many things. I would like to explore more a few hobbies of mine. Writing blog posts is also a major thing that I wanted to do but did less and less because of time concerns. Recently I published videos in Italian language explaining technological concepts to the general public, I had fun doing that and received good feedbacks, maybe I’ll do more of that as well. Anyway I guess some of you know that I’m active on Twitter as @antirez. If you are interested in what an old, strange programmer will do next, see you there. |
@@ -0,0 +1,187 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="fr"> | |||
<!-- Has to be within the first 1024 bytes, hence before the <title> | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>lion affranchi (archive) — David Larlet</title> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f0f0ea"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f0f0ea"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2020-06-19.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script type="text/javascript"> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="https://www.la-grange.net/2020/07/01/affranchi"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick"> | |||
<article> | |||
<h1>lion affranchi</h1> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil" tabindex="1">🏠</a> | |||
</p> | |||
</nav> | |||
<hr> | |||
<h2><a href="https://www.la-grange.net/2020/07/01/affranchi">Source originale du contenu</a></h2> | |||
<figure> | |||
<img src="https://www.la-grange.net/2020/07/01/8269-tampon-lion.jpg" alt="Lion en marbre"/> | |||
<figcaption>Tsujido, Japon, 1er juillet 2020</figcaption> | |||
</figure> | |||
<blockquote> | |||
<p>Good times are going to come our way too, she'd say. We just have to keep doing out best and work hard.— That's the way she was always thinking. I guess that's why she kept working with a vengeance.<br/> | |||
— Comrade Taguchi's Sorrow (An anthology of Japanese Proletarian Literature) - Kobayashi Takiji, urn:isbn:978-0-226-06837-4</p> | |||
</blockquote> | |||
<p>Dans la maison d'une artiste, laissée à l'abandon, qu'un ami a racheté, tout était en place, juste avec un peu plus de poussières. J'ai récupéré des objets ici et là, dont deux petits lions en marbre qui sont des sceaux encreurs au nom de l'artiste.</p> | |||
<p>Je les regarde souvent. Ils me rappellent le moment de la découverte de la maison, la poésie de son oubli. Je me demande aussi souvent si je devais réaliser un <a href="https://www.la-grange.net/2020/06/03/sceau">sceau</a> similaire, quel serait le motif sculpté sur le dessus ? Un chêne ? Une représentation de La Grange ? Et quels caractères pour le sceau, mon nom en japonais comme le sceau actuel, ou le mot Grange (納屋). Et pourquoi y mettre un nom ? L'objet doit il être uniquement fonctionnel ou avoir le caractère d'une émotion.</p> | |||
<h2>sur le bord du chemin</h2> | |||
<ul> | |||
<li><p><a href="https://argdown.org/">argdown</a>. Une syntaxe texte pour décrire et gérer un débat à propos d'un sujet. Il est possible de voir une représentation graphique du débat. Voir <a href="https://argdown.org/sandbox/html">cet example</a>.</p> | |||
</li> | |||
<li><p>20% du <a href="https://seabed2030.gebco.net/news/gebco_2020_release.html">fond des océans est maintenant cartographié</a>. En 2017 uniquement 6% était cartographié.</p> | |||
<blockquote> | |||
<p>The sustained increase in data available to map the ocean floor will enable Seabed 2030 to play a leading role in delivering a comprehensive set of <strong>authoritative data that is freely available for all to use</strong>.</p> | |||
</blockquote> | |||
<p><a href="https://www.gebco.net/data_and_products/">data set and products</a>. Il existe aussi un <a href="https://www.ngdc.noaa.gov/gazetteer/">outil de navigation de la carte</a>.</p> | |||
<p><img src="https://www.la-grange.net/2020/07/01/ocean-japon.jpg" alt="" fond="" de="" l="" pr="" du="" japon=""/></p> | |||
<p>Peut-être un jour donnerons-nous des noms encore plus localisés ? Il existe des « rivières » au fond de l'océan. Près de Tokyo, le <a href="https://www.sciencedirect.com/science/article/abs/pii/002532279090038L">Canyon de Boso</a> semble se jeter dans le bassin de Katsuura.</p> | |||
<p><img src="https://www.la-grange.net/2020/07/01/boso-canyon.jpg" alt="" carte="" du="" canyon="" boso=""/></p> | |||
</li> | |||
<li><p><a href="http://antirez.com/news/133">The end of the Redis adventure</a>.</p> | |||
<blockquote> | |||
<p>I write code in order to express myself, and I consider what I code an artifact, rather than just something useful to get things done. I would say that what I write is useful just as a side effect, but my first goal is to make something that is, in some way, beautiful. <strong>In essence, I would rather be remembered as a bad artist than a good programmer</strong>.</p> | |||
</blockquote> | |||
</li> | |||
<li><p>Sur la boîte aux lettres, cherchant un abri pour éviter la pluie, un <a href="https://en.wikipedia.org/wiki/Acalolepta_fraudatrix">Acalolepta fraudatrix</a>. Il a de très <a href="http://www.forest.kyushu-u.ac.jp/photo/hokkaido/db-image/image00447.jpg">longues antennes</a> et a un corps long de près de 3 cm. J'ai oublié de prendre une photo. Dommage.</p> | |||
</li> | |||
</ul> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil">🏠</a> • | |||
<a href="/david/log/" title="Accès au flux RSS">🤖</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> • | |||
<abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script type="text/javascript"> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,35 @@ | |||
title: lion affranchi | |||
url: https://www.la-grange.net/2020/07/01/affranchi | |||
hash_url: 613da2c8a82cb70c50391a34565800c4 | |||
<figure> | |||
<img src="https://www.la-grange.net/2020/07/01/8269-tampon-lion.jpg" alt="Lion en marbre"/> | |||
<figcaption>Tsujido, Japon, 1er juillet 2020</figcaption> | |||
</figure> | |||
<blockquote> | |||
<p>Good times are going to come our way too, she'd say. We just have to keep doing out best and work hard.— That's the way she was always thinking. I guess that's why she kept working with a vengeance.<br/> | |||
— Comrade Taguchi's Sorrow (An anthology of Japanese Proletarian Literature) - Kobayashi Takiji, urn:isbn:978-0-226-06837-4</p> | |||
</blockquote> | |||
<p>Dans la maison d'une artiste, laissée à l'abandon, qu'un ami a racheté, tout était en place, juste avec un peu plus de poussières. J'ai récupéré des objets ici et là, dont deux petits lions en marbre qui sont des sceaux encreurs au nom de l'artiste.</p> | |||
<p>Je les regarde souvent. Ils me rappellent le moment de la découverte de la maison, la poésie de son oubli. Je me demande aussi souvent si je devais réaliser un <a href="https://www.la-grange.net/2020/06/03/sceau">sceau</a> similaire, quel serait le motif sculpté sur le dessus ? Un chêne ? Une représentation de La Grange ? Et quels caractères pour le sceau, mon nom en japonais comme le sceau actuel, ou le mot Grange (納屋). Et pourquoi y mettre un nom ? L'objet doit il être uniquement fonctionnel ou avoir le caractère d'une émotion.</p> | |||
<h2>sur le bord du chemin</h2> | |||
<ul> | |||
<li><p><a href="https://argdown.org/">argdown</a>. Une syntaxe texte pour décrire et gérer un débat à propos d'un sujet. Il est possible de voir une représentation graphique du débat. Voir <a href="https://argdown.org/sandbox/html">cet example</a>.</p> | |||
</li> | |||
<li><p>20% du <a href="https://seabed2030.gebco.net/news/gebco_2020_release.html">fond des océans est maintenant cartographié</a>. En 2017 uniquement 6% était cartographié.</p> | |||
<blockquote> | |||
<p>The sustained increase in data available to map the ocean floor will enable Seabed 2030 to play a leading role in delivering a comprehensive set of <strong>authoritative data that is freely available for all to use</strong>.</p> | |||
</blockquote> | |||
<p><a href="https://www.gebco.net/data_and_products/">data set and products</a>. Il existe aussi un <a href="https://www.ngdc.noaa.gov/gazetteer/">outil de navigation de la carte</a>.</p> | |||
<p><img src="https://www.la-grange.net/2020/07/01/ocean-japon.jpg" alt="" fond="" de="" l="" pr="" du="" japon=""/></p> | |||
<p>Peut-être un jour donnerons-nous des noms encore plus localisés ? Il existe des « rivières » au fond de l'océan. Près de Tokyo, le <a href="https://www.sciencedirect.com/science/article/abs/pii/002532279090038L">Canyon de Boso</a> semble se jeter dans le bassin de Katsuura.</p> | |||
<p><img src="https://www.la-grange.net/2020/07/01/boso-canyon.jpg" alt="" carte="" du="" canyon="" boso=""/></p> | |||
</li> | |||
<li><p><a href="http://antirez.com/news/133">The end of the Redis adventure</a>.</p> | |||
<blockquote> | |||
<p>I write code in order to express myself, and I consider what I code an artifact, rather than just something useful to get things done. I would say that what I write is useful just as a side effect, but my first goal is to make something that is, in some way, beautiful. <strong>In essence, I would rather be remembered as a bad artist than a good programmer</strong>.</p> | |||
</blockquote> | |||
</li> | |||
<li><p>Sur la boîte aux lettres, cherchant un abri pour éviter la pluie, un <a href="https://en.wikipedia.org/wiki/Acalolepta_fraudatrix">Acalolepta fraudatrix</a>. Il a de très <a href="http://www.forest.kyushu-u.ac.jp/photo/hokkaido/db-image/image00447.jpg">longues antennes</a> et a un corps long de près de 3 cm. J'ai oublié de prendre une photo. Dommage.</p> | |||
</li> | |||
</ul> |
@@ -0,0 +1,181 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="fr"> | |||
<!-- Has to be within the first 1024 bytes, hence before the <title> | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>Isabelle Attard : « L’écologie doit s’inscrire au sein du mouvement révolutionnaire » (archive) — David Larlet</title> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f0f0ea"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f0f0ea"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2020-06-19.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script type="text/javascript"> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="https://www.revue-ballast.fr/isabelle-attard-lecologie-doit-sinscrire-au-sein-du-mouvement-revolutionnaire"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick"> | |||
<article> | |||
<h1>Isabelle Attard : « L’écologie doit s’inscrire au sein du mouvement révolutionnaire »</h1> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil" tabindex="1">🏠</a> | |||
</p> | |||
</nav> | |||
<hr> | |||
<h2><a href="https://www.revue-ballast.fr/isabelle-attard-lecologie-doit-sinscrire-au-sein-du-mouvement-revolutionnaire">Source originale du contenu</a></h2> | |||
<p><span><em>Le temps d’un mandat, Isabelle Attard, archéozoologue de formation, a défendu à l’Assemblée nationale les couleurs d’Europe Écologie – les Verts. Sous les ors du palais Bourbon, elle est l’une des rares députés à s’opposer, en 2015, à la prolongation de l’état d’urgence et, la même année, à celle des frappes aériennes sur le sol syrien. Deux ans après la fin de sa députation, elle publie le livre </em>Comment je suis devenue anarchiste : <em>un ralliement explicite à la tradition libertaire, doublé d’un constat sans appel quant à la possibilité de changer le système de l’intérieur. Certaine que la lutte écologique, féministe et anticapitaliste ne passera plus par la prise du pouvoir central, elle aspire à la création, ici et maintenant, d’espaces parallèles autonomes. Nous en discutons ensemble.<br/> </em></span></p> | |||
<p><hr/> | |||
<p><span><strong><picture class="wp-image-73706 size-full alignleft"> | |||
<source type="image/webp" data-lazy-srcset="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg.webp 300w" srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-lazy-sizes="(max-width: 300px) 100vw, 300px"/> | |||
<img src="" data-lazy-srcset="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg 300w, https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle-150x150.jpg 150w, https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle-100x100.jpg 100w" data-lazy-sizes="(max-width: 300px) 100vw, 300px" data-lazy-src="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg"/> | |||
</picture> | |||
<noscript><picture class="wp-image-73706 size-full alignleft"> | |||
<source type="image/webp" srcset="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg.webp 300w" sizes="(max-width: 300px) 100vw, 300px"/> | |||
<img src="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg" srcset="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg 300w, https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle-150x150.jpg 150w, https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle-100x100.jpg 100w" sizes="(max-width: 300px) 100vw, 300px"/> | |||
</picture> | |||
</noscript>Vous avez été députée cinq ans. Votre constat est sans appel : on ne peut rien faire bouger au sein des institutions. À vos yeux, l’opposition parlementaire est-elle candide, tristement lucide ou vraiment complice ?</strong></span></p><p>Effectivement. Et je peux même dire que je n’étais pas vraiment prévue au programme puisque la circonscription dans laquelle je me suis présentée ne m’était pas du tout favorable. Je débutais en politique et très peu de personnes croyaient en une victoire possible. Je ne la dois finalement qu’à la grande division qui régnait alors à droite comme à gauche. Lorsque je suis entrée à l’Assemblée nationale, je ne faisais pas partie du sérail, j’ai donc découvert son fonctionnement, ainsi que les combinaisons politiques, en me jetant directement dans le grand bain. Comme n’importe quelle personne qui croit encore à ce système, j’étais pétrie de grands principes républicains et d’idéaux démocratiques. J’ai assez vite déchanté. Lorsque je n’ai pas voté le budget en 2013, je me suis de facto retrouvée dans la position d’une opposante à la majorité présidentielle. Dès lors, celle-ci n’a eu de cesse de me marginaliser. La plupart du temps, elle préférait d’ailleurs m’ignorer — il serait même encore plus juste de dire qu’elle me dédaignait. Il n’existe que deux camps à l’Assemblée : soit vous soutenez la majorité, soit vous vous y opposez. C’est très manichéen. Or si j’étais franchement en désaccord avec la politique du gouvernement, je n’avais rien à voir avec l’<span class="caps">UMP</span> ou le <span class="caps">FN</span>. J’ai bien essayé, avec d’autres collègues, déçus comme moi, de proposer en 2015 la création d’un groupe « rouge-rose-vert » qui aurait alors permis d’apporter une autre voix, mais nous n’avons reçu que très peu d’écho.</p> | |||
<p><span><strong>Comment l’expliquez-vous ?</strong></span></p><blockquote><p>« L’Assemblée nationale est un grand théâtre dans lequel la pièce est déjà écrite à l’avance. Chacun y tient le rôle qui lui a été attribué. »</p></blockquote><p>Ça ne correspondait pas à la stratégie des écuries présidentielles de l’époque. Et je ne suis toujours pas convaincue que ça corresponde à celle des partis en place aujourd’hui. L’Assemblée nationale est un grand théâtre dans lequel la pièce est déjà écrite à l’avance. Chacun y tient le rôle qui lui a été attribué. Si vous déviez un tant soit peu de la ligne, vous vous faites aussitôt « excommunier ». Alors, pour répondre à votre question, je pense qu’on peut dire que l’opposition parlementaire joue son rôle : elle s’oppose. Parfois de manière grandiose mais, la plupart du temps, en usant surtout de démagogie car elle sait très bien qu’il lui est impossible de proposer autre chose que des coups d’éclats médiatiques et symboliques. Comment lui en vouloir ? Tout est prévu pour que ça se passe comme ça, et uniquement comme ça.</p> | |||
<p><span><strong>Depuis, vous tenez au mot « anarchisme ». Qu’a‑t-il à vos yeux de plus fécond que « socialisme » ou « communisme » ?</strong></span></p><p>C’est assez simple et, il me semble, très cohérent avec ce que je viens de vous dire. Il faut néanmoins revenir à l’histoire de ces différents courants politiques pour comprendre pourquoi je me suis tournée vers l’anarchisme et pourquoi, aujourd’hui, je revendique fièrement ce mot. <a href="https://www.revue-ballast.fr/tancrede-ramonet/" target="_blank" rel="noopener noreferrer">Tancrède Ramonet</a> l’explique très bien dans son documentaire <em>Ni Dieu ni maître</em>, qui fait partie des ressources qui m’ont accompagnées lors de ce processus de déconstruction-reconstruction politique. Historiquement, le mouvement socialiste s’est divisé en trois grands courants : réformiste, marxiste et anarchiste. Vous aurez bien compris que je ne croyais dorénavant plus au premier, qui a abandonné depuis longtemps l’idée de révolutionner la société et de mettre fin au capitalisme… Quant au deuxième, s’il est possible de partager de nombreuses analyses, voire un objectif commun, je ne me retrouve pas du tout dans la vision autoritaire qui en découle. Mikhaïl Bakounine disait que «<em> la liberté sans le socialisme, c’est le privilège et l’injustice, et le socialisme sans la liberté, c’est l’esclavage et la brutalité</em> ». Je pense également que si le terme « libertaire » n’est pas étroitement associé à ceux de « socialisme » ou de « communisme », alors la société qu’on souhaite construire ne m’intéresse pas. Elle ne m’intéresse d’ailleurs pas du tout, si elle n’est pas aussi féministe et écologiste. Et justement, l’anarchisme a ceci d’incomparable avec les autres courants qui se positionnent à gauche : il s’oppose farouchement à toutes formes de dominations, quelles qu’elles soient.</p> | |||
<p><span><strong>En théorie, en tout cas…</strong></span></p><p>Dans la pratique, il n’est évidemment pas exempt de tous reproches. Derrière des idées, il ne faut jamais oublier qu’il y a des femmes et des hommes qui les défendent. L’aspect psychologique est très présent en politique — et tout le monde n’est pas au même stade de déconstruction ou de reconstruction. Tout le monde n’a pas le même vécu, la même interprétation, les mêmes névroses. Mais il suffit de visionner des documentaires ou de lire des livres sur l’anarchie, écrits par des anarchistes, pour se rendre compte de la grande richesse de cette philosophie. D’ailleurs, si les idées anarchistes n’étaient pas aussi révolutionnaires, on les enseignerait très certainement en classe de terminale. Or on préfère les dénigrer en confondant le terme « anarchie » avec celui de « chaos ». Ça permet ainsi de masquer le véritable chaos, celui qui provient du capitalisme et du libéralisme.</p> | |||
<p><span><strong>C’est d’ailleurs pour cette raison que vous préférez le mot « anarchiste » à celui de « libertaire ».</strong> </span></p><p>J’ai même mis un point d’honneur à l’utiliser dans le titre de mon livre. Il me semble qu’il est temps de le réhabiliter et de l’assumer comme le font de nombreuses autres personnes aujourd’hui. Et puis, il a l’énorme avantage d’être des plus clairs. La clarté, à une époque où le confusionnisme règne, c’est primordial !</p> | |||
<p><span><strong>Noam Chomsky se revendique lui aussi de l’anarchisme. Face au « <em>gang de fous psychopathes</em> » que sont Trump et les siens, il a récemment appelé à voter pour le fort peu révolutionnaire Biden — au motif que refuser de voter pour le moins pire, c’est soutenir « <em>le pire</em> ». Cet argument vous parle-t-il encore ?</strong></span></p><blockquote><p>« Je peux comprendre qu’on puisse préférer un Obama à un Trump. Mais si, dans la forme, ça n’a évidemment rien à voir, sur le fond, les différences se situent seulement à la marge. »</p></blockquote><p>Chomsky est avant tout membre de l’<a href="https://fr.wikipedia.org/wiki/Industrial_Workers_of_the_World" target="_blank" rel="noopener noreferrer">Industrial Workers of the World</a>. Je le précise car il me semble que ça permet de comprendre pourquoi son approche est différente de la plupart des anarchistes. Les <em>Wobblies</em> proviennent de tendances différentes — syndicalistes, socialistes, libertaires, anarchistes ou syndicalistes révolutionnaires — et ont pour objectif de s’unir au sein d’un seul grand syndicat — « One Big Union ». Je trouve l’idée de cette plateforme commune intéressante, mais elle amène à faire certains compromis. Chomsky dit partager l’idéal anarchiste, c’est-à-dire celui qui tend vers un démantèlement du pouvoir étatique. En même temps, il considère que cet idéal entre en conflit direct avec des objectifs immédiats, qui sont de défendre, voire de renforcer certains aspects de l’autorité de l’État. Il l’explique d’ailleurs d’autant mieux dans une analogie qu’il a reprise chez des travailleurs brésiliens. L’État serait une cage qui nous protégerait des fauves que sont les compagnies privées et qui sont en-dehors de celle-ci. La seule perspective que nous donne finalement Noam Chomsky est celle d<em>’étendre les barreaux de la cage</em> en attendant que nous soyons capables de les briser et de combattre les fauves nous-mêmes.<a href="https://www.revue-ballast.fr/labecedaire-de-murray-bookchin/"> Murray Bookchin</a> considérait qu’il était pure folie de vouloir jouer le jeu d’un État centralisé qui avait toujours démontré une excessive complaisance envers ces compagnies. Je pense exactement la même chose que lui.</p><p>Il n’y a rien à attendre des États-nations qui protègent avant tout les intérêts capitalistes. Par contre, je peux comprendre qu’on puisse préférer un Barack Obama à un Donald Trump. Mais si, dans la forme, ça n’a évidemment rien à voir, sur le fond, les différences se situent seulement à la marge. Nous en avons eu l’exemple flagrant dernièrement lorsque Joe Biden a suggéré à la police de viser les jambes plutôt que le cœur pour réduire les tirs mortels. Il n’y a donc jamais de remise en cause globale du système. Il est totalement illusoire de penser qu’il est possible de changer les choses de l’intérieur, notamment en appliquant la « stratégie des petits pas ». Ça ne mène généralement à rien. Par contre, le concept de « gradualisme révolutionnaire » d’<a href="https://fr.wikipedia.org/wiki/Errico_Malatesta" target="_blank" rel="noopener noreferrer">Errico Malatesta</a> me parle beaucoup plus. S’il rejette l’idée d’un Grand Soir révolutionnaire, il n’envisage pas, pour autant, de renforcer l’autorité de l’État. Au contraire, l’idée est d’avancer vers l’anarchie en réalisant un travail de sape qui permettra, au terme d’un processus graduel, de s’émanciper de cette autorité. La renforcer est donc un non-sens. Ce qui n’empêche cependant pas de lutter pour ses droits.</p> | |||
<p><span><strong>Vous avez dit dans une conférence que, écologiquement, nous avons déjà franchi un « <em>point de non retour</em> » : cela signifie-t-il que l’horizon de l’émancipation est de sauver les meubles ?</strong></span></p><p>Il est assez difficile de nier que nous sommes effectivement arrivés à ce point en ce qui concerne le climat et la biodiversité. D’ailleurs, avec le confinement, nous avons pu constater <em>in situ</em> l’impact du capitalisme sur ceux-ci. Il va être très difficile pour les climato-sceptiques d’argumenter après ça — même si je les en crois tout à fait capables… Toutes les études scientifiques vont dans le même sens : nous assistons à une augmentation des températures moyennes océaniques et atmosphériques et à une chute extrêmement brutale de la biodiversité. Ne pas comprendre qu’il s’agit là de phénomènes irréversibles s’appelle tout simplement du déni. Les conséquences, à plus ou moins long terme, auront un impact sur l’ensemble de nos sociétés, tant d’un point de vue écologique que social ou démocratique. Ça a d’ailleurs déjà commencé. Alors je dois avouer que j’ai un peu de mal avec les mouvements qui prétendent qu’« il est encore temps » et qui laissent à penser que nous allons pouvoir sauver la maison des flammes en ne s’attaquant pas au pyromane : le capitalisme. Je sais très bien qu’en disant ceci, je passe pour une personne radicale — mais je considère qu’être radicale est la condition <em>sine qua non</em> à toutes les luttes d’aujourd’hui. D’ailleurs, le mot « radical » me tient tout autant à cœur que celui d’« anarchie ». On en a fait un mot qui fait peur pour dissuader les gens de le devenir : pourtant, ça ne signifie pas autre chose que s’attaquer à la racine du problème !</p><blockquote><p>« J’entends bien cette petite musique lancinante qui cherche à nous convaincre que le problème provient de <q>l’humain</q>. »</p></blockquote><p>Toutefois, je ne suis pas dupe. J’entends bien cette petite musique lancinante qui cherche à nous convaincre que le problème provient de l’humain, de son incapacité à comprendre l’urgence dans laquelle nous nous trouvons aujourd’hui. Cette analyse est dangereuse car elle suggère que la solution se trouve dans la mise en place d’un pouvoir coercitif, voire d’une dictature. Or, qu’elle soit verte, rouge ou bleue, une dictature reste une dictature. Je ne pense pas non plus que la solution viendra de la technologie, qui ne fait que déplacer le problème et qui permet seulement aux multinationales de paraître un peu plus vertes. L’horizon de l’émancipation n’est donc absolument pas de sauver les meubles, et encore moins de ces manières-là. La solution, nous l’avons entre les mains, c’est ce que l’anarchie a prouvé à maintes reprises au cours de notre histoire récente : « <em><span class="noTypo">Don’t mourn, organize! </span></em>» (« <em>Ne vous lamentez pas, organisez vous !</em> » [ndlr])</p> | |||
<p><span><strong>L’écologie, telle qu’on la connaît sous ses formes électorales depuis les années 1970, a‑t-elle entièrement échoué ?<br/> </strong></span></p><p>Si on résume l’écologie politique, et même la politique plus généralement, à l’idée de conquérir le pouvoir par les élections ou par la participation au gouvernement, alors oui, je pense qu’elle a échoué dans son objectif de transformation sociale et sociétale. Elle a peut-être contribué à une meilleure prise en compte de certains sujets ces dernières années mais elle ne s’est pas donnée les moyens de changer radicalement les choses en se bornant à cette stratégie purement électoraliste. La bonne nouvelle, c’est que l’écologie ne se réduit pas uniquement à ça. Il me paraît évident que les mouvements anti-nucléaires, la lutte pour préserver les terres sur le plateau du Larzac, ou encore la <span class="caps">ZAD</span> de Notre-Dame-des-Landes, ont permis d’apporter des propositions beaucoup plus concrètes, de rendre l’utopie palpable. De mon point de vue, l’écologie doit désormais s’inscrire au sein du mouvement révolutionnaire. Et c’est en lisant le livre de <a href="https://www.revue-ballast.fr/floreal-romero-communalisme-se-doter-dune-organisation-1-2/">Floréal Romero</a> et Vincent Gerber,<em> Murray Bookchin, pour une écologie sociale et radicale</em>, que je l’ai enfin compris. Le mouvement écologiste a longtemps ignoré le travail de Murray Bookchin qui a été un précurseur dans les années 1960. Aujourd’hui, il est à la mode : tant mieux ! Pour autant, il s’agit de rester vigilant sur la réappropriation qui peut en être faite. Je me réfère souvent <a href="https://www.revue-ballast.fr/le-moment-communaliste/">à un article de l’un de vos auteurs</a>, Elias Boisjean, qui rappelle qu’«<em> on ne saurait […] enrôler Bookchin sans saisir la cohésion d’ensemble de sa doctrine</em> » et qu’«<em> intégrer un conseil municipal, voire diriger une ville, n’est d’aucun secours si cela ne participe pas d’une transformation globale sans </em><q>compromis avec cet ordre social</q>.<em> Donc de la fin du règne capitaliste au profit d’une</em> <q>société communiste libertaire</q> ».</p> | |||
<p><span><strong>Vous avez d’ailleurs postfacé l’ouvrage <em>Agir ici et maintenant</em>, consacré à Bookchin, à l’écologie sociale et au communalisme. Comment cette proposition permet-elle de répondre à « l’effondrement » dont vous parlez ?</strong></span></p><p>Comme je l’exprime dans mon livre, la lecture de Bookchin a été pour moi une sacrée claque. Comme beaucoup, j’étais passée à côté de son travail et je ne l’ai découvert que très tardivement. Et c’est bien dommage ! Je ne suis pas pour autant une « bookchiniste », dans le sens où je ne considère pas qu’il serait à lui seul l’alpha et l’oméga d’une solution toute prête à un effondrement écologique, social et démocratique. Il reste néanmoins un auteur très important dans le débat anarchiste, même s’il a lui-même été<span>, </span>pour des raisons plus ou moins claires, relativement critique envers le mouvement. Son apport est considérable : il est l’un des premiers à avoir apporté une analyse globale et assez fine de la situation, en y incluant la notion d’écologie qui pouvait parfois faire défaut. Je ne dis pas que l’anarchisme ne se préoccupait pas d’écologie avant lui mais il me semble qu’il a réussi à en faire la pierre angulaire du projet de société qu’il propose.</p><p>La véritable claque a été de comprendre qu’il fallait arrêter de jouer à un jeu auquel nous serions toujours perdants et qu’il s’agissait dorénavant de créer une déviation ou une dérivation du système, si nous voulions radicalement et foncièrement en sortir. L’effondrement, même si on peut employer d’autres mots tant celui-ci a été récupéré, sera vraisemblablement assez violent. C’est logique, puisque nous sommes déjà entrés dans une ère de transformation dont nous ne maîtrisons plus entièrement le processus. Il va donc falloir que nous réfléchissions à nous adapter à ces changements, à plus ou moins long terme. L’État, qui protège les intérêts des compagnies privées et plus généralement du capitalisme, va continuer à durcir ses relations avec celles et ceux qui s’opposent à lui. Nous pouvons donc continuer exclusivement à nous opposer frontalement à lui en espérant qu’il s’effondre de lui-même, ce qui me semble hasardeux et peut-être même dangereux puisque nous risquons le conflit direct avec des forces réactionnaires. Mais nous pouvons aussi commencer à créer cette dérivation dont je parle, en créant des espaces autonomes et en les reliant entre eux. Dans mon esprit, les deux choix ne sont pas incompatibles.</p> | |||
<p><span><strong>Comment ça ?</strong></span></p><blockquote><p>« Nous avons un exemple concret devant nos yeux, au Rojava. Nous ne partons pas de zéro — même si les conditions ne sont pas entièrement semblables. »</p></blockquote><p>Ça correspond à l’esprit du gradualisme révolutionnaire de Malatesta, dont je vous parlais. L’écologie sociale a cette particularité qui permet à la fois d’amortir le choc auquel nous allons devoir nous confronter mais aussi de préparer « l’après », dans la perspective d’un effondrement de l’État-nation. C’est en lisant le livre de <a href="https://www.revue-ballast.fr/lemancipation-kurde-face-aux-pouvoirs-syriens/">Raphaël Lebrujah</a> sur le Rojava, <i>Comprendre le Rojava dans la guerre civile syrienne</i>, que je me suis aperçue que nous avions un exemple concret devant nos yeux. Nous ne partons pas de zéro — même si les conditions ne sont pas entièrement semblables et même si la culture politique peut s’avérer aussi relativement différente.</p> | |||
<p><span><strong>Dans son dernier ouvrage, <em>Trop tard pour être pessimistes !</em>, l’écosocialiste Daniel Tanuro objecte aux tenants des solutions locales ou communales qu’il faut, face aux « <em>défis terribles</em> » auxquels nous sommes confrontés, travailler à un «<em> plan de transition</em> » écologique coordonné, lequel passe obligatoirement par la prise du pouvoir politique, c’est-à-dire de l’État. Cette objection ne vous convainc donc pas ?</strong></span></p><p>Je n’ai pas encore pu lire ce livre [<em>paru le 10 juin 2020, ndlr</em>] : je me garderai donc bien d’en parler. Surtout que, d’après la quatrième de couverture, il semblerait que nous partagions plus ou moins le même constat sur la collapsologie, le capitalisme vert ou le Green New Deal. Par contre, si l’idée est de conquérir le pouvoir et, comme vous dites, par extension l’État, je ne vois rien de révolutionnaire là-dedans. Nous pourrions alors réellement dire que cela signifie que l’horizon de l’émancipation consiste à sauver les meubles. Il m’est impossible de concevoir l’émancipation si ça ne permet pas aux individus de prendre part, de manière directe, au fonctionnement démocratique. C’est un principe de base. C’est pour cette raison que je suis anarchiste. En tous cas, je suis d’accord avec le titre du livre de Daniel Tanuro : oui, il est trop tard pour être pessimistes. Et, là encore, je vais faire référence à Malatesta lorsqu’il pense que la révolution est un acte de volonté et que son action a deux objectifs bien clairs : la destruction violente des obstacles à la liberté, et la diffusion graduelle de la pratique de la liberté, privée de toutes coercitions. Le seul moyen de faire face aux « défis terribles » qui s’annoncent me semble d’y répondre justement de manière audacieuse, et l’anarchie s’y prête merveilleusement bien.</p> | |||
<p><span><strong>La police française compte environ 150 000 agents, la gendarmerie 100 000 et l’armée plus de 40 000. L’extrême droite y est massivement présente. Comment imaginer les possibilités d’une transformation radicale face à cette colossale puissance de feu, qui, l’Histoire en est témoin, se rangera aux côtés du capital si celui-ci est menacé ?</strong></span></p><p>L’État dispose effectivement d’un outil très puissant, dont il se sert à outrance depuis quelques temps déjà. Le fait que l’extrême droite y soit massivement représentée n’arrange rien, même si ça ne change rien à l’affaire. C’est pour cette raison que je vous disais que la confrontation directe avec l’État n’était peut-être pas, à mes yeux, la meilleure stratégie. En tous cas, elle ne peut être la seule. Maintenant, je peux comprendre que le niveau de colère des gens soit tel qu’ils souhaitent en découdre avec ce qui symbolise, un peu trop à mon goût, l’État et le gouvernement. Il est impossible d’éluder la question de la confrontation physique avec les forces réactionnaires lors d’un processus révolutionnaire. Penser que le changement se fera intégralement de manière non-violente, en se déguisant en bisounours, est totalement illusoire. Ou alors, c’est que le changement proposé est très loin d’être radical, quand il n’est pas carrément un faux-nez du capitalisme. Je suis pacifiste et anti-militariste, mais je ne suis pas naïve. Bookchin parle d’ailleurs de constituer une milice populaire pour défendre les communes libertaires. C’était déjà la question lors de la Commune de Paris. En 1936, les républicains et les anarchistes avaient aussi dû constituer des milices pour combattre les troupes de Franco. Au Rojava ou au Chiapas, les populations luttent physiquement et quotidiennement pour défendre leur révolution. C’est pour cette raison qu’il est primordial, avant toute chose, de constituer un réseau solide de soutien et de solidarité dès le début, localement mais aussi internationalement. Ceci dit, je m’inscris légèrement en faux avec l’idée qu’historiquement les « forces de l’ordre », pour globaliser, se rangent systématiquement aux côtés du capital.</p> | |||
<p><span><strong>À quoi pensez-vous exactement ?</strong> </span></p><blockquote><p>« Je m’inscris légèrement en faux avec l’idée qu’historiquement les <q>forces de l’ordre</q> se rangent systématiquement aux côtés du capital. »</p></blockquote><p>Il existe quelques exemples, certes rares, qui montrent que ce n’est pas toujours aussi fiable. En 1871, la garde nationale parisienne s’était rangée du côté des communards. En février 1917, à Pétrograd, une partie des troupes avait rejoint les insurgés, c’est d’ailleurs ce qui a fait basculer la révolution de leur côté. En 1974, au Portugal, la révolution des Œillets a été portée par l’armée. Évidemment, tout ça n’a pas forcément débouché sur une société anarchiste, mais il existe parfois de bonnes surprises. Très récemment encore, aux États-Unis, en plein mouvement Black Lives Matter, on a pu voir quelques exemples de policiers ou de gardes nationaux qui ont posé le genou à terre en signe de solidarité. Un démocrate de la chambre des représentants, ancien marine, a appelé les soldats à déposer les armes et à rejoindre les manifestants. Quant au chef du Pentagone, il a exclu de recourir à l’armée alors que Donald Trump le lui avait demandé.</p> | |||
<p><span><strong>Ça reste marginal…</strong></span></p><p>Oui, et il est possible que quelques-uns aient cédé à la pression populaire. Je ne suis pas certaine qu’on verra ceci un jour en France mais, heureusement, rien n’est jamais définitivement écrit. Je voudrais insister sur une époque de l’Histoire qui me semble essentielle, tant elle a de choses à nous apprendre : la révolution sociale espagnole de 1936. Les anarchistes, notamment la <a href="https://fr.wikipedia.org/wiki/Conf%C3%A9d%C3%A9ration_nationale_du_travail_(Espagne)" target="_blank" rel="noopener noreferrer"><span class="caps">CNT-FAI</span></a>, et le <a href="https://fr.wikipedia.org/wiki/Parti_ouvrier_d%27unification_marxiste" target="_blank" rel="noopener noreferrer"><span class="caps">POUM</span></a> ont donc constitué des milices pour défendre la révolution et combattre le fascisme. La situation n’était pas simple mais celles-ci tenaient assez bien leurs positions. Le problème venait du manque d’armes qui leur étaient fournies par l’<span class="caps">URSS</span> de Staline et qui leur étaient refusées par les « démocraties » capitalistes. Or le gouvernement, sous la pression du Parti communiste espagnol, et malgré son consentement apparent aux thèses révolutionnaires, n’a eu de cesse de faire du chantage aux armes et de casser les milices confédérales afin de les remplacer par une armée dont elle pouvait avoir entièrement le contrôle. La morale de cette histoire, c’est qu’il est impossible de faire confiance à l’État et au gouvernement, même quand celui-ci revêt les habits de la révolution.</p> | |||
<p><span><strong>Nous commençons à sortir d’une crise sanitaire mondiale : des États, justement, ont confiné des gens par millions par la force de la loi. À quoi aurait pu ressembler une gestion anarchiste de la pandémie ?</strong></span></p><p>Nous avons eu quelques exemples concrets en France durant le confinement, comme à Dijon, où plusieurs collectifs affiliés à l’espace autogéré des Tanneries ont mis en place un réseau d’entraide pour ravitailler les plus démunis. À Marseille aussi, un McDo a été réquisitionné dans le même but par un autre collectif autogéré. Et on retrouve d’autres exemples de ce type au travers le mouvement des Brigades de solidarité populaire, principalement en Seine-Saint-Denis, mais aussi à Lyon, Nantes, Lille, ceci en collaboration avec les Gilets noirs. Leur slogan en dit long : « Seul le peuple sauve le peuple, pour une autodéfense sanitaire ». Il faut dire qu’avec la gestion totalement catastrophique du gouvernement et l’absence de réponse concrète de l’État, la population a dû très rapidement se convertir à l’autogestion. Chose incroyable pour ses détracteurs : les gens étaient véritablement heureux de pouvoir s’organiser par eux-mêmes ! Dans les quartiers populaires, beaucoup souhaitent d’ailleurs continuer à s’auto-organiser et à agir sans attendre l’État. C’est assez encourageant. Il y a vraiment de quoi être optimiste.</p> | |||
<p><span><strong>C’est à vos yeux une tendance de fond populaire et irréversible ?</strong> </span></p><blockquote><p>« Avec le recul, on peut même se poser la question de l’efficacité des grèves étudiantes pour le climat du vendredi, comme de celle des manifestations… »</p></blockquote><p>Elle l’est. L’envie de faire les choses soi-même, de cultiver de manière saine et de devenir de plus en plus autonome — ce qui est en partie un moyen de s’émanciper. Le problème, c’est que tout le monde n’en est pas au même stade et n’aura pas les mêmes moyens d’atteindre cette autonomie. Et c’est là que peuvent intervenir les anarchistes en créant des réseaux de soutien et de l’entraide entre les zones urbaines et rurales. Il existe un champ des possibles extraordinaire. Et nous comptons bien y participer aussi, avec mon compagnon, en Bretagne où nous souhaitons faire vivre un lieu d’accueil et d’éducation populaire.</p> | |||
<p><span><strong>Début 2019, <span><a href="https://reporterre.net/Le-capitalisme-vert-utilise-Greta-Thunberg" target="_blank" rel="noopener noreferrer">vous aviez mis en garde</a></span> contre les liens qui existent entre Greta Thunberg et le capitalisme vert. Qu’ajouteriez-vous à cet article, remarqué à l’époque, un an plus tard ?</strong></span></p><p>Pas grand-chose. Cette chronique était absolument factuelle et a permis de mettre en avant des éléments que n’importe quel journaliste aurait pu trouver en effectuant quelques recherches sur Internet. Tout a d’ailleurs été vérifié, et confirmé par la suite. À la base, j’effectuais moi-même des recherches pour écrire une chronique sur le problème d’« adultsplaining » que j’avais pu déceler dans diverses émissions. Nous étions alors au tout début de la mobilisation des grèves pour le climat en France. Cette chronique n’a jamais remis en question la sincérité de Greta Thunberg. D’ailleurs, je pense qu’elle a globalement raison dans son analyse concernant la situation écologique dans laquelle nous nous trouvons. Mais comme j’étais la seule voix de gauche à se poser des questions, on a très vite voulu m’assimiler aux attaques de la droite, qui, elles, étaient franchement dégueulasses. Je ne regrette absolument pas d’avoir écrit cette chronique — même si j’ai eu le droit à des insultes qui n’avaient rien à envier à celles que j’avais reçues lors de mon vote en faveur de la loi sur le mariage pour tous ou encore celui où je m’opposais à la prolongation de l’état d’urgence. Ça montre bien cette difficulté à laquelle on doit faire face lorsqu’on ose apporter une critique qui touche une personne que tout le monde a érigé au rang de sauveur. Avec le recul, on peut même se poser la question de l’efficacité des grèves étudiantes pour le climat du vendredi, comme de celle des manifestations…</p> | |||
<p><span><strong>Pourquoi ?</strong></span></p><p>Elles n’avaient pas d’autre objectif que de faire pression sur un gouvernement… qui s’en fiche éperdument. Au mieux, ça aura permis à Yannick Jadot et <span class="caps">EELV</span> de faire un bon score aux élections européennes, ou à quelques <span class="caps">ONG</span> de récolter des financements. J’ai envie de dire : « Quoi d’autre ? » Ce qui me gêne aussi dans la démarche, c’est qu’elle concerne principalement une population urbaine, issue des classes moyennes blanches de l’hémisphère Nord, alors que les premiers concernés par le changement climatique sont plutôt ceux de l’hémisphère Sud. Un mouvement, lorsqu’il se veut révolutionnaire, doit pouvoir être irrigué de toutes parts, que ce soit pour l’écologie, le féminisme, les luttes contre les violences policières, contre les discriminations raciales ou celles fondées sur l’orientation sexuelle et l’identité de genre — il est nécessaire que ce soit très clair et radical, afin d’éviter toute récupération et confusion possible. Aujourd’hui, alors qu’on entame la seconde phase du déconfinement, on entend beaucoup moins toutes ces voix qui s’élevaient à l’époque. On parle encore d’écologie mais on s’attarde bien plus sur la question de la reprise économique. C’est tout à fait légitime puisque ce sont les plus fragiles qui vont subir les effets de la récession, mais ça montre aussi la relative hypocrisie qui règne durant les campagnes électorales.</p><hr/> | |||
<p><span>Illustration de bannière :<a class="preserve-whitespace" href="https://kodap.com/projects"> Carlos Quitério</a> </span><br/> <span>Photographie de vignette : Liberté Bonhomme Libre</span></p></p> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil">🏠</a> • | |||
<a href="/david/log/" title="Accès au flux RSS">🤖</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> • | |||
<abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script type="text/javascript"> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,32 @@ | |||
title: Isabelle Attard : « L’écologie doit s’inscrire au sein du mouvement révolutionnaire » | |||
url: https://www.revue-ballast.fr/isabelle-attard-lecologie-doit-sinscrire-au-sein-du-mouvement-revolutionnaire | |||
hash_url: 703ceb55d78ebb11d4a3035b68d9f956 | |||
<p><span><em>Le temps d’un mandat, Isabelle Attard, archéozoologue de formation, a défendu à l’Assemblée nationale les couleurs d’Europe Écologie – les Verts. Sous les ors du palais Bourbon, elle est l’une des rares députés à s’opposer, en 2015, à la prolongation de l’état d’urgence et, la même année, à celle des frappes aériennes sur le sol syrien. Deux ans après la fin de sa députation, elle publie le livre </em>Comment je suis devenue anarchiste : <em>un ralliement explicite à la tradition libertaire, doublé d’un constat sans appel quant à la possibilité de changer le système de l’intérieur. Certaine que la lutte écologique, féministe et anticapitaliste ne passera plus par la prise du pouvoir central, elle aspire à la création, ici et maintenant, d’espaces parallèles autonomes. Nous en discutons ensemble.<br/> </em></span></p><hr/> | |||
<p><span><strong><picture class="wp-image-73706 size-full alignleft"> | |||
<source type="image/webp" data-lazy-srcset="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg.webp 300w" srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-lazy-sizes="(max-width: 300px) 100vw, 300px"/> | |||
<img src="" data-lazy-srcset="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg 300w, https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle-150x150.jpg 150w, https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle-100x100.jpg 100w" data-lazy-sizes="(max-width: 300px) 100vw, 300px" data-lazy-src="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg"/> | |||
</picture> | |||
<noscript><picture class="wp-image-73706 size-full alignleft"> | |||
<source type="image/webp" srcset="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg.webp 300w" sizes="(max-width: 300px) 100vw, 300px"/> | |||
<img src="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg" srcset="https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle.jpg 300w, https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle-150x150.jpg 150w, https://www.revue-ballast.fr/wp-content/uploads/2020/06/attard-isabelle-100x100.jpg 100w" sizes="(max-width: 300px) 100vw, 300px"/> | |||
</picture> | |||
</noscript>Vous avez été députée cinq ans. Votre constat est sans appel : on ne peut rien faire bouger au sein des institutions. À vos yeux, l’opposition parlementaire est-elle candide, tristement lucide ou vraiment complice ?</strong></span></p><p>Effectivement. Et je peux même dire que je n’étais pas vraiment prévue au programme puisque la circonscription dans laquelle je me suis présentée ne m’était pas du tout favorable. Je débutais en politique et très peu de personnes croyaient en une victoire possible. Je ne la dois finalement qu’à la grande division qui régnait alors à droite comme à gauche. Lorsque je suis entrée à l’Assemblée nationale, je ne faisais pas partie du sérail, j’ai donc découvert son fonctionnement, ainsi que les combinaisons politiques, en me jetant directement dans le grand bain. Comme n’importe quelle personne qui croit encore à ce système, j’étais pétrie de grands principes républicains et d’idéaux démocratiques. J’ai assez vite déchanté. Lorsque je n’ai pas voté le budget en 2013, je me suis de facto retrouvée dans la position d’une opposante à la majorité présidentielle. Dès lors, celle-ci n’a eu de cesse de me marginaliser. La plupart du temps, elle préférait d’ailleurs m’ignorer — il serait même encore plus juste de dire qu’elle me dédaignait. Il n’existe que deux camps à l’Assemblée : soit vous soutenez la majorité, soit vous vous y opposez. C’est très manichéen. Or si j’étais franchement en désaccord avec la politique du gouvernement, je n’avais rien à voir avec l’<span class="caps">UMP</span> ou le <span class="caps">FN</span>. J’ai bien essayé, avec d’autres collègues, déçus comme moi, de proposer en 2015 la création d’un groupe « rouge-rose-vert » qui aurait alors permis d’apporter une autre voix, mais nous n’avons reçu que très peu d’écho.</p> | |||
<p><span><strong>Comment l’expliquez-vous ?</strong></span></p><blockquote><p>« L’Assemblée nationale est un grand théâtre dans lequel la pièce est déjà écrite à l’avance. Chacun y tient le rôle qui lui a été attribué. »</p></blockquote><p>Ça ne correspondait pas à la stratégie des écuries présidentielles de l’époque. Et je ne suis toujours pas convaincue que ça corresponde à celle des partis en place aujourd’hui. L’Assemblée nationale est un grand théâtre dans lequel la pièce est déjà écrite à l’avance. Chacun y tient le rôle qui lui a été attribué. Si vous déviez un tant soit peu de la ligne, vous vous faites aussitôt « excommunier ». Alors, pour répondre à votre question, je pense qu’on peut dire que l’opposition parlementaire joue son rôle : elle s’oppose. Parfois de manière grandiose mais, la plupart du temps, en usant surtout de démagogie car elle sait très bien qu’il lui est impossible de proposer autre chose que des coups d’éclats médiatiques et symboliques. Comment lui en vouloir ? Tout est prévu pour que ça se passe comme ça, et uniquement comme ça.</p> | |||
<p><span><strong>Depuis, vous tenez au mot « anarchisme ». Qu’a‑t-il à vos yeux de plus fécond que « socialisme » ou « communisme » ?</strong></span></p><p>C’est assez simple et, il me semble, très cohérent avec ce que je viens de vous dire. Il faut néanmoins revenir à l’histoire de ces différents courants politiques pour comprendre pourquoi je me suis tournée vers l’anarchisme et pourquoi, aujourd’hui, je revendique fièrement ce mot. <a href="https://www.revue-ballast.fr/tancrede-ramonet/" target="_blank" rel="noopener noreferrer">Tancrède Ramonet</a> l’explique très bien dans son documentaire <em>Ni Dieu ni maître</em>, qui fait partie des ressources qui m’ont accompagnées lors de ce processus de déconstruction-reconstruction politique. Historiquement, le mouvement socialiste s’est divisé en trois grands courants : réformiste, marxiste et anarchiste. Vous aurez bien compris que je ne croyais dorénavant plus au premier, qui a abandonné depuis longtemps l’idée de révolutionner la société et de mettre fin au capitalisme… Quant au deuxième, s’il est possible de partager de nombreuses analyses, voire un objectif commun, je ne me retrouve pas du tout dans la vision autoritaire qui en découle. Mikhaïl Bakounine disait que «<em> la liberté sans le socialisme, c’est le privilège et l’injustice, et le socialisme sans la liberté, c’est l’esclavage et la brutalité</em> ». Je pense également que si le terme « libertaire » n’est pas étroitement associé à ceux de « socialisme » ou de « communisme », alors la société qu’on souhaite construire ne m’intéresse pas. Elle ne m’intéresse d’ailleurs pas du tout, si elle n’est pas aussi féministe et écologiste. Et justement, l’anarchisme a ceci d’incomparable avec les autres courants qui se positionnent à gauche : il s’oppose farouchement à toutes formes de dominations, quelles qu’elles soient.</p> | |||
<p><span><strong>En théorie, en tout cas…</strong></span></p><p>Dans la pratique, il n’est évidemment pas exempt de tous reproches. Derrière des idées, il ne faut jamais oublier qu’il y a des femmes et des hommes qui les défendent. L’aspect psychologique est très présent en politique — et tout le monde n’est pas au même stade de déconstruction ou de reconstruction. Tout le monde n’a pas le même vécu, la même interprétation, les mêmes névroses. Mais il suffit de visionner des documentaires ou de lire des livres sur l’anarchie, écrits par des anarchistes, pour se rendre compte de la grande richesse de cette philosophie. D’ailleurs, si les idées anarchistes n’étaient pas aussi révolutionnaires, on les enseignerait très certainement en classe de terminale. Or on préfère les dénigrer en confondant le terme « anarchie » avec celui de « chaos ». Ça permet ainsi de masquer le véritable chaos, celui qui provient du capitalisme et du libéralisme.</p> | |||
<p><span><strong>C’est d’ailleurs pour cette raison que vous préférez le mot « anarchiste » à celui de « libertaire ».</strong> </span></p><p>J’ai même mis un point d’honneur à l’utiliser dans le titre de mon livre. Il me semble qu’il est temps de le réhabiliter et de l’assumer comme le font de nombreuses autres personnes aujourd’hui. Et puis, il a l’énorme avantage d’être des plus clairs. La clarté, à une époque où le confusionnisme règne, c’est primordial !</p> | |||
<p><span><strong>Noam Chomsky se revendique lui aussi de l’anarchisme. Face au « <em>gang de fous psychopathes</em> » que sont Trump et les siens, il a récemment appelé à voter pour le fort peu révolutionnaire Biden — au motif que refuser de voter pour le moins pire, c’est soutenir « <em>le pire</em> ». Cet argument vous parle-t-il encore ?</strong></span></p><blockquote><p>« Je peux comprendre qu’on puisse préférer un Obama à un Trump. Mais si, dans la forme, ça n’a évidemment rien à voir, sur le fond, les différences se situent seulement à la marge. »</p></blockquote><p>Chomsky est avant tout membre de l’<a href="https://fr.wikipedia.org/wiki/Industrial_Workers_of_the_World" target="_blank" rel="noopener noreferrer">Industrial Workers of the World</a>. Je le précise car il me semble que ça permet de comprendre pourquoi son approche est différente de la plupart des anarchistes. Les <em>Wobblies</em> proviennent de tendances différentes — syndicalistes, socialistes, libertaires, anarchistes ou syndicalistes révolutionnaires — et ont pour objectif de s’unir au sein d’un seul grand syndicat — « One Big Union ». Je trouve l’idée de cette plateforme commune intéressante, mais elle amène à faire certains compromis. Chomsky dit partager l’idéal anarchiste, c’est-à-dire celui qui tend vers un démantèlement du pouvoir étatique. En même temps, il considère que cet idéal entre en conflit direct avec des objectifs immédiats, qui sont de défendre, voire de renforcer certains aspects de l’autorité de l’État. Il l’explique d’ailleurs d’autant mieux dans une analogie qu’il a reprise chez des travailleurs brésiliens. L’État serait une cage qui nous protégerait des fauves que sont les compagnies privées et qui sont en-dehors de celle-ci. La seule perspective que nous donne finalement Noam Chomsky est celle d<em>’étendre les barreaux de la cage</em> en attendant que nous soyons capables de les briser et de combattre les fauves nous-mêmes.<a href="https://www.revue-ballast.fr/labecedaire-de-murray-bookchin/"> Murray Bookchin</a> considérait qu’il était pure folie de vouloir jouer le jeu d’un État centralisé qui avait toujours démontré une excessive complaisance envers ces compagnies. Je pense exactement la même chose que lui.</p><p>Il n’y a rien à attendre des États-nations qui protègent avant tout les intérêts capitalistes. Par contre, je peux comprendre qu’on puisse préférer un Barack Obama à un Donald Trump. Mais si, dans la forme, ça n’a évidemment rien à voir, sur le fond, les différences se situent seulement à la marge. Nous en avons eu l’exemple flagrant dernièrement lorsque Joe Biden a suggéré à la police de viser les jambes plutôt que le cœur pour réduire les tirs mortels. Il n’y a donc jamais de remise en cause globale du système. Il est totalement illusoire de penser qu’il est possible de changer les choses de l’intérieur, notamment en appliquant la « stratégie des petits pas ». Ça ne mène généralement à rien. Par contre, le concept de « gradualisme révolutionnaire » d’<a href="https://fr.wikipedia.org/wiki/Errico_Malatesta" target="_blank" rel="noopener noreferrer">Errico Malatesta</a> me parle beaucoup plus. S’il rejette l’idée d’un Grand Soir révolutionnaire, il n’envisage pas, pour autant, de renforcer l’autorité de l’État. Au contraire, l’idée est d’avancer vers l’anarchie en réalisant un travail de sape qui permettra, au terme d’un processus graduel, de s’émanciper de cette autorité. La renforcer est donc un non-sens. Ce qui n’empêche cependant pas de lutter pour ses droits.</p> | |||
<p><span><strong>Vous avez dit dans une conférence que, écologiquement, nous avons déjà franchi un « <em>point de non retour</em> » : cela signifie-t-il que l’horizon de l’émancipation est de sauver les meubles ?</strong></span></p><p>Il est assez difficile de nier que nous sommes effectivement arrivés à ce point en ce qui concerne le climat et la biodiversité. D’ailleurs, avec le confinement, nous avons pu constater <em>in situ</em> l’impact du capitalisme sur ceux-ci. Il va être très difficile pour les climato-sceptiques d’argumenter après ça — même si je les en crois tout à fait capables… Toutes les études scientifiques vont dans le même sens : nous assistons à une augmentation des températures moyennes océaniques et atmosphériques et à une chute extrêmement brutale de la biodiversité. Ne pas comprendre qu’il s’agit là de phénomènes irréversibles s’appelle tout simplement du déni. Les conséquences, à plus ou moins long terme, auront un impact sur l’ensemble de nos sociétés, tant d’un point de vue écologique que social ou démocratique. Ça a d’ailleurs déjà commencé. Alors je dois avouer que j’ai un peu de mal avec les mouvements qui prétendent qu’« il est encore temps » et qui laissent à penser que nous allons pouvoir sauver la maison des flammes en ne s’attaquant pas au pyromane : le capitalisme. Je sais très bien qu’en disant ceci, je passe pour une personne radicale — mais je considère qu’être radicale est la condition <em>sine qua non</em> à toutes les luttes d’aujourd’hui. D’ailleurs, le mot « radical » me tient tout autant à cœur que celui d’« anarchie ». On en a fait un mot qui fait peur pour dissuader les gens de le devenir : pourtant, ça ne signifie pas autre chose que s’attaquer à la racine du problème !</p><blockquote><p>« J’entends bien cette petite musique lancinante qui cherche à nous convaincre que le problème provient de <q>l’humain</q>. »</p></blockquote><p>Toutefois, je ne suis pas dupe. J’entends bien cette petite musique lancinante qui cherche à nous convaincre que le problème provient de l’humain, de son incapacité à comprendre l’urgence dans laquelle nous nous trouvons aujourd’hui. Cette analyse est dangereuse car elle suggère que la solution se trouve dans la mise en place d’un pouvoir coercitif, voire d’une dictature. Or, qu’elle soit verte, rouge ou bleue, une dictature reste une dictature. Je ne pense pas non plus que la solution viendra de la technologie, qui ne fait que déplacer le problème et qui permet seulement aux multinationales de paraître un peu plus vertes. L’horizon de l’émancipation n’est donc absolument pas de sauver les meubles, et encore moins de ces manières-là. La solution, nous l’avons entre les mains, c’est ce que l’anarchie a prouvé à maintes reprises au cours de notre histoire récente : « <em><span class="noTypo">Don’t mourn, organize! </span></em>» (« <em>Ne vous lamentez pas, organisez vous !</em> » [ndlr])</p> | |||
<p><span><strong>L’écologie, telle qu’on la connaît sous ses formes électorales depuis les années 1970, a‑t-elle entièrement échoué ?<br/> </strong></span></p><p>Si on résume l’écologie politique, et même la politique plus généralement, à l’idée de conquérir le pouvoir par les élections ou par la participation au gouvernement, alors oui, je pense qu’elle a échoué dans son objectif de transformation sociale et sociétale. Elle a peut-être contribué à une meilleure prise en compte de certains sujets ces dernières années mais elle ne s’est pas donnée les moyens de changer radicalement les choses en se bornant à cette stratégie purement électoraliste. La bonne nouvelle, c’est que l’écologie ne se réduit pas uniquement à ça. Il me paraît évident que les mouvements anti-nucléaires, la lutte pour préserver les terres sur le plateau du Larzac, ou encore la <span class="caps">ZAD</span> de Notre-Dame-des-Landes, ont permis d’apporter des propositions beaucoup plus concrètes, de rendre l’utopie palpable. De mon point de vue, l’écologie doit désormais s’inscrire au sein du mouvement révolutionnaire. Et c’est en lisant le livre de <a href="https://www.revue-ballast.fr/floreal-romero-communalisme-se-doter-dune-organisation-1-2/">Floréal Romero</a> et Vincent Gerber,<em> Murray Bookchin, pour une écologie sociale et radicale</em>, que je l’ai enfin compris. Le mouvement écologiste a longtemps ignoré le travail de Murray Bookchin qui a été un précurseur dans les années 1960. Aujourd’hui, il est à la mode : tant mieux ! Pour autant, il s’agit de rester vigilant sur la réappropriation qui peut en être faite. Je me réfère souvent <a href="https://www.revue-ballast.fr/le-moment-communaliste/">à un article de l’un de vos auteurs</a>, Elias Boisjean, qui rappelle qu’«<em> on ne saurait […] enrôler Bookchin sans saisir la cohésion d’ensemble de sa doctrine</em> » et qu’«<em> intégrer un conseil municipal, voire diriger une ville, n’est d’aucun secours si cela ne participe pas d’une transformation globale sans </em><q>compromis avec cet ordre social</q>.<em> Donc de la fin du règne capitaliste au profit d’une</em> <q>société communiste libertaire</q> ».</p> | |||
<p><span><strong>Vous avez d’ailleurs postfacé l’ouvrage <em>Agir ici et maintenant</em>, consacré à Bookchin, à l’écologie sociale et au communalisme. Comment cette proposition permet-elle de répondre à « l’effondrement » dont vous parlez ?</strong></span></p><p>Comme je l’exprime dans mon livre, la lecture de Bookchin a été pour moi une sacrée claque. Comme beaucoup, j’étais passée à côté de son travail et je ne l’ai découvert que très tardivement. Et c’est bien dommage ! Je ne suis pas pour autant une « bookchiniste », dans le sens où je ne considère pas qu’il serait à lui seul l’alpha et l’oméga d’une solution toute prête à un effondrement écologique, social et démocratique. Il reste néanmoins un auteur très important dans le débat anarchiste, même s’il a lui-même été<span>, </span>pour des raisons plus ou moins claires, relativement critique envers le mouvement. Son apport est considérable : il est l’un des premiers à avoir apporté une analyse globale et assez fine de la situation, en y incluant la notion d’écologie qui pouvait parfois faire défaut. Je ne dis pas que l’anarchisme ne se préoccupait pas d’écologie avant lui mais il me semble qu’il a réussi à en faire la pierre angulaire du projet de société qu’il propose.</p><p>La véritable claque a été de comprendre qu’il fallait arrêter de jouer à un jeu auquel nous serions toujours perdants et qu’il s’agissait dorénavant de créer une déviation ou une dérivation du système, si nous voulions radicalement et foncièrement en sortir. L’effondrement, même si on peut employer d’autres mots tant celui-ci a été récupéré, sera vraisemblablement assez violent. C’est logique, puisque nous sommes déjà entrés dans une ère de transformation dont nous ne maîtrisons plus entièrement le processus. Il va donc falloir que nous réfléchissions à nous adapter à ces changements, à plus ou moins long terme. L’État, qui protège les intérêts des compagnies privées et plus généralement du capitalisme, va continuer à durcir ses relations avec celles et ceux qui s’opposent à lui. Nous pouvons donc continuer exclusivement à nous opposer frontalement à lui en espérant qu’il s’effondre de lui-même, ce qui me semble hasardeux et peut-être même dangereux puisque nous risquons le conflit direct avec des forces réactionnaires. Mais nous pouvons aussi commencer à créer cette dérivation dont je parle, en créant des espaces autonomes et en les reliant entre eux. Dans mon esprit, les deux choix ne sont pas incompatibles.</p> | |||
<p><span><strong>Comment ça ?</strong></span></p><blockquote><p>« Nous avons un exemple concret devant nos yeux, au Rojava. Nous ne partons pas de zéro — même si les conditions ne sont pas entièrement semblables. »</p></blockquote><p>Ça correspond à l’esprit du gradualisme révolutionnaire de Malatesta, dont je vous parlais. L’écologie sociale a cette particularité qui permet à la fois d’amortir le choc auquel nous allons devoir nous confronter mais aussi de préparer « l’après », dans la perspective d’un effondrement de l’État-nation. C’est en lisant le livre de <a href="https://www.revue-ballast.fr/lemancipation-kurde-face-aux-pouvoirs-syriens/">Raphaël Lebrujah</a> sur le Rojava, <i>Comprendre le Rojava dans la guerre civile syrienne</i>, que je me suis aperçue que nous avions un exemple concret devant nos yeux. Nous ne partons pas de zéro — même si les conditions ne sont pas entièrement semblables et même si la culture politique peut s’avérer aussi relativement différente.</p> | |||
<p><span><strong>Dans son dernier ouvrage, <em>Trop tard pour être pessimistes !</em>, l’écosocialiste Daniel Tanuro objecte aux tenants des solutions locales ou communales qu’il faut, face aux « <em>défis terribles</em> » auxquels nous sommes confrontés, travailler à un «<em> plan de transition</em> » écologique coordonné, lequel passe obligatoirement par la prise du pouvoir politique, c’est-à-dire de l’État. Cette objection ne vous convainc donc pas ?</strong></span></p><p>Je n’ai pas encore pu lire ce livre [<em>paru le 10 juin 2020, ndlr</em>] : je me garderai donc bien d’en parler. Surtout que, d’après la quatrième de couverture, il semblerait que nous partagions plus ou moins le même constat sur la collapsologie, le capitalisme vert ou le Green New Deal. Par contre, si l’idée est de conquérir le pouvoir et, comme vous dites, par extension l’État, je ne vois rien de révolutionnaire là-dedans. Nous pourrions alors réellement dire que cela signifie que l’horizon de l’émancipation consiste à sauver les meubles. Il m’est impossible de concevoir l’émancipation si ça ne permet pas aux individus de prendre part, de manière directe, au fonctionnement démocratique. C’est un principe de base. C’est pour cette raison que je suis anarchiste. En tous cas, je suis d’accord avec le titre du livre de Daniel Tanuro : oui, il est trop tard pour être pessimistes. Et, là encore, je vais faire référence à Malatesta lorsqu’il pense que la révolution est un acte de volonté et que son action a deux objectifs bien clairs : la destruction violente des obstacles à la liberté, et la diffusion graduelle de la pratique de la liberté, privée de toutes coercitions. Le seul moyen de faire face aux « défis terribles » qui s’annoncent me semble d’y répondre justement de manière audacieuse, et l’anarchie s’y prête merveilleusement bien.</p> | |||
<p><span><strong>La police française compte environ 150 000 agents, la gendarmerie 100 000 et l’armée plus de 40 000. L’extrême droite y est massivement présente. Comment imaginer les possibilités d’une transformation radicale face à cette colossale puissance de feu, qui, l’Histoire en est témoin, se rangera aux côtés du capital si celui-ci est menacé ?</strong></span></p><p>L’État dispose effectivement d’un outil très puissant, dont il se sert à outrance depuis quelques temps déjà. Le fait que l’extrême droite y soit massivement représentée n’arrange rien, même si ça ne change rien à l’affaire. C’est pour cette raison que je vous disais que la confrontation directe avec l’État n’était peut-être pas, à mes yeux, la meilleure stratégie. En tous cas, elle ne peut être la seule. Maintenant, je peux comprendre que le niveau de colère des gens soit tel qu’ils souhaitent en découdre avec ce qui symbolise, un peu trop à mon goût, l’État et le gouvernement. Il est impossible d’éluder la question de la confrontation physique avec les forces réactionnaires lors d’un processus révolutionnaire. Penser que le changement se fera intégralement de manière non-violente, en se déguisant en bisounours, est totalement illusoire. Ou alors, c’est que le changement proposé est très loin d’être radical, quand il n’est pas carrément un faux-nez du capitalisme. Je suis pacifiste et anti-militariste, mais je ne suis pas naïve. Bookchin parle d’ailleurs de constituer une milice populaire pour défendre les communes libertaires. C’était déjà la question lors de la Commune de Paris. En 1936, les républicains et les anarchistes avaient aussi dû constituer des milices pour combattre les troupes de Franco. Au Rojava ou au Chiapas, les populations luttent physiquement et quotidiennement pour défendre leur révolution. C’est pour cette raison qu’il est primordial, avant toute chose, de constituer un réseau solide de soutien et de solidarité dès le début, localement mais aussi internationalement. Ceci dit, je m’inscris légèrement en faux avec l’idée qu’historiquement les « forces de l’ordre », pour globaliser, se rangent systématiquement aux côtés du capital.</p> | |||
<p><span><strong>À quoi pensez-vous exactement ?</strong> </span></p><blockquote><p>« Je m’inscris légèrement en faux avec l’idée qu’historiquement les <q>forces de l’ordre</q> se rangent systématiquement aux côtés du capital. »</p></blockquote><p>Il existe quelques exemples, certes rares, qui montrent que ce n’est pas toujours aussi fiable. En 1871, la garde nationale parisienne s’était rangée du côté des communards. En février 1917, à Pétrograd, une partie des troupes avait rejoint les insurgés, c’est d’ailleurs ce qui a fait basculer la révolution de leur côté. En 1974, au Portugal, la révolution des Œillets a été portée par l’armée. Évidemment, tout ça n’a pas forcément débouché sur une société anarchiste, mais il existe parfois de bonnes surprises. Très récemment encore, aux États-Unis, en plein mouvement Black Lives Matter, on a pu voir quelques exemples de policiers ou de gardes nationaux qui ont posé le genou à terre en signe de solidarité. Un démocrate de la chambre des représentants, ancien marine, a appelé les soldats à déposer les armes et à rejoindre les manifestants. Quant au chef du Pentagone, il a exclu de recourir à l’armée alors que Donald Trump le lui avait demandé.</p> | |||
<p><span><strong>Ça reste marginal…</strong></span></p><p>Oui, et il est possible que quelques-uns aient cédé à la pression populaire. Je ne suis pas certaine qu’on verra ceci un jour en France mais, heureusement, rien n’est jamais définitivement écrit. Je voudrais insister sur une époque de l’Histoire qui me semble essentielle, tant elle a de choses à nous apprendre : la révolution sociale espagnole de 1936. Les anarchistes, notamment la <a href="https://fr.wikipedia.org/wiki/Conf%C3%A9d%C3%A9ration_nationale_du_travail_(Espagne)" target="_blank" rel="noopener noreferrer"><span class="caps">CNT-FAI</span></a>, et le <a href="https://fr.wikipedia.org/wiki/Parti_ouvrier_d%27unification_marxiste" target="_blank" rel="noopener noreferrer"><span class="caps">POUM</span></a> ont donc constitué des milices pour défendre la révolution et combattre le fascisme. La situation n’était pas simple mais celles-ci tenaient assez bien leurs positions. Le problème venait du manque d’armes qui leur étaient fournies par l’<span class="caps">URSS</span> de Staline et qui leur étaient refusées par les « démocraties » capitalistes. Or le gouvernement, sous la pression du Parti communiste espagnol, et malgré son consentement apparent aux thèses révolutionnaires, n’a eu de cesse de faire du chantage aux armes et de casser les milices confédérales afin de les remplacer par une armée dont elle pouvait avoir entièrement le contrôle. La morale de cette histoire, c’est qu’il est impossible de faire confiance à l’État et au gouvernement, même quand celui-ci revêt les habits de la révolution.</p> | |||
<p><span><strong>Nous commençons à sortir d’une crise sanitaire mondiale : des États, justement, ont confiné des gens par millions par la force de la loi. À quoi aurait pu ressembler une gestion anarchiste de la pandémie ?</strong></span></p><p>Nous avons eu quelques exemples concrets en France durant le confinement, comme à Dijon, où plusieurs collectifs affiliés à l’espace autogéré des Tanneries ont mis en place un réseau d’entraide pour ravitailler les plus démunis. À Marseille aussi, un McDo a été réquisitionné dans le même but par un autre collectif autogéré. Et on retrouve d’autres exemples de ce type au travers le mouvement des Brigades de solidarité populaire, principalement en Seine-Saint-Denis, mais aussi à Lyon, Nantes, Lille, ceci en collaboration avec les Gilets noirs. Leur slogan en dit long : « Seul le peuple sauve le peuple, pour une autodéfense sanitaire ». Il faut dire qu’avec la gestion totalement catastrophique du gouvernement et l’absence de réponse concrète de l’État, la population a dû très rapidement se convertir à l’autogestion. Chose incroyable pour ses détracteurs : les gens étaient véritablement heureux de pouvoir s’organiser par eux-mêmes ! Dans les quartiers populaires, beaucoup souhaitent d’ailleurs continuer à s’auto-organiser et à agir sans attendre l’État. C’est assez encourageant. Il y a vraiment de quoi être optimiste.</p> | |||
<p><span><strong>C’est à vos yeux une tendance de fond populaire et irréversible ?</strong> </span></p><blockquote><p>« Avec le recul, on peut même se poser la question de l’efficacité des grèves étudiantes pour le climat du vendredi, comme de celle des manifestations… »</p></blockquote><p>Elle l’est. L’envie de faire les choses soi-même, de cultiver de manière saine et de devenir de plus en plus autonome — ce qui est en partie un moyen de s’émanciper. Le problème, c’est que tout le monde n’en est pas au même stade et n’aura pas les mêmes moyens d’atteindre cette autonomie. Et c’est là que peuvent intervenir les anarchistes en créant des réseaux de soutien et de l’entraide entre les zones urbaines et rurales. Il existe un champ des possibles extraordinaire. Et nous comptons bien y participer aussi, avec mon compagnon, en Bretagne où nous souhaitons faire vivre un lieu d’accueil et d’éducation populaire.</p> | |||
<p><span><strong>Début 2019, <span><a href="https://reporterre.net/Le-capitalisme-vert-utilise-Greta-Thunberg" target="_blank" rel="noopener noreferrer">vous aviez mis en garde</a></span> contre les liens qui existent entre Greta Thunberg et le capitalisme vert. Qu’ajouteriez-vous à cet article, remarqué à l’époque, un an plus tard ?</strong></span></p><p>Pas grand-chose. Cette chronique était absolument factuelle et a permis de mettre en avant des éléments que n’importe quel journaliste aurait pu trouver en effectuant quelques recherches sur Internet. Tout a d’ailleurs été vérifié, et confirmé par la suite. À la base, j’effectuais moi-même des recherches pour écrire une chronique sur le problème d’« adultsplaining » que j’avais pu déceler dans diverses émissions. Nous étions alors au tout début de la mobilisation des grèves pour le climat en France. Cette chronique n’a jamais remis en question la sincérité de Greta Thunberg. D’ailleurs, je pense qu’elle a globalement raison dans son analyse concernant la situation écologique dans laquelle nous nous trouvons. Mais comme j’étais la seule voix de gauche à se poser des questions, on a très vite voulu m’assimiler aux attaques de la droite, qui, elles, étaient franchement dégueulasses. Je ne regrette absolument pas d’avoir écrit cette chronique — même si j’ai eu le droit à des insultes qui n’avaient rien à envier à celles que j’avais reçues lors de mon vote en faveur de la loi sur le mariage pour tous ou encore celui où je m’opposais à la prolongation de l’état d’urgence. Ça montre bien cette difficulté à laquelle on doit faire face lorsqu’on ose apporter une critique qui touche une personne que tout le monde a érigé au rang de sauveur. Avec le recul, on peut même se poser la question de l’efficacité des grèves étudiantes pour le climat du vendredi, comme de celle des manifestations…</p> | |||
<p><span><strong>Pourquoi ?</strong></span></p><p>Elles n’avaient pas d’autre objectif que de faire pression sur un gouvernement… qui s’en fiche éperdument. Au mieux, ça aura permis à Yannick Jadot et <span class="caps">EELV</span> de faire un bon score aux élections européennes, ou à quelques <span class="caps">ONG</span> de récolter des financements. J’ai envie de dire : « Quoi d’autre ? » Ce qui me gêne aussi dans la démarche, c’est qu’elle concerne principalement une population urbaine, issue des classes moyennes blanches de l’hémisphère Nord, alors que les premiers concernés par le changement climatique sont plutôt ceux de l’hémisphère Sud. Un mouvement, lorsqu’il se veut révolutionnaire, doit pouvoir être irrigué de toutes parts, que ce soit pour l’écologie, le féminisme, les luttes contre les violences policières, contre les discriminations raciales ou celles fondées sur l’orientation sexuelle et l’identité de genre — il est nécessaire que ce soit très clair et radical, afin d’éviter toute récupération et confusion possible. Aujourd’hui, alors qu’on entame la seconde phase du déconfinement, on entend beaucoup moins toutes ces voix qui s’élevaient à l’époque. On parle encore d’écologie mais on s’attarde bien plus sur la question de la reprise économique. C’est tout à fait légitime puisque ce sont les plus fragiles qui vont subir les effets de la récession, mais ça montre aussi la relative hypocrisie qui règne durant les campagnes électorales.</p><hr/> | |||
<p><span>Illustration de bannière :<a class="preserve-whitespace" href="https://kodap.com/projects"> Carlos Quitério</a> </span><br/> <span>Photographie de vignette : Liberté Bonhomme Libre</span></p> |
@@ -0,0 +1,187 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="fr"> | |||
<!-- Has to be within the first 1024 bytes, hence before the <title> | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>Missing structure in technical discussions (archive) — David Larlet</title> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f0f0ea"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f0f0ea"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2020-06-19.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script type="text/javascript"> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="http://kvark.github.io/tech/arguments/2020/06/30/technical-discussions.html"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick"> | |||
<article> | |||
<h1>Missing structure in technical discussions</h1> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil" tabindex="1">🏠</a> | |||
</p> | |||
</nav> | |||
<hr> | |||
<h2><a href="http://kvark.github.io/tech/arguments/2020/06/30/technical-discussions.html">Source originale du contenu</a></h2> | |||
<p>People are amazing creatures. When discussing a complex issue, they are able to keep multiple independent | |||
arguments in their heads, the pieces of supporting and disproving evidence, and can collapse this system | |||
into a concrete solution. We can spend hours navigating through the issue comments on Github, reconstructing | |||
the points of view, and making sense of the discussion. Problem is: we don’t actually want to apply this | |||
superpower and waste time nearly as often.</p> | |||
<h2 id="problem-with-technical-discussions">Problem with technical discussions</h2> | |||
<p>Have you heard of <code class="language-plaintext highlighter-rouge">async</code> in Rust? Ever wondered why the core team opted into a completely new syntax for this feature? Let’s dive in and find out! Here is <a href="https://github.com/rust-lang/rust/issues/57640">#57640</a> with 512 comments, kindly asking everyone to check <a href="https://github.com/rust-lang/rust/issues/50547">#50547</a> (with just 308 comments) before expressing their point of view. Following this discussion must have been exhausting. I don’t know how it would be possible to navigate it without the <a href="https://github.com/rust-lang/rust/issues/57640#issuecomment-456624074">summary</a> <a href="https://github.com/rust-lang/rust/issues/57640#issuecomment-456625030">comments</a>.</p> | |||
<p>Another example is the loop syntax in WebGPU. Issue <a href="https://github.com/gpuweb/gpuweb/issues/569">#569</a> has only 70 comments, with multiple attempts to <a href="https://github.com/gpuweb/gpuweb/issues/569#issuecomment-610041440">summarize</a> the discussion in the middle. It would probably take a few hours at the minimum to get a gist of the group reasoning for somebody from the outside. And that doesn’t include the call transcripts.</p> | |||
<p>Github has emojis which allow certain comments to show more support. Unfortunately, our nature is such that comments are getting liked when we agree with them, not when they advance the discussion in a constructive way. They are all over the place and don’t really help.</p> | |||
<p>What would help though is having a non-linear structure for the discussion. Trees! They make following HN and Reddit threads much easier, but they too have problems. Sometimes, a really important comment is buried deep in one of the branches. Plus, trees don’t work well for a dialog, when there is some back-and-forth between people.</p> | |||
<p>That brings us to the point: most technical discussions are <em>terrible</em>. Not in a sense that people can’t make good points and progress through it, but rather that there is no structure to a discussion, and it’s too hard to follow. What I see in reality is a lot of focus from a very few dedicated people, and delegation by the other ones to those focused. Many views get misrepresented, and many perspectives never heard, because the flow of comments quickly filters out most potential participants.</p> | |||
<h2 id="structured-discussion">Structured discussion</h2> | |||
<p>My first stop in the search of a solution was on <a href="https://www.discourse.org/">Discourse</a>. It is successfully used by many communities, including <a href="https://users.rust-lang.org/">Rust users</a>. Unfortunately, it still has linear structure, and doesn’t bring a lot to the table on top of Github. Try following <a href="https://users.rust-lang.org/t/rust-2020-growth/34956">this discussion | |||
</a> about Rust in 2020 for example.</p> | |||
<p>Then I looked at platforms designed specifically for a structured argumentation. One of the most popular today is <a href="https://www.kialo.com/">Kialo</a>. I haven’t done a good evaluation on it, but it seemed that Kialo isn’t targeted at engineers, and it’s a platform that we’d have to register in for use. Wishing to use Markdown with a system like that, I stumbled upon <a href="https://argdown.org/">Argdown</a>, and realized that it concluded my search.</p> | |||
<p>Argdown introduces a syntax for defining the structure of an argument in text. Statements, arguments, propositions, conclusions - it has it all, written simply in your text editor (especially if its VSCode, for which there is a plugin), or in the <a href="https://argdown.org/sandbox/html">playground</a>. It has command-line tools to produce all sorts of derivatives, like dot graphs, web components, JSON, you name it, from an <code class="language-plaintext highlighter-rouge">.argdown</code> file. Naturally, formatting with Markdown in it is also supported.</p> | |||
<p>That discovery led me to two questions. (1) - what would an <em>existing</em> debate look like in such a system? And (2) - how could we shift the workflow towards using one?</p> | |||
<p>So I picked the most contentious topic in WebGPU discussions and tried to reconstruct it. Topic was about choosing the shading language, and why SPIR-V wasn’t accepted. It was discussed by the W3C group over the course of 2+ years, and it’s evident that there is <a href="https://github.com/gpuweb/gpuweb/issues/847#issuecomment-642497578">some</a> <a href="https://news.ycombinator.com/item?id=23089745">misunderstanding</a> of why the decision was made to go with WGSL, taking Google’s Tint proposal as a starting point.</p> | |||
<p>I attempted to reconstruct the debate in https://github.com/kvark/webgpu-debate, building the <a href="https://github.com/kvark/webgpu-debate/blob/b28252ea99aef8989858ece09f74dc0758e3d46c/arguments/SPIR-V.argdown">SPIR-V.argdown</a> with the first version of the argumentation graph, solving (1). The repository accepts pull requests that are checked by CI for syntax correctness, inviting everyone to collaborate, solving (2). Moreover, the artifacts are automatically uploaded to Github-pages, rendering the <a href="https://kvark.github.io/webgpu-debate/SPIR-V.component.html">discussion</a> in a way that is easy to explore.</p> | |||
<h2 id="way-forward">Way forward</h2> | |||
<p>I’m excited to have this new way of preserving and growing the structure of a technical debate. We can keep using the code hosting platforms, and arguing on the issues and PR, while solidifying the core points in these <code class="language-plaintext highlighter-rouge">.argdown</code> files. I hope to see it applied more widely to the workflows of technical working groups.</p> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil">🏠</a> • | |||
<a href="/david/log/" title="Accès au flux RSS">🤖</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> • | |||
<abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script type="text/javascript"> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,40 @@ | |||
title: Missing structure in technical discussions | |||
url: http://kvark.github.io/tech/arguments/2020/06/30/technical-discussions.html | |||
hash_url: 892a6dcf591157833a162335d4878043 | |||
<p>People are amazing creatures. When discussing a complex issue, they are able to keep multiple independent | |||
arguments in their heads, the pieces of supporting and disproving evidence, and can collapse this system | |||
into a concrete solution. We can spend hours navigating through the issue comments on Github, reconstructing | |||
the points of view, and making sense of the discussion. Problem is: we don’t actually want to apply this | |||
superpower and waste time nearly as often.</p> | |||
<h2 id="problem-with-technical-discussions">Problem with technical discussions</h2> | |||
<p>Have you heard of <code class="language-plaintext highlighter-rouge">async</code> in Rust? Ever wondered why the core team opted into a completely new syntax for this feature? Let’s dive in and find out! Here is <a href="https://github.com/rust-lang/rust/issues/57640">#57640</a> with 512 comments, kindly asking everyone to check <a href="https://github.com/rust-lang/rust/issues/50547">#50547</a> (with just 308 comments) before expressing their point of view. Following this discussion must have been exhausting. I don’t know how it would be possible to navigate it without the <a href="https://github.com/rust-lang/rust/issues/57640#issuecomment-456624074">summary</a> <a href="https://github.com/rust-lang/rust/issues/57640#issuecomment-456625030">comments</a>.</p> | |||
<p>Another example is the loop syntax in WebGPU. Issue <a href="https://github.com/gpuweb/gpuweb/issues/569">#569</a> has only 70 comments, with multiple attempts to <a href="https://github.com/gpuweb/gpuweb/issues/569#issuecomment-610041440">summarize</a> the discussion in the middle. It would probably take a few hours at the minimum to get a gist of the group reasoning for somebody from the outside. And that doesn’t include the call transcripts.</p> | |||
<p>Github has emojis which allow certain comments to show more support. Unfortunately, our nature is such that comments are getting liked when we agree with them, not when they advance the discussion in a constructive way. They are all over the place and don’t really help.</p> | |||
<p>What would help though is having a non-linear structure for the discussion. Trees! They make following HN and Reddit threads much easier, but they too have problems. Sometimes, a really important comment is buried deep in one of the branches. Plus, trees don’t work well for a dialog, when there is some back-and-forth between people.</p> | |||
<p>That brings us to the point: most technical discussions are <em>terrible</em>. Not in a sense that people can’t make good points and progress through it, but rather that there is no structure to a discussion, and it’s too hard to follow. What I see in reality is a lot of focus from a very few dedicated people, and delegation by the other ones to those focused. Many views get misrepresented, and many perspectives never heard, because the flow of comments quickly filters out most potential participants.</p> | |||
<h2 id="structured-discussion">Structured discussion</h2> | |||
<p>My first stop in the search of a solution was on <a href="https://www.discourse.org/">Discourse</a>. It is successfully used by many communities, including <a href="https://users.rust-lang.org/">Rust users</a>. Unfortunately, it still has linear structure, and doesn’t bring a lot to the table on top of Github. Try following <a href="https://users.rust-lang.org/t/rust-2020-growth/34956">this discussion | |||
</a> about Rust in 2020 for example.</p> | |||
<p>Then I looked at platforms designed specifically for a structured argumentation. One of the most popular today is <a href="https://www.kialo.com/">Kialo</a>. I haven’t done a good evaluation on it, but it seemed that Kialo isn’t targeted at engineers, and it’s a platform that we’d have to register in for use. Wishing to use Markdown with a system like that, I stumbled upon <a href="https://argdown.org/">Argdown</a>, and realized that it concluded my search.</p> | |||
<p>Argdown introduces a syntax for defining the structure of an argument in text. Statements, arguments, propositions, conclusions - it has it all, written simply in your text editor (especially if its VSCode, for which there is a plugin), or in the <a href="https://argdown.org/sandbox/html">playground</a>. It has command-line tools to produce all sorts of derivatives, like dot graphs, web components, JSON, you name it, from an <code class="language-plaintext highlighter-rouge">.argdown</code> file. Naturally, formatting with Markdown in it is also supported.</p> | |||
<p>That discovery led me to two questions. (1) - what would an <em>existing</em> debate look like in such a system? And (2) - how could we shift the workflow towards using one?</p> | |||
<p>So I picked the most contentious topic in WebGPU discussions and tried to reconstruct it. Topic was about choosing the shading language, and why SPIR-V wasn’t accepted. It was discussed by the W3C group over the course of 2+ years, and it’s evident that there is <a href="https://github.com/gpuweb/gpuweb/issues/847#issuecomment-642497578">some</a> <a href="https://news.ycombinator.com/item?id=23089745">misunderstanding</a> of why the decision was made to go with WGSL, taking Google’s Tint proposal as a starting point.</p> | |||
<p>I attempted to reconstruct the debate in https://github.com/kvark/webgpu-debate, building the <a href="https://github.com/kvark/webgpu-debate/blob/b28252ea99aef8989858ece09f74dc0758e3d46c/arguments/SPIR-V.argdown">SPIR-V.argdown</a> with the first version of the argumentation graph, solving (1). The repository accepts pull requests that are checked by CI for syntax correctness, inviting everyone to collaborate, solving (2). Moreover, the artifacts are automatically uploaded to Github-pages, rendering the <a href="https://kvark.github.io/webgpu-debate/SPIR-V.component.html">discussion</a> in a way that is easy to explore.</p> | |||
<h2 id="way-forward">Way forward</h2> | |||
<p>I’m excited to have this new way of preserving and growing the structure of a technical debate. We can keep using the code hosting platforms, and arguing on the issues and PR, while solidifying the core points in these <code class="language-plaintext highlighter-rouge">.argdown</code> files. I hope to see it applied more widely to the workflows of technical working groups.</p> |
@@ -0,0 +1,192 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="fr"> | |||
<!-- Has to be within the first 1024 bytes, hence before the <title> | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>Towards carbon negativity (archive) — David Larlet</title> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f0f0ea"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f0f0ea"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2020-06-19.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script type="text/javascript"> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="https://m.signalvnoise.com/towards-carbon-negativity/"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick"> | |||
<article> | |||
<h1>Towards carbon negativity</h1> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil" tabindex="1">🏠</a> | |||
</p> | |||
</nav> | |||
<hr> | |||
<h2><a href="https://m.signalvnoise.com/towards-carbon-negativity/">Source originale du contenu</a></h2> | |||
<p>Humans have been pumping greenhouse gases into Earth’s atmosphere at an unsustainable rate. It’s on us to reverse course as quickly as possible to stay below the <a href="https://www.ipcc.ch/sr15/" target="_blank" rel="noreferrer noopener">tipping point of 1.5℃</a> global warming. Without action, the future is beyond bleak.</p> | |||
<p><strong>At Basecamp, we’re committing to becoming carbon negative for our cumulative history and moving forward.<br/><br/></strong>The first step of that commitment is understanding the size of our carbon footprint. We’ve just completed our first carbon footprinting exercise as a company and are publishing our results. By sharing our approach, we hope to make it easier for other companies to also join the collective mission to carbon negativity. </p> | |||
<p><strong>In 2019, Basecamp’s estimated carbon footprint was ~820 t</strong><a href="https://www.theguardian.com/environment/2011/apr/27/co2e-global-warming-potential" target="_blank" rel="noreferrer noopener"><strong>CO2e</strong></a><strong>.</strong> Here’s how that breaks down:</p> | |||
<p>🏘 <strong>Remote offices: ~5 tCO2e</strong><br/>Basecamp is a remote company which means even in the pre-COVID era, we mostly <a href="https://m.signalvnoise.com/remote-working-the-home-office-desks-of-basecamp/" target="_blank" rel="noreferrer noopener">work from home</a>. The power drawn to run our work computers and monitors are attributable to Basecamp. We roughly estimated power drawn for 50 Basecampers whose homes are not powered by renewable energy, a laptop + monitor/person for 40 hours/week/Basecamper, 47 work weeks/year, and a CO2e/kWH emissions factor from the US electricity supply average.</p> | |||
<p>🛌 <strong>Event lodging and meals: ~20 tCO2e<br/></strong>As a company, we typically hold two in-person gatherings a year. We also occasionally travel to attend conferences for professional development or train new team members. The majority of the non-transportation emissions from these gatherings are tied to hotel stays, using emission factors from the <a href="https://www.hotelfootprints.org/footprinting" target="_blank" rel="noreferrer noopener">Cornell Hotel Sustainability Benchmarking Index</a>.</p> | |||
<p>💻 <strong>Hardware manufacturing + end-of-life: ~25 tCO2e<br/></strong>There are emissions associated with the production and disposal of each laptop, monitor, on-prem server, etc. we use as a company. Those emissions can be prorated by the hardware’s expected lifespan for each year. Several manufacturers helpfully publish their own carbon footprint estimates for their devices so we used those specs to calculate the emissions associated with 56 laptops and monitors and 55 on-prem databases.</p> | |||
<p>✈️ <strong>Transportation: ~75 tCO2e<br/></strong>Basecampers flew nearly 400k miles (644k km) and traveled roughly 35k miles (56k km) over ground combined in 2019 for meetups, conferences, and trainings. Those travels translate into roughly 63 tCO2e for flights and 12 tCO2e for ground transport based on <a href="https://www.epa.gov/sites/production/files/2020-01/documents/egrid2018_summary_tables.pdf" target="_blank" rel="noreferrer noopener">EPA emissions data</a>.</p> | |||
<p><strong>🗄 On-prem hosting: ~80 tCO2e<br/></strong>We run several of our applications in on-prem data centers. It takes energy to host the apps, to the tune of roughly 330,000 kWH in 2019. One of our on-prem data centers is powered via an emission-free energy supply contract. After excluding the power from that data center, we translated the power consumption from our remaining on-prem data servers using emissions factors from the <a href="https://www.eia.gov/electricity/state/" target="_blank" rel="noreferrer noopener">US Energy Information Administration</a> and global warming potentials from the <a href="https://www.epa.gov/ghgemissions/overview-greenhouse-gases" target="_blank" rel="noreferrer noopener">US Environmental Protection Agency</a>.</p> | |||
<p>🏢 <strong> Company office: ~120 tCO2e<br/></strong>For the last ten years, Basecamp has <a href="https://basecamp.com/about/office" target="_blank" rel="noreferrer noopener">had a headquarters office</a> in Chicago. It’s a beautiful space that was the gathering grounds for our company meetups. Turns out, that office is also heated by electricity and we used a whopping 261,130 kWH in 2019. In Illinois, 60% of power is generated from fossil fuels so that consumption translates into more emissions than all of our company transportation in 2019. This realization was one of the most shocking findings from our carbon footprint. We’re <a href="https://rework.fm/office-space/" target="_blank" rel="noreferrer noopener">saying goodbye to the office in July</a>. </p> | |||
<p>📚 <strong>Printed books: ~135 tCO2e<br/></strong>Basecamp’s founders have written several <a href="https://basecamp.com/books" target="_blank" rel="noreferrer noopener">books</a> including <em>REMOTE</em>, <em>REWORK</em>, and <em>It Doesn’t Have to be Crazy at Work</em>. Approximately 45k copies sold in 2019 combined. Using a <a href="https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1530-9290.2011.00414.x" target="_blank" rel="noreferrer noopener">benchmark</a> of 3 kg CO2e/book puts the footprint of these books in the same ballpark as the company office emissions.</p> | |||
<p><strong>☁️ Cloud hosting (including data transfers and storage): ~285 tCO2e<br/></strong>We also use Amazon Web Services to run our apps, with a few supporting infrastructure on Google Cloud Platform. Cloud data centers use a lot of electricity, though there are efficiencies gained by scale. However, not all cloud services are equal from a climate change perspective. Since 2017, GCP has <a href="https://cloud.google.com/sustainability/" target="_blank" rel="noreferrer noopener">added enough additional renewable energy</a>sources to the grids its data centers are on to be considered carbon neutral. AWS <a href="https://aws.amazon.com/about-aws/sustainability/" target="_blank" rel="noreferrer noopener">can’t say the same thing</a>. </p> | |||
<p>It’s tough to estimate the carbon footprint of AWS service usage as they do not share power consumption as a metric. So to estimate, we broke down data we do have — server hours used, GB data transferred, and GB stored — and converted to energy consumed and carbon emissions from there. We assumed a 30% discount in power usage for AWS’ servers, based on their own <a href="https://d39w7f4ix9f5s9.cloudfront.net/e3/79/42bf75c94c279c67d777f002051f/carbon-reduction-opportunity-of-moving-to-aws.pdf" target="_blank" rel="noreferrer noopener">commissioned report</a> on how much savings typically comes from facility efficiency and renewable energy usage. We then used an extrapolated <a href="https://3.basecamp.com/2914079/buckets/13688293/uploads/2691570270">research estimate</a> of kWh/GB used to transfer data over the Internet. Overall, this method led to an estimated 580,000 kWH for cloud compute, 633,000 kWH for data transfer, and 140,000 kWH for data storage in regions that aren’t fully carbon offset in 2019.</p> | |||
<p>There is a lot of uncertainty in this estimate, in both directions:</p> | |||
<ul><li>On one hand, AWS could merit a higher discount on emissions. Their current stated goal is to get to 100% energy offset by 2030 and a significant portion of the renewable energy projects they have invested in appear to be going into the grids that power our apps. We just don’t know for sure and so erred on the environmentally conservative side.</li><li>On the other hand, the extrapolated energy intensity we used for data transfer emissions could have been too generous. If there are any informed experts on the carbon footprint of data transfer out there, we’d love to learn from your work.</li></ul> | |||
<p><strong>🐛 Wiggle room: 75 tCO2e<br/></strong>Since this is our first time doing a carbon footprinting, we assume we’ve missed something decently substantial. For instance, we have not gone through to footprint the upstream indirect emissions from other software vendors, many of which are also hosted on AWS. In an attempt to account for these unknowns, this wiggle room category is an additional 10% of associated emissions.</p> | |||
<p><strong>So in total, this puts us at ~820 tCO2e for 2019. </strong>We’ve also projected a footprint of ~770 tCO2e for 2020 and estimated a very rough historical cumulative carbon footprint of 6,000 tCO2e for 1999-2018.</p> | |||
<p>But there’s one more unaccounted for unknown worth mentioning:</p> | |||
<p>💰 <strong>Banking: ??? tCO2e<br/></strong>Money makes the world run and we’re cognizant that our banking partner could easily be the largest source of indirect emissions. In the course of our research, we found a <a href="https://www.ran.org/wp-content/uploads/2018/06/financing_global_warming_(1).pdf" target="_blank" rel="noreferrer noopener">2008 report from the Rainforest Action Network</a> that was very eye-opening on the potential footprint. We’re looking for more recent research or data that could help us factor in the indirect emissions from our deposit accounts.</p> | |||
<hr class="wp-block-separator"/> | |||
<p>In the next few weeks, Basecamp will purchase enough certified carbon credits to offset our estimated cumulative carbon footprint and make us carbon neutral. To get to carbon negative, we further invest at least a further $100,000 each year starting this year (2020) to sponsor new carbon offsetting projects. </p> | |||
<p>We will also place even more emphasis internally on the <em>reduction </em>of our own emissions: through our choice of vendors, our company events, and our software design. The environmental benefit of not emitting is more certain and immediate than the eventual carbon sequestration from reforestation projects and emerging technologies. We can emit less and we’re going to do the work to do so.</p> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil">🏠</a> • | |||
<a href="/david/log/" title="Accès au flux RSS">🤖</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> • | |||
<abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script type="text/javascript"> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,84 @@ | |||
title: Towards carbon negativity | |||
url: https://m.signalvnoise.com/towards-carbon-negativity/ | |||
hash_url: 8ecfc6fbf4a4d3293144458db9c8a57d | |||
<p>Humans have been pumping greenhouse gases into Earth’s atmosphere at an unsustainable rate. It’s on us to reverse course as quickly as possible to stay below the <a href="https://www.ipcc.ch/sr15/" target="_blank" rel="noreferrer noopener">tipping point of 1.5℃</a> global warming. Without action, the future is beyond bleak.</p> | |||
<p><strong>At Basecamp, we’re committing to becoming carbon negative for our cumulative history and moving forward.<br/><br/></strong>The first step of that commitment is understanding the size of our carbon footprint. We’ve just completed our first carbon footprinting exercise as a company and are publishing our results. By sharing our approach, we hope to make it easier for other companies to also join the collective mission to carbon negativity. </p> | |||
<p><strong>In 2019, Basecamp’s estimated carbon footprint was ~820 t</strong><a href="https://www.theguardian.com/environment/2011/apr/27/co2e-global-warming-potential" target="_blank" rel="noreferrer noopener"><strong>CO2e</strong></a><strong>.</strong> Here’s how that breaks down:</p> | |||
<p>🏘 <strong>Remote offices: ~5 tCO2e</strong><br/>Basecamp is a remote company which means even in the pre-COVID era, we mostly <a href="https://m.signalvnoise.com/remote-working-the-home-office-desks-of-basecamp/" target="_blank" rel="noreferrer noopener">work from home</a>. The power drawn to run our work computers and monitors are attributable to Basecamp. We roughly estimated power drawn for 50 Basecampers whose homes are not powered by renewable energy, a laptop + monitor/person for 40 hours/week/Basecamper, 47 work weeks/year, and a CO2e/kWH emissions factor from the US electricity supply average.</p> | |||
<p>🛌 <strong>Event lodging and meals: ~20 tCO2e<br/></strong>As a company, we typically hold two in-person gatherings a year. We also occasionally travel to attend conferences for professional development or train new team members. The majority of the non-transportation emissions from these gatherings are tied to hotel stays, using emission factors from the <a href="https://www.hotelfootprints.org/footprinting" target="_blank" rel="noreferrer noopener">Cornell Hotel Sustainability Benchmarking Index</a>.</p> | |||
<p>💻 <strong>Hardware manufacturing + end-of-life: ~25 tCO2e<br/></strong>There are emissions associated with the production and disposal of each laptop, monitor, on-prem server, etc. we use as a company. Those emissions can be prorated by the hardware’s expected lifespan for each year. Several manufacturers helpfully publish their own carbon footprint estimates for their devices so we used those specs to calculate the emissions associated with 56 laptops and monitors and 55 on-prem databases.</p> | |||
<p>✈️ <strong>Transportation: ~75 tCO2e<br/></strong>Basecampers flew nearly 400k miles (644k km) and traveled roughly 35k miles (56k km) over ground combined in 2019 for meetups, conferences, and trainings. Those travels translate into roughly 63 tCO2e for flights and 12 tCO2e for ground transport based on <a href="https://www.epa.gov/sites/production/files/2020-01/documents/egrid2018_summary_tables.pdf" target="_blank" rel="noreferrer noopener">EPA emissions data</a>.</p> | |||
<p><strong>🗄 On-prem hosting: ~80 tCO2e<br/></strong>We run several of our applications in on-prem data centers. It takes energy to host the apps, to the tune of roughly 330,000 kWH in 2019. One of our on-prem data centers is powered via an emission-free energy supply contract. After excluding the power from that data center, we translated the power consumption from our remaining on-prem data servers using emissions factors from the <a href="https://www.eia.gov/electricity/state/" target="_blank" rel="noreferrer noopener">US Energy Information Administration</a> and global warming potentials from the <a href="https://www.epa.gov/ghgemissions/overview-greenhouse-gases" target="_blank" rel="noreferrer noopener">US Environmental Protection Agency</a>.</p> | |||
<p>🏢 <strong> Company office: ~120 tCO2e<br/></strong>For the last ten years, Basecamp has <a href="https://basecamp.com/about/office" target="_blank" rel="noreferrer noopener">had a headquarters office</a> in Chicago. It’s a beautiful space that was the gathering grounds for our company meetups. Turns out, that office is also heated by electricity and we used a whopping 261,130 kWH in 2019. In Illinois, 60% of power is generated from fossil fuels so that consumption translates into more emissions than all of our company transportation in 2019. This realization was one of the most shocking findings from our carbon footprint. We’re <a href="https://rework.fm/office-space/" target="_blank" rel="noreferrer noopener">saying goodbye to the office in July</a>. </p> | |||
<p>📚 <strong>Printed books: ~135 tCO2e<br/></strong>Basecamp’s founders have written several <a href="https://basecamp.com/books" target="_blank" rel="noreferrer noopener">books</a> including <em>REMOTE</em>, <em>REWORK</em>, and <em>It Doesn’t Have to be Crazy at Work</em>. Approximately 45k copies sold in 2019 combined. Using a <a href="https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1530-9290.2011.00414.x" target="_blank" rel="noreferrer noopener">benchmark</a> of 3 kg CO2e/book puts the footprint of these books in the same ballpark as the company office emissions.</p> | |||
<p><strong>☁️ Cloud hosting (including data transfers and storage): ~285 tCO2e<br/></strong>We also use Amazon Web Services to run our apps, with a few supporting infrastructure on Google Cloud Platform. Cloud data centers use a lot of electricity, though there are efficiencies gained by scale. However, not all cloud services are equal from a climate change perspective. Since 2017, GCP has <a href="https://cloud.google.com/sustainability/" target="_blank" rel="noreferrer noopener">added enough additional renewable energy</a>sources to the grids its data centers are on to be considered carbon neutral. AWS <a href="https://aws.amazon.com/about-aws/sustainability/" target="_blank" rel="noreferrer noopener">can’t say the same thing</a>. </p> | |||
<p>It’s tough to estimate the carbon footprint of AWS service usage as they do not share power consumption as a metric. So to estimate, we broke down data we do have — server hours used, GB data transferred, and GB stored — and converted to energy consumed and carbon emissions from there. We assumed a 30% discount in power usage for AWS’ servers, based on their own <a href="https://d39w7f4ix9f5s9.cloudfront.net/e3/79/42bf75c94c279c67d777f002051f/carbon-reduction-opportunity-of-moving-to-aws.pdf" target="_blank" rel="noreferrer noopener">commissioned report</a> on how much savings typically comes from facility efficiency and renewable energy usage. We then used an extrapolated <a href="https://3.basecamp.com/2914079/buckets/13688293/uploads/2691570270">research estimate</a> of kWh/GB used to transfer data over the Internet. Overall, this method led to an estimated 580,000 kWH for cloud compute, 633,000 kWH for data transfer, and 140,000 kWH for data storage in regions that aren’t fully carbon offset in 2019.</p> | |||
<p>There is a lot of uncertainty in this estimate, in both directions:</p> | |||
<ul><li>On one hand, AWS could merit a higher discount on emissions. Their current stated goal is to get to 100% energy offset by 2030 and a significant portion of the renewable energy projects they have invested in appear to be going into the grids that power our apps. We just don’t know for sure and so erred on the environmentally conservative side.</li><li>On the other hand, the extrapolated energy intensity we used for data transfer emissions could have been too generous. If there are any informed experts on the carbon footprint of data transfer out there, we’d love to learn from your work.</li></ul> | |||
<p><strong>🐛 Wiggle room: 75 tCO2e<br/></strong>Since this is our first time doing a carbon footprinting, we assume we’ve missed something decently substantial. For instance, we have not gone through to footprint the upstream indirect emissions from other software vendors, many of which are also hosted on AWS. In an attempt to account for these unknowns, this wiggle room category is an additional 10% of associated emissions.</p> | |||
<p><strong>So in total, this puts us at ~820 tCO2e for 2019. </strong>We’ve also projected a footprint of ~770 tCO2e for 2020 and estimated a very rough historical cumulative carbon footprint of 6,000 tCO2e for 1999-2018.</p> | |||
<p>But there’s one more unaccounted for unknown worth mentioning:</p> | |||
<p>💰 <strong>Banking: ??? tCO2e<br/></strong>Money makes the world run and we’re cognizant that our banking partner could easily be the largest source of indirect emissions. In the course of our research, we found a <a href="https://www.ran.org/wp-content/uploads/2018/06/financing_global_warming_(1).pdf" target="_blank" rel="noreferrer noopener">2008 report from the Rainforest Action Network</a> that was very eye-opening on the potential footprint. We’re looking for more recent research or data that could help us factor in the indirect emissions from our deposit accounts.</p> | |||
<hr class="wp-block-separator"/> | |||
<p>In the next few weeks, Basecamp will purchase enough certified carbon credits to offset our estimated cumulative carbon footprint and make us carbon neutral. To get to carbon negative, we further invest at least a further $100,000 each year starting this year (2020) to sponsor new carbon offsetting projects. </p> | |||
<p>We will also place even more emphasis internally on the <em>reduction </em>of our own emissions: through our choice of vendors, our company events, and our software design. The environmental benefit of not emitting is more certain and immediate than the eventual carbon sequestration from reforestation projects and emerging technologies. We can emit less and we’re going to do the work to do so.</p> |
@@ -0,0 +1,196 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="fr"> | |||
<!-- Has to be within the first 1024 bytes, hence before the <title> | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>On dependency (archive) — David Larlet</title> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f0f0ea"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f0f0ea"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2020-06-19.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script type="text/javascript"> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="https://v7.robweychert.com/blog/2020/06/v7-on-dependency/"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick"> | |||
<article> | |||
<h1>On dependency</h1> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil" tabindex="1">🏠</a> | |||
</p> | |||
</nav> | |||
<hr> | |||
<h2><a href="https://v7.robweychert.com/blog/2020/06/v7-on-dependency/">Source originale du contenu</a></h2> | |||
<p>I might have expected quarantine life to be a boon to my site’s redesign process since most of my preferred social distractions were nullified. Instead, I’ve been using the time in isolation to make music videos, finalize a home purchase, move into said home, and try to find my place in our national reckoning on racism and public safety reform. But as I slowly shift some of my attention back to the redesign, I’ve been thinking about one aspect of it through the lens of the pandemic.<p> | |||
<p>Early in the lockdown, when the future of the supply chain was uncertain and everyone was panic shopping, I imagined all the doomsday preppers out there must have been feeling pretty smug. While the rest of the world freaked out, I pictured them calmly swinging their bunker doors shut and gazing fetishistically at their stockpiles of food, fuel, and ammunition, secure in their self-sufficiency. But how self-sufficient are they really? Did they grow and can that food? Did they smelt the steel and fashion their firearms from it? Did they mix the gunpowder? Did they build the internal combustion engines that power their generators? Did they extract and refine the oil that powers those engines?</p> | |||
<p>This coronavirus crisis has shone a light on one of the defining conflicts of American society: individualism versus collectivism. How much should we be willing to collectively sacrifice for the sake of relatively few individuals? Where do we fall on the spectrum between Ayn Rand and Karl Marx? Where do <em>I</em> end and <em>we</em> begin? When 20 million jobs evaporated in the space of a month, it wasn’t because the “free market” and “individual liberty,” two phrases that often appear in close proximity, are actually compatible. The enraged libertarians who flooded statehouses and demanded that the economy reopen were, on the one hand, insisting that they shouldn’t be affected by what they see as other people’s problems. On the other hand, ironically, they were expressing <em>a need to interact with other people</em>; people who can do things for them that they can’t or don’t want to do for themselves: cut their hair, serve them a cocktail, sell them a gun.</p> | |||
<p>If everyone were truly self-sufficient, most of us would be too busy tending our crops and repairing our roofs to do much else. Advances in technology, medicine, art, sport, and so much more would be sacrificed for the sake of a lot of replicated effort with middling results. We’d be alive, but we’d hardly be living. Instead, we develop more focused skillsets and work together. I can make hammers and you can make nails; I’ll trade you some of mine for some of yours. By depending on each other, we can accomplish more and better things.</p> | |||
<hr> | |||
<p>Back in the world of web design, I sometimes kid myself that I operate with a degree of self-sufficiency. I’m formally trained in graphic design and I’ve spent decades honing skills in user experience design, HTML, and CSS. My work is generally more content-focused than app-focused, so my limited JavaScript skills aren’t often an impediment. If you want a simple informational website (which, in my opinion, tends to be the best kind), I’ve got you covered.</p> | |||
<p>But I can’t host your site or even my own site. I didn’t build the CMS. Other people made the hardware and software I use to generate and optimize images. Other people made the fonts. Other people standardized the digital formats for those images and fonts. I didn’t write the HTML and CSS specifications, nor the browsers that interpret them, nor the operating systems that run the browsers. I didn’t solder the circuit boards. And so on.</p> | |||
<p>I say all this in the hopes of making it painfully clear that I’m a big believer in the power of collaboration, the reduction of replicated effort, and the beauty of human interdependency.</p> | |||
<p>The open source community has produced countless wonderful examples of what collaboration and interdependency can achieve. My own work has benefitted greatly from it, and in recent years I’ve stepped up my efforts to contribute, making <a href="https://github.com/propublica/column-setter">tools</a> available and sharing detailed write-ups of how my projects are <a href="https://v6.robweychert.com/blog/2019/02/introducing-tinnitus-tracker/">conceived</a> and <a href="https://v6.robweychert.com/blog/2018/09/revisiting-incomplete-open-cubes/">created</a>.</p> | |||
<p><strong>Nevertheless, I’m very selective about how I depend on other people’s work in my personal projects. Here are the factors I consider when evaluating dependencies.</strong></p> | |||
<h3 id="complexity">Complexity</h3> | |||
<p><em>How complex is it, who absorbs the cost of that complexity, and is that acceptable?</em></p> | |||
<p>The more use cases something is meant to accommodate, the more complex it is, and therefore, the less efficient it is. In many cases, this isn’t a big deal. Adobe Illustrator can do a zillion things I don’t need, but for the stuff I do need from it, the outsize CPU and hard drive space it uses are a worthy sacrifice. However, I prefer not to assume that someone visiting my website is willing to make that same sacrifice. A 2K SVG icon I created with Illustrator shouldn’t require you to download all 1.39GB of Illustrator to view that icon. That would be <a href="https://daverupert.com/2020/06/tradeoffs-and-shifting-complexity/">passing too much complexity</a>—and therefore inefficiency—to the user, and I’m not okay with that. This is why I can’t abide frameworks like React and Bootstrap. They’re excessively complex, and the user shares the cost to an unacceptable degree.</p> | |||
<h3 id="comprehensibility">Comprehensibility</h3> | |||
<p><em>Do I understand how it works, and if not, does that matter?</em> | |||
<p>I’m a designer who writes front-end code. I don’t wish to pretend that makes me a software developer. So I try to keep my command line interactions to a minimum: mostly just a handful of Git, Sass, and Jekyll commands. I don’t understand their inner workings, but I have a satisfactory mental model of what they do, I know what to expect from them, and I rarely get into trouble.</p> | |||
<p>Where I do get into trouble is with complicated tool chains: the “modern dev stack.” I get why they’re popular—compiling, optimizing, minifying, and deploying all in one keystroke sure can save you time. But even if, like Git and Sass, I understand well enough what each individual piece does, things get confusing quickly when they’re all bundled together. These tool chains are only as good as their weakest link, and when things start going wrong, I find myself in the weeds pretty quickly. The constant need for updates, Node version management, Bash versus Zsh, dependencies on dependencies on dependencies… No thanks. Maybe someday I’ll get onboard with that way of working, but for now, the extensibility isn’t worth the frustration of the incessant troubleshooting. I don’t understand well enough how it works (and believe me, I’ve tried), and that matters.</p> | |||
<h3 id="reliability">Reliability</h3> | |||
<p><em>How consistently and for how long can I expect it to work?</em></p> | |||
<p>I try to build things to last, so I need the stuff they’re made of to be sturdy. Hopefully it goes without saying that I want well constructed code and assets, but a big part of the reliability factor is also making sure those things have a stable home. Central to my current site redesign is reclaiming my content from ephemeral and/or otherwise untrustworthy social media services. Why shouldn’t I want to own the design as much as I own the content? As much as possible, I prefer to buy rather than rent, and to keep everything under one roof, which keeps me away from things like remote CDNs like AWS and hosted web font services like Typekit. I want to have access to all the pieces of my site in perpetuity, and I want them to live at a domain I control.</p> | |||
<hr> | |||
<p>At the end of the day, I try to make sure every piece of what I put on the web is appropriate, necessary, and as simple as possible, which generally requires me to essentially handcraft the vast majority of it myself. My preferred approach isn’t a terribly efficient way of working. Starting with a simple boilerplate HTML file in lieu of “<code>npx create-react-app my-app</code>” has been somewhat derisively <a href="https://dev.to/richharris/in-defense-of-the-modern-web-2nia">described</a> as “old guard” and “artisanal.” And I suppose it is to some degree tantamount to swinging my bunker door shut and gazing fetishistically at my stockpile of food, fuel, and ammunition.</p> | |||
<p>But I have no illusions about being some kind of lone wolf. All the stuff I’m making “by hand”—the way it approaches form, function, and materials—has been informed by philosophies and techniques developed by an amorphous community that spans generations. This work proliferates through byzantine open source projects, yes, but it also proliferates through books, blog posts, and videos with titles like “<a href="https://css-tricks.com/custom-styling-form-inputs-with-modern-css-features/">Custom Styling Form Inputs With Modern CSS Features</a>.” When I’m making things, that’s how I prefer to depend on others and have them depend on me: by sharing strong, simple ideas as a collective, and recombining them in novel ways with rigorous specificity as individuals.</p> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil">🏠</a> • | |||
<a href="/david/log/" title="Accès au flux RSS">🤖</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> • | |||
<abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script type="text/javascript"> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,49 @@ | |||
title: On dependency | |||
url: https://v7.robweychert.com/blog/2020/06/v7-on-dependency/ | |||
hash_url: 959add1c9fe6dc27e1ee1ee8960b930b | |||
<p>I might have expected quarantine life to be a boon to my site’s redesign process since most of my preferred social distractions were nullified. Instead, I’ve been using the time in isolation to make music videos, finalize a home purchase, move into said home, and try to find my place in our national reckoning on racism and public safety reform. But as I slowly shift some of my attention back to the redesign, I’ve been thinking about one aspect of it through the lens of the pandemic.<p> | |||
<p>Early in the lockdown, when the future of the supply chain was uncertain and everyone was panic shopping, I imagined all the doomsday preppers out there must have been feeling pretty smug. While the rest of the world freaked out, I pictured them calmly swinging their bunker doors shut and gazing fetishistically at their stockpiles of food, fuel, and ammunition, secure in their self-sufficiency. But how self-sufficient are they really? Did they grow and can that food? Did they smelt the steel and fashion their firearms from it? Did they mix the gunpowder? Did they build the internal combustion engines that power their generators? Did they extract and refine the oil that powers those engines?</p> | |||
<p>This coronavirus crisis has shone a light on one of the defining conflicts of American society: individualism versus collectivism. How much should we be willing to collectively sacrifice for the sake of relatively few individuals? Where do we fall on the spectrum between Ayn Rand and Karl Marx? Where do <em>I</em> end and <em>we</em> begin? When 20 million jobs evaporated in the space of a month, it wasn’t because the “free market” and “individual liberty,” two phrases that often appear in close proximity, are actually compatible. The enraged libertarians who flooded statehouses and demanded that the economy reopen were, on the one hand, insisting that they shouldn’t be affected by what they see as other people’s problems. On the other hand, ironically, they were expressing <em>a need to interact with other people</em>; people who can do things for them that they can’t or don’t want to do for themselves: cut their hair, serve them a cocktail, sell them a gun.</p> | |||
<p>If everyone were truly self-sufficient, most of us would be too busy tending our crops and repairing our roofs to do much else. Advances in technology, medicine, art, sport, and so much more would be sacrificed for the sake of a lot of replicated effort with middling results. We’d be alive, but we’d hardly be living. Instead, we develop more focused skillsets and work together. I can make hammers and you can make nails; I’ll trade you some of mine for some of yours. By depending on each other, we can accomplish more and better things.</p> | |||
<hr> | |||
<p>Back in the world of web design, I sometimes kid myself that I operate with a degree of self-sufficiency. I’m formally trained in graphic design and I’ve spent decades honing skills in user experience design, HTML, and CSS. My work is generally more content-focused than app-focused, so my limited JavaScript skills aren’t often an impediment. If you want a simple informational website (which, in my opinion, tends to be the best kind), I’ve got you covered.</p> | |||
<p>But I can’t host your site or even my own site. I didn’t build the CMS. Other people made the hardware and software I use to generate and optimize images. Other people made the fonts. Other people standardized the digital formats for those images and fonts. I didn’t write the HTML and CSS specifications, nor the browsers that interpret them, nor the operating systems that run the browsers. I didn’t solder the circuit boards. And so on.</p> | |||
<p>I say all this in the hopes of making it painfully clear that I’m a big believer in the power of collaboration, the reduction of replicated effort, and the beauty of human interdependency.</p> | |||
<p>The open source community has produced countless wonderful examples of what collaboration and interdependency can achieve. My own work has benefitted greatly from it, and in recent years I’ve stepped up my efforts to contribute, making <a href="https://github.com/propublica/column-setter">tools</a> available and sharing detailed write-ups of how my projects are <a href="https://v6.robweychert.com/blog/2019/02/introducing-tinnitus-tracker/">conceived</a> and <a href="https://v6.robweychert.com/blog/2018/09/revisiting-incomplete-open-cubes/">created</a>.</p> | |||
<p><strong>Nevertheless, I’m very selective about how I depend on other people’s work in my personal projects. Here are the factors I consider when evaluating dependencies.</strong></p> | |||
<h3 id="complexity">Complexity</h3> | |||
<p><em>How complex is it, who absorbs the cost of that complexity, and is that acceptable?</em></p> | |||
<p>The more use cases something is meant to accommodate, the more complex it is, and therefore, the less efficient it is. In many cases, this isn’t a big deal. Adobe Illustrator can do a zillion things I don’t need, but for the stuff I do need from it, the outsize CPU and hard drive space it uses are a worthy sacrifice. However, I prefer not to assume that someone visiting my website is willing to make that same sacrifice. A 2K SVG icon I created with Illustrator shouldn’t require you to download all 1.39GB of Illustrator to view that icon. That would be <a href="https://daverupert.com/2020/06/tradeoffs-and-shifting-complexity/">passing too much complexity</a>—and therefore inefficiency—to the user, and I’m not okay with that. This is why I can’t abide frameworks like React and Bootstrap. They’re excessively complex, and the user shares the cost to an unacceptable degree.</p> | |||
<h3 id="comprehensibility">Comprehensibility</h3> | |||
<p><em>Do I understand how it works, and if not, does that matter?</em> | |||
<p>I’m a designer who writes front-end code. I don’t wish to pretend that makes me a software developer. So I try to keep my command line interactions to a minimum: mostly just a handful of Git, Sass, and Jekyll commands. I don’t understand their inner workings, but I have a satisfactory mental model of what they do, I know what to expect from them, and I rarely get into trouble.</p> | |||
<p>Where I do get into trouble is with complicated tool chains: the “modern dev stack.” I get why they’re popular—compiling, optimizing, minifying, and deploying all in one keystroke sure can save you time. But even if, like Git and Sass, I understand well enough what each individual piece does, things get confusing quickly when they’re all bundled together. These tool chains are only as good as their weakest link, and when things start going wrong, I find myself in the weeds pretty quickly. The constant need for updates, Node version management, Bash versus Zsh, dependencies on dependencies on dependencies… No thanks. Maybe someday I’ll get onboard with that way of working, but for now, the extensibility isn’t worth the frustration of the incessant troubleshooting. I don’t understand well enough how it works (and believe me, I’ve tried), and that matters.</p> | |||
<h3 id="reliability">Reliability</h3> | |||
<p><em>How consistently and for how long can I expect it to work?</em></p> | |||
<p>I try to build things to last, so I need the stuff they’re made of to be sturdy. Hopefully it goes without saying that I want well constructed code and assets, but a big part of the reliability factor is also making sure those things have a stable home. Central to my current site redesign is reclaiming my content from ephemeral and/or otherwise untrustworthy social media services. Why shouldn’t I want to own the design as much as I own the content? As much as possible, I prefer to buy rather than rent, and to keep everything under one roof, which keeps me away from things like remote CDNs like AWS and hosted web font services like Typekit. I want to have access to all the pieces of my site in perpetuity, and I want them to live at a domain I control.</p> | |||
<hr> | |||
<p>At the end of the day, I try to make sure every piece of what I put on the web is appropriate, necessary, and as simple as possible, which generally requires me to essentially handcraft the vast majority of it myself. My preferred approach isn’t a terribly efficient way of working. Starting with a simple boilerplate HTML file in lieu of “<code>npx create-react-app my-app</code>” has been somewhat derisively <a href="https://dev.to/richharris/in-defense-of-the-modern-web-2nia">described</a> as “old guard” and “artisanal.” And I suppose it is to some degree tantamount to swinging my bunker door shut and gazing fetishistically at my stockpile of food, fuel, and ammunition.</p> | |||
<p>But I have no illusions about being some kind of lone wolf. All the stuff I’m making “by hand”—the way it approaches form, function, and materials—has been informed by philosophies and techniques developed by an amorphous community that spans generations. This work proliferates through byzantine open source projects, yes, but it also proliferates through books, blog posts, and videos with titles like “<a href="https://css-tricks.com/custom-styling-form-inputs-with-modern-css-features/">Custom Styling Form Inputs With Modern CSS Features</a>.” When I’m making things, that’s how I prefer to depend on others and have them depend on me: by sharing strong, simple ideas as a collective, and recombining them in novel ways with rigorous specificity as individuals.</p> |
@@ -0,0 +1,176 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="fr"> | |||
<!-- Has to be within the first 1024 bytes, hence before the <title> | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>Ned Batchelder: 2500 (archive) — David Larlet</title> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f0f0ea"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f0f0ea"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2020-06-19.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script type="text/javascript"> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="https://nedbatchelder.com//blog/202006/2500.html"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick"> | |||
<article> | |||
<h1>Ned Batchelder: 2500</h1> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil" tabindex="1">🏠</a> | |||
</p> | |||
</nav> | |||
<hr> | |||
<h2><a href="https://nedbatchelder.com//blog/202006/2500.html">Source originale du contenu</a></h2> | |||
<p>This is the 2500th post on this blog. That’s a lot of writing. I estimate | |||
this site has about 480,000 words in total, enough for five books.</p> | |||
<p>I’ve been writing here for more than 18 years. The pace is different than | |||
when I started: last year I wrote <a href="//nedbatchelder.com/blog/archive/year2019.html">33 | |||
posts</a>. Compare that to 2003, when I wrote more than ten times as many: | |||
<a href="//nedbatchelder.com/blog/archive/year2003.html">441 posts</a>! | |||
<a href="https://twitter.com/nedbat" rel="external noopener">Twitter</a> has siphoned off some of the | |||
short-post energy, but also interests shift over time.</p> | |||
<p>Writing is a good way to understand things, and to learn things. People | |||
mostly think of writing as a way to teach and explain, and I am glad when my | |||
posts can do that. But I also really value the feedback loop of learning as I | |||
explain, and the deeper understanding I find when I teach.</p> | |||
<p>Here’s a common piece of advice from people who create things: to make better | |||
things, make more things. Not only does it give you constant practice at making | |||
things, but it gives you more chances at lucking into making a good thing.</p> | |||
<p>These days I set myself a goal of writing two posts a month. I find the goal | |||
helpful. It prods me to dig for topics. Some will be duds, but sometimes an | |||
apparently boring idea will turn out well.</p> | |||
<p>I can’t promise everything (or anything!) will be interesting or insightful. | |||
But I’ll keep writing here. Thanks for reading.</p> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil">🏠</a> • | |||
<a href="/david/log/" title="Accès au flux RSS">🤖</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> • | |||
<abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script type="text/javascript"> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,19 @@ | |||
title: Ned Batchelder: 2500 | |||
url: https://nedbatchelder.com//blog/202006/2500.html | |||
hash_url: b7f574586eccd0b9c844876c18ac0ca5 | |||
<p>This is the 2500th post on this blog. That’s a lot of writing. I estimate | |||
this site has about 480,000 words in total, enough for five books.</p><p>I’ve been writing here for more than 18 years. The pace is different than | |||
when I started: last year I wrote <a href="//nedbatchelder.com/blog/archive/year2019.html">33 | |||
posts</a>. Compare that to 2003, when I wrote more than ten times as many: | |||
<a href="//nedbatchelder.com/blog/archive/year2003.html">441 posts</a>! | |||
<a href="https://twitter.com/nedbat" rel="external noopener">Twitter</a> has siphoned off some of the | |||
short-post energy, but also interests shift over time.</p><p>Writing is a good way to understand things, and to learn things. People | |||
mostly think of writing as a way to teach and explain, and I am glad when my | |||
posts can do that. But I also really value the feedback loop of learning as I | |||
explain, and the deeper understanding I find when I teach.</p><p>Here’s a common piece of advice from people who create things: to make better | |||
things, make more things. Not only does it give you constant practice at making | |||
things, but it gives you more chances at lucking into making a good thing.</p><p>These days I set myself a goal of writing two posts a month. I find the goal | |||
helpful. It prods me to dig for topics. Some will be duds, but sometimes an | |||
apparently boring idea will turn out well.</p><p>I can’t promise everything (or anything!) will be interesting or insightful. | |||
But I’ll keep writing here. Thanks for reading.</p> |
@@ -0,0 +1,380 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="fr"> | |||
<!-- Has to be within the first 1024 bytes, hence before the <title> | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>Fuck Costco (archive) — David Larlet</title> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f0f0ea"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f0f0ea"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2020-06-19.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script type="text/javascript"> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="https://www.leteignoir.com/2020/06/fuck-costco.html"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick"> | |||
<article> | |||
<h1>Fuck Costco</h1> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil" tabindex="1">🏠</a> | |||
</p> | |||
</nav> | |||
<hr> | |||
<h2><a href="https://www.leteignoir.com/2020/06/fuck-costco.html">Source originale du contenu</a></h2> | |||
<p> | |||
Les Québécois ont un trouble obsessionnel-compulsif avec le Costco. Ou monomaniaque, je ne sais trop, je ne suis pas psychiatre, même si je suis capable de reconnaître des malades quand j’en vois. Quand elle m’a entendu lire « Fuck le troisième lien », Myriam Ségal m’a accusé de mépriser les banlieusards et le déclencheur - le<i> trigger</i>, comme disent les jeunes - fut que je m’en prisse à la triade « boulot-costco-dodo », un syntagme que j’empruntais, je dois lui en faire crédit, à Samuel Archibald. Comme tous les Québécois, Ségal parle régulièrement du Costco, lequel semblait se mêler étrangement à son argumentaire en faveur du troisième lien, malgré qu’il existe deux autres franchises du grossiste sur la rive nord. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Le Costco est un incontournable des réunions de famille. Mes parents en parlent tout le temps, engageant des discussions animées qui me font une mise à jour ponctuelle des progrès de l'ingénierie culinaire dans la société de consommation avancée : une machine d’emballage sous vide, un lave-vaisselle de comptoir, une éclateuse à pop-corn, que sais-je encore. Je ferme ma gueule, n’ayant rien à dire. C’est généralement le moment où je m’éclipse pour jouer avec les enfants. Mes parents s’insèrent, ceci dit, dans une tendance sociale profonde : un groupe sur facebook, Les accrocs du Costco, compte 200 000 membres, et plusieurs autres groupes similaires en ajoutent quelques dizaines de milliers au total. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Le Costco est un lieu commun de la psyché collective. Tout le monde s’y reconnaît. En dépit de son apparente banalité, et contrairement aux trivialités de la vie quotidienne, tout ce qui est relié à la catégorie Costco est toujours digne de mention. Aller au Costco, dire qu’on a pris quelque chose au Costco, comparer les prix des produits en rapport de ce qu’ils coûtent au Costco, faire sonner le mot Costco dans les conversations - tout cela semble animer des passions enfouies et met de la vie dans les discussions. Le Costco est une expérience définitive de la vie québécoise. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
En semblant mépriser ouvertement le Costco, je faisais preuve - <i>encore</i> - de mon étrangeté au corps social auquel je prétends appartenir. Il y a un principe d’identité fort exprimé par Myriam Ségal : le Québec est une banlieue, et vivre en banlieue c’est aller au Costco. La radio de Québec nous l’enseigne depuis longtemps, il y a le vrai monde qui travaille et consomme, et les hippies du centre-ville qui critiquent les premiers en se pognant le beigne. Ils sont à la fois pauvres et snobs, ils n’ont pas de char ou pas de famille ou pas des deux, et donc ne vont pas au Costco.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Je pourrais quand même pas parler de quelque chose que je ne connais pas, right ? Alors comme je suis un essayiste de terrain, j’ai demandé à une amie de m’y amener lorsque l’état de ses stocks le justifierait. « On va en profiter pour arrêter à la SQDC en passant » me dit-elle, savourant au passage cette nouvelle normalité québécoise. Pour être bien honnête, ma mère m’y avait amené quand j’étais jeune pis que ça s’appelait Club Price. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Ça n’a pas beaucoup changé. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
<b>***</b></p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Le monstre est en périphérie, proche des autoroutes, pratique pour le transport des marchandises et des consommateurs motorisés. Nouvelle modalité de la pauvreté contemporaine : le commun n’a pas accès à la beauté. Les centre-villes ne sont pas gentrifiés pour rien. La proximité, la communauté, le patrimoine construit, le raffinement - café, restos, culture - sont réclamés par les nouveaux riches du capital symbolique. Les autres sont poussés en-dehors, volontairement ou pas, selon qu’ils ont beaucoup ou peu d’argent. Il n’y a pas de hasard à ce que le mouvement des gilets jaunes, en France, ait trouvé son origine dans les périphéries. La pauvreté de leurs paysages - si peu et tellement français à la fois - faisait écho aux nôtres. Costco venait d’ailleurs d’y ouvrir sa première franchise.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Le chemin qui mène au Costco est stressant. Cela demande une planification stratégique au même titre que les déplacements quotidiens : il faut éviter le trafic et les heures de pointe, ce qui est un défi quand tout le monde travaille aux mêmes heures, et fait son épicerie dans les deux jours hebdomadaires qu’il reste. Les retraités et travailleurs aux horaires atypiques iront tôt les jours de semaine, les autres se taperont la masse. Aller au Costco reproduit la lutte de tous contre tous qui se déroule chaque jour dans la circulation automobile. « C’est l’enfer » disent les chroniqueurs à la circulation des radios privées ; et quelque part, en effet, ils ont raison. Non pas métaphoriquement, mais dans l’absolu.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
À l’arrivée, le parking est plein et dangereux. L’automobiliste vit dans la peur permanente de froisser la tôle d’un autre automobiliste, et rien ne gêne plus la vue d’une auto que les autres autos, qu’elles roulent ou qu’elles soient arrêtées. Il faut ensuite atteindre le magasin sans se faire écraser. À l’intérieur, c’est immense, mais hors de l’ilôt central, la vue est bouchée par des étagères qui montent jusqu’au toit. La disposition des allées semble répondre à une logique, mais cette logique est constamment brisée par des palettes de produits qui semblent abandonnées dans l’ilôt central par des employés trop pressés. Pas moyen de s’arrêter avec son chariot pour tenter de s’orienter ou de repérer un produit ; on est constamment poussé par le flot des consommateurs. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Autrefois, nous avions appelé avec quelques amis <i>dépressionnisme</i> ce mouvement qui consiste à envelopper et nourrir l’expérience humaine de phénomènes propres à instiller une déprime générale de telle façon que rien de son état antérieur ne subsiste, pas même en souvenir. En cela, Costco est une expérience dépressionniste totale : autoroutes, automobiles, stationnements, entrepôts, alimentation industrielle, emballages de plastique, interactions humaines strictement marchandes. Ne me demandez pas pourquoi la dystopie est devenu un genre dominant à notre époque, ni pourquoi, contrairement aux autres genres de la science-fiction, on ne se donne même plus la peine de la situer dans le futur. Je m’attends seulement à ce que Costco fasse bientôt l’objet d’un épisode de la série <i>Black Mirror</i>.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
<b>***</b></p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Aller au Costco coûte cher. Genre, crissement fucking cher. Dans cette société qui a convaincu chaque individu qu’il est l’entrepreneur de sa propre vie, et dont la famille constitue la PME, on va au Costco faire des économies d’échelle, oubliant au passage un principe fondamental, connu des vrais entrepreneurs, selon lequel les meilleures dépenses sont celles qu’on ne fait pas. Peu importe, à titre de père de famille nombreuse, je n’ai pas mis beaucoup de temps à constater que les fruits et légumes coûtaient au mieux la même chose qu’au Super C (ma vie est pleine de poésie). Pour le reste, le principe d’économie de gros est anesthésié par l’absence de points de comparaison valables ; les quantités sont plus grosses que partout ailleurs - contenants d’un kilo ou plus, produits vendus en paquets de trois ou cinq - et conséquemment tout coûte plus cher. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
C’est sans compter les achats compulsifs. Les allées débordent de boissons, collations et d’en-cas produits par l’industrie alimentaire, qui peuvent sembler pratiques a priori, mais qui n’étaient pas prévus sur la liste. Ce kilo de cajous à 21$ est une bonne affaire, vu le prix consternant de ces noix dans le commerce au détail ; on en aura pour au moins un an pour des sautés et des tofus. Je les ai quand même pris grillés et salés, à tout hasard, et longue histoire courte, ils n’ont pas toffé deux semaines puisqu’ils se trouvent qu’ils agrémentent aussi très bien la bière. Rendu là, de toute façon,la logique d’économie est renversée : on est au Costco pour consommer et pour se gratifier - une nouvelle bébelle, des snacks sucrés salés, et pourquoi pas un hot-dog / pepsi en sortant, c’est pas cher. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Et pourtant, la seule certitude d’une visite au Costco, c’est le montant astronomique du total, qui ferait faire une crise cardiaque à n’importe laquelle de nos grands-mères, et qui enclenche des calculs secrets sur la place disponible sur la carte de crédit et laquelle des payes à venir sera capable d’en effacer le solde. C’est le tabou ultime de la classe moyenne, qui se définit moins par son pouvoir d’achat que par sa capacité d’encaisser de pareilles factures sans broncher. Il se passe la même chose dans les restaurants qu’elle se paye en guise de récompense de ses durs labeurs. À défaut de contrôle, il y a une forme d’abandon total à sa position dominée dans l’économie capitaliste. Être dans la classe moyenne, c’est se faire fourrer. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
<b>***</b></p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Aller au Costco, c’est faire partie d’un club sélect qui paradoxalement accepte tout le monde. Il y a une carte de membre obligatoire, qui coûte 60$ par année, et dont le premier effet est de renvoyer le consommateur à ses calculs d’entrepreneur : il faut maintenant rentabiliser cet investissement. C’est 60$ d’économies perdues qu’il faut récupérer sur le long terme en achetant à des volumes encore plus gros. La carte de membre et les factures exorbitantes servent quand même de facteurs discriminants. Le plouc comme moi qui voudrait profiter d’une épicerie annuelle à coût moindre sur des produits spécifiques - disons, les noix (la libéralité avec laquelle Ricardo crisse des pignons de pin dans la moitié de ses recettes me laisse toujours pantois) - doit se faire inviter par un membre du club. Les membres ont droit à un invité, qui se fait rappeler qu’il est un invité en devant passer à la caisse avec son chaperon.</p> | |||
<p> | |||
<br/></p> | |||
<div><p> | |||
Il y a, dans le membership du Costco, un souvenir du Club Price initial, qui n’était ouvert, jusque dans les années 1990, qu’aux petits commerçants, ainsi qu’aux employés de la fonction publique, d’institutions bancaires et de quelques autres. Cette discrimination aux frontières floues et arbitraires était justifiée assez brutalement par le fondateur Robert Price </p><a href="https://www.latimes.com/archives/la-xpm-1985-03-11-fi-34135-story.html">dans une entrevue au LA Times en 1985</a><p> : « </p><i>Our members are better than the general public because their employment is stable, they write fewer bad checks and don’t steal</i><p>. » On peut penser que l’ouverture au grand public s’est faite alors qu’il était plus facile de le surveiller - les achats sont d’ailleurs inspectés à la sortie, après être passé à la caisse - et que se sont généralisées les cartes de crédit. La classe moyenne reconnaissante s’est alors fait dire qu’elle était un peu riche, et y a vu une forme de promotion sociale. Les pauvres vont au Wal-Mart.</p></div> | |||
<p> | |||
<br/></p> | |||
<p> | |||
<b>***</b></p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Ainsi donc, le Costco fonctionne sur des systèmes antithétiques : l’abondance de la marchandise dans le désert du vivant, l’économie d’échelle dans la dépense excessive, l’exclusivité du membership donnée à tout le monde, le privilège qui se paye plutôt qu’il ne se reçoit.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
C’est à l’image de sa société.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
La société de consommation occidentale est fondée sur un crime économique et écologique, et ne peut fonctionner que dans un système de double-pensée orwellien où ce crime est à la fois reconnu en théorie et nié dans la pratique. Chaque trimestre, on peut lire les économistes déplorer l’endettement des ménages, ceci dans un contexte historique où les taux d’intérêts sont maintenus au plancher et où, conséquemment, les consommateurs devront affronter son relèvement. Pire, le spectre de la récession guette, cadeau notamment de populistes aux politiques irresponsables - guerres commerciales, Brexit - qui prétendaient pourtant défendre la classe moyenne. Des alarmes récurrentes disent que cette économie fondée sur le crédit et la spéculation devrait éclater. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
D’autre part, l’époque est marquée par l’écart maintenant fulgurant entre la conscience aiguë des dangers écologiques qui guettent, et l’absence complète d’actions capables de les endiguer. La moindre réflexion sur le précaire équilibre qui est le nôtre se fait désormais sur le mode manifestaire : <i>il faut</i> arrêter de prendre l’avion, <i>il faut</i> réduire notre consommation de viande, <i>il faut</i> éviter le plastique, <i>il faut</i> en finir avec les énergies fossiles et pourquoi pas, pendant qu’on y est,<i> il faut </i>en finir avec l’extractivisme et le consumérisme. Il y a quelque chose de désarmant, pour quelqu’un qui a vécu les dernières années de la guerre froide, de lire régulièrement des appels à mettre fin au capitalisme avec la désinvolture d’un fumeur qui se débarrasse de son botch de cigarette. C’est devenu une tarte à la crème : tout le monde est d’accord là-dessus. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Enfin, sauf les cons.</p> | |||
<p> | |||
<br/></p> | |||
<div><p> | |||
Les tendances socio-économiques, elles, vont toutes dans le sens contraire. Les canadiens émettent </p><a href="https://www.lesoleil.com/actualite/environnement/g20-le-canada-champion-des-emissions-de-ges-par-personne-bc0b0e6b94d7dd5989a3d8ec4b962907" target="_blank">le plus de CO2 par habitant</a><p> du G20 ; </p><a href="http://plus.lapresse.ca/screens/792303c8-24e5-411b-9a0c-888a2752ae29__7C___0.html" target="_blank">61% des véhicules qu’ils achètent sont des VUS</a><p> ou des camionnettes. </p><a href="https://www.journaldemontreal.com/2019/01/04/le-ford-serie-f-demeure-le-vehicule-le-plus-vendu-au-pays" target="_blank">Le Ford F150 est le véhicule le plus vendu</a><p> depuis près d'une décennie. Ils sont aussi parmi </p><a href="https://www.lapresse.ca/actualites/environnement/201907/03/01-5232619-le-canada-lun-des-plus-gros-producteurs-de-dechets-de-la-planete.php" target="_blank">les plus gros producteurs de déchets de la planète</a><p> ; des pays d’Asie leur en renvoient </p><a href="https://www.lapresse.ca/debats/editoriaux/201907/25/01-5235116-exportation-de-dechets-nous-devrions-avoir-honte.php" target="_blank">par conteneurs entiers</a><p>. La banlieue s’étend comme de la mélasse, devenue le mode de vie dominant, au détriment des terres agricoles, de la biodiversité. La préoccupation pour la pollution de plastique est arrivée avec les cafetières à capsules. Quand on a parlé de la pollution de l'air, on s'est mis à voir des VUS partout. Quand on s’est soucié de notre consommation de viande, on a mis le feu à l’Amazonie pour des paturages de vaches. Quand on a parlé de protéger les sites naturels et historiques est arrivé Instagram et tout le monde voulait prendre la même photo avec sa face devant.</p></div> | |||
<p> | |||
<br/></p> | |||
<div><p> | |||
La classe moyenne n’est pas insensible à ces réalités et, contrairement aux politiciens qui prétendent la défendre, ne fait pas de déni. Elle est consciente des dangers qui la guette, mais ne sait pas comment les éviter. Dans son essai </p><i>Le sel de la terre</i><p>, Samuel Archibald postulait très clairement cette conscience qui habite la classe moyenne, qui s’abreuve dans la fiction de scénarios catastrophes, et particulièrement de films de zombies dont il constatait avec étonnement la résurgence. Il voyait dans la popularité d’une série comme </p><i>The Walking Dead</i><p> une manière d’expier la peur de sa propre fin qui la tenaille. L’auteur se réfère à une scène célèbre de </p><i>Dawn of the Dead</i><p> de George A. Romero, où les zombies prennent d'assaut un centre d'achat : | |||
</p><blockquote class="tr_bq"> | |||
<i>- What are they doing ? Why do they come here ?</i><br/> | |||
<i>- Some kind of instinct. A memory of what they used to do. This was an important place in their lives. </i></blockquote> | |||
</div> | |||
<p> | |||
<br/></p> | |||
<p> | |||
En fait, le clou de l’essai d’Archibald est que la classe moyenne est un marqueur identitaire. Comme faire des voyages et manger dans les restaurants branchouilles, aller au Costco est une manière d’affirmer son appartenance à la classe moyenne ; c’est une émancipation autant individuelle que collective, et le dernier lieu commun - au sens d’expérience partagée - dans une société autrement déchirée et polarisée par la politique et les inégalités, et terrifiée par la crise écologique à venir. Toutes ces actions servent à la fois de force de décompression (<i>on a travaillé fort, on l’a mérité</i>), de marque d’émancipation économique (j<i>e consomme, je ne suis pas pauvre</i>), mais aussi, à la fin, elles témoignent de l’impossibilité de faire quoi que ce soit d’autre (<i>au québec, c’est comme ça qu’on vit</i>).</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
<b>***</b></p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Aux fins de mon étude, je me suis abonné au groupe Les accrocs du Costco pour essayer de comprendre mon objet. Pendant des mois, j’ai vu dans mon fil d’actualité des photos de sèche-mitaines, de sapins de Noël en pot, de gros beignes en forme de gâteau empilés jusqu’au plafond, accompagnés de commentaires enthousiastes dans un français décomposé. « C’est pas bon pour toi » m’a dit ma blonde, qui commence à me connaître. Ce n’était pas bon, en effet, mais ce n’était pas la célébration de breloques inutiles qui me minait. J’étais tourmenté pour une autre raison : je n’arrivais pas à comprendre. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Comment extraire du sens de la vacuité ? Que se cache-t-il, en arrière du Costco ?</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Puis il y a eu l’ouverture du nouveau Costco de Saint-Bruno. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Il y eut la traditionnelle coupe du ruban, des discours, plusieurs journalistes, le maire de Saint-Bruno et des représentants de la chambre de commerce, puis sont entrés les premiers clients sous une haie d’honneur et des applaudissements nourris. L’ouverture était prévue pour 8h00, mais vu le froid, on a fait entrer les premiers clients arrivés dès 5h00. À 9h00, le stationnement était plein. Un mercredi. Une espèce de frénésie a gagné le groupe, une excitation, une euphorie, un volume de messages inédit. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
C’était la fête.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Un party en ligne.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Et là j’ai compris.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
En ces temps troubles de catastrophe écologique et de capitalisme en phase terminale, le Costco est une aberration. Ça ne devrait pas exister, ces choses ne devraient plus être permises, et pourtant elles sont là. Nous sommes comme les zombies de Romero, qui continuent de fréquenter le centre d’achat en souvenir de notre existence antérieure, celle où la consommation était une promesse de bonheur, l’abondance un signe de richesse, où ce mode de vie n’était pas recouvert d’un voile de soupçon, condamné par un système économique et une planète qui menacent de s’écrouler tous en même temps, à brève échéance.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Nous sommes là pour célébrer le fait qu’on est encore capable, et que c’est encore possible. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Avant que ça finisse.</p> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil">🏠</a> • | |||
<a href="/david/log/" title="Accès au flux RSS">🤖</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> • | |||
<abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script type="text/javascript"> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,159 @@ | |||
title: Fuck Costco | |||
url: https://www.leteignoir.com/2020/06/fuck-costco.html | |||
hash_url: c039e15f24fb1dc53a5cae21c30a2bf7 | |||
<p> | |||
Les Québécois ont un trouble obsessionnel-compulsif avec le Costco. Ou monomaniaque, je ne sais trop, je ne suis pas psychiatre, même si je suis capable de reconnaître des malades quand j’en vois. Quand elle m’a entendu lire « Fuck le troisième lien », Myriam Ségal m’a accusé de mépriser les banlieusards et le déclencheur - le<i> trigger</i>, comme disent les jeunes - fut que je m’en prisse à la triade « boulot-costco-dodo », un syntagme que j’empruntais, je dois lui en faire crédit, à Samuel Archibald. Comme tous les Québécois, Ségal parle régulièrement du Costco, lequel semblait se mêler étrangement à son argumentaire en faveur du troisième lien, malgré qu’il existe deux autres franchises du grossiste sur la rive nord. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Le Costco est un incontournable des réunions de famille. Mes parents en parlent tout le temps, engageant des discussions animées qui me font une mise à jour ponctuelle des progrès de l'ingénierie culinaire dans la société de consommation avancée : une machine d’emballage sous vide, un lave-vaisselle de comptoir, une éclateuse à pop-corn, que sais-je encore. Je ferme ma gueule, n’ayant rien à dire. C’est généralement le moment où je m’éclipse pour jouer avec les enfants. Mes parents s’insèrent, ceci dit, dans une tendance sociale profonde : un groupe sur facebook, Les accrocs du Costco, compte 200 000 membres, et plusieurs autres groupes similaires en ajoutent quelques dizaines de milliers au total. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Le Costco est un lieu commun de la psyché collective. Tout le monde s’y reconnaît. En dépit de son apparente banalité, et contrairement aux trivialités de la vie quotidienne, tout ce qui est relié à la catégorie Costco est toujours digne de mention. Aller au Costco, dire qu’on a pris quelque chose au Costco, comparer les prix des produits en rapport de ce qu’ils coûtent au Costco, faire sonner le mot Costco dans les conversations - tout cela semble animer des passions enfouies et met de la vie dans les discussions. Le Costco est une expérience définitive de la vie québécoise. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
En semblant mépriser ouvertement le Costco, je faisais preuve - <i>encore</i> - de mon étrangeté au corps social auquel je prétends appartenir. Il y a un principe d’identité fort exprimé par Myriam Ségal : le Québec est une banlieue, et vivre en banlieue c’est aller au Costco. La radio de Québec nous l’enseigne depuis longtemps, il y a le vrai monde qui travaille et consomme, et les hippies du centre-ville qui critiquent les premiers en se pognant le beigne. Ils sont à la fois pauvres et snobs, ils n’ont pas de char ou pas de famille ou pas des deux, et donc ne vont pas au Costco.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Je pourrais quand même pas parler de quelque chose que je ne connais pas, right ? Alors comme je suis un essayiste de terrain, j’ai demandé à une amie de m’y amener lorsque l’état de ses stocks le justifierait. « On va en profiter pour arrêter à la SQDC en passant » me dit-elle, savourant au passage cette nouvelle normalité québécoise. Pour être bien honnête, ma mère m’y avait amené quand j’étais jeune pis que ça s’appelait Club Price. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Ça n’a pas beaucoup changé. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
<b>***</b></p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Le monstre est en périphérie, proche des autoroutes, pratique pour le transport des marchandises et des consommateurs motorisés. Nouvelle modalité de la pauvreté contemporaine : le commun n’a pas accès à la beauté. Les centre-villes ne sont pas gentrifiés pour rien. La proximité, la communauté, le patrimoine construit, le raffinement - café, restos, culture - sont réclamés par les nouveaux riches du capital symbolique. Les autres sont poussés en-dehors, volontairement ou pas, selon qu’ils ont beaucoup ou peu d’argent. Il n’y a pas de hasard à ce que le mouvement des gilets jaunes, en France, ait trouvé son origine dans les périphéries. La pauvreté de leurs paysages - si peu et tellement français à la fois - faisait écho aux nôtres. Costco venait d’ailleurs d’y ouvrir sa première franchise.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Le chemin qui mène au Costco est stressant. Cela demande une planification stratégique au même titre que les déplacements quotidiens : il faut éviter le trafic et les heures de pointe, ce qui est un défi quand tout le monde travaille aux mêmes heures, et fait son épicerie dans les deux jours hebdomadaires qu’il reste. Les retraités et travailleurs aux horaires atypiques iront tôt les jours de semaine, les autres se taperont la masse. Aller au Costco reproduit la lutte de tous contre tous qui se déroule chaque jour dans la circulation automobile. « C’est l’enfer » disent les chroniqueurs à la circulation des radios privées ; et quelque part, en effet, ils ont raison. Non pas métaphoriquement, mais dans l’absolu.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
À l’arrivée, le parking est plein et dangereux. L’automobiliste vit dans la peur permanente de froisser la tôle d’un autre automobiliste, et rien ne gêne plus la vue d’une auto que les autres autos, qu’elles roulent ou qu’elles soient arrêtées. Il faut ensuite atteindre le magasin sans se faire écraser. À l’intérieur, c’est immense, mais hors de l’ilôt central, la vue est bouchée par des étagères qui montent jusqu’au toit. La disposition des allées semble répondre à une logique, mais cette logique est constamment brisée par des palettes de produits qui semblent abandonnées dans l’ilôt central par des employés trop pressés. Pas moyen de s’arrêter avec son chariot pour tenter de s’orienter ou de repérer un produit ; on est constamment poussé par le flot des consommateurs. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Autrefois, nous avions appelé avec quelques amis <i>dépressionnisme</i> ce mouvement qui consiste à envelopper et nourrir l’expérience humaine de phénomènes propres à instiller une déprime générale de telle façon que rien de son état antérieur ne subsiste, pas même en souvenir. En cela, Costco est une expérience dépressionniste totale : autoroutes, automobiles, stationnements, entrepôts, alimentation industrielle, emballages de plastique, interactions humaines strictement marchandes. Ne me demandez pas pourquoi la dystopie est devenu un genre dominant à notre époque, ni pourquoi, contrairement aux autres genres de la science-fiction, on ne se donne même plus la peine de la situer dans le futur. Je m’attends seulement à ce que Costco fasse bientôt l’objet d’un épisode de la série <i>Black Mirror</i>.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
<b>***</b></p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Aller au Costco coûte cher. Genre, crissement fucking cher. Dans cette société qui a convaincu chaque individu qu’il est l’entrepreneur de sa propre vie, et dont la famille constitue la PME, on va au Costco faire des économies d’échelle, oubliant au passage un principe fondamental, connu des vrais entrepreneurs, selon lequel les meilleures dépenses sont celles qu’on ne fait pas. Peu importe, à titre de père de famille nombreuse, je n’ai pas mis beaucoup de temps à constater que les fruits et légumes coûtaient au mieux la même chose qu’au Super C (ma vie est pleine de poésie). Pour le reste, le principe d’économie de gros est anesthésié par l’absence de points de comparaison valables ; les quantités sont plus grosses que partout ailleurs - contenants d’un kilo ou plus, produits vendus en paquets de trois ou cinq - et conséquemment tout coûte plus cher. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
C’est sans compter les achats compulsifs. Les allées débordent de boissons, collations et d’en-cas produits par l’industrie alimentaire, qui peuvent sembler pratiques a priori, mais qui n’étaient pas prévus sur la liste. Ce kilo de cajous à 21$ est une bonne affaire, vu le prix consternant de ces noix dans le commerce au détail ; on en aura pour au moins un an pour des sautés et des tofus. Je les ai quand même pris grillés et salés, à tout hasard, et longue histoire courte, ils n’ont pas toffé deux semaines puisqu’ils se trouvent qu’ils agrémentent aussi très bien la bière. Rendu là, de toute façon,la logique d’économie est renversée : on est au Costco pour consommer et pour se gratifier - une nouvelle bébelle, des snacks sucrés salés, et pourquoi pas un hot-dog / pepsi en sortant, c’est pas cher. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Et pourtant, la seule certitude d’une visite au Costco, c’est le montant astronomique du total, qui ferait faire une crise cardiaque à n’importe laquelle de nos grands-mères, et qui enclenche des calculs secrets sur la place disponible sur la carte de crédit et laquelle des payes à venir sera capable d’en effacer le solde. C’est le tabou ultime de la classe moyenne, qui se définit moins par son pouvoir d’achat que par sa capacité d’encaisser de pareilles factures sans broncher. Il se passe la même chose dans les restaurants qu’elle se paye en guise de récompense de ses durs labeurs. À défaut de contrôle, il y a une forme d’abandon total à sa position dominée dans l’économie capitaliste. Être dans la classe moyenne, c’est se faire fourrer. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
<b>***</b></p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Aller au Costco, c’est faire partie d’un club sélect qui paradoxalement accepte tout le monde. Il y a une carte de membre obligatoire, qui coûte 60$ par année, et dont le premier effet est de renvoyer le consommateur à ses calculs d’entrepreneur : il faut maintenant rentabiliser cet investissement. C’est 60$ d’économies perdues qu’il faut récupérer sur le long terme en achetant à des volumes encore plus gros. La carte de membre et les factures exorbitantes servent quand même de facteurs discriminants. Le plouc comme moi qui voudrait profiter d’une épicerie annuelle à coût moindre sur des produits spécifiques - disons, les noix (la libéralité avec laquelle Ricardo crisse des pignons de pin dans la moitié de ses recettes me laisse toujours pantois) - doit se faire inviter par un membre du club. Les membres ont droit à un invité, qui se fait rappeler qu’il est un invité en devant passer à la caisse avec son chaperon.</p> | |||
<p> | |||
<br/></p> | |||
<div><p> | |||
Il y a, dans le membership du Costco, un souvenir du Club Price initial, qui n’était ouvert, jusque dans les années 1990, qu’aux petits commerçants, ainsi qu’aux employés de la fonction publique, d’institutions bancaires et de quelques autres. Cette discrimination aux frontières floues et arbitraires était justifiée assez brutalement par le fondateur Robert Price </p><a href="https://www.latimes.com/archives/la-xpm-1985-03-11-fi-34135-story.html">dans une entrevue au LA Times en 1985</a><p> : « </p><i>Our members are better than the general public because their employment is stable, they write fewer bad checks and don’t steal</i><p>. » On peut penser que l’ouverture au grand public s’est faite alors qu’il était plus facile de le surveiller - les achats sont d’ailleurs inspectés à la sortie, après être passé à la caisse - et que se sont généralisées les cartes de crédit. La classe moyenne reconnaissante s’est alors fait dire qu’elle était un peu riche, et y a vu une forme de promotion sociale. Les pauvres vont au Wal-Mart.</p></div> | |||
<p> | |||
<br/></p> | |||
<p> | |||
<b>***</b></p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Ainsi donc, le Costco fonctionne sur des systèmes antithétiques : l’abondance de la marchandise dans le désert du vivant, l’économie d’échelle dans la dépense excessive, l’exclusivité du membership donnée à tout le monde, le privilège qui se paye plutôt qu’il ne se reçoit.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
C’est à l’image de sa société.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
La société de consommation occidentale est fondée sur un crime économique et écologique, et ne peut fonctionner que dans un système de double-pensée orwellien où ce crime est à la fois reconnu en théorie et nié dans la pratique. Chaque trimestre, on peut lire les économistes déplorer l’endettement des ménages, ceci dans un contexte historique où les taux d’intérêts sont maintenus au plancher et où, conséquemment, les consommateurs devront affronter son relèvement. Pire, le spectre de la récession guette, cadeau notamment de populistes aux politiques irresponsables - guerres commerciales, Brexit - qui prétendaient pourtant défendre la classe moyenne. Des alarmes récurrentes disent que cette économie fondée sur le crédit et la spéculation devrait éclater. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
D’autre part, l’époque est marquée par l’écart maintenant fulgurant entre la conscience aiguë des dangers écologiques qui guettent, et l’absence complète d’actions capables de les endiguer. La moindre réflexion sur le précaire équilibre qui est le nôtre se fait désormais sur le mode manifestaire : <i>il faut</i> arrêter de prendre l’avion, <i>il faut</i> réduire notre consommation de viande, <i>il faut</i> éviter le plastique, <i>il faut</i> en finir avec les énergies fossiles et pourquoi pas, pendant qu’on y est,<i> il faut </i>en finir avec l’extractivisme et le consumérisme. Il y a quelque chose de désarmant, pour quelqu’un qui a vécu les dernières années de la guerre froide, de lire régulièrement des appels à mettre fin au capitalisme avec la désinvolture d’un fumeur qui se débarrasse de son botch de cigarette. C’est devenu une tarte à la crème : tout le monde est d’accord là-dessus. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Enfin, sauf les cons.</p> | |||
<p> | |||
<br/></p> | |||
<div><p> | |||
Les tendances socio-économiques, elles, vont toutes dans le sens contraire. Les canadiens émettent </p><a href="https://www.lesoleil.com/actualite/environnement/g20-le-canada-champion-des-emissions-de-ges-par-personne-bc0b0e6b94d7dd5989a3d8ec4b962907" target="_blank">le plus de CO2 par habitant</a><p> du G20 ; </p><a href="http://plus.lapresse.ca/screens/792303c8-24e5-411b-9a0c-888a2752ae29__7C___0.html" target="_blank">61% des véhicules qu’ils achètent sont des VUS</a><p> ou des camionnettes. </p><a href="https://www.journaldemontreal.com/2019/01/04/le-ford-serie-f-demeure-le-vehicule-le-plus-vendu-au-pays" target="_blank">Le Ford F150 est le véhicule le plus vendu</a><p> depuis près d'une décennie. Ils sont aussi parmi </p><a href="https://www.lapresse.ca/actualites/environnement/201907/03/01-5232619-le-canada-lun-des-plus-gros-producteurs-de-dechets-de-la-planete.php" target="_blank">les plus gros producteurs de déchets de la planète</a><p> ; des pays d’Asie leur en renvoient </p><a href="https://www.lapresse.ca/debats/editoriaux/201907/25/01-5235116-exportation-de-dechets-nous-devrions-avoir-honte.php" target="_blank">par conteneurs entiers</a><p>. La banlieue s’étend comme de la mélasse, devenue le mode de vie dominant, au détriment des terres agricoles, de la biodiversité. La préoccupation pour la pollution de plastique est arrivée avec les cafetières à capsules. Quand on a parlé de la pollution de l'air, on s'est mis à voir des VUS partout. Quand on s’est soucié de notre consommation de viande, on a mis le feu à l’Amazonie pour des paturages de vaches. Quand on a parlé de protéger les sites naturels et historiques est arrivé Instagram et tout le monde voulait prendre la même photo avec sa face devant.</p></div> | |||
<p> | |||
<br/></p> | |||
<div><p> | |||
La classe moyenne n’est pas insensible à ces réalités et, contrairement aux politiciens qui prétendent la défendre, ne fait pas de déni. Elle est consciente des dangers qui la guette, mais ne sait pas comment les éviter. Dans son essai </p><i>Le sel de la terre</i><p>, Samuel Archibald postulait très clairement cette conscience qui habite la classe moyenne, qui s’abreuve dans la fiction de scénarios catastrophes, et particulièrement de films de zombies dont il constatait avec étonnement la résurgence. Il voyait dans la popularité d’une série comme </p><i>The Walking Dead</i><p> une manière d’expier la peur de sa propre fin qui la tenaille. L’auteur se réfère à une scène célèbre de </p><i>Dawn of the Dead</i><p> de George A. Romero, où les zombies prennent d'assaut un centre d'achat : | |||
</p><blockquote class="tr_bq"> | |||
<i>- What are they doing ? Why do they come here ?</i><br/> | |||
<i>- Some kind of instinct. A memory of what they used to do. This was an important place in their lives. </i></blockquote> | |||
</div> | |||
<p> | |||
<br/></p> | |||
<p> | |||
En fait, le clou de l’essai d’Archibald est que la classe moyenne est un marqueur identitaire. Comme faire des voyages et manger dans les restaurants branchouilles, aller au Costco est une manière d’affirmer son appartenance à la classe moyenne ; c’est une émancipation autant individuelle que collective, et le dernier lieu commun - au sens d’expérience partagée - dans une société autrement déchirée et polarisée par la politique et les inégalités, et terrifiée par la crise écologique à venir. Toutes ces actions servent à la fois de force de décompression (<i>on a travaillé fort, on l’a mérité</i>), de marque d’émancipation économique (j<i>e consomme, je ne suis pas pauvre</i>), mais aussi, à la fin, elles témoignent de l’impossibilité de faire quoi que ce soit d’autre (<i>au québec, c’est comme ça qu’on vit</i>).</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
<b>***</b></p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Aux fins de mon étude, je me suis abonné au groupe Les accrocs du Costco pour essayer de comprendre mon objet. Pendant des mois, j’ai vu dans mon fil d’actualité des photos de sèche-mitaines, de sapins de Noël en pot, de gros beignes en forme de gâteau empilés jusqu’au plafond, accompagnés de commentaires enthousiastes dans un français décomposé. « C’est pas bon pour toi » m’a dit ma blonde, qui commence à me connaître. Ce n’était pas bon, en effet, mais ce n’était pas la célébration de breloques inutiles qui me minait. J’étais tourmenté pour une autre raison : je n’arrivais pas à comprendre. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Comment extraire du sens de la vacuité ? Que se cache-t-il, en arrière du Costco ?</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Puis il y a eu l’ouverture du nouveau Costco de Saint-Bruno. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Il y eut la traditionnelle coupe du ruban, des discours, plusieurs journalistes, le maire de Saint-Bruno et des représentants de la chambre de commerce, puis sont entrés les premiers clients sous une haie d’honneur et des applaudissements nourris. L’ouverture était prévue pour 8h00, mais vu le froid, on a fait entrer les premiers clients arrivés dès 5h00. À 9h00, le stationnement était plein. Un mercredi. Une espèce de frénésie a gagné le groupe, une excitation, une euphorie, un volume de messages inédit. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
C’était la fête.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Un party en ligne.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Et là j’ai compris.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
En ces temps troubles de catastrophe écologique et de capitalisme en phase terminale, le Costco est une aberration. Ça ne devrait pas exister, ces choses ne devraient plus être permises, et pourtant elles sont là. Nous sommes comme les zombies de Romero, qui continuent de fréquenter le centre d’achat en souvenir de notre existence antérieure, celle où la consommation était une promesse de bonheur, l’abondance un signe de richesse, où ce mode de vie n’était pas recouvert d’un voile de soupçon, condamné par un système économique et une planète qui menacent de s’écrouler tous en même temps, à brève échéance.</p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Nous sommes là pour célébrer le fait qu’on est encore capable, et que c’est encore possible. </p> | |||
<p> | |||
<br/></p> | |||
<p> | |||
Avant que ça finisse.</p> |
@@ -60,6 +60,8 @@ | |||
<article> | |||
<ul> | |||
<li><a href="/david/cache/2020/b7f574586eccd0b9c844876c18ac0ca5/" title="Accès à l'article caché">Ned Batchelder: 2500</a> (<a href="https://nedbatchelder.com//blog/202006/2500.html" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/dd11327ac0ac5bf42163e3a6315012b8/" title="Accès à l'article caché">Teens have figured out how to mess with Instagram's tracking algorithm</a> (<a href="https://www.cnet.com/news/teens-have-figured-out-how-to-mess-with-instagrams-tracking-algorithm/" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/4f88ece170719f58ce09ba4b1818730a/" title="Accès à l'article caché">Get Static</a> (<a href="https://meyerweb.com/eric/thoughts/2020/03/22/get-static/" title="Accès à l'article original">original</a>)</li> | |||
@@ -72,6 +74,8 @@ | |||
<li><a href="/david/cache/2020/d991865574f0f29b42f75b29e768354b/" title="Accès à l'article caché">Québec solidaire propose un Plan d’indépendance alimentaire pour subvenir aux besoins du Québec</a> (<a href="https://quebecsolidaire.net/nouvelle/quebec-solidaire-propose-un-plan-dindependance-alimentaire-pour-subvenir-aux-besoins-du-quebec" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/8ecfc6fbf4a4d3293144458db9c8a57d/" title="Accès à l'article caché">Towards carbon negativity</a> (<a href="https://m.signalvnoise.com/towards-carbon-negativity/" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/ef0bea4e3633945e71c7bda351661797/" title="Accès à l'article caché">Dark Ecology</a> (<a href="https://orionmagazine.org/article/dark-ecology/" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/911b72ae5d6e140268adf8591aae7df3/" title="Accès à l'article caché">Journal-Hydration</a> (<a href="https://adactio.com/journal/16404" title="Accès à l'article original">original</a>)</li> | |||
@@ -92,6 +96,8 @@ | |||
<li><a href="/david/cache/2020/91a099e7f48f8733274f7b27cb68b772/" title="Accès à l'article caché">Exercice pour préparer l’après crise sanitaire pour être sûr que tout ne reprenne pas comme avant</a> (<a href="http://www.bruno-latour.fr/fr/node/851.html" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/2020e2b3c28d37ec6cf7eabfa607ffe2/" title="Accès à l'article caché">On Priorities</a> (<a href="https://vgpena.github.io/on-priorities/" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/384b330b3de6f4f2bac8c81f0f04c404/" title="Accès à l'article caché">Atlanta Asks Google Whether It Targeted Black Homeless People</a> (<a href="https://www.nytimes.com/2019/10/04/technology/google-facial-recognition-atlanta-homeless.html" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/fb2849b42586654e0c899bf1a31fa5a5/" title="Accès à l'article caché">Sparrow’s Guide To Meditation</a> (<a href="https://www.thesunmagazine.org/issues/529/sparrows-guide-to-meditation" title="Accès à l'article original">original</a>)</li> | |||
@@ -160,8 +166,12 @@ | |||
<li><a href="/david/cache/2020/f61e3ce56d0360e061f4b22e0bb20e47/" title="Accès à l'article caché">Enough</a> (<a href="https://pjrvs.com/enough" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/5e366e8fe10507c713ca8d581daeb17c/" title="Accès à l'article caché">The end of the Redis adventure</a> (<a href="http://antirez.com/news/133" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/10a0e890ada0487e0adf4548960f056f/" title="Accès à l'article caché">How To Keep Believing in the Internet</a> (<a href="https://jenmyers.net/daily/how-to-keep-believing-in-the-internet.html" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/703ceb55d78ebb11d4a3035b68d9f956/" title="Accès à l'article caché">Isabelle Attard : « L’écologie doit s’inscrire au sein du mouvement révolutionnaire »</a> (<a href="https://www.revue-ballast.fr/isabelle-attard-lecologie-doit-sinscrire-au-sein-du-mouvement-revolutionnaire" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/5db0711c2794aed3bf1433b48084064c/" title="Accès à l'article caché">Plus rien à craindre</a> (<a href="https://nrkn.fr/blog/2020/06/13/plus-rien-a-craindre/" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/24f52bba99b1423102f93cf86b948c5b/" title="Accès à l'article caché">Journal-Lightweight</a> (<a href="https://adactio.com/journal/16797" title="Accès à l'article original">original</a>)</li> | |||
@@ -210,8 +220,14 @@ | |||
<li><a href="/david/cache/2020/81585c1eca04b8e13fa1d096f70c96ec/" title="Accès à l'article caché">Rétro-confinement</a> (<a href="http://www.aubryconseil.com/post/Retro-confinement" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/959add1c9fe6dc27e1ee1ee8960b930b/" title="Accès à l'article caché">On dependency</a> (<a href="https://v7.robweychert.com/blog/2020/06/v7-on-dependency/" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/2343cdf9e5f75cc6bfba098799f0f2fd/" title="Accès à l'article caché">A Future with No Future: Depression, the Left, and the Politics of Mental Health</a> (<a href="https://lareviewofbooks.org/article/future-no-future-depression-left-politics-mental-health/" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/bdffc3b5eb59b81d90d9fa1d7e21ce11/" title="Accès à l'article caché">Des termes problématiques</a> (<a href="https://boris.schapira.dev/notes/2020-06-des-termes-problematiques/" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/613da2c8a82cb70c50391a34565800c4/" title="Accès à l'article caché">lion affranchi</a> (<a href="https://www.la-grange.net/2020/07/01/affranchi" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/cbef115a80c646c9eddc61ac077a6891/" title="Accès à l'article caché">Sonos in bricked speaker 'recycling' row</a> (<a href="https://www.bbc.co.uk/news/technology-50948868" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/42b02cc81a7fface539dfb3397f0a464/" title="Accès à l'article caché">How to Fake a Traffic Jam on Google Maps</a> (<a href="https://www.vice.com/en_us/article/9393w7/this-man-created-traffic-jams-on-google-maps-using-a-red-wagon-full-of-phones" title="Accès à l'article original">original</a>)</li> | |||
@@ -226,6 +242,8 @@ | |||
<li><a href="/david/cache/2020/73dc1ad4719144f3768002aa5cef60ef/" title="Accès à l'article caché">Indefinite leave to remain</a> (<a href="https://colly.com/articles/indefinite-leave-to-remain" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/240b647e699da81b505d43af39257996/" title="Accès à l'article caché">Git Branch Rename</a> (<a href="https://github.com/chancancode/branch-rename/blob/main/README.md" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/ebaa216561b046ae17b29b399305b294/" title="Accès à l'article caché">Second-guessing the modern web</a> (<a href="https://macwright.org/2020/05/10/spa-fatigue.html" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/4c5cc5e59531ef04e068c883a1a0e166/" title="Accès à l'article caché">Running a Paid Membership Program</a> (<a href="https://craigmod.com/essays/membership_programs/" title="Accès à l'article original">original</a>)</li> | |||
@@ -252,6 +270,8 @@ | |||
<li><a href="/david/cache/2020/0fd34b15eca024dc3997303386b7476e/" title="Accès à l'article caché">Coronavirus : l’étonnante politique de la Suède</a> (<a href="https://www.contrepoints.org/2020/04/28/370150-coronavirus-letonnante-politique-de-la-suede" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/c039e15f24fb1dc53a5cae21c30a2bf7/" title="Accès à l'article caché">Fuck Costco</a> (<a href="https://www.leteignoir.com/2020/06/fuck-costco.html" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/02c4fd680fe2704b27f59a71a269b3db/" title="Accès à l'article caché">COVID-19, l’ami des dominants</a> (<a href="http://www.ardeur.net/2020/04/covid-19-lami-des-dominants/" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/7e8f31c1021b2049977e3c92d3a3b356/" title="Accès à l'article caché">Il n'y aura pas de retour à la normale</a> (<a href="https://www.terrestres.org/2020/03/24/il-ny-aura-pas-de-retour-a-la-normale/" title="Accès à l'article original">original</a>)</li> | |||
@@ -264,6 +284,8 @@ | |||
<li><a href="/david/cache/2020/322e7a8997c732a5fdca0baaea7b9ede/" title="Accès à l'article caché">Guide to Internal Communication, the Basecamp Way</a> (<a href="https://basecamp.com/guides/how-we-communicate" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/0a6f84ae641abbb6a46cbe9ebaec4a8c/" title="Accès à l'article caché">How to Stockpile Food</a> (<a href="https://www.theatlantic.com/politics/archive/2020/03/stockpile-food-my-garage/608290/" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/efc69100e48d4016a6e167797da7ee13/" title="Accès à l'article caché">Researchers Find 'Anonymized' Data Is Even Less Anonymous Than We Thought</a> (<a href="https://www.vice.com/en_us/article/dygy8k/researchers-find-anonymized-data-is-even-less-anonymous-than-we-thought" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/a70068c881eba36604b2f4f8aec54670/" title="Accès à l'article caché">HTML: The Inaccessible Parts</a> (<a href="https://daverupert.com/2020/02/html-the-inaccessible-parts/" title="Accès à l'article original">original</a>)</li> | |||
@@ -320,6 +342,8 @@ | |||
<li><a href="/david/cache/2020/f8ef3c28cb75d299fc723d88fb8d0744/" title="Accès à l'article caché">Des technocrates aux algocrates</a> (<a href="https://www.ledevoir.com/societe/le-devoir-de-philo-histoire/580735/des-technocrates-aux-algocrates" title="Accès à l'article original">original</a>)</li> | |||
<li><a href="/david/cache/2020/892a6dcf591157833a162335d4878043/" title="Accès à l'article caché">Missing structure in technical discussions</a> (<a href="http://kvark.github.io/tech/arguments/2020/06/30/technical-discussions.html" title="Accès à l'article original">original</a>)</li> | |||
</ul> | |||
</article> | |||