remote-helper: Create patch drafts via `git push`
This is now possible via the `-o patch.draft` push option.
This commit is contained in:
parent
6bbdc574f0
commit
547fdcc03b
|
|
@ -7,9 +7,11 @@ $ git commit -a -m "Nothing to see here.." -q --allow-empty
|
||||||
|
|
||||||
To open a patch in draft mode, we use the `--draft` option:
|
To open a patch in draft mode, we use the `--draft` option:
|
||||||
|
|
||||||
```
|
``` (stderr)
|
||||||
$ rad patch open --draft -m "Nothing yet" --quiet
|
$ git push -o patch.draft -o patch.message="Nothing yet" rad HEAD:refs/patches
|
||||||
c639a0f9895a0fdf2ba2d04533290937cb6fd2f7
|
✓ Patch c639a0f9895a0fdf2ba2d04533290937cb6fd2f7 drafted
|
||||||
|
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||||
|
* [new reference] HEAD -> refs/patches
|
||||||
```
|
```
|
||||||
|
|
||||||
We can confirm it's a draft by running `show`:
|
We can confirm it's a draft by running `show`:
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,12 @@ pub enum Error {
|
||||||
List(#[from] list::Error),
|
List(#[from] list::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
/// Don't sync after push.
|
/// Don't sync after push.
|
||||||
no_sync: bool,
|
no_sync: bool,
|
||||||
|
/// Open patch in draft mode.
|
||||||
|
draft: bool,
|
||||||
/// Patch message.
|
/// Patch message.
|
||||||
message: cli::patch::Message,
|
message: cli::patch::Message,
|
||||||
}
|
}
|
||||||
|
|
@ -108,6 +110,7 @@ pub fn run(profile: radicle::Profile) -> Result<(), Error> {
|
||||||
match *args {
|
match *args {
|
||||||
["sync"] => opts.no_sync = false,
|
["sync"] => opts.no_sync = false,
|
||||||
["no-sync"] => opts.no_sync = true,
|
["no-sync"] => opts.no_sync = true,
|
||||||
|
["patch.draft"] => opts.draft = true,
|
||||||
_ => {
|
_ => {
|
||||||
let args = args.join(" ");
|
let args = args.join(" ");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ pub fn run(
|
||||||
let working = git::raw::Repository::open(working)?;
|
let working = git::raw::Repository::open(working)?;
|
||||||
|
|
||||||
if dst == &*rad::PATCHES_REFNAME {
|
if dst == &*rad::PATCHES_REFNAME {
|
||||||
patch_open(opts.message.clone(), src, &nid, &working, stored, &signer)
|
patch_open(src, &nid, &working, stored, &signer, opts.clone())
|
||||||
} else {
|
} else {
|
||||||
let dst = git::Qualified::from_refstr(dst)
|
let dst = git::Qualified::from_refstr(dst)
|
||||||
.ok_or_else(|| Error::InvalidQualifiedRef(dst.clone()))?;
|
.ok_or_else(|| Error::InvalidQualifiedRef(dst.clone()))?;
|
||||||
|
|
@ -184,7 +184,6 @@ pub fn run(
|
||||||
let oid = git::Oid::from_str(oid)?;
|
let oid = git::Oid::from_str(oid)?;
|
||||||
|
|
||||||
patch_update(
|
patch_update(
|
||||||
opts.message.clone(),
|
|
||||||
src,
|
src,
|
||||||
&dst,
|
&dst,
|
||||||
*force,
|
*force,
|
||||||
|
|
@ -193,6 +192,7 @@ pub fn run(
|
||||||
&working,
|
&working,
|
||||||
stored,
|
stored,
|
||||||
&signer,
|
&signer,
|
||||||
|
opts.clone(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
push(src, &dst, *force, &nid, &working, stored, &signer)
|
push(src, &dst, *force, &nid, &working, stored, &signer)
|
||||||
|
|
@ -237,12 +237,12 @@ pub fn run(
|
||||||
|
|
||||||
/// Open a new patch.
|
/// Open a new patch.
|
||||||
fn patch_open<G: Signer>(
|
fn patch_open<G: Signer>(
|
||||||
msg: cli::patch::Message,
|
|
||||||
src: &git::RefStr,
|
src: &git::RefStr,
|
||||||
nid: &NodeId,
|
nid: &NodeId,
|
||||||
working: &git::raw::Repository,
|
working: &git::raw::Repository,
|
||||||
stored: &storage::git::Repository,
|
stored: &storage::git::Repository,
|
||||||
signer: &G,
|
signer: &G,
|
||||||
|
opts: Options,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let reference = working.find_reference(src.as_str())?;
|
let reference = working.find_reference(src.as_str())?;
|
||||||
let commit = reference.peel_to_commit()?;
|
let commit = reference.peel_to_commit()?;
|
||||||
|
|
@ -259,26 +259,48 @@ fn patch_open<G: Signer>(
|
||||||
|
|
||||||
let (_, target) = stored.canonical_head()?;
|
let (_, target) = stored.canonical_head()?;
|
||||||
let base = stored.backend.merge_base(*target, commit.id())?;
|
let base = stored.backend.merge_base(*target, commit.id())?;
|
||||||
let (title, description) =
|
let (title, description) = cli::patch::get_create_message(
|
||||||
cli::patch::get_create_message(msg, &stored.backend, &base.into(), &commit.id().into())?;
|
opts.message,
|
||||||
|
&stored.backend,
|
||||||
|
&base.into(),
|
||||||
|
&commit.id().into(),
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut patches = patch::Patches::open(stored)?;
|
let mut patches = patch::Patches::open(stored)?;
|
||||||
let result = match patches.create(
|
let patch = if opts.draft {
|
||||||
&title,
|
patches.draft(
|
||||||
&description,
|
&title,
|
||||||
patch::MergeTarget::default(),
|
&description,
|
||||||
base,
|
patch::MergeTarget::default(),
|
||||||
commit.id(),
|
base,
|
||||||
&[],
|
commit.id(),
|
||||||
signer,
|
&[],
|
||||||
) {
|
signer,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
patches.create(
|
||||||
|
&title,
|
||||||
|
&description,
|
||||||
|
patch::MergeTarget::default(),
|
||||||
|
base,
|
||||||
|
commit.id(),
|
||||||
|
&[],
|
||||||
|
signer,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let result = match patch {
|
||||||
Ok(patch) => {
|
Ok(patch) => {
|
||||||
|
let action = if patch.is_draft() {
|
||||||
|
"drafted"
|
||||||
|
} else {
|
||||||
|
"opened"
|
||||||
|
};
|
||||||
let patch = patch.id;
|
let patch = patch.id;
|
||||||
|
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{} Patch {} opened",
|
"{} Patch {} {action}",
|
||||||
cli::format::positive("✓"),
|
cli::format::positive("✓"),
|
||||||
cli::format::tertiary(patch)
|
cli::format::tertiary(patch),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create long-lived patch head reference, now that we know the Patch ID.
|
// Create long-lived patch head reference, now that we know the Patch ID.
|
||||||
|
|
@ -339,7 +361,6 @@ fn patch_open<G: Signer>(
|
||||||
/// Update an existing patch.
|
/// Update an existing patch.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn patch_update<G: Signer>(
|
fn patch_update<G: Signer>(
|
||||||
msg: cli::patch::Message,
|
|
||||||
src: &git::RefStr,
|
src: &git::RefStr,
|
||||||
dst: &git::Qualified,
|
dst: &git::Qualified,
|
||||||
force: bool,
|
force: bool,
|
||||||
|
|
@ -348,6 +369,7 @@ fn patch_update<G: Signer>(
|
||||||
working: &git::raw::Repository,
|
working: &git::raw::Repository,
|
||||||
stored: &storage::git::Repository,
|
stored: &storage::git::Repository,
|
||||||
signer: &G,
|
signer: &G,
|
||||||
|
opts: Options,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let reference = working.find_reference(src.as_str())?;
|
let reference = working.find_reference(src.as_str())?;
|
||||||
let commit = reference.peel_to_commit()?;
|
let commit = reference.peel_to_commit()?;
|
||||||
|
|
@ -366,7 +388,7 @@ fn patch_update<G: Signer>(
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let message = cli::patch::get_update_message(
|
let message = cli::patch::get_update_message(
|
||||||
msg,
|
opts.message,
|
||||||
&stored.backend,
|
&stored.backend,
|
||||||
patch.latest().1,
|
patch.latest().1,
|
||||||
&commit.id().into(),
|
&commit.id().into(),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue