Radish alpha
r
rad:z371PVmDHdjJucejRoRYJcDEvD5pp
Radicle website including documentation and guides
Radicle
Git
user guide: add ch2 & ch3
Merged did:key:z6Mkw1Yy...qkRm opened 2 years ago
1 file changed +898 -5 a37f2357 cc58cf58
modified _guides/user.md
@@ -123,9 +123,9 @@ This command runs an installer script that automates the setup process, by:

> 👾
>
-
> If you want the above to be installed in a different
-
> location than `~/.radicle`, you can set the `RAD_PATH` environment variable
-
> before running the installation script.
+
> If you want the above to be installed in a different location than
+
> `~/.radicle`, you can set the `RAD_PATH` environment variable before running
+
> the installation script.
>
> Note that if you don't want to use the installer script, you can also always
> compile from the [source code][heartwood] or get the [binaries][] if you
@@ -673,7 +673,7 @@ some way, for example by pushing a branch or commenting on an issue, simply run
> is called the *scope*.
>
> By default, when cloning or seeding a repository, your node will subscribe to
-
> content from _all_ peers. This behavior is part of the seeding policy and can
+
> content from *all* peers. This behavior is part of the seeding policy and can
> be changed by passing `--scope followed` to the `seed` and `clone` commands,
> to only subscribe to content from the repository *delegates* plus any node
> that is explicitly followed via `rad follow`.
@@ -691,6 +691,898 @@ issues and patches from the unique perspectives of both contributors and
delegates. It's here that the true kernel of *code collaboration* begins to
unfold.

+
## 2. Collaborating the Radicle Way
+

+
Now is the time to delve into Radicle's approach to storing and working with
+
social artifacts like issues and patches. In the context of version control
+
systems, social artifacts refer to collaborative features that facilitate
+
discussions, bug tracking, and code review. Patches, in particular, represent
+
proposed changes to the codebase, often in response to issues or feature
+
requests. Unlike traditional centralized forges, Radicle leverages Git's
+
distributed version control system to allow you to maintain local copies of your
+
repository's associated issues and patches, alongside the repository itself.
+

+
If you're familiar with Git, you know that when you `commit` code changes, a
+
unique hash called a commit hash is generated to identify them. In Radicle,
+
issues, patches, and their associated comments work similarly to commits. They
+
are stored as Git objects within the repository itself, each with its own unique
+
Git Object ID (OID). This means that all collaborative interactions, such as
+
creating issues, submitting patches, and commenting, are self-contained within
+
the Git repository.
+

+
Furthermore, these objects are cryptographically signed by their author,
+
providing an additional layer of security and trust. This allows all
+
participants to independently verify the authenticity of the collaborative
+
interactions, ensuring the integrity of the project's history. By storing social
+
artifacts within the repository and leveraging cryptographic signatures, Radicle
+
enables projects to operate independently of centralized platforms, giving users
+
full control over their collaborative data.
+

+
<aside> The <strong>Git OID</strong> is a SHA-1 hash, which is a 40-character
+
string that uniquely identifies objects within a Git repository. This
+
identification is part of Git's content-addressable storage system, ensuring the
+
integrity of every data piece. </aside>
+

+
You know what this all means? One day, creating an AI agent that codes and thinks
+
like you will be much easier than if you were to download the deepest parts of
+
your brain onto a platform owned by a megacorporation. There, it is an unknown
+
abyss, where your issues and thoughts are not hashed nor associated with public
+
keys. The platform has an iron grip on your data, feeding it to their mysterious
+
AI models without even giving you a peek behind the curtain.
+

+
That's the old system. The beauty of local-first systems like Radicle is that
+
everything is hashed and all your data is readily accessible from your local
+
machine. There is no need for complex API calls or special bots to extract
+
data for the projects you're working on, as you'll get it anytime you fetch.
+

+
> 🧠
+
>
+
>
+
> While we don't have a plugin for creating sovereign AI agents just yet, the
+
potential is there. If you're interested in exploring this idea further,
+
[let us know][zulip]!
+

+
### Working with issues
+

+
<div class="poem"> The more we git together<br>
+
Together, together<br>
+
The more we git together<br>
+
The happier we'll be</div>
+

+
<aside class="span-5" class="kicker">A <strong>Conflict-Free Replicated Data
+
Type (CRDT)</strong> is a data structure that allows distributed systems to
+
update data independentlyand resolve inconsistencies without central coordination.
+
CRDTs ensure that all copies converge to the same state, making them ideal for
+
environments with intermittent connectivity or where immediate consistency is
+
not required.</aside>
+

+
Before we get into *issue management*, you should first get to know our trusted
+
friend, the COB. Discussing issues and patches is not natively supported
+
by Git, so we had to extend it. We named this data type a *Collaborative Object*
+
or COB for short. They use Conflict-Free Replicated Data Types (CRDTs) for data
+
consistency and are one of the fundamental building blocks of the Radicle protocol.
+

+
<aside class="span-4">
+
Git has a built-in command called <code>git format-patch</code> that generates a
+
patch file from commits. This patch file contains the changes made in the
+
commits, along with metadata such as the commit message, author, and date. The
+
patch file can then be easily shared with others via email or other means for
+
review and discussion. This patch-based workflow is particularly popular in the
+
Linux kernel development community, where patches are often sent to mailing
+
lists for review before being applied to the main repository.
+
</aside>
+

