Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle: add tags fetch refspec
Fintan Halpenny committed 1 year ago
commit 46c2637f777d1629bcba515e302dae96866a060b
parent 6763bf31e1af93e9b6ef72ad99c47f3b9359b7ac
4 files changed +41 -8
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()))?;
    }