<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Home | Blog</title><description/><link>https://julianhofer.eu/</link><language>en</language><item><title>Scripting is More Fun With Nushell</title><link>https://julianhofer.eu/blog/2025/nushell/</link><guid isPermaLink="true">https://julianhofer.eu/blog/2025/nushell/</guid><description>In this blog post we will interactively build up a script with Nushell and have fun along the way

</description><pubDate>Sun, 31 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There are multiple ways to improve your experience in the terminal.
You can get a nice prompt with &lt;a href=&quot;https://starship.rs/&quot;&gt;starship&lt;/a&gt;.
On Linux and macOS, you can switch to the &lt;a href=&quot;https://fishshell.com&quot;&gt;fish&lt;/a&gt; shell.
A lot of nice things like syntax highlighting, tab completion with help text and inline suggestions simply work out of the box.&lt;/p&gt;
&lt;p&gt;However, I went for &lt;a href=&quot;https://www.nushell.sh/&quot;&gt;Nushell&lt;/a&gt;.
Unlike fish, Nu also works on Windows.
Nu’s interactive experience is nearly as nice as fish’s out-of-the-box and just as nice with a few configuration tweaks.
Since I don’t use Windows as my daily driver that shouldn’t matter all that much to me, but it can be an extra benefit.&lt;/p&gt;
&lt;p&gt;Another common way of use case of shells is for scripting.
After experimenting with commands in your terminal, you put the very same commands in a text file.
In the case of Nu, you then execute that script with &lt;code dir=&quot;auto&quot;&gt;nu script.nu&lt;/code&gt;.
This is the workflow where shells shine, and Nu is a prime example for that.&lt;/p&gt;
&lt;p&gt;So let’s take a look at the pitch on Nu’s homepage:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nu pipelines use structured data so you can safely select, filter, and sort the same way every time. Stop parsing strings and start solving problems.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When I first read this, it didn’t really resonate with me.
Maybe I didn’t write enough shell scripts at that time.&lt;/p&gt;
&lt;aside aria-label=&quot;Note&quot;&gt;&lt;p aria-hidden=&quot;true&quot;&gt;Note&lt;/p&gt;&lt;div&gt;&lt;p&gt;At the time of this writing, Nu still makes breaking releases from time to time.
If you are using Nu scripts in production, it is recommended to pin the version of Nu.&lt;/p&gt;&lt;/div&gt;&lt;/aside&gt;
&lt;div&gt;&lt;h2 id=&quot;extract-the-top-issues-from-a-repository&quot;&gt;Extract the Top Issues From a Repository&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Let’s look at a non-trivial example to find out why it’s a big deal that Nu deals with structured data.
Some GitHub repositories like &lt;a href=&quot;https://github.com/zed-industries/zed&quot;&gt;Zed’s&lt;/a&gt; have an &lt;a href=&quot;https://github.com/zed-industries/zed/issues/6952&quot;&gt;issue&lt;/a&gt; that shows the issues with the highest number of 👍 reactions created within in the last week.&lt;/p&gt;
&lt;p&gt;We will now do the same with the help of Nushell.&lt;/p&gt;
&lt;p&gt;I will use the &lt;a href=&quot;https://pixi.sh/latest/&quot;&gt;Pixi&lt;/a&gt; repository,
but any other repository with enough community engagement will do as well.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;prefix-dev/pixi&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Many modern CLI tools have a JSON interface and &lt;a href=&quot;https://julianhofer.eu/blog/2025/git-forges/&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;gh&lt;/code&gt;&lt;/a&gt; is not different.
We need the following fields:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;createdAt&lt;/code&gt; so we only take the ones from last week&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;reactionGroups&lt;/code&gt; so we can extract the 👍 reactions&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;title&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;url&lt;/code&gt; to display them later&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the end we will get a &lt;a href=&quot;https://www.nushell.sh/lang-guide/chapters/types/basic_types/list.html#list&quot;&gt;list&lt;/a&gt; of &lt;a href=&quot;https://www.nushell.sh/lang-guide/chapters/types/basic_types/record.html#record&quot;&gt;records&lt;/a&gt; also known as a &lt;a href=&quot;https://www.nushell.sh/lang-guide/chapters/types/basic_types/table.html#table&quot;&gt;table&lt;/a&gt;.
Each record represents one issue, and we pick one in order to get familiar with the structure.
Please note that this will return a different issue for you, since more issues will have been opened on this repo by the time you read this.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╭────────────────┬────────────────────────────────────────────────────────────╮&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ createdAt      │ 2025-08-29T13:11:13Z                                       │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│                │ ╭───┬───────────┬────────────────────╮                     │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ reactionGroups │ │ # │  content  │       users        │                     │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│                │ ├───┼───────────┼────────────────────┤                     │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│                │ │ 0 │ THUMBS_UP │ ╭────────────┬───╮ │                     │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│                │ │   │           │ │ totalCount │ 1 │ │                     │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│                │ │   │           │ ╰────────────┴───╯ │                     │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│                │ ╰───┴───────────┴────────────────────╯                     │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ title          │ Ability to split pixi.lock (not toml!) into multiple files │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ url            │ https://github.com/prefix-dev/pixi/issues/4467             │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╰────────────────┴────────────────────────────────────────────────────────────╯&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Notice that Nu pretty prints the record per default.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;only-take-issues-from-last-week&quot;&gt;Only take Issues From Last Week&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Nu also has first class support for &lt;a href=&quot;https://www.nushell.sh/lang-guide/chapters/types/basic_types/datetime.html#datetime&quot;&gt;datetime&lt;/a&gt; objects.
This makes it easy to only take the rows of our table where &lt;code dir=&quot;auto&quot;&gt;createdAt&lt;/code&gt; falls within the last week.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;$it.createdAt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;into datetime&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;date now&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1wk&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;last&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╭───┬──────────────────────╮&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 0 │ 2025-08-25T11:28:37Z │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 1 │ 2025-08-25T10:19:22Z │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 2 │ 2025-08-25T10:07:58Z │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 3 │ 2025-08-25T07:21:52Z │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 4 │ 2025-08-24T17:00:35Z │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╰───┴──────────────────────╯&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;We took the last 5 elements.
Considering that this blog has been written on August 31st, these results seem pretty reasonable.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;extract-the--reactions&quot;&gt;Extract the 👍 Reactions&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;We don’t have a nice way to extract the 👍 reactions yet, so let’s work on that.
As a reminder, that’s how &lt;code dir=&quot;auto&quot;&gt;reactionGroup&lt;/code&gt; value looks like for the issue we looked at originally.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;$it.createdAt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;into datetime&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;date now&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1wk&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╭───┬───────────┬────────────────────╮&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ # │  content  │       users        │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;├───┼───────────┼────────────────────┤&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 0 │ THUMBS_UP │ ╭────────────┬───╮ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │           │ │ totalCount │ 1 │ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │           │ ╰────────────┴───╯ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╰───┴───────────┴────────────────────╯&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;This issue, however, does not have reactions at all.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;$it.createdAt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;into datetime&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;date now&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1wk&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╭────────────╮&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ empty list │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╰────────────╯&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Let’s insert a new column &lt;code dir=&quot;auto&quot;&gt;thumbsUp&lt;/code&gt;, which is based on the column &lt;code dir=&quot;auto&quot;&gt;reactionGroup&lt;/code&gt;.
Of this reaction table, it only takes rows with &lt;code dir=&quot;auto&quot;&gt;THUMBS_UP&lt;/code&gt; reaction.
Rows that don’t have any &lt;code dir=&quot;auto&quot;&gt;THUMBS_UP&lt;/code&gt; reactions will result in an empty list.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;$it.createdAt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;into datetime&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;date now&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1wk&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;$in.reactionGroups&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;THUMBS_UP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╭───┬────────────────────────────────────────╮&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 0 │ [list 0 items]                         │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 1 │ ╭───┬───────────┬────────────────────╮ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ │ # │  content  │       users        │ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ ├───┼───────────┼────────────────────┤ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ │ 0 │ THUMBS_UP │ ╭────────────┬───╮ │ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ │   │           │ │ totalCount │ 1 │ │ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ │   │           │ ╰────────────┴───╯ │ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ ╰───┴───────────┴────────────────────╯ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 2 │ [list 0 items]                         │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 3 │ [list 0 items]                         │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 4 │ ╭───┬───────────┬────────────────────╮ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ │ # │  content  │       users        │ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ ├───┼───────────┼────────────────────┤ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ │ 0 │ THUMBS_UP │ ╭────────────┬───╮ │ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ │   │           │ │ totalCount │ 5 │ │ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ │   │           │ ╰────────────┴───╯ │ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ ╰───┴───────────┴────────────────────╯ │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╰───┴────────────────────────────────────────╯&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;We care about the total count.
We get that by accessing &lt;code dir=&quot;auto&quot;&gt;users.totalCount&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;$it.createdAt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;into datetime&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;date now&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1wk&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;$in.reactionGroups&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;THUMBS_UP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;users.totalCount&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╭───┬────────────────╮&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 0 │ [list 0 items] │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 1 │ ╭───┬───╮      │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ │ 0 │ 1 │      │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ ╰───┴───╯      │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 2 │ [list 0 items] │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 3 │ [list 0 items] │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 4 │ ╭───┬───╮      │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ │ 0 │ 5 │      │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │ ╰───┴───╯      │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╰───┴────────────────╯&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Some rows now have empty lists, and some have lists containing a single entry: the number of 👍 reactions.
With &lt;code dir=&quot;auto&quot;&gt;get 0&lt;/code&gt; we get the first element of a list.
By adding &lt;code dir=&quot;auto&quot;&gt;--optional&lt;/code&gt;, this command doesn’t fail on empty lists but returns &lt;code dir=&quot;auto&quot;&gt;null&lt;/code&gt; instead.
We replace &lt;code dir=&quot;auto&quot;&gt;null&lt;/code&gt; with 0, by running &lt;code dir=&quot;auto&quot;&gt;default 0&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;$it.createdAt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;into datetime&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;date now&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1wk&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;$in.reactionGroups&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;THUMBS_UP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;users.totalCount&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;optional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╭───┬───╮&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 0 │ 0 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 1 │ 1 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 2 │ 0 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 3 │ 0 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 4 │ 5 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╰───┴───╯&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;get-the-five-issues-with-the-most--reactions&quot;&gt;Get the Five Issues With the Most 👍 Reactions&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The three columns we truly care about are &lt;code dir=&quot;auto&quot;&gt;thumbsUp&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;title&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;url&lt;/code&gt;, so let’s select those.
We also sort the table, so that the issues with the most 👍 reactions come first.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;$it.createdAt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;into datetime&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;date now&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1wk&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;$in.reactionGroups&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;THUMBS_UP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;users.totalCount&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;optional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sort-by&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;reverse&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╭───┬──────────┬─────────────────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────╮&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ # │ thumbsUp │                                        title                                        │                      url                       │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;├───┼──────────┼─────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────┤&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 0 │        5 │ Proposal to allow the use of Pixi workspaces through a named registry of workspaces │ https://github.com/prefix-dev/pixi/issues/4461 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 1 │        1 │ pixi-build: load variants from packages or files                                    │ https://github.com/prefix-dev/pixi/issues/4429 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 2 │        1 │ `pixi run echo &apos;{{ hello }}&apos;` fails                                                 │ https://github.com/prefix-dev/pixi/issues/4432 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 3 │        1 │ Environment variable of tasks are broken when defined inside task                   │ https://github.com/prefix-dev/pixi/issues/4451 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 4 │        1 │ Documentation: Add switchable pyproject.toml / pixi.toml code snippets              │ https://github.com/prefix-dev/pixi/issues/4452 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╰───┴──────────┴─────────────────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────╯&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;rename-thumbsup-column&quot;&gt;Rename &lt;code dir=&quot;auto&quot;&gt;thumbsUp&lt;/code&gt; Column&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Unicode can be a bit annoying to type in the terminal, but now it’s time to rename our &lt;code dir=&quot;auto&quot;&gt;thumbsUp&lt;/code&gt; column to 👍.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;$it.createdAt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;into datetime&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;date now&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1wk&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;$in.reactionGroups&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;THUMBS_UP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;users.totalCount&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;optional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sort-by&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;reverse&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rename&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;👍&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╭───┬────┬─────────────────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────╮&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ # │ 👍 │                                        title                                        │                      url                       │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;├───┼────┼─────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────┤&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 0 │  5 │ Proposal to allow the use of Pixi workspaces through a named registry of workspaces │ https://github.com/prefix-dev/pixi/issues/4461 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 1 │  1 │ pixi-build: load variants from packages or files                                    │ https://github.com/prefix-dev/pixi/issues/4429 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 2 │  1 │ `pixi run echo &apos;{{ hello }}&apos;` fails                                                 │ https://github.com/prefix-dev/pixi/issues/4432 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 3 │  1 │ Environment variable of tasks are broken when defined inside task                   │ https://github.com/prefix-dev/pixi/issues/4451 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│ 4 │  1 │ Documentation: Add switchable pyproject.toml / pixi.toml code snippets              │ https://github.com/prefix-dev/pixi/issues/4452 │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;╰───┴────┴─────────────────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────╯&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;format-table-in-markdown-format&quot;&gt;Format Table in Markdown Format&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;In the end, we want to add this table to the body of a GitHub issue.
Luckily, Nu has integrated support to convert its values to Markdown.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;top_issues_week&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;createdAt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;reactionGroups&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from json&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;$it.createdAt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;into datetime&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;date now&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1wk&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;$in.reactionGroups&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;THUMBS_UP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;users.totalCount&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;optional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sort-by&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;reverse&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rename&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;/span&gt;&lt;span&gt;thumbsUp&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;👍&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;to md&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;What you can see here is the Markdown table directly embedded in this post, which is also written in Markdown.&lt;/p&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;👍&lt;/th&gt;&lt;th&gt;title&lt;/th&gt;&lt;th&gt;url&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Proposal to allow the use of Pixi workspaces through a named registry of workspaces&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/prefix-dev/pixi/issues/4461&quot;&gt;https://github.com/prefix-dev/pixi/issues/4461&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;pixi-build: load variants from packages or files&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/prefix-dev/pixi/issues/4429&quot;&gt;https://github.com/prefix-dev/pixi/issues/4429&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;pixi run echo &apos;{{ hello }}&apos;&lt;/code&gt; fails&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/prefix-dev/pixi/issues/4432&quot;&gt;https://github.com/prefix-dev/pixi/issues/4432&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Environment variable of tasks are broken when defined inside task&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/prefix-dev/pixi/issues/4451&quot;&gt;https://github.com/prefix-dev/pixi/issues/4451&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Documentation: Add switchable pyproject.toml / pixi.toml code snippets&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/prefix-dev/pixi/issues/4452&quot;&gt;https://github.com/prefix-dev/pixi/issues/4452&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;&lt;h2 id=&quot;create-the-issue&quot;&gt;Create the Issue&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Now we can create an issue with the table we just generated.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh &lt;/span&gt;&lt;span&gt;issue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Top issues last week&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;$top_issues_week&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;How to update an existing issue is left as an exercise to the reader.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;I hope I convinced you that scripting with Nushell can be a lot of fun.
It’s quick to type like bash, and has proper data types like Python.&lt;/p&gt;
&lt;p&gt;With Nu, it’s easy to interact with your data: you extend your pipeline until you are happy with what it does.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Many thanks to &lt;a href=&quot;https://github.com/M-Sabrina&quot;&gt;Sabrina&lt;/a&gt; and &lt;a href=&quot;https://github.com/lucascolley&quot;&gt;Lucas&lt;/a&gt; for their comments and suggestions on this article&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You can find the discussion at this Mastodon &lt;a href=&quot;https://chaos.social/@ju/115127516911589690&quot;&gt;post&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>Nushell</category><category>GitHub</category><category>Scripting</category></item><item><title>Git Forges Made Simple: gh &amp; glab</title><link>https://julianhofer.eu/blog/2025/git-forges/</link><guid isPermaLink="true">https://julianhofer.eu/blog/2025/git-forges/</guid><pubDate>Mon, 04 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When I set the goal for myself to contribute to open source back in 2018,
I mostly struggled with two technical challenges:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python virtual environments, and&lt;/li&gt;
&lt;li&gt;Git together with GitHub.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Solving the former is nowadays my &lt;a href=&quot;https://prefix.dev/&quot;&gt;job&lt;/a&gt;,
so let me write up my current workflow for the latter.&lt;/p&gt;