+
> 🧠
+
>
+
> Radicle's COBs are associated with unique namespaces, such as
+
> `xyz.radicle.issue` and `xyz.radicle.patch`, to prevent naming collisions.
+
> This reverse domain name notation not only houses Radicle's predefined COBs
+
> but also accommodates user-defined ones.
+
>
+
> For example, if a user or organization were to define a new COB type under their
+
> domain, it might look something like `com.acme.task`, for some hypothetical
+
> "task" COB under the `acme.com` domain. This extensibility allows for an
+
> unlimited set of new collaboration primitives to be defined by users like you!
+
>
+
> If you're interested in creating a custom COB, pop into our [chatroom][zulip]
+
> and we can get you started.
+

+
<aside>
+
In Radicle, a <strong>delegate</strong> refers to a role or entity that has
+
been granted the authority to sign for and manage a repository and its metadata.
+
</aside>
+

+
Now, to see how COBs are transformed via the process of collaboration, we'll
+
kick off from Paxel's perspective, as they open an issue in a repository where
+
they are a contributor, but not a delegate.
+

+
Paxel is going to `cd` into their directory for the `dark-star-data` project
+
that they are collaborating on, and create an issue with `rad issue open` by
+
also passing in a title and description with the command.
+

+
    $ cd dark-star-data
+
    $ rad issue open  --title "Establish data standards for IUI Dark Star Data group" --description "As we go out and recruit the Neboriens and other intelligences to join the Intergalactic Union of Intelligences (IUI), we are going to have to establish standards for Dark Star data submissions."
+
    ╭───────────────────────────────────────────────────────────────╮
+
    │ Title   Establish data standards for IUI Dark Star Data group │
+
    │ Issue   e4255cc2a0a65b543c2b5badac14bf9e0d9f409f              │
+
    │ Author  paxel (you)                                           │
+
    │ Status  open                                                  │
+
    │                                                               │
+
    │ As we go out and recruit the Neboriens and other              │
+
    │ intelligences to join the Intergalactic Union of              │
+
    │ Intelligences (IUI), we are going to have to establish        │
+
    │ standards for Dark Star data submissions.                     │
+
    ╰───────────────────────────────────────────────────────────────╯
+
    ✓ Synced with 1 node(s)
+

+
Behind the scenes, `rad issue open` conjures up a brand-new COB for the issue,
+
bestowing upon it a unique identifier. This COB becomes the guardian of all the
+
metadata and interactions associated with the issue, ready to be replicated and
+
synced across the Radicle network.
+

+
COBs like issues and patches can be created even when offline, since Radicle is
+
local-first. The local COB you create will simply synchronize with the network
+
once you connect to the internet.
+

+
You can always see a table with all of the issues associated to a repository
+
by running `rad issue` within its directory.
+

+
    $ rad issue
+
    ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
+
    │ ●   ID        Title                                                    Author                     Labels      Assignees │
+
    ├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
+
    │ ●   80464b3   Categorize initial dataset                               paxel    (you)                                   │
+
    │ ●   3e2f653   Add anomalous data from ship 897AF                       calyx    z6Mkgom…unurCap               paxel     │
+
    │ ●   badda04   Recruit Neboriens to join IUI and share dark star data   calyx    z6Mkgom…unurCap               paxel     │
+
    │ ●   e4255cc   Establish data standards for IUI Dark Star Data group    paxel    (you)             standards             │
+
    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+

+
<aside>It's possible you may have to widen your terminal window to see all of
+
the available columns.</aside>
+

+
While exploring the repository's open issues, Paxel happens upon one that piques
+
their interest and displays it with the command `rad issue show <issue-id>`:
+

+
    $ rad issue show 3e2f65
+
    ╭─────────────────────────────────────────────────────────────╮
+
    │ Title   Add anomalous data from ship 897AF                  │
+
    │ Issue   3e2f653383f0d2fe21ef4e859a25925c364c740a            │
+
    │ Author  calyx                                               │
+
    │ Status  open                                                │
+
    │                                                             │
+
    │ Before we onboard new IUI members like the Neborians, it is │
+
    │ important we upload the data from ship 897AF. I just        │
+
    │ reviewed the database and it seems this is missing.         │
+
    ╰─────────────────────────────────────────────────────────────╯
+

+
The issue, originally opened by Calyx, the repository's delegate, outlines a
+
task that aligns perfectly with Paxel's knowledge area. They compose a comment,
+
with `rad issue comment <issue-id> --message "<message>"`, expressing their
+
interest in tackling it.
+

+
    $ rad issue comment 3e2f65 --message "I can help."
+
    ╭─────────────────────────╮
+
    │ paxel (you) now 74faf0e │
+
    │ I can help.             │
+
    ╰─────────────────────────╯
+

+
> 👾
+
>
+
> IKYKI: Full identifiers do not need to be used in the commands! An unambiguous
+
> prefix, like the one listed in the ID column of the issue table will work 99.9%
+
> of the time.
+

+
### Assigning issues
+

+
Now, utilizing *remote viewing* superpowers, we'll embark on a mental journey to
+
Calyx's workstation, giving us a glimpse of issue management from the
+
maintainer's perspective.
+

+
<aside> <strong>Remote viewing</strong> is an alleged paranormal ability that
+
involves gaining information about a distant or unseen object, event, person, or
+
location by relying solely on the power of their mental faculties.</aside>
+

+
Calyx is starting their day, gazing into a fresh terminal window, where they
+
enter `rad inbox`:
+

+
    $ rad inbox
