Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Add canonical remote to `init` and `checkout`
Alexis Sellier committed 3 years ago
commit 6346931ce2bd8fd3ec87c2b4e83efd02da401589
parent d6cebf613f7be0d5d06fa55e10301e46a2bf1705
15 files changed +98 -99
modified radicle-cli/examples/rad-checkout-repo-config-linux.md
@@ -12,8 +12,9 @@ $ cat .git/config
	filemode = true
	logallrefupdates = true
[remote "rad"]
-
	url = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
	url = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji
	fetch = +refs/heads/*:refs/remotes/rad/*
+
	pushurl = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
[branch "master"]
	remote = rad
	merge = refs/heads/master
modified radicle-cli/examples/rad-checkout-repo-config-macos.md
@@ -14,8 +14,9 @@ $ cat .git/config
	precomposeunicode = true
	logallrefupdates = true
[remote "rad"]
-
	url = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
	url = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji
	fetch = +refs/heads/*:refs/remotes/rad/*
+
	pushurl = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
[branch "master"]
	remote = rad
	merge = refs/heads/master
modified radicle-cli/examples/rad-checkout.md
@@ -32,7 +32,7 @@ Check the remote configuration:

```
$ git remote --verbose
-
rad	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (fetch)
+
rad	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji (fetch)
rad	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (push)
```

modified radicle-cli/examples/rad-clone.md
@@ -36,7 +36,7 @@ We can also take a look at the remotes:

```
$ git remote -v
-
rad	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (fetch)
+
rad	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji (fetch)
rad	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (push)
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (fetch)
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (push)
modified radicle-cli/examples/rad-remote.md
@@ -9,8 +9,9 @@ Now, we can see that there is a new remote in the list of remotes:

```
$ rad remote list
-
❲fetch❳ bob z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
-
❲fetch❳ rad z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
bob z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (fetch)
+
rad the canonical upstream                           (fetch)
+
rad z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (push)
```

You can see both `bob` and `rad` as remotes.  The `rad` remote is our personal remote of the project.
@@ -28,10 +29,3 @@ Now, add another time `bob` but without specify the `name`, so we should be able
$ rad remote add did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
✓ Remote bob added with rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
```
-

-
and then we remove again remote just added
-

-
```
-
$ rad remote rm bob
-
✓ Remote `bob` removed
-
```
deleted radicle-cli/examples/workflow/2-cloning.md
@@ -1,54 +0,0 @@
-
To create a local copy of a repository on the radicle network, we use the
-
`clone` command, followed by the identifier or *RID* of the repository:
-

-
```
-
$ rad clone rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
-
✓ Tracking relationship established for rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
-
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MknSL…StBU8Vi..
-
✓ Forking under z6Mkt67…v4N1tRk..
-
✓ Creating checkout in ./heartwood..
-
✓ Remote z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi created
-
✓ Remote-tracking branch z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/master created for z6MknSL…StBU8Vi
-
✓ Repository successfully cloned under [..]/heartwood/
-
```
-

-
We can now have a look at the new working copy that was created from the cloned
-
repository:
-

-
```
-
$ cd heartwood
-
$ ls
-
README
-
$ cat README
-
Hello World!
-
```
-

-
Let's check that the remote tracking branch was setup correctly:
-

-
```
-
$ git branch --remotes
-
  rad/master
-
  z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/master
-
```
-

-
The first branch is ours, and the second points to the repository delegate.
-
We can also take a look at the remotes:
-

-
```
-
$ git remote -v
-
rad	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (fetch)
-
rad	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (push)
-
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (fetch)
-
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi	rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (push)
-
```
-

-
Finally, let's inspect the last commit!
-

-
```
-
$ git log -n 1
-
commit f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354
-
Author: anonymous <anonymous@radicle.xyz>
-
Date:   Mon Jan 1 14:39:16 2018 +0000
-

-
    Second commit
-
```
added radicle-cli/examples/workflow/2-cloning.md
@@ -0,0 +1 @@
+
../rad-clone.md

\ No newline at end of file
modified radicle-cli/examples/workflow/5-patching-maintainer.md
@@ -86,3 +86,9 @@ $ rad patch --merged
│ ✓ merged by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) [      ...        ]│
╰───────────────────────────────────────────────────────────────────────────────────────────────╯
```
+

+
To publish our new state to the network, we simply push:
+

+
```
+
$ git push
+
```
added radicle-cli/examples/workflow/6-pulling-contributor.md
@@ -0,0 +1,39 @@
+
Now that the patch is merged, we can update our master branch to the canonical
+
master, which includes our patch.
+

+
First, we confirm that our master is behind:
+
```
+
$ git rev-parse master
+
f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354
+
```
+

+
Then, we call `rad sync --fetch` to fetch from the maintainer:
+
```
+
$ rad sync --fetch
+
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MknSL…StBU8Vi..
+
✓ Fetched repository from 1 seed(s)
+
```
+

+
Now let's checkout `master` and pull the maintainer's changes:
+
```
+
$ git checkout master
+
Your branch is up to date with 'rad/master'.
+
$ git pull --all
+
Fetching rad
+
Fetching z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
Updating f2de534..f6484e0
+
Fast-forward
+
 README.md       | 0
+
 REQUIREMENTS.md | 0
+
 2 files changed, 0 insertions(+), 0 deletions(-)
+
 create mode 100644 README.md
+
 create mode 100644 REQUIREMENTS.md
+
```
+

+
Now our master branch is up to date with the maintainer's master:
+

+
```
+
$ git rev-parse master
+
f6484e0f43e48a8983b9b39bf9bd4cd889f1d520
+
$ git diff master..z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/master
+
```
modified radicle-cli/src/commands/remote/list.rs
@@ -3,33 +3,26 @@ use radicle_term::{Element, Table};
use crate::git;
use crate::terminal as term;

-
#[inline]
-
fn format_direction(d: &git::Direction) -> String {
-
    match d {
-
        git::Direction::Fetch => "fetch".to_owned(),
-
        git::Direction::Push => "push".to_owned(),
-
    }
-
}
-

pub fn run(repo: &git::Repository) -> anyhow::Result<()> {
    let mut table = Table::default();
    let remotes = git::rad_remotes(repo)?;
    for r in remotes {
-
        for spec in r.refspecs() {
-
            let dir = spec.direction();
-
            let url = r.url.clone();
-
            let name = r.name.clone();
-
            let nid_row = url.namespace.map_or(
-
                term::format::dim("This is the canonical upstream".to_string()),
-
                |namespace| term::format::highlight(namespace.to_string()),
+
        for (dir, url) in [("fetch", Some(r.url)), ("push", r.pushurl)] {
+
            let Some(url) = url else {
+
                continue;
+
            };
+
            let nid = url.namespace.map_or(
+
                term::format::dim("the canonical upstream".to_string()).italic(),
+
                |namespace| term::format::tertiary(namespace.to_string()),
            );
            table.push([
-
                term::format::badge_positive(format_direction(&dir)),
-
                term::format::highlight(name.to_owned()),
-
                nid_row,
+
                term::format::bold(r.name.clone()),
+
                nid,
+
                term::format::parens(term::format::secondary(dir.to_owned())),
            ]);
        }
    }
    table.print();
+

    Ok(())
}
modified radicle-cli/src/git.rs
@@ -76,13 +76,10 @@ pub enum RemoteError {
pub struct Remote<'a> {
    pub(crate) name: String,
    pub(crate) url: radicle::git::Url,
-
    inner: git2::Remote<'a>,
-
}
+
    pub(crate) pushurl: Option<radicle::git::Url>,

-
impl Remote<'_> {
-
    pub fn refspecs(&self) -> git2::Refspecs {
-
        self.inner.refspecs()
-
    }
+
    #[allow(dead_code)]
+
    inner: git2::Remote<'a>,
}

impl<'a> TryFrom<git2::Remote<'a>> for Remote<'a> {
@@ -92,10 +89,16 @@ impl<'a> TryFrom<git2::Remote<'a>> for Remote<'a> {
        let url = value.url().map_or(Err(RemoteError::MissingUrl), |url| {
            Ok(radicle::git::Url::from_str(url)?)
        })?;
+
        let pushurl = value
+
            .pushurl()
+
            .map(radicle::git::Url::from_str)
+
            .transpose()?;
        let name = value.name().ok_or(RemoteError::MissingName)?;
+

        Ok(Self {
            name: name.to_owned(),
            url,
+
            pushurl,
            inner: value,
        })
    }
modified radicle-cli/src/project.rs
@@ -22,7 +22,7 @@ impl<'a> SetupRemote<'a> {
    /// Run the setup for the given peer.
    pub fn run(&self, node: NodeId) -> anyhow::Result<Option<(Remote, RefString)>> {
        let url = radicle::git::Url::from(self.project).with_namespace(node);
-
        let mut remote = radicle::git::configure_remote(self.repo, &node.to_string(), &url)?;
+
        let mut remote = radicle::git::configure_remote(self.repo, &node.to_string(), &url, &url)?;

        // Fetch the refs into the working copy.
        if self.fetch {
modified radicle-cli/tests/commands.rs
@@ -769,4 +769,12 @@ fn rad_workflow() {
        [],
    )
    .unwrap();
+

+
    test(
+
        "examples/workflow/6-pulling-contributor.md",
+
        &working.join("bob").join("heartwood"),
+
        Some(&bob.home),
+
        [],
+
    )
+
    .unwrap();
}
modified radicle/src/git.rs
@@ -375,10 +375,12 @@ pub fn write_tree<'r>(
pub fn configure_remote<'r>(
    repo: &'r git2::Repository,
    name: &str,
-
    url: &Url,
+
    fetch: &Url,
+
    push: &Url,
) -> Result<git2::Remote<'r>, git2::Error> {
-
    let fetch = format!("+refs/heads/*:refs/remotes/{name}/*");
-
    let remote = repo.remote_with_fetch(name, url.to_string().as_str(), &fetch)?;
+
    let fetchspec = format!("+refs/heads/*:refs/remotes/{name}/*");
+
    let remote = repo.remote_with_fetch(name, fetch.to_string().as_str(), &fetchspec)?;
+
    repo.remote_set_pushurl(name, Some(push.to_string().as_str()))?;

    Ok(remote)
}
modified radicle/src/rad.rs
@@ -70,9 +70,9 @@ pub fn init<G: Signer, S: WriteStorage>(
    })?;
    let doc = identity::Doc::initial(proj, delegate).verified()?;
    let (project, _) = Repository::init(&doc, pk, storage, signer)?;
-
    let url = git::Url::from(project.id).with_namespace(*pk);
+
    let url = git::Url::from(project.id);

-
    git::configure_remote(repo, &REMOTE_NAME, &url)?;
+
    git::configure_remote(repo, &REMOTE_NAME, &url, &url.clone().with_namespace(*pk))?;
    git::push(
        repo,
        &REMOTE_NAME,
@@ -221,10 +221,15 @@ pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>(
    opts.no_reinit(true).description(project.description());

    let repo = git2::Repository::init_opts(path.as_ref(), &opts)?;
-
    let url = git::Url::from(proj).with_namespace(*remote);
+
    let url = git::Url::from(proj);

    // Configure and fetch all refs from remote.
-
    git::configure_remote(&repo, &REMOTE_NAME, &url)?;
+
    git::configure_remote(
+
        &repo,
+
        &REMOTE_NAME,
+
        &url,
+
        &url.clone().with_namespace(*remote),
+
    )?;
    git::fetch(&repo, &REMOTE_NAME).map_err(CheckoutError::Fetch)?;

    {