Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Don't fork on clone
cloudhead committed 2 years ago
commit d773659d66fe64e639904d9c47e8af347b6edc5e
parent ecb59d687b216a3661f455f63e753e43842e3bda
10 files changed +97 -131
modified radicle-cli/examples/rad-clone-all.md
@@ -2,7 +2,6 @@
$ rad clone rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --scope all
✓ Seeding policy updated for rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji with scope 'all'
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MknSL…StBU8Vi..
-
✓ Forking under z6Mkux1…nVhib7Z..
✓ Creating checkout in ./heartwood..
✓ Remote alice@z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi added
✓ Remote-tracking branch alice@z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/master created for z6MknSL…StBU8Vi
@@ -24,7 +23,7 @@ $ cat README
Hello World!
```

-
Let's check that we have all the namespaces in storage:
+
Let's check that we have Bob and Alice's namespaces in storage:

```
$ rad inspect --refs
@@ -44,12 +43,6 @@ z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
    │   └── master
    └── rad
        └── sigrefs
-
z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z
-
└── refs
-
    ├── heads
-
    │   └── master
-
    └── rad
-
        └── sigrefs
```

We can then setup a git remote for `bob`:
@@ -72,3 +65,36 @@ $ git branch --remotes
  bob/master
  rad/master
```
+

+
We can also create our own fork just by pushing:
+

+
``` (stderr)
+
$ git push -o no-sync rad master
+
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z
+
 * [new branch]      master -> master
+
```
+
```
+
$ rad inspect --refs
+
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
└── refs
+
    ├── cobs
+
    │   └── xyz.radicle.id
+
    │       └── [...]
+
    ├── heads
+
    │   └── master
+
    └── rad
+
        ├── id
+
        └── sigrefs
+
z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
+
└── refs
+
    ├── heads
+
    │   └── master
+
    └── rad
+
        └── sigrefs
+
z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z
+
└── refs
+
    ├── heads
+
    │   └── master
+
    └── rad
+
        └── sigrefs
+
```
modified radicle-cli/examples/rad-clone-connect.md
@@ -8,7 +8,6 @@ $ rad clone rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MknSL…StBU8Vi..
✓ Connecting to z6Mkt67…v4N1tRk@[..]
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6Mkt67…v4N1tRk..
-
✓ Forking under z6Mkux1…nVhib7Z..
✓ Creating checkout in ./heartwood..
✓ Remote alice@z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi added
✓ Remote-tracking branch alice@z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/master created for z6MknSL…StBU8Vi
modified radicle-cli/examples/rad-clone.md
@@ -5,7 +5,6 @@ To create a local copy of a repository on the radicle network, we use the
$ rad clone rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --scope followed
✓ Seeding policy updated for rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji with scope 'followed'
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MknSL…StBU8Vi..
-
✓ Forking under z6Mkt67…v4N1tRk..
✓ Creating checkout in ./heartwood..
✓ Remote alice@z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi added
✓ Remote-tracking branch alice@z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/master created for z6MknSL…StBU8Vi
@@ -27,6 +26,11 @@ $ ls
README
$ cat README
Hello World!
+
$ git status
+
On branch master
+
Your branch is up to date with 'rad/master'.
+