+
    ╭────────────────────────────────────────────────────────────────────────────────────────────╮
+
    │ dark-star-data                                                                             │
+
    ├────────────────────────────────────────────────────────────────────────────────────────────┤
+
    │ 004   ●   3e2f653   Add anomalous data from ship 897AF   issue   open   calyx   1 week ago │
+
    ╰────────────────────────────────────────────────────────────────────────────────────────────╯
+

+
The inbox is akin to a Radicle notifications viewing center, displaying issues
+
and patches that are newly created or have unread comments.
+

+
> 👾
+
> 
+
> If your working directory is a Radicle repository, it only shows item
+
> belonging to this repository, unless `--all` is used. If the command is run
+
> outside a Radicle repository, all items for all repositories will be displayed.
+
 
+
 Calyx decides to display one of the issues in their inbox with `rad issue show <issue-id>`:
+

+
    $ rad issue show 3e2f65
+
    ╭─────────────────────────────────────────────────────────────╮
+
    │ Title   Add anomalous data from ship 897AF                  │
+
    │ Issue   3e2f653383f0d2fe21ef4e859a25925c364c740a            │
+
    │ Author  calyx (you)                                         │
+
    │ Status  open                                                │
+
    │                                                             │
+
    │ Before we onboard new IUI members like the Neborians, it is │
+
    │ important we upload the data from ship 897AF. I just        │
+
    │ reviewed the database and it seems this is missing.         │
+
    ├─────────────────────────────────────────────────────────────┤
+
    │ paxel z6MkvZw…7aCGq3C 6 hours ago 74faf0e                   │
+
    │ I can help.                                                 │
+
    ╰─────────────────────────────────────────────────────────────╯
+

+
They see that Paxel is interested in helping with the issue, and decides to
+
assign it to them with `rad issue assign <issue-id> --add <radicle-id>`, then
+
they add a comment to the issue as well.
+

+
    $ rad issue assign 3e2f653 --add did:key:z6MkvZwzK64f3GuDcAs6dEcje89ddfHkBjS1v9Dkh7aCGq3C
+

+
    $ rad issue comment 3e2f653 --message "Great, I've assigned it to you."
+

+
As a delegate of `dark-star-data`, Calyx has the rights to assign this issue to
+
Paxel. Calyx then uses `rad issue show <issue-id>`, to see the current state of
+
the issue:
+

+
    $ rad issue show 3e2f65
+
    ╭─────────────────────────────────────────────────────────────╮
+
    │ Title   Add anomalous data from ship 897AF                  │
+
    │ Issue   3e2f653383f0d2fe21ef4e859a25925c364c740a            │
+
    │ Author  calyx (you)                                         │
+
    │ Assignees  z6MkvZw…7aCGq3C                                  │    
+
    │ Status  open                                                │
+
    │                                                             │
+
    │ Before we onboard new IUI members like the Neborians, it is │
+
    │ important we upload the data from ship 897AF. I just        │
+
    │ reviewed the database and it seems this is missing.         │
+
    ├─────────────────────────────────────────────────────────────┤
+
    │ paxel z6MkvZw…7aCGq3C 6 hours ago 39134b6                   │
+
    │ I can help.                                                 │
+
    ├─────────────────────────────────────────────────────────────┤
+
    │ calyx (you) 2 minutes ago 922fac7                           │
+
    │ Great, I've assigned it to you.                             │
+
    ╰─────────────────────────────────────────────────────────────╯
+

+
They see it was successfully assigned to Paxel and that their comment made it
+
through as well!
+

+
> 👾
+
>
+
> There's a lot more you can do with issues, such as:
+
>
+
> * Deleting with `rad issue delete <issue-id>`
+
> * Editing with `rad issue edit <issue-id>`
+
> * Labeling with `rad issue label <issue-id> --add <label>`
+
>
+
> We don't want to overwhelm you though! Check out `rad issue --help` for more details.
+
  
+
### Creating a patch, as if by magic
+

+
The collaboration voyage doesn't stop at issues though! In the realm of code,
+
issues typically lead to patches.
+

+
We will now zoom back to Paxel's machine to continue with the contributor's
+
journey. They notice Calyx has assigned them the issue, and to address it,
+
they'll make changes on a new feature branch of their working copy and then
+
create a patch.
+

+
*Let's dive in to the step-by-step:*
+

+
First, they'll navigate to the working copy of the repository. Then they'll
+
create and checkout a new branch, create a new file that addresses the issue,
+
and lastly `git add` and `git commit` the changes:
+

+
    $ cd dark-star-data
+
    $ git checkout -b add/anomalous-data-2219281
+
    ... add new file ...
+
    $ git add anomalous-data-2219281.csv
+
    $ git commit -m 'add anomalous data from 2219281'
+

+
Once their changes are ready to be proposed as a patch, they push them with the command:
+

+
    $ git push rad HEAD:refs/patches 
+

+
Radicle will then open an editor, where the patch title can be edited and a
+
description can be added. The first line of text will be the patch title,
+
while the subsequent lines will make up the description.
+

+
> 👾
+
>
+
> In `git push rad HEAD:refs/patches`, `HEAD` is used to represent the currently
+
> checked-out branch's latest commit, but the branch name or even an arbitrary
+
> commit hash can also be used.
+

+
Paxel enters details describing the patch, then saves and exits the editor.
+
This opens the patch, with its identifier displayed.
+
  
+
    $ git push rad HEAD:refs/patches
