Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: add name option to rad patch checkout
Fintan Halpenny committed 2 years ago
commit 81dc849bce4ea10387c8c499fc94398608cf0cf7
parent 30ad7e4d67a079bd129d8cbf75504f6118d56947
4 files changed +54 -23
modified radicle-cli/examples/rad-patch-checkout-force.md
@@ -26,9 +26,9 @@ $ cd heartwood
$ rad sync -f
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MknSL…StBU8Vi..
✓ Fetched repository from 1 seed(s)
-
$ rad patch checkout 6ff4f09
-
✓ Switched to branch patch/6ff4f09
-
✓ Branch patch/6ff4f09 setup to track rad/patches/6ff4f09c1b5a81347981f59b02ef43a31a07cdae
+
$ rad patch checkout 6ff4f09 --name alice-init
+
✓ Switched to branch alice-init
+
✓ Branch alice-init setup to track rad/patches/6ff4f09c1b5a81347981f59b02ef43a31a07cdae
```

Meanwhile, we may see some more changes that we need to make, so we
@@ -62,7 +62,7 @@ From rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji

``` ~bob
$ git status
-
On branch patch/6ff4f09
+
On branch alice-init
Your branch is behind 'rad/patches/6ff4f09c1b5a81347981f59b02ef43a31a07cdae' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

@@ -76,11 +76,10 @@ to use the `--force` (`-f`) flag to ensure that they are looking at
the latest changes:

``` ~bob
-
$ rad patch checkout 6ff4f09 -f
-
✓ Switched to branch patch/6ff4f09
-
✓ Branch patch/6ff4f09 setup to track rad/patches/6ff4f09c1b5a81347981f59b02ef43a31a07cdae
+
$ rad patch checkout 6ff4f09 -f --name alice-init
+
✓ Switched to branch alice-init
$ git status
-
On branch patch/6ff4f09
+
On branch alice-init
Your branch is up to date with 'rad/patches/6ff4f09c1b5a81347981f59b02ef43a31a07cdae'.

nothing to commit, working tree clean
modified radicle-cli/src/commands/patch.rs
@@ -87,6 +87,7 @@ Ready options

Checkout options

+
        --name <string>        Provide a name for the branch to checkout
    -f, --force                Checkout the head of the revision, even if the branch already exists

Other options
@@ -155,7 +156,7 @@ pub enum Operation {
    },
    Checkout {
        revision_id: Rev,
-
        force: bool,
+
        opts: checkout::Options,
    },
    Comment {
        revision_id: Rev,
@@ -203,7 +204,7 @@ impl Args for Options {
        let mut diff = false;
        let mut undo = false;
        let mut reply_to: Option<Rev> = None;
-
        let mut force = false;
+
        let mut checkout_opts = checkout::Options::default();

        while let Some(arg) = parser.next()? {
            match arg {
@@ -259,7 +260,12 @@ impl Args for Options {

                // Checkout options
                Long("force") | Short('f') if op == Some(OperationName::Checkout) => {
-
                    force = true;
+
                    checkout_opts.force = true;
+
                }
+

+
                Long("name") if op == Some(OperationName::Checkout) => {
+
                    let val = parser.value()?;
+
                    checkout_opts.name = Some(term::args::refstring("name", val)?);
                }

                // List options.
@@ -351,7 +357,7 @@ impl Args for Options {
            },
            OperationName::Checkout => Operation::Checkout {
                revision_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?,
-
                force,
+
                opts: checkout_opts,
            },
            OperationName::Comment => Operation::Comment {
                revision_id: patch_id
@@ -431,13 +437,13 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
            let patch_id = patch_id.resolve::<PatchId>(&repository.backend)?;
            delete::run(&patch_id, &profile, &repository)?;
        }
-
        Operation::Checkout { revision_id, force } => {
+
        Operation::Checkout { revision_id, opts } => {
            let revision_id = revision_id.resolve::<radicle::git::Oid>(&repository.backend)?;
            checkout::run(
                &patch::RevisionId::from(revision_id),
                &repository,
                &workdir,
-
                force,
+
                opts,
            )?;
        }
        Operation::Comment {
modified radicle-cli/src/commands/patch/checkout.rs
@@ -1,19 +1,41 @@
use anyhow::anyhow;

+
use git_ref_format::Qualified;
use radicle::cob::patch;
use radicle::cob::patch::RevisionId;
use radicle::git::RefString;
+
use radicle::patch::PatchId;
use radicle::storage::git::Repository;
use radicle::storage::ReadRepository;
use radicle::{git, rad};

use crate::terminal as term;

+
#[derive(Debug, Default)]
+
pub struct Options {
+
    pub name: Option<RefString>,
+
    pub force: bool,
+
}
+

+
impl Options {
+
    fn branch(&self, id: PatchId) -> anyhow::Result<RefString> {
+
        match &self.name {
+
            Some(refname) => Ok(Qualified::from_refstr(refname)
+
                .map_or_else(|| refname.clone(), |q| q.to_ref_string())),
+
            // SAFETY: Patch IDs are valid refstrings.
+
            None => {
+
                Ok(git::refname!("patch")
+
                    .join(RefString::try_from(term::format::cob(&id)).unwrap()))
+
            }
+
        }
+
    }
+
}
+

pub fn run(
    revision_id: &RevisionId,
    stored: &Repository,
    working: &git::raw::Repository,
-
    force: bool,
+
    opts: Options,
) -> anyhow::Result<()> {
    let patches = patch::Patches::open(stored)?;

@@ -32,13 +54,11 @@ pub fn run(
    };

    let mut spinner = term::spinner("Performing checkout...");
-
    let patch_branch =
-
        // SAFETY: Patch IDs are valid refstrings.
-
        git::refname!("patch").join(RefString::try_from(term::format::cob(&patch_id)).unwrap());
+
    let patch_branch = opts.branch(patch_id)?;

    let commit =
        match working.find_branch(patch_branch.as_str(), radicle::git::raw::BranchType::Local) {
-
            Ok(branch) if !force => branch.get().peel_to_commit()?,
+
            Ok(branch) if !opts.force => branch.get().peel_to_commit()?,
            Ok(branch) => {
                let commit = find_patch_commit(revision, stored, working)?;
                let mut r = branch.into_reference();
@@ -54,10 +74,10 @@ pub fn run(
            Err(e) => return Err(e.into()),
        };

-
    if force {
-
        let mut opts = radicle::git::raw::build::CheckoutBuilder::new();
-
        opts.force();
-
        working.checkout_tree(commit.as_object(), Some(&mut opts))?;
+
    if opts.force {
+
        let mut builder = radicle::git::raw::build::CheckoutBuilder::new();
+
        builder.force();
+
        working.checkout_tree(commit.as_object(), Some(&mut builder))?;
    } else {
        working.checkout_tree(commit.as_object(), None)?;
    }
modified radicle/src/rad.rs
@@ -325,6 +325,12 @@ pub fn setup_patch_upstream<'a>(
    };

    let branch = git::raw::Branch::wrap(r);
+

+
    // Only set the upstream if it's missing or `force` is `true`
+
    if branch.upstream().is_ok() && !force {
+
        return Ok(None);
+
    }
+

    let name: Option<git::RefString> = branch.name()?.and_then(|b| b.try_into().ok());
    let remote_branch = git::refs::workdir::patch_upstream(patch);
    let remote_branch = working.reference(