&lt;p&gt;Most people use Git in combination with modern Git forges like GitHub and GitLab.
Git doesn’t know anything about these forges, which is why CLI tools exist to close that gap.
It’s still good to know how to handle things without them, so I will also explain how to do things with only Git.
For GitHub there’s &lt;a href=&quot;https://cli.github.com/&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;gh&lt;/code&gt;&lt;/a&gt; and for GitLab there’s &lt;a href=&quot;https://docs.gitlab.com/editor_extensions/gitlab_cli/&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;glab&lt;/code&gt;&lt;/a&gt;.
Both of them are Go binaries without any dependencies that work on Linux, macOS and Windows.
If you don’t like any of the provided installation methods, you can simply download the binary, make it executable and put it in your &lt;code dir=&quot;auto&quot;&gt;PATH&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Luckily, they also have mostly the same command line interface.
First, you have to login with the command that corresponds to your git forge:&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;forge&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-20&quot; id=&quot;tab-20&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  GitHub &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-21&quot; id=&quot;tab-21&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  GitLab &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-20&quot; aria-labelledby=&quot;tab-20&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;auth&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;login&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-21&quot; aria-labelledby=&quot;tab-21&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;glab&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;auth&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;login&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;p&gt;In the case of &lt;code dir=&quot;auto&quot;&gt;gh&lt;/code&gt; this even authenticates Git with GitHub.
With GitLab, you still have to set up authentication via &lt;a href=&quot;https://docs.gitlab.com/user/ssh/&quot;&gt;SSH&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;working-solo&quot;&gt;Working Solo&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The simplest way to use Git is to use it like a backup system.
First, you create a new repository on either &lt;a href=&quot;https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-new-repository&quot;&gt;Github&lt;/a&gt; or &lt;a href=&quot;https://docs.gitlab.com/user/project/&quot;&gt;GitLab&lt;/a&gt;.
Then you clone the repository:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clone&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;REPO&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;From that point on, all you have to do is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;do some work&lt;/li&gt;
&lt;li&gt;commit&lt;/li&gt;
&lt;li&gt;push&lt;/li&gt;
&lt;li&gt;repeat&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On its own there aren’t a lot of reasons to choose this approach over a file syncing service like &lt;a href=&quot;https://nextcloud.com/sign-up/&quot;&gt;Nextcloud&lt;/a&gt;.
No, the main reason you do this, is because you are either already familiar with the git workflow, or want to get used to it.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;contributing&quot;&gt;Contributing&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Git truly shines as soon as you start collaborating with others.
On a high level this works like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You modify some files in a Git repository,&lt;/li&gt;
&lt;li&gt;you propose your changes via the Git forge,&lt;/li&gt;
&lt;li&gt;maintainers of the repository review your changes, and&lt;/li&gt;
&lt;li&gt;as soon as they are happy with your changes, they will integrate your changes into the main branch of the repository.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h3 id=&quot;starting-out-with-a-fresh-branch&quot;&gt;Starting Out With a Fresh Branch&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Let’s go over the exact commands.&lt;/p&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;p&gt;You will want to start out with the latest upstream changes in the default branch.
You can find out its name by running the following command:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ls-remote&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--symref&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;origin&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HEAD&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Chances are it displays either &lt;code dir=&quot;auto&quot;&gt;ref/heads/main&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;refs/heads/master&lt;/code&gt;.
The last component is the branch, so the default branch will be called either &lt;code dir=&quot;auto&quot;&gt;main&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;master&lt;/code&gt;.
Before you start a new branch, you will run the following two commands to make sure you start with the latest state of the repository:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;switch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;DEFAULT-BRANCH&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pull&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You switch and create a new branch with:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;switch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--create&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;BRANCH&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;That way you can work on multiple features at the same time and easily keep your default branch synchronized with the remote repository.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;h3 id=&quot;open-a-pull-request&quot;&gt;Open a Pull Request&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The next step is to open a pull request on GitHub or merge request on GitLab.
Even though they are named differently, they are exactly the same thing.
Therefore, I will call both of them pull requests from now on.
The idea of a pull request is to integrate the changes from one branch into another branch (typically the default branch).
However, you don’t necessarily want to give every potential contributor the power to create new branches on your repository.
That is why the concept of forks exists.
Forks are copies of a repository that are hosted on the same Git forge.
Contributors can now create branches on their own forks and open pull requests based on these branches.&lt;/p&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;p&gt;If you don’t have push access to the repository, now it’s time to create your own fork.&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;with-without&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-34&quot; id=&quot;tab-34&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  With Forge Tools &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-35&quot; id=&quot;tab-35&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Without Forge Tools &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-34&quot; aria-labelledby=&quot;tab-34&quot; role=&quot;tabpanel&quot;&gt; &lt;p&gt;With the Git forge tools, you only need a single command to both fork the repository and set up the git remotes.&lt;/p&gt;&lt;starlight-tabs data-sync-key=&quot;forge&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-22&quot; id=&quot;tab-22&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  GitHub &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-23&quot; id=&quot;tab-23&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  GitLab &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-22&quot; aria-labelledby=&quot;tab-22&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fork&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--remote&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;I don’t know why &lt;code dir=&quot;auto&quot;&gt;gh repo fork&lt;/code&gt; doesn’t set that for you,
but now we need to tell &lt;code dir=&quot;auto&quot;&gt;gh&lt;/code&gt; which repository is the default.
That way it knows against which repository you want to extend when opening a pull request.
We want to extend the original repository, so let’s select that with the interactive picker.&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;set-default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-23&quot; aria-labelledby=&quot;tab-23&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;glab&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fork&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--remote&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;   &lt;/div&gt;&lt;div id=&quot;tab-panel-35&quot; aria-labelledby=&quot;tab-35&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;p&gt;Without the forge CLI tools, you first fork the repository in the web interface.&lt;/p&gt;&lt;p&gt;Then, you run the following commands:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remote&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rename&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;origin&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;upstream&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remote&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;origin&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;FORK&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;When you cloned your repository, Git set the default branch of the original repo as the upstream branch for your local default branch.
This is preserved by the remote rename, which is why the default branch can still be updated from upstream with &lt;code dir=&quot;auto&quot;&gt;git pull&lt;/code&gt; and no additional arguments.&lt;/p&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then, you open the Pull Request&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;with-without&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-36&quot; id=&quot;tab-36&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  With Forge Tools &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-37&quot; id=&quot;tab-37&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Without Forge Tools &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-36&quot; aria-labelledby=&quot;tab-36&quot; role=&quot;tabpanel&quot;&gt; &lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;pr create&lt;/code&gt; directly pushes and sets up your branch, and then opens the pull request for you.
If you have a fork available, it will ask whether you want to push your branch there:&lt;/p&gt;&lt;starlight-tabs data-sync-key=&quot;forge&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-24&quot; id=&quot;tab-24&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  GitHub &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-25&quot; id=&quot;tab-25&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  GitLab &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-24&quot; aria-labelledby=&quot;tab-24&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-25&quot; aria-labelledby=&quot;tab-25&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;glab&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;   &lt;/div&gt;&lt;div id=&quot;tab-panel-37&quot; aria-labelledby=&quot;tab-37&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;p&gt;With Git, you first have to tell it that it should create the corresponding branch on the remote and set it as upstream branch.&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--set-upstream&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;origin&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;BRANCH&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Next, you open the repository in the web interface, where it will suggest opening a pull request.
The upstream branch of your local branch is now configured, which means you can update your remote by running &lt;code dir=&quot;auto&quot;&gt;git push&lt;/code&gt; without any additional arguments.&lt;/p&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;h2 id=&quot;checking-out-pull-requests&quot;&gt;Checking out Pull Requests&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Often, you want to check out a pull request on your own machine to verify that it works as expected.&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;with-without&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-38&quot; id=&quot;tab-38&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  With Forge Tools &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-39&quot; id=&quot;tab-39&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Without Forge Tools &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-38&quot; aria-labelledby=&quot;tab-38&quot; role=&quot;tabpanel&quot;&gt; &lt;article&gt; &lt;p&gt;  &lt;span&gt;&lt;/span&gt; &lt;/p&gt; &lt;div&gt;&lt;p&gt;First you check out which pull requests are available&lt;/p&gt;&lt;starlight-tabs data-sync-key=&quot;forge&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-26&quot; id=&quot;tab-26&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  GitHub &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-27&quot; id=&quot;tab-27&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  GitLab &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-26&quot; aria-labelledby=&quot;tab-26&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-27&quot; aria-labelledby=&quot;tab-27&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;glab&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  &lt;p&gt;You remember the ID and use it to check out the pull request.&lt;/p&gt;&lt;starlight-tabs data-sync-key=&quot;forge&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-28&quot; id=&quot;tab-28&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  GitHub &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-29&quot; id=&quot;tab-29&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  GitLab &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-28&quot; aria-labelledby=&quot;tab-28&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;checkout&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;PR_ID&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-29&quot; aria-labelledby=&quot;tab-29&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;glab&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;checkout&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;MR_ID&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  &lt;p&gt;This works no matter if the pull request is coming from the repo itself or a fork, and it doesn’t set up any additional remotes.&lt;/p&gt;&lt;p&gt;You can check out the status of your pull request with &lt;code dir=&quot;auto&quot;&gt;pr view&lt;/code&gt;.
By adding &lt;code dir=&quot;auto&quot;&gt;--web&lt;/code&gt;, it will directly open the web browser for you:&lt;/p&gt;&lt;starlight-tabs data-sync-key=&quot;forge&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-30&quot; id=&quot;tab-30&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  GitHub &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-31&quot; id=&quot;tab-31&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  GitLab &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-30&quot; aria-labelledby=&quot;tab-30&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;gh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;view&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--web&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-31&quot; aria-labelledby=&quot;tab-31&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;glab&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;view&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--web&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  &lt;/div&gt; &lt;/article&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-39&quot; aria-labelledby=&quot;tab-39&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;article&gt; &lt;p&gt;  &lt;span&gt;&lt;/span&gt; &lt;/p&gt; &lt;div&gt;&lt;p&gt;Checking out a pull request is surprisingly involved with Git alone.
First, navigate to the pull request in your web browser.&lt;/p&gt;&lt;starlight-tabs&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-32&quot; id=&quot;tab-32&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  Fork &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-33&quot; id=&quot;tab-33&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Same Repository &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-32&quot; aria-labelledby=&quot;tab-32&quot; role=&quot;tabpanel&quot;&gt; &lt;p&gt;In this example, can see that the pull request proposes changes from the repository by &lt;code dir=&quot;auto&quot;&gt;Hofer-Julian&lt;/code&gt; to a repository by &lt;code dir=&quot;auto&quot;&gt;prefix-dev&lt;/code&gt;.
If the both branches are on the same repository, click on the tab “Same Repository” above.
&lt;img src=&quot;https://julianhofer.eu/_astro/github-pull-request-fork.C5aSdXC2_1xfIiz.webp&quot; srcset=&quot;/_astro/github-pull-request-fork.C5aSdXC2_ZBhsMQ.webp 640w, /_astro/github-pull-request-fork.C5aSdXC2_ZH0F1E.webp 750w, /_astro/github-pull-request-fork.C5aSdXC2_Z23dhtX.webp 828w, /_astro/github-pull-request-fork.C5aSdXC2_Z29Y4P0.webp 1080w, /_astro/github-pull-request-fork.C5aSdXC2_ZsRiDo.webp 1280w, /_astro/github-pull-request-fork.C5aSdXC2_1xfIiz.webp 1664w&quot; alt=&quot;Web view of the pull request displaying that it comes from a fork&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1664px) 1664px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-fit=&quot;cover&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1664&quot; height=&quot;564&quot;&gt;&lt;/p&gt;&lt;p&gt;If the pull request comes from a fork, you execute the following commands:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# Add a remote for the user who opened the pull request&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remote&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;USER&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;FORK_OF_USER&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# Fetch their repo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;USER&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# Check out their branch&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;switch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;BRANCH&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-33&quot; aria-labelledby=&quot;tab-33&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;p&gt;In this example, can see that the pull request proposes changes from the repository by &lt;code dir=&quot;auto&quot;&gt;Hofer-Julian&lt;/code&gt; to a repository by &lt;code dir=&quot;auto&quot;&gt;prefix-dev&lt;/code&gt;.
If the branches are on the different repositories, click on the tab “Fork” above.
&lt;img src=&quot;https://julianhofer.eu/_astro/github-pull-request-same-repo.D8g_Zodw_ZuDCjO.webp&quot; srcset=&quot;/_astro/github-pull-request-same-repo.D8g_Zodw_Z1z0uBX.webp 640w, /_astro/github-pull-request-same-repo.D8g_Zodw_1L12MT.webp 750w, /_astro/github-pull-request-same-repo.D8g_Zodw_2r9rqS.webp 828w, /_astro/github-pull-request-same-repo.D8g_Zodw_21xy3y.webp 1080w, /_astro/github-pull-request-same-repo.D8g_Zodw_Z53mop.webp 1280w, /_astro/github-pull-request-same-repo.D8g_Zodw_1tVM4q.webp 1668w, /_astro/github-pull-request-same-repo.D8g_Zodw_ZuDCjO.webp 1734w&quot; alt=&quot;Web view of the pull request displaying that it comes from a fork&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 1734px) 1734px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-fit=&quot;cover&quot; data-astro-image-pos=&quot;center&quot; width=&quot;1734&quot; height=&quot;452&quot;&gt;&lt;/p&gt;&lt;p&gt;If it’s the same repository, you run checkout the pull request like this:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;origin&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;switch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;BRANCH&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;  &lt;/starlight-tabs&gt;  &lt;/div&gt; &lt;/article&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;div&gt;&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;When I first heard of &lt;code dir=&quot;auto&quot;&gt;gh&lt;/code&gt;’s predecessor &lt;code dir=&quot;auto&quot;&gt;hub&lt;/code&gt;, I thought this is merely a tool for people who insist on doing everything in the terminal.
I only realized relatively recently that Git forge tools are in fact the missing piece to an efficient Git workflow.
Hopefully, you now have a better idea of the appeal of these tools!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Many thanks to &lt;a href=&quot;https://github.com/M-Sabrina&quot;&gt;Sabrina&lt;/a&gt; and &lt;a href=&quot;https://github.com/lucascolley&quot;&gt;Lucas&lt;/a&gt; for their comments and suggestions on this article&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You can find the discussion at this Mastodon &lt;a href=&quot;https://chaos.social/@ju/114966203312328797&quot;&gt;post&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>Git</category><category>GitHub</category><category>GitLab</category></item><item><title>How to send Emails via Python</title><link>https://julianhofer.eu/blog/2022/python-mail/</link><guid isPermaLink="true">https://julianhofer.eu/blog/2022/python-mail/</guid><pubDate>Wed, 28 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ve assumed that sending emails via a CLI would be easy.
That might even be the case, but sending them in a way that they actually show up in the receiver’s mailbox is quite a different story.&lt;/p&gt;