+
nothing to commit, working tree clean
```

Let's check that the remote tracking branch was setup correctly:
@@ -61,7 +65,7 @@ Date: Mon Jan 1 14:39:16 2018 +0000

Cloned repositories show up in `rad ls`:
```
-
$ rad ls
+
$ rad ls --all
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Name        RID                                 Visibility   Head      Description                        │
├───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
modified radicle-cli/examples/rad-id-multi-delegate.md
@@ -4,9 +4,24 @@ $ rad id update --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --title "Add Bob" --des
```

``` ~bob
+
$ rad watch --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --node z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z -r 'refs/rad/sigrefs' -t 95cd447c57de8d232c6154f5dba0451aa593520e -i 500 --timeout 5000
$ rad sync --fetch rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MknSL…StBU8Vi..
✓ Fetched repository from 1 seed(s)
+
$ rad id --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
+
╭────────────────────────────────────────────────────────────────────────────────╮
+
│ ●   ID        Title              Author                     Status     Created │
+
├────────────────────────────────────────────────────────────────────────────────┤
+
│ ●   069e7d5   Add Bob            alice    z6MknSL…StBU8Vi   accepted   now     │
+
│ ●   0656c21   Initial revision   alice    z6MknSL…StBU8Vi   accepted   now     │
+
╰────────────────────────────────────────────────────────────────────────────────╯
+
$ rad inspect rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --sigrefs
+
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi [..]
+
z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk [..]
+
z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z [..]
+
$ rad inspect rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --delegates
+
did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (alice)
+
did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (bob)
$ rad id update --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --title "Add Eve" --description "" --delegate did:key:z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z --no-confirm
✓ Identity revision 3cd3c7f9900de0fcb19705856a7cc339a38fb0b3 created
╭────────────────────────────────────────────────────────────────────────╮
modified radicle-cli/examples/rad-patch-pull-update.md
@@ -22,7 +22,6 @@ To push changes, run `git push`.
$ rad clone rad:zhbMU4DUXrzB8xT6qAJh6yZ7bFMK
✓ Seeding policy updated for rad:zhbMU4DUXrzB8xT6qAJh6yZ7bFMK with scope 'all'
✓ Fetching rad:zhbMU4DUXrzB8xT6qAJh6yZ7bFMK from z6MknSL…StBU8Vi..
-
✓ Forking under z6Mkt67…v4N1tRk..
✓ Creating checkout in ./heartwood..
✓ Remote alice@z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi added
✓ Remote-tracking branch alice@z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/master created for z6MknSL…StBU8Vi
@@ -35,18 +34,20 @@ $ rad clone rad:zhbMU4DUXrzB8xT6qAJh6yZ7bFMK
Run `cd ./heartwood` to go to the project directory.
```

-
We wait for Alice to sync our fork.
+
We fork the repository by pushing to `master`, and wait for Alice to sync
+
our fork:

-
``` ~bob
-
$ rad node events -n 2 --timeout 1
-
{"type":"refsAnnounced","nid":"z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi","rid":"rad:zhbMU4DUXrzB8xT6qAJh6yZ7bFMK","refs":[{"remote":"z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk","at":"161b775a3509c8098de67f57f750972bba015b31"}],"timestamp":[..]}
-
{"type":"refsSynced","remote":"z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi","rid":"rad:zhbMU4DUXrzB8xT6qAJh6yZ7bFMK","at":"161b775a3509c8098de67f57f750972bba015b31"}
+
``` ~bob (stderr)
+
$ cd heartwood
+
$ git push rad master
+
✓ Synced with 1 node(s)
+
To rad://zhbMU4DUXrzB8xT6qAJh6yZ7bFMK/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
+
 * [new branch]      master -> master
```

Bob then opens a patch.

``` ~bob (stderr)
-
$ cd heartwood
$ git checkout -b bob/feature -q
$ git commit --allow-empty -m "Bob's commit #1" -q
$ git push rad -o sync -o patch.message="Bob's patch" HEAD:refs/patches
modified radicle-cli/examples/workflow/5-patching-maintainer.md
@@ -21,7 +21,6 @@ $ rad remote add z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk --name bob
$ git fetch bob
✓ Synced with 1 peer(s)
From rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
-
 * [new branch]      master     -> bob/master
 * [new branch]      patches/3581e83ad18f5cdd806ab50fa11cfd5dd4e8ae1c -> bob/patches/3581e83ad18f5cdd806ab50fa11cfd5dd4e8ae1c
```

@@ -29,7 +28,6 @@ The contributor's changes are now visible to us.

