cli: add name option to rad patch checkout
Add the `--name` option to `rad patch checkout`. This allows the user to name the branch they are checking out, rather than use the `patch/<short-id>` format. This change includes returning early for setting the upstream branch, if the upstream already existed. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
parent
30ad7e4d67
commit
81dc849bce
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Reference in New Issue