+
    ✓ Patch e5f0a5a5adaa33c3b931235967e4930ece9bb617 opened
+
    hint: to update, run `git push` or `git push rad -f HEAD:patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617`
+
    ✓ Synced with 1 node(s)
+

+
      https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z3cyotNHuasWowQ2h4yF9c3tFFdvc/patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617
+

+
    To rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc/z6MkvZwzK64f3GuDcAs6dEcje89ddfHkBjS1v9Dkh7aCGq3C
+
    * [new reference]   HEAD -> refs/patches
+

+
When you push changes to a cloned repository for the first time using Radicle, a
+
local fork of the repository becomes associated to your Node ID. If this push
+
includes a patch, the use of `refs/patches` acts as a *magic ref*. While this
+
looks like a special Git branch name, it's more of a command that is processed
+
by Radicle's remote helper to execute specific actions. It is termed a *magic ref*
+
due to its ability to extend standard Git functionality, integrating Radicle's
+
flavor of patch management directly into the Git workflow.
+

+
<aside> <strong>Magic refs</strong> were inspired by Gerrit, a code
+
collaboration tool developed by Google, which initially introduced this concept.</aside>
+

+
> 🧠
+
>
+
> Rather than pushing directly to this ref, the operation involves:
+
> 
+
> 1. Opening the patch by generating a unique Git Object ID (OID) for it and
+
storing it along with your other collaborative objects (COBs) in Radicle's
+
storage system.
+
> 2. It creates a remote tracking branch and sets your branch upstream to a path
+
like `rad/patches/<OID>`, or like in our example above, `rad/patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617`.
+

+
Consequently, any subsequent pushes from your original branch will update the
+
patch, maintaining synchronization between your local changes and the remote
+
branch that is published to the network.
+

+
Let's take a look at remote tracking branches with the common command
+
`git branch -r` to understand this better.
+

+
    $ git branch -r
+
      calyx@z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap/main
+
      rad/main
+
      rad/patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617
+

+
Here we see the repository delegate's default branch (starting with `calyx`),
+
the other is Paxel's default branch `rad/main`, and we also see the branch for the
+
patch Paxel just opened, starting with `rad/patches`.
+

+
We can also confirm that the patch branch is in storage with `git ls-remote`:
+

+
    $ git ls-remote
+
    From rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc
+
    e81db74197f48cc5198d9c03cceaec955af82abf        refs/heads/main
+
    80b8d420658834afc444a13c03f0c3ff6875a71c        refs/heads/patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617
+
  
+
### Sometimes you update patches
+

+
*Sometimes you submit a patch prematurely. Sometimes you update patches.*
+

+
Paxel realized they forgot to include data relevant to the issue they were
+
addressing, so they made their changes locally, committed the changes via
+
`git commit --amend` and formally updated the patch with a `git push --force`.
+

+
    $ open anomalous-data-2219281.csv
+
    ... make changes ...
+
    $ git commit --amend
+
    $ git push --force
+

+
In this current example, the `--force` option is used, since the commit was
+
amended. This is common practice when a patch has been reworked after receiving
+
a review.
+

+
As with opening a patch, this opens an editor to enter a reason for updating the
+
patch. To skip entering a reason, it can be left blank.
+

+
    $ git push --force
+
    ✓ Patch e5f0a5a updated to revision 4d0c1156f8ac7af2297d1314cd7556185cd16ae4
+
    ✓ Synced with 1 node(s)
+

+
      https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z3cyotNHuasWowQ2h4yF9c3tFFdvc/patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617
+

+
    To rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc/z6MkvZwzK64f3GuDcAs6dEcje89ddfHkBjS1v9Dkh7aCGq3C
+
     + b766431...80b8d42 add/anomalous-data-2219281 -> patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617 (forced update)
+

+
Here we see the change that was just force pushed is represented by a
+
revision identifier.
+

+
Note that this will only work if the current branch upstream is set correctly
+
(this upstream is set automatically when a patch is opened from a branch).
+

+
> 👾
+
>
+
> If the branch upstream is not set to the patch reference, eg.
+
> `rad/patches/<patch-id>`, you can use `rad patch set <patch-id>`.
+

+
You can always display the patch metadata and comments using
+
`rad patch show <patch-id>`. Similar to issues, you don't have to use the full
+
patch identifier.
+

+
    $ rad patch show e5f0a5a5adaa3
+
    ╭────────────────────────────────────────────────────────────────────────────────╮
+
    │ Title     add anomalous data from 2219281                                      │
+
    │ Patch     e5f0a5a5adaa33c3b931235967e4930ece9bb617                             │
+
    │ Author    paxel (you)                                                          │
+
    │ Head      80b8d420658834afc444a13c03f0c3ff6875a71c                             │
+
    │ Branches  add/anomalous-data-2219281                                           │
+
    │ Commits   ahead 1, behind 0                                                    │
+
    │ Status    open                                                                 │
+
    │                                                                                │
+
    │ this is the data from ship 897AF. i want to contribute it to the               │
+
    │ dataset.                                                                       │
+
    ├────────────────────────────────────────────────────────────────────────────────┤
+
    │ 80b8d42 add anomalous data from 2219281                                        │
+
    ├────────────────────────────────────────────────────────────────────────────────┤
+
    │ ● opened by paxel (you) (b766431) 58 minutes ago                               │
+
    │ ↑ updated to 4d0c1156f8ac7af2297d1314cd7556185cd16ae4 (80b8d42) 44 minutes ago │