&lt;p&gt;After following multiple tutorials and using tools from &lt;code dir=&quot;auto&quot;&gt;sendmail&lt;/code&gt; to &lt;code dir=&quot;auto&quot;&gt;mailx&lt;/code&gt;, not a single email arrived.
Since I wanted to send the mail from within a Python script anyway, I moved on to a Real Python &lt;a href=&quot;https://realpython.com/python-send-email/&quot;&gt;tutorial&lt;/a&gt;.
This is the snippet they use to send an email.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; smtplib, ssl&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;port &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;465&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# For SSL&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;smtp_server &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;smtp.domain.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sender_email &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;my@domain.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# Enter your address&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;receiver_email &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;your@domain.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# Enter receiver address&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;password &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;MY_PASSWORD&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;# Enter password&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;message &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Subject: Hi there&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;This message is sent from Python.&lt;/span&gt;&lt;span&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;context &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ssl.&lt;/span&gt;&lt;span&gt;create_default_context&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; smtplib.&lt;/span&gt;&lt;span&gt;SMTP_SSL&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;smtp_server&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; port&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; server:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server.&lt;/span&gt;&lt;span&gt;login&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sender_email&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; password&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server.&lt;/span&gt;&lt;span&gt;sendmail&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sender_email&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; receiver_email&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;And again, nothing arrived at my preferred receiver &lt;a href=&quot;https://proton.me/mail&quot;&gt;protonmail&lt;/a&gt;.
However, if you try to email to a gmail address, you get a helpful error back.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Our system has detected that this message is not RFC 550-5.7.1 5322&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;compliant: &apos;From&apos; header is missing. To reduce the amount of spam sent&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;to Gmail, this message has been blocked.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;This is how the snippet looks after adding the ‘From’ header:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; smtplib, ssl&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;port &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;465&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# For SSL&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;smtp_server &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;smtp.domain.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sender_email &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;my@domain.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# Enter your address&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;receiver_email &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;your@domain.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# Enter receiver address&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;password &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;MY_PASSWORD&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;# Enter password&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 👇 The string is now a f-string and the &apos;From&apos; header has been added&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;message &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;From: &amp;#x3C;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;sender_email&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Subject: Hi there&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;This message is sent from Python.&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;context &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ssl.&lt;/span&gt;&lt;span&gt;create_default_context&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; smtplib.&lt;/span&gt;&lt;span&gt;SMTP_SSL&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;smtp_server&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; port&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; server:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server.&lt;/span&gt;&lt;span&gt;login&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sender_email&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; password&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server.&lt;/span&gt;&lt;span&gt;sendmail&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sender_email&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; receiver_email&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;And voilà, the email arrives at gmail.
Again nothing at protonmail, but now it wasn’t too hard to guess that it might want a ‘To’ header.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; smtplib, ssl&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;port &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;465&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# For SSL&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;smtp_server &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;smtp.domain.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sender_email &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;my@domain.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# Enter your address&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;receiver_email &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;your@domain.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# Enter receiver address&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;password &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;MY_PASSWORD&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;# Enter password&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 👇 The &apos;To&apos; header has been added&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;message &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;From: &amp;#x3C;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;sender_email&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;To: &amp;#x3C;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;receiver_email&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Subject: Hi there&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;This message is sent from Python.&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;context &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ssl.&lt;/span&gt;&lt;span&gt;create_default_context&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; smtplib.&lt;/span&gt;&lt;span&gt;SMTP_SSL&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;smtp_server&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; port&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; server:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server.&lt;/span&gt;&lt;span&gt;login&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sender_email&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; password&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server.&lt;/span&gt;&lt;span&gt;sendmail&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sender_email&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; receiver_email&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The Real Python tutorial is from 2018, so chances are that there are better ways to send emails nowadays.
After looking through the standard library docs, I think the following snippet is a more idiomatic way to achieve the same thing in 2022.
The main difference is that it removes duplication with the help of the &lt;code dir=&quot;auto&quot;&gt;EmailMessage&lt;/code&gt; class.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; smtplib, ssl&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; email.message &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; EmailMessage&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;port &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;465&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# For SSL&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;smtp_server &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;smtp.domain.net&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sender_email &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;my@domain.at&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;       &lt;/span&gt;&lt;span&gt;# Enter your address&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;receiver_email &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;your@domain.com&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# Enter receiver address&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;password &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;MY_PASSWORD&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;# Enter password&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;subject &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Hi there&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;content &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;This message is sent from Python.&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;msg &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;EmailMessage&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;msg[&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;Subject&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; subject&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;msg[&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;From&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sender_email&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;msg[&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;To&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; receiver_email&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;msg.&lt;/span&gt;&lt;span&gt;set_content&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;context &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ssl.&lt;/span&gt;&lt;span&gt;create_default_context&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; smtplib.&lt;/span&gt;&lt;span&gt;SMTP_SSL&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;smtp_server&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; port&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; server:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server.&lt;/span&gt;&lt;span&gt;login&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sender_email&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; password&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server.&lt;/span&gt;&lt;span&gt;send_message&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;You can find the discussion at this Mastodon &lt;a href=&quot;https://chaos.social/@ju/109489141171195265&quot;&gt;post&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>Python</category><category>Email</category><category>Scripting</category></item><item><title>How to install Nix on Fedora Silverblue</title><link>https://julianhofer.eu/blog/2022/silverblue-nix/</link><guid isPermaLink="true">https://julianhofer.eu/blog/2022/silverblue-nix/</guid><description>There is a lot to like about Fedora Silverblue. The base of your operating system is immutable, so you cannot really break your system with updates. However, that also means that installing packages with dnf doesn&apos;t work anymore. This post is about how to install Nix, which allows you to install CLI tools without modifying your base system.