```
$ git branch -r
-
  bob/master
  bob/patches/3581e83ad18f5cdd806ab50fa11cfd5dd4e8ae1c
  rad/master
$ rad patch show 3581e83
modified radicle-cli/src/commands/clone.rs
@@ -18,7 +18,6 @@ use radicle::prelude::*;
use radicle::rad;
use radicle::storage;
use radicle::storage::git::Storage;
-
use radicle::storage::RemoteRepository as _;
use radicle::storage::RepositoryError;

use crate::commands::rad_checkout as checkout;
@@ -40,7 +39,6 @@ Usage
Options

    --scope <scope>   Follow scope (default: all)
-
    --no-announce     Do not announce our new refs to the network
    --help            Print help

"#,
@@ -49,7 +47,6 @@ Options
#[derive(Debug)]
pub struct Options {
    id: Id,
-
    announce: bool,
    scope: Scope,
}

@@ -59,7 +56,6 @@ impl Args for Options {

        let mut parser = lexopt::Parser::from_args(args);
        let mut id: Option<Id> = None;
-
        let mut announce = true;
        let mut scope = Scope::All;

        while let Some(arg) = parser.next()? {
@@ -73,12 +69,6 @@ impl Args for Options {
                    // We keep this flag here for consistency though it doesn't have any effect,
                    // since the command is fully non-interactive.
                }
-
                Long("no-announce") => {
-
                    announce = false;
-
                }
-
                Long("announce") => {
-
                    announce = true;
-
                }
                Long("help") | Short('h') => {
                    return Err(Error::Help.into());
                }
@@ -95,14 +85,7 @@ impl Args for Options {
        let id =
            id.ok_or_else(|| anyhow!("to clone, an RID must be provided; see `rad clone --help`"))?;

-
        Ok((
-
            Options {
-
                id,
-
                scope,
-
                announce,
-
            },
-
            vec![],
-
        ))
+
        Ok((Options { id, scope }, vec![]))
    }
}

@@ -119,7 +102,6 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {

    let (working, repo, doc, proj) = clone(
        options.id,
-
        options.announce,
        options.scope,
        &mut node,
        &signer,
@@ -180,8 +162,6 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
pub enum CloneError {
    #[error("node: {0}")]
    Node(#[from] node::Error),
-
    #[error("fork: {0}")]
-
    Fork(#[from] rad::ForkError),
    #[error("storage: {0}")]
    Storage(#[from] storage::Error),
    #[error("checkout: {0}")]
@@ -200,7 +180,6 @@ pub enum CloneError {

pub fn clone<G: Signer>(
    id: Id,
-
    announce: bool,
    scope: Scope,
    node: &mut Node,
    signer: &G,
@@ -240,26 +219,6 @@ pub fn clone<G: Signer>(
        }
    };

-
    // Create a local fork of the project, under our own id, unless we have one already.
-
    if repository.remote(signer.public_key()).is_err() {
-
        let mut spinner = term::spinner(format!(
-
            "Forking under {}..",
-
            term::format::tertiary(term::format::node(&me))
-
        ));
-
        rad::fork(id, signer, &storage)?;
-

-
        if announce {
-
            if let Err(e) = node.announce_refs(id) {
-
                spinner.message("Announcing fork..");
-
                spinner.error(e);
-
            } else {
-
                spinner.finish();
-
            }
-
        } else {
-
            spinner.finish();
-
        }
-
    }
-

    let doc = repository.identity_doc()?;
    let proj = doc.project()?;
    let path = Path::new(proj.name());
modified radicle-cli/src/terminal.rs
@@ -14,7 +14,7 @@ use std::process;

pub use radicle_term::*;

-
use radicle::profile::Profile;
+
use radicle::profile::{ConfigError, Profile};

use crate::terminal;

modified radicle-cli/tests/commands.rs
@@ -265,13 +265,8 @@ fn rad_id() {
    alice.connect(&bob).converge([&bob]);
    let events = alice.handle.events();

-
    test(
-
        "examples/rad-clone.md",
-
        working.join("bob"),
-
        Some(&bob.home),
-
        [],
-
    )
-
    .unwrap();
+
    bob.fork(acme, bob.home.path()).unwrap();
+
    bob.announce(acme, bob.home.path()).unwrap();
    alice.has_inventory_of(&acme, &bob.id);

    // Alice must have Bob to try add them as a delegate
@@ -321,23 +316,11 @@ fn rad_id_multi_delegate() {
    alice.connect(&bob).converge([&bob]);
    eve.connect(&alice).converge([&alice]);

-
    test(
-
        "examples/rad-clone.md",
-
        working.join("bob"),
-
        Some(&bob.home),
-
        [],
-
    )
-
    .unwrap();
+
    bob.fork(acme, working.join("bob")).unwrap();
    bob.has_inventory_of(&acme, &alice.id);
    alice.has_inventory_of(&acme, &bob.id);

-
    test(
-
        "examples/rad-clone-all.md",
-
        working.join("eve"),
-
        Some(&eve.home),
-
        [],
-
    )
-
    .unwrap();
+
    eve.fork(acme, working.join("eve")).unwrap();
    eve.has_inventory_of(&acme, &bob.id);
    alice.has_inventory_of(&acme, &eve.id);

@@ -384,13 +367,8 @@ fn rad_id_conflict() {

    alice.connect(&bob).converge([&bob]);

-
    test(
-
        "examples/rad-clone.md",
-
        working.join("bob"),
-
        Some(&bob.home),
-
        [],
-
    )
-
    .unwrap();
+
    bob.fork(acme, working.join("bob")).unwrap();
+
    bob.announce(acme, bob.home.path()).unwrap();
    alice.has_inventory_of(&acme, &bob.id);

    formula(&environment.tmp(), "examples/rad-id-conflict.md")
@@ -705,16 +683,10 @@ fn rad_clean() {
    bob.connect(&alice).converge([&alice]);
    eve.connect(&alice).converge([&alice]);

-
    test(
-
        "examples/rad-clone.md",
-
        working.join("bob"),
-
        Some(&bob.home),
-
        [],
-
    )
-
    .unwrap();
-

    eve.handle.fetch(acme, alice.id, DEFAULT_TIMEOUT).unwrap();

+
    bob.fork(acme, bob.home.path()).unwrap();
+
    bob.announce(acme, bob.home.path()).unwrap();
    bob.has_inventory_of(&acme, &alice.id);
    alice.has_inventory_of(&acme, &bob.id);
    eve.has_inventory_of(&acme, &alice.id);
@@ -795,13 +767,9 @@ fn rad_clone_all() {
    bob.connect(&alice).converge([&alice]);
    eve.connect(&alice).converge([&alice]);

-
    test(
-
        "examples/rad-clone.md",
-
        working.join("bob"),
-
        Some(&bob.home),
-
        [],
-
    )
-
    .unwrap();
+
    // Fork and sync repo.
+
    bob.fork(acme, bob.home.path()).unwrap();
+
    bob.announce(acme, bob.home.path()).unwrap();
    bob.has_inventory_of(&acme, &alice.id);
    alice.has_inventory_of(&acme, &bob.id);

@@ -1109,8 +1077,7 @@ fn test_cob_replication() {
    alice.connect(&bob);

    bob.routes_to(&[(rid, alice.id)]);
-
    bob.rad("clone", &[rid.to_string().as_str()], working.path())
-
        .unwrap();
+
    bob.fork(rid, working.path()).unwrap();

    // Wait for Alice to fetch the clone refs.
    events
@@ -1307,8 +1274,7 @@ fn test_replication_via_seed() {
    let seed_events = seed.handle.events();
    let alice_events = alice.handle.events();

-
    bob.rad("clone", &[rid.to_string().as_str()], working.join("bob"))
-
        .unwrap();
+
    bob.fork(rid, working.join("bob")).unwrap();

    alice.routes_to(&[(rid, alice.id), (rid, seed.id), (rid, bob.id)]);
    seed.routes_to(&[(rid, alice.id), (rid, seed.id), (rid, bob.id)]);
@@ -1364,9 +1330,8 @@ fn rad_remote() {

    bob.connect(&alice);
    bob.routes_to(&[(rid, alice.id)]);
-
    bob.rad("clone", &[rid.to_string().as_str()], &working)
-
        .unwrap();
-

+
    bob.fork(rid, bob.home.path()).unwrap();
+
    bob.announce(rid, bob.home.path()).unwrap();
    alice.has_inventory_of(&rid, &bob.id);

    test(
@@ -1611,14 +1576,7 @@ fn git_push_diverge() {
    let mut bob = bob.spawn();

    bob.connect(&alice).converge([&alice]);
-

-
    test(
-
        "examples/rad-clone.md",
-
        working.join("bob"),
-
        Some(&bob.home),
-
        [],
-
    )
-
    .unwrap();
+
    bob.fork(acme, working.join("bob")).unwrap();
    alice.has_inventory_of(&acme, &bob.id);

    formula(&environment.tmp(), "examples/git/git-push-diverge.md")
@@ -1659,16 +1617,7 @@ fn rad_push_and_pull_patches() {
    let mut bob = bob.spawn();

    bob.connect(&alice).converge([&alice]);
-

-
    logger::init(log::Level::Debug);
-

-
    test(
-
        "examples/rad-clone.md",
-
        working.join("bob"),
-
        Some(&bob.home),
-
        [],
-
    )
-
    .unwrap();
+
    bob.fork(acme, working.join("bob")).unwrap();
    alice.has_inventory_of(&acme, &bob.id);

    formula(&environment.tmp(), "examples/rad-push-and-pull-patches.md")
modified radicle-node/src/test/environment.rs
@@ -275,6 +275,20 @@ impl<G: Signer + cyphernet::Ecdh> NodeHandle<G> {
        self.rad("clone", &[rid.to_string().as_str()], cwd)
    }

+
    /// Fork a repo.
+
    pub fn fork<P: AsRef<Path>>(&self, rid: Id, cwd: P) -> io::Result<()> {
+
        self.clone(rid, &cwd)?;
+
        self.rad("fork", &[rid.to_string().as_str()], &cwd)?;
+
        self.announce(rid, &cwd)?;
+

+
        Ok(())
+
    }
+

+
    /// Announce a repo.
+
    pub fn announce<P: AsRef<Path>>(&self, rid: Id, cwd: P) -> io::Result<()> {
+
        self.rad("sync", &[rid.to_string().as_str(), "--announce"], cwd)
+
    }
+

    /// Run a `rad` CLI command.
    pub fn rad<P: AsRef<Path>>(&self, cmd: &str, args: &[&str], cwd: P) -> io::Result<()> {
        let cwd = cwd.as_ref();
@@ -295,6 +309,7 @@ impl<G: Signer + cyphernet::Ecdh> NodeHandle<G> {
            .env("RAD_PASSPHRASE", "radicle")
            .env("TZ", "UTC")
            .env("LANG", "C")
+
            .env(radicle::cob::git::RAD_COMMIT_TIME, "1671125284")
            .envs(git::env::GIT_DEFAULT_CONFIG)
            .current_dir(cwd)
            .arg(cmd)