+
    ╰────────────────────────────────────────────────────────────────────────────────╯
+

+
At the bottom, we see that the patch was updated to revision
+
`4d0c1156f8ac7af2297d1314cd7556185cd16ae4`, which relates to a commit hash
+
`80b8d420658834afc444a13c03f0c3ff6875a71c`, which is the current HEAD of the patch.
+

+
### Merging patches into the canonical
+

+
Now that Paxel has opened the patch, let's switch perspectives again and return
+
to Calyx-land. Imagine you're Calyx, the repository's sole delegate, looking at
+
the patch Paxel submitted. As Calyx you will `checkout` the patch, review it,
+
make changes, and then merge it. Let's walk through this process together.
+

+
First, within the repository, Calyx runs `rad patch` and notices there is a new patch.
+

+
    $ rad patch
+
    ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮
+
    │ ●  ID       Title                            Author                   Head     +   -   Updated    │
+
    ├───────────────────────────────────────────────────────────────────────────────────────────────────┤
+
    │ ●  e5f0a5a  add anomalous data from 2219281          z6MkvZw…7aCGq3C  80b8d42  +4  -0  1 hour ago │
+
    ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯
+

+
Calyx then runs `rad patch checkout <patch-id>`
+

+
    $ rad patch checkout e5f0a5a
+
    ✓ Switched to branch patch/e5f0a5a
+
    ✓ Branch patch/e5f0a5a setup to track rad/patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617
+

+
When working with patches opened by peers, it’s often useful to be able to
+
checkout the code in its own branch. With a patch checkout, you can browse the
+
code, run tests and even propose your own update to the patch.
+

+
What `rad patch checkout` does is create and switch to a new local branch on
+
Calyx's device, `patch/e5f0a5a`,  which is synchronized with the patch head --
+
also known as the patch's remote tracking branch initially created by Paxel,
+
`rad/patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617`.
+

+
It's a rare occasion that someone submits patch and doesn't miss something.
+
There's likely always a nit. Sometimes it's important you just take control and
+
make the change yourself, for efficiency.
+

+
<aside> In code reviews, the term <strong>nit</strong> refers to <em>nitpicking</em>:
+
the identification of minor issues that, while not significantly impacting the
+
functionality of the code, are still incorrect. Examples include typos in
+
comments, unnecessary semicolons, or superfluous empty lines.</aside>  
+

+
Upon reviewing the patch, Calyx notices a mistake in the column name in the
+
associated data file. They update the file, commit changes, and then push them
+
with `git push rad -o patch.message="<message>"`. The latter `-o patch.message`
+
option allows Calyx to directly provide a comment related his revision while
+
bypassing the editor.
+

+
    $ open anomalous-data-2219281.csv
+
    ... make changes ...
+
    $ git add .
+
    $ git commit -m "Updated column name to Zone from Location"
+
    $ git push rad -o patch.message="Fix location column so it is called Zone"
+

+
Updating it this way will tell others about the corrections needed before
+
merging the changes.
+

+
    $ git push rad -o patch.message="Fix location column so it is called Zone"
+
    ✓ Patch e5f0a5a updated to revision 1e0596d917725c447106b1efc900bebf4b95a810
+
    ✓ Synced with 1 node(s)
+

+
      https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z3cyotNHuasWowQ2h4yF9c3tFFdvc/patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617
+

+
    To rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc/z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap
+
    * [new branch]      patch/e5f0a5a -> patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617
+

+
Now, they use `rad patch show <patch-id>` to review the state of the patch:
+
  
+
    $ rad patch show e5f0a5a
+
    ╭─────────────────────────────────────────────────────────────────────────────╮
+
    │ Title    add anomalous data from 2219281                                    │
+
    │ Patch    e5f0a5a5adaa33c3b931235967e4930ece9bb617                           │
+
    │ Author   z6MkvZw…7aCGq3C                                                    │
+
    │ Head     80b8d420658834afc444a13c03f0c3ff6875a71c                           │
+
    │ Commits  ahead 1, behind 0                                                  │
+
    │ Status   open                                                               │
+
    │                                                                             │
+
    │ this is the data from my spacecraft. i want to contribute it to the         │
+
    │ dataset.                                                                    │
+
    ├─────────────────────────────────────────────────────────────────────────────┤
+
    │ 80b8d42 add anomalous data from 2219281                                     │
+
    ├─────────────────────────────────────────────────────────────────────────────┤
+
    │ ● opened by z6MkvZw…7aCGq3C (b766431) 2 hours ago                           │
+
    │ ↑ updated to 4d0c1156f8ac7af2297d1314cd7556185cd16ae4 (80b8d42) 2 hours ago │
+
    │ * revised by calyx (you) in 1e0596d (25f8515) 3 minutes ago                 │
+
    ╰─────────────────────────────────────────────────────────────────────────────╯
+

+
Here we see that Calyx's changes are associated to the revision identifier
+
starting with `1e0596d` and to the commit hash starting with `25f8515`. For this
+
revision to be considered the official state of the patch, they also have to
+
*accept* it via `rad patch review <patch-id> --revision <revision-id> --accept`.
+

+
    $ rad patch review e5f0a5a --revision 1e0596d --accept
+
    ✓ Patch e5f0a5a accepted
+
    ✓ Synced with 1 node(s)
+

