radicle_cli/
project.rs

1use radicle::prelude::*;
2
3use crate::git;
4use radicle::git::RefStr;
5use radicle::node::NodeId;
6
7/// Setup a repository remote and tracking branch.
8pub struct SetupRemote<'a> {
9    /// The repository id.
10    pub rid: RepoId,
11    /// Whether or not to setup a remote tracking branch.
12    pub tracking: Option<BranchName>,
13    /// Whether or not to fetch the remote immediately.
14    pub fetch: bool,
15    /// The repository in which to setup the remote.
16    pub repo: &'a git::Repository,
17}
18
19impl SetupRemote<'_> {
20    /// Run the setup for the given peer.
21    pub fn run(
22        &self,
23        name: impl AsRef<RefStr>,
24        node: NodeId,
25    ) -> anyhow::Result<(git::Remote, Option<BranchName>)> {
26        let remote_url = radicle::git::Url::from(self.rid).with_namespace(node);
27        let remote_name = name.as_ref();
28
29        if git::is_remote(self.repo, remote_name)? {
30            anyhow::bail!("remote `{remote_name}` already exists");
31        }
32
33        let remote =
34            radicle::git::configure_remote(self.repo, remote_name, &remote_url, &remote_url)?;
35        let mut remote = git::Remote::try_from(remote)?;
36
37        // Fetch the refs into the working copy.
38        if self.fetch {
39            remote.fetch::<&str>(&[], None, None)?;
40        }
41        // Setup remote-tracking branch.
42        if let Some(branch) = &self.tracking {
43            let tracking_branch = remote_name.join(branch);
44            let local_branch = radicle::git::refs::workdir::branch(tracking_branch.as_refstr());
45            radicle::git::set_upstream(self.repo, remote_name, &tracking_branch, local_branch)?;
46
47            return Ok((remote, Some(tracking_branch)));
48        }
49        Ok((remote, None))
50    }
51}