cli: Don't fork on clone

Since forking creates your `rad/sigrefs`, which then needs to be backed
up forever, we avoid forking on `rad clone`. This should make little or
no difference for users, as the "fork" will be created on `git push`.
This commit is contained in:
cloudhead 2023-12-11 13:18:12 +01:00
parent ecb59d687b
commit d773659d66
No known key found for this signature in database
10 changed files with 97 additions and 131 deletions

View File

@ -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
@ -39,12 +38,6 @@ z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
      ├── id
      └── sigrefs
z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
└── refs
   ├── heads
   │   └── master
   └── rad
      └── sigrefs
z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z
└── refs
   ├── heads
   │   └── master
@ -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
```

View File

@ -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

View File

@ -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 │
├───────────────────────────────────────────────────────────────────────────────────────────────────────────┤

View File

@ -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
╭────────────────────────────────────────────────────────────────────────╮

View File

@ -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

View File

@ -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

View File

@ -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());

View File

@ -14,7 +14,7 @@ use std::process;
pub use radicle_term::*;
use radicle::profile::Profile;
use radicle::profile::{ConfigError, Profile};
use crate::terminal;

View File

@ -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")

View File

@ -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)