+
But there are a few more steps to get this patch merged into the repository's
+
default branch `main`. Calyx needs to `git checkout main`, then
+
`git merge patch/e5f0a5a` which merges the revised patch branch into their local
+
main branch, and then finally `git push rad main` to publish their changes to the
+
network. Since Calyx is the only delegate on this repository, this results in
+
the canonical repository version (or head reference) being updated.
+

+
    $ git checkout main
+
    Switched to branch 'main'
+
    Your branch is up to date with 'rad/main'.
+
    $ git merge patch/e5f0a5a
+
    Updating e81db74..25f8515
+
    Fast-forward
+
    anomalous-data-2219281.csv | 5 +++++
+
    1 file changed, 5 insertions(+)
+
    create mode 100644 anomalous-data-2219281.csv
+
    $ git push rad main
+
    ✓ Patch e5f0a5a5adaa33c3b931235967e4930ece9bb617 merged at revision 1e0596d
+
    ✓ Canonical head updated to 25f851529d68180a780cfafc15a48b89208ba8c4
+
    ✓ Synced with 1 node(s)
+

+
      https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z3cyotNHuasWowQ2h4yF9c3tFFdvc/tree/25f851529d68180a780cfafc15a48b89208ba8c4
+

+
    To rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc/z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap
+
      e81db74..25f8515  main -> main
+

+
Once published to the network, the patch is automatically closed. This happens
+
when the commit hash of the default branch matches the commit hash of the patch.
+

+
    $ rad patch
+
    Nothing to show.
+

+
> 👾
+
>
+
> Patch commands work similar to issues. You can:
+
>
+
> * Delete with `rad patch delete <patch-id>`
+
> * Edit with `rad patch edit <patch-id>`
+
> * Label with `rad patch label <patch-id> --add <label>`
+
>
+
> For more advanced details on how to work with patches, read the manual:
+
> `rad patch --help`
+
  
+
### From remote viewing to adding remotes
+

+
Whenever you `init` or `clone` a repository, you follow all peers by default
+
which means that everyone's patches will always be displayed as remotes.
+

+
But if a peer becomes a regular project collaborator, it would be important for
+
maintainers to add the peer as a Radicle remote to track their changes
+
and directly `checkout` their branches that haven't been submitted as patches yet.
+

+
So while we have been metaphorically remote viewing Calyx's operations,
+
technically all peers can *remote view* any other peer's branches that have been
+
pushed to the network, by adding them as a remote with
+
`rad remote add <nodeID> --name <alias> --sync --fetch`.
+

+
Calyx decides to do this, and adds Paxel as a remote:
+
  
+
    rad remote add z6MkvZwzK64f3GuDcAs6dEcje89ddfHkBjS1v9Dkh7aCGq3C --name paxel --sync --fetch
+

+
This allows Calyx to follow Paxel and keep up with their changes, and creates a
+
remote tracking branch in Calyx's working copy.
+

+
    $ git remote -v
+
    paxel   rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc/z6MkvZwzK64f3GuDcAs6dEcje89ddfHkBjS1v9Dkh7aCGq3C (fetch)
+
    paxel   rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc/z6MkvZwzK64f3GuDcAs6dEcje89ddfHkBjS1v9Dkh7aCGq3C (push)
+
    rad     rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc (fetch)
+
    rad     rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc/z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap (push)
+

+
In the above output, we see the names of the remotes in the left. To switch to
+
the remote that Calyx just added, they can use `rad remote --name paxel`.
+

+
    $ rad remote --name paxel
+
    paxel z6MkvZwzK64f3GuDcAs6dEcje89ddfHkBjS1v9Dkh7aCGq3C (fetch)
+
    rad   (canonical upstream)                             (fetch)
+
    rad   z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap (push)
+

+
Next they fetch Paxel's latest changes with `git fetch paxel`:
+

+
    $ git fetch paxel
+
      From rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc/z6MkvZwzK64f3GuDcAs6dEcje89ddfHkBjS1v9Dkh7aCGq3C
+
        * [new branch]      feature-branch       -> paxel/feature-branch
+

+
They see that they Paxel created a new branch, `feature-branch`. Calyx can also
+
take a look at all Paxel's branches with `git branch -a`.
+
  
+
    $ git branch -a
+
      add/anomalous-data-2219281
+
    * main
+
      patch/e5f0a5a
+
      remotes/paxel/main
+
      remotes/paxel/feature-branch
+
      remotes/paxel/patches/e5f0a5a5adaa33c3b931235967e4930ece9bb617
+
      remotes/rad/main
+

+
Here we see Paxel's branches starting with `remotes/paxel`. If they were so
+
inclined and wanted to peek around, Calyx could checkout one of these remote
+
branches via `git checkout`.
+

+
It might feel like we're revisiting Git basics, but the point is to show you how
+
Radicle uses remotes to provide you with the capability of *peering into each peer*,
+
leveraging paranormal powers -- I mean, novel Git peer-to-peer networking magic.
+

+
### Synchronizing the canonical
+

+
Back at Paxel's workstation, they are thrilled to see the patch merged into the
+
`main` branch by Calyx. There are a few steps that Paxel needs to now take to
+
synchronize their local `main` branch to the canonical, default repository state,
+
which now includes their patch.
+

+
First, Paxel confirms that their `main` is behind:
+

+
    $ git rev-parse main
+
    e81db74197f48cc5198d9c03cceaec955af82abf
+

+
In the merging step, we saw that the canonical head was updated to
+
`25f851529d68180a780cfafc15a48b89208ba8c4`, hence this is indeed behind.
+

