Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
radicle: add tags fetch refspec
Merged fintohaps opened 1 year ago

Add a fetch refspec to fetch tags from a Radicle remote. The --no-tag option is also included. This is to ensure that it is easy to collaborate by having tags placed in the remote namespace of another peer. However, if the namespace is the default rad remote, then tags are expected to be allowed – this is to pave way for the feature of canonical tags.

In the tests, the --tags option is removed – and is generally recommended that it is not used. This is to ensure that it does not override the --no-tag option.

4 files changed +41 -8 6763bf31 46c2637f
modified radicle-cli/examples/git/git-tag.md
@@ -11,12 +11,26 @@ $ git tag v1.0 -a -m "Release v1.0"
```

``` ~alice (stderr)
-
$ git push rad v1.0 --tags
+
$ git push rad v1.0
✓ Synced with 1 node(s)
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
 * [new tag]         v1.0 -> v1.0
```

+
Since the `rad` remote is setup to push `tags` using the refspec:
+

+
~~~
+
fetch = +refs/tags/*:refs/remotes/<name>/tags/*
+
~~~
+

+
there's no need to use the `--tags` flag. In fact, we avoid fetching tags into
+
the global `tags` namespace to keep tags for each remote separate. This is
+
achieved by also adding the following option to the remote configuration:
+

+
~~~
+
tagOpt = --no-tags
+
~~~
+

Bob fetches the tag from Alice, by adding her as a remote:

``` ~bob
@@ -28,13 +42,13 @@ $ rad remote add z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --name alice
✓ Remote-tracking branch alice/master created for z6MknSL…StBU8Vi
```

-
Bob is able to fetch Alice's tag into his working copy by using the
-
`--tags` flag:
+
Bob is able to fetch Alice's tag into his working copy, and they're fetched
+
under the `alice` remote:

``` ~bob (stderr)
-
$ git fetch alice --tags
+
$ git fetch alice
From rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
-
 * [new tag]         v1.0       -> v1.0
+
 * [new tag]         v1.0       -> alice/tags/v1.0
```

Alice forcefully creates a new version of the tag (let's say she made
@@ -64,7 +78,7 @@ $ rad sync -f
```

``` ~bob (stderr)
-
$ git fetch alice --tags -f
+
$ git fetch alice -f
From rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
-
 t [tag update]      v1.0       -> v1.0
+
   62d19fd..9dbdebc  v1.0       -> alice/tags/v1.0
```
modified radicle-cli/examples/rad-checkout-repo-config-linux.md
@@ -16,6 +16,7 @@ $ cat .git/config
[remote "rad"]
	url = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji
	fetch = +refs/heads/*:refs/remotes/rad/*
+
	fetch = +refs/tags/*:refs/remotes/rad/tags/*
	pushurl = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
[branch "master"]
	remote = rad
modified radicle-cli/examples/rad-checkout-repo-config-macos.md
@@ -18,6 +18,7 @@ $ cat .git/config
[remote "rad"]
	url = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji
	fetch = +refs/heads/*:refs/remotes/rad/*
+
	fetch = +refs/tags/*:refs/remotes/rad/tags/*
	pushurl = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
[branch "master"]
	remote = rad
modified radicle/src/git.rs
@@ -11,6 +11,7 @@ use once_cell::sync::Lazy;
use crate::collections::RandomMap;
use crate::crypto::PublicKey;
use crate::node::Alias;
+
use crate::rad;
use crate::storage;
use crate::storage::refs::Refs;
use crate::storage::RemoteId;
@@ -532,7 +533,9 @@ pub fn configure_repository(repo: &git2::Repository) -> Result<(), git2::Error>
/// [remote.<name>]
///   url = <fetch>
///   pushurl = <push>
-
///   fetch +refs/heads/*:refs/remotes/<name>/*
+
///   fetch = +refs/heads/*:refs/remotes/<name>/*
+
///   fetch = +refs/tags/*:refs/remotes/<name>/tags/*
+
///   tagOpt = --no-tags
/// ```
pub fn configure_remote<'r>(
    repo: &'r git2::Repository,
@@ -543,6 +546,20 @@ pub fn configure_remote<'r>(
    let fetchspec = format!("+refs/heads/*:refs/remotes/{name}/*");
    let remote = repo.remote_with_fetch(name, fetch.to_string().as_str(), &fetchspec)?;

+
    // We want to be able fetch tags from a peer's namespace and this is
+
    // necessary to do so, since Git assumes that tags should always be fetched
+
    // from the top-level `refs/tags` namespace
+
    let tags = format!("+refs/tags/*:refs/remotes/{name}/tags/*");
+
    repo.remote_add_fetch(name, &tags)?;
+

+
    // Because of the above, if we don't set `--no-tags` then the tags will be
+
    // fetched into `refs/tags` as well. We don't want to do this *unless* it's
+
    // the `rad` remote, which will have the canonical tags
+
    if name != (*rad::REMOTE_NAME).as_str() {
+
        let mut config = repo.config()?;
+
        config.set_str(&format!("remote.{name}.tagOpt"), "--no-tags")?;
+
    }
+

    if push != fetch {
        repo.remote_set_pushurl(name, Some(push.to_string().as_str()))?;
    }