</description><pubDate>Fri, 25 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;aside aria-label=&quot;Caution&quot;&gt;&lt;p aria-hidden=&quot;true&quot;&gt;Caution&lt;/p&gt;&lt;div&gt;&lt;p&gt;Since Fedora 42, the Determinate Nix installer &lt;a href=&quot;https://github.com/DeterminateSystems/nix-installer/issues/1445&quot;&gt;doesn’t work anymore&lt;/a&gt; out of the box.
As of 2026, Nix is packaged on Fedora.
This means you can layer it on top of your installation, or install it in single-user mode in your toolbx.
Both options are described in the &lt;a href=&quot;https://src.fedoraproject.org/rpms/nix/blob/rawhide/f/README.md&quot;&gt;README&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;There is a lot to like about &lt;a href=&quot;https://docs.fedoraproject.org/en-US/fedora-silverblue/&quot;&gt;Fedora Silverblue&lt;/a&gt;.
Updates are atomic and if there is something wrong with the newest version, you can always roll back.
You always move between immutable images of your operating system, but that also means that installing packages with &lt;code dir=&quot;auto&quot;&gt;dnf&lt;/code&gt; doesn’t work anymore.
For GUI applications, the answers to this are &lt;code dir=&quot;auto&quot;&gt;flatpak&lt;/code&gt; and its app store &lt;a href=&quot;https://flathub.org/home&quot;&gt;flathub&lt;/a&gt;.
For everything else you can enter a mutable Fedora container with the help of &lt;a href=&quot;https://containertoolbx.org/&quot;&gt;toolbx&lt;/a&gt;.
There, the &lt;code dir=&quot;auto&quot;&gt;dnf&lt;/code&gt; command is readily available and can be used as usual.
This is convenient for development, but not necessarily outside it.
Whenever you want to use an installed CLI tool, you now have to enter the toolbx beforehand.
Also, there are a couple of system directories that are inaccessible from within the container.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;nix&quot;&gt;Nix&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Nix is a cross-platform package manager with the &lt;a href=&quot;https://repology.org/repositories/statistics/total&quot;&gt;largest repository&lt;/a&gt; at the time of this writing.
Like with Silverblue, upgrades in Nix are atomic and can be rolled back.
In order to install it, we run the &lt;a href=&quot;https://github.com/DeterminateSystems/nix-installer&quot;&gt;Determinate Nix installer&lt;/a&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--proto&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;=https&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--tlsv1.2&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-sSf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-L&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://install.determinate.systems/nix&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-s&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;To get started using Nix, open a new shell or run source &lt;code dir=&quot;auto&quot;&gt;nix-daemon.sh&lt;/code&gt; as shown below:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Now you can install tools on your machine with &lt;a href=&quot;https://nixos.org/manual/nix/stable/command-ref/nix-env.html&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;nix-env&lt;/code&gt;&lt;/a&gt;.
If that’s all you want, then you can skip over to the last &lt;a href=&quot;./#distrobox&quot;&gt;section&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;home-manager&quot;&gt;Home Manager&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Home Manager is a tool that allows declarative configuration of user specific packages and dotfiles.
This not only helps you to keep track which changes you made to your user environment, but also greatly reduces the amount of work necessary to migrate to a new machine.
Convinced?
Then let’s get started!&lt;/p&gt;
&lt;p&gt;First, we add the &lt;code dir=&quot;auto&quot;&gt;nixpkgs-unstable&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;home-manager&lt;/code&gt; channels.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;nix-channel&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--add&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://nixos.org/channels/nixpkgs-unstable&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;nix-channel&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--add&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://github.com/nix-community/home-manager/archive/master.tar.gz&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;home-manager&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Then we update our nix-channels.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;nix-channel&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--update&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Now we can install &lt;code dir=&quot;auto&quot;&gt;home-manager&lt;/code&gt; with &lt;code dir=&quot;auto&quot;&gt;nix-shell&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;nix-shell&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;&amp;#x3C;home-manager&gt;&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-A&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;You can edit its config file by executing:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;home-manager&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;edit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;This should open your editor with a couple of values already set.
In the following snippet you see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;how to set your git data with useful &lt;a href=&quot;https://leosiddle.com/posts/2020/07/git-config-pull-rebase-autostash/&quot;&gt;extra config&lt;/a&gt;, and&lt;/li&gt;
&lt;li&gt;how to ensure that a set of &lt;a href=&quot;https://search.nixos.org/packages?channel=unstable&quot;&gt;nix packages&lt;/a&gt; is installed.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{ &lt;/span&gt;&lt;span&gt;config,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pkgs,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;... &lt;/span&gt;&lt;span&gt;}:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# Leave `home.username`, `home.homeDirectory`, `home.stateVersion`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# and `programs.home-manager.enable` as they are&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# Set git config&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;programs&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;enable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userName&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Julian Hofer&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userEmail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;julianhofer@gnome.org&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;extraConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;defaultBranch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;pull&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;rebase&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;rebase&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;autostash&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# Ensure that the following packages are installed&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;home&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;packages&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pkgs&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;bat&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;gh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;glab&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ripgrep&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Now we activate our config file by executing&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;home-manager&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;switch&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;This also means that if you remove a setting or package in the config file, it will be removed on your system as well.&lt;/p&gt;
&lt;p&gt;In order to update your environment run:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;nix-channel&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--update&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;unpacking&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;channels...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;home-manager&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;switch&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;distrobox&quot;&gt;Distrobox&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://distrobox.privatedns.org/&quot;&gt;Distrobox&lt;/a&gt; is a tool that creates container that are tightly integrated with the host.
This makes it perfect for development tasks.&lt;/p&gt;
&lt;p&gt;First install distrobox.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;rpm-ostree&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--apply-live&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;distrobox&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Enter your distrobox with:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;distrobox&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;enter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Distrobox mounts &lt;code dir=&quot;auto&quot;&gt;/nix&lt;/code&gt; inside of your container.
This way you can continue using Nix and the apps you’ve installed with it.
To see if everything is working as expected, you can try to view your git config with the cat-replacement &lt;a href=&quot;https://github.com/sharkdp/bat#syntax-highlighting&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;bat&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;bat&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;~/.config/git/config&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;img alt=&quot;The content of git config on a terminal as displayed by bat with syntax highlighting&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 695px) 695px, 100vw&quot; data-astro-image=&quot;constrained&quot; width=&quot;695&quot; height=&quot;372&quot; src=&quot;https://julianhofer.eu/_astro/bat-output.C99C8y6X_Z20lmPn.webp&quot; srcset=&quot;/_astro/bat-output.C99C8y6X_2pn6PG.webp 640w, /_astro/bat-output.C99C8y6X_Z20lmPn.webp 695w&quot;&gt;&lt;/p&gt;
&lt;p&gt;You can find the discussion at this Mastodon &lt;a href=&quot;https://chaos.social/@ju/110933089661444452&quot;&gt;post&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gitlab.com/ahayzen/silverblue-nix&quot;&gt;gitlab.com/ahayzen/silverblue-nix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.reddit.com/r/SteamDeck/comments/yxpmlq/nix_homemanager_on_steam_deck/&quot;&gt;reddit.com/r/SteamDeck/comments/yxpmlq/nix_homemanager_on_steam_deck&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>Fedora</category><category>Silverblue</category><category>Nix</category></item></channel></rss>