+
Next, Paxel calls `rad sync --fetch` to fetch the latest changes from the network:
+

+
    $ rad sync --fetch
+
    ✓ Fetching rad:z3cyotNHuasWowQ2h4yF9c3tFFdvc from z6MkrLM…ocNYPm7..
+
    ✓ Fetching rad:z3cyotNHuasWowQ2h4yF9c3tFFdvc from z6Mkg5Z…4Q8qCHw..
+
    ✓ Fetched repository from 2 seed(s)
+

+
Lastly, they checkout the default `main` branch with `git checkout main` and
+
pull the maintainer's changes via `git pull --all --ff`.
+

+
    $ git checkout main
+
    Switched to branch 'main'
+
    Your branch is up to date with 'rad/main'.
+
    $ git pull --all --ff
+
    Fetching rad
+
    From rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc
+
      e81db74..25f8515  main       -> rad/main
+
    Fetching calyx@z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap
+
    From rad://z3cyotNHuasWowQ2h4yF9c3tFFdvc/z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap
+
      e81db74..25f8515  main       -> calyx@z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap/main
+
    Updating e81db74..25f8515
+
    Fast-forward
+
    anomalous-data-2219281.csv | 5 +++++
+
    1 file changed, 5 insertions(+)
+
    create mode 100644 anomalous-data-2219281.csv
+

+
That essentially brings Paxel up to date! For a sanity check, they verify the
+
commit hash with `git rev-parse main`, and notice it is now synchronized.
+

+
    $ git rev-parse main
+
    25f851529d68180a780cfafc15a48b89208ba8c4
+

+
<!--### Collaborating the web interface way
+

+
You may be curious -- can you work with issues and patches with a web interface?
+
The answer is: Yes!
+

+
If you missed it, first check out [the web interfaces section of Chapter 1][ch1web].
+
Basically, make sure your node is running, and then open the interface by
+
running `rad web`:
+

+
    rad web
+

+
This will open the web client at `app.radicle.xyz` and if properly authenticated,
+
you'll see a list of your repositories. You can click on one, and then navigate
+
to its issues and patches. New issues can be both created, commented on, and
+
updated with the web interface. Patches cannot be created from the interface,
+
but their name & description can be edited, and you can add comments.-->
+

+
*And, that's a wrap!*
+

+
You now know the most relevant nitty gritty details of how to leverage Radicle
+
for code collaboration. Consider continuing on to [Chapter 3][ch3] to further
+
expand your Radicle consciousness and learn about setting policies and
+
configurations for how your node seeds repositories.
+

+
> 👾
+
> 
+
> One thing to keep in mind is that Radicle doesn't have code review features
+
> yet for patches, but that is coming up in a near-term release. If you still
+
> feel you're in need of additional guidance, don't hesitate to join us in our
+
> [chatroom on Zulip][zulip] and ask your questions in the support channel.
+

+
## 3. Grow Resilient with Seeding
+

+
Radicle stands as a sovereign convergence point for those eager to host and
+
synchronize not just their own Git repositories, but also to become *seeds* for
+
the repositories of others. Inspired by BitTorrent, we have adopted the
+
terminology *seeding* to describe the synergetic act of hosting, distributing,
+
and synchronizing a repository across the network.
+

+
Seeding in this context transcends mere synchronization; it embodies the act of
+
contributing to the network's vitality by providing essential resources like
+
bandwidth, storage, and data availability. This network effort ensures that
+
every Git repository, whether one's own or that of a fellow developer, remains
+
accessible and in perpetual sync, fostering a collaborative ecosystem where data
+
sovereignty flourishes.
+

+
Your Radicle node doesn't seed random repositories. Instead, you have an active
+
choice in deciding which data is hosted on your device. Each time you use the
+
`rad clone` or `rad seed` or `rad init` commands, your node's *seeding policy*
+
updates to specify new repositories to seed.
+

+
In this chapter, you are going to learn more about the ins and outs of seeding
+
and the different commands that make changes to your node's seeding policy. We
+
will start from the beginning, refreshing your memory on the points we went
+
through in [Chapter 1][ch1] when we first covered seeding, while providing a more
+
comprehensive overview.
+

+
This particular guide is oriented toward the more prominent Radicle user we are
+
expecting, where the node is installed on a personal computer or laptop. If
+
you're interested in learning more about how to set up an always-on seed node,
+
that is either a public seed node or set up as sovereign infrastructure for your
+
community, check out the [Seeder's Guide][seeder] instead.
+

+
### Understanding Node Defaults
+

+
First, it is important to understand your node's configuration file, which
+
defines your default seeding policy.
+

+
When you set up your Radicle Node using `rad auth`, it creates a configuration
+
file populated with default settings. You can view this file by running
+
`rad config` in your terminal.
+

+
    rad config
+

+
At the very bottom of this file, you will see the *policy* and *scope* parameters:
+

+
    ...
+
    "policy": "block",
+
    "scope": "followed"
+
    ...
+

+
When your node's policy is set to `block` and the scope to `followed`, it means
+
your node *selectively seeds repositories*. This selective seeding is based on
+
the modifications you actively make to your node, a common practice for user
+
nodes. Note that the possible options for *policy* are `allow` or `block`, while
+
for *scope* the options are `all` or `followed`. We will discuss how an
+
alternate configuration works after we go over the default way.
+

+
> 👾
+
>
+
> You can also view your node's *policy* alone with `rad config get node.policy`
+
> and your *scope* with `rad config get node.scope`.
+

+
### Selectively seeding repositories
+

+
When the default policy is `block`, you make exceptions to this policy by
+
*allowing* specific repositories to be seeded by calling the `rad clone` or
+
`rad seed` commands and providing a Repository Identifier (RID). The primary
+
difference between commands is that `rad clone` also creates a working copy, so
+
you'd run that when you are interested in both seeding and collaborating on the codebase.
+

+
These commands override the default `block` policy, resulting in your node
+
becoming a seed of the repositories you explicitly specify. These repositories
+
by default will have a policy of `allow` and a scope of `all`, respectively,
+
meaning that your node will subscribe to updates from *all peers* for your
+
repositories of interest.
+

+
<aside> Whenever you initialize a repository onto the network with
+
<code>rad init</code>, your seeding policy is also updated in the same way where
+
your node will subscribe to updates from <em>all peers</em>, ensuring that
+
you can seamlessly collaborate.</aside>
+

+
What this means is that both your node has a *policy* and *scope*, as does each
+
repository. Let's see what happens as we seed the Heartwood repository:
+

+
    $ rad seed rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
+
    ✓ Seeding policy updated for rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 with scope 'all'
+
    ✓ Fetching rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 from z6Mkk4R…SBiyXVM..
+

+
When you seed a repository, it updates your seeding policy to subscribe to
+
updates, essentially adding an exception to the default `block` rule for the
+
specified repository. It also fetches a copy of the repository under your local
+
storage, and provides a replica to the network.
+

+
If on the other hand you want to stop seeding a repository, simply run
+
`rad unseed`.
+

+
    rad unseed rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
+

+
Now without a seeding policy for this repository, the default node policy of `block`
+
will apply again. Note that all repositories will fallback to this default
+
`block` policy if you haven't established any repository-specific policy.
+

+
To view the policy of a specific repository, you can use the `rad inspect`
+
command. For example:
+

+
    rad inspect rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 --policy
+

+
Additionally, to view all seeding policies that have been configured on repositories,
+
simply enter `rad seed` with no options.
+

+
    rad seed
+

+
Finally, you can list all of your seeded repositories by passing the
+
`--seeded` flag with the `rad ls` command, for example:
+

+
    rad ls --seeded
+

+
The difference between these two commands is that `rad ls` will display the commit
+
hash of the repository head, and won't display details regarding the scope or policy.
+

+
### Selectively blocking repositories
+

+
On the flipside, in the case of a node with an *open* seeding policy, where the
+
default node policy is `allow`, and all repositories are seeded by default, we
+
instead can choose to explicitly *block* certain repositories from being seeded.
+
For example:
+

+
    rad block rad:z9DV738hJpCa6aQXqvQC4SjaZvsi
+

+
This will override the default `allow` policy and ensure that this repository is
+
never replicated on your node.
+

+
If for some reason you no longer want to block the repository, you can use the inverse
+
`unblock` subcommand:
+

+
    rad unblock rad:z9DV738hJpCa6aQXqvQC4SjaZvsi
+

+
> 👾
+
>
+
> It is not recommended that you change your node's default policy to `allow`
+
> unless you want to seed all the repositories submitted to the network. If
+
> that intrigues you, check out the [Seeder's Guide][seeder] for instructions,
+
> as there are other considerations to take into account.
+

+
### Following selective peers
+

+
When you run `rad seed` or `rad clone` without specifying a scope, your node
+
will subscribe to updates from *all of the repository's peers*. This default
+
behavior can be modified by passing `--scope followed` with these commands, to
+
only subscribe to updates from the repository delegates plus any node that is
+
explicitly followed.
+

+
Let's walk through this step-by-step. First, we run this modified version of
+
`rad seed`:
+

+
    rad seed rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 --scope followed
+

+

+
But this command wouldn't do much without you actively managing your
+
*follow policy* which specifies the nodes you are following. It's as simple as
+
`rad follow <nid>` to make updates to this *follow policy*, where `<nid>` is the
+
NodeID of the peer whose updates you want to follow.
+

+
    rad follow z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap
+

+
If you change your mind, you can always remove a node with the inverse `rad unfollow`:
+

+
    rad unfollow z6Mkgom1bTxdh9fMFxFNXFMw3SbXnma6NARdsfcFuunurCap
+

+
> 👾
+
>
+
> If `--scope followed` was not originally provided when seeding or cloning the
+
> repository, or you want to make updates to one of the repositories you've
+
> initialized, you can always update the repository's policy at any point in the
+
> future by running `rad seed` along with this option.
+

+
Seeding in Radicle strengthens the network by enhancing data availability to
+
foster a sovereign ecosystem for code collaboration. The more repositories
+
you seed, the more you contribute to the growth of a resilient network. We hope
+
that you now have a better understanding of how to adjust your node's seeding
+
and follow policies, as they play an important in how you participate in the network!
+

+
Happy seeding! 🌱
+

+
<!-- References -->
[proto]: /guides/protocol/
[seeder]: /guides/seeder/
[zulip]: https://radicle.zulipchat.com/
@@ -698,4 +1590,5 @@ unfold.
[ssb]: https://en.wikipedia.org/wiki/Secure_Scuttlebutt
[bt]: https://en.wikipedia.org/wiki/BitTorrent
[heartwood]: https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
-

+
[ch1]: /guides/user/#1-getting-started
+
[ch3]: /guides/user/#3-grow-resilient-with-seeding

\ No newline at end of file