remote-helper: Patch message option when pushing
Allows for setting a patch message during a push. Eg.:
$ git push -o patch.message="My Title" -o patch.message="My description" \
rad HEAD:refs/patches
Works the same way as the `-m` flag of `git commit`.
This commit is contained in:
parent
6578fedfbb
commit
e86e061a12
|
|
@ -7,8 +7,8 @@ When we push to this ref, a patch is created from our commits.
|
||||||
$ git checkout -b feature/1
|
$ git checkout -b feature/1
|
||||||
Switched to a new branch 'feature/1'
|
Switched to a new branch 'feature/1'
|
||||||
$ git commit -a -m "Add things" -q --allow-empty
|
$ git commit -a -m "Add things" -q --allow-empty
|
||||||
$ git push rad HEAD:refs/patches
|
$ git push -o patch.message="Add things #1" -o patch.message="See commits for details." rad HEAD:refs/patches
|
||||||
✓ Patch 37f53b4104edaafcf6beb65e7292147711a06ad0 opened
|
✓ Patch 2647168c23e7c2b2c1936d695443944e143bc3f7 opened
|
||||||
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||||
* [new reference] HEAD -> refs/patches
|
* [new reference] HEAD -> refs/patches
|
||||||
```
|
```
|
||||||
|
|
@ -16,15 +16,17 @@ To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkE
|
||||||
We can see a patch was created:
|
We can see a patch was created:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ rad patch show 37f53b4
|
$ rad patch show 2647168
|
||||||
╭────────────────────────────────────────────────────────────────────╮
|
╭────────────────────────────────────────────────────────────────────╮
|
||||||
│ Title Add things │
|
│ Title Add things #1 │
|
||||||
│ Patch 37f53b4104edaafcf6beb65e7292147711a06ad0 │
|
│ Patch 2647168c23e7c2b2c1936d695443944e143bc3f7 │
|
||||||
│ Author did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi │
|
│ Author did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi │
|
||||||
│ Head 42d894a83c9c356552a57af09ccdbd5587a99045 │
|
│ Head 42d894a83c9c356552a57af09ccdbd5587a99045 │
|
||||||
│ Branches feature/1 │
|
│ Branches feature/1 │
|
||||||
│ Commits ahead 1, behind 0 │
|
│ Commits ahead 1, behind 0 │
|
||||||
│ Status open │
|
│ Status open │
|
||||||
|
│ │
|
||||||
|
│ See commits for details. │
|
||||||
├────────────────────────────────────────────────────────────────────┤
|
├────────────────────────────────────────────────────────────────────┤
|
||||||
│ 42d894a Add things │
|
│ 42d894a Add things │
|
||||||
├────────────────────────────────────────────────────────────────────┤
|
├────────────────────────────────────────────────────────────────────┤
|
||||||
|
|
@ -37,7 +39,7 @@ branch associated with this patch:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git branch -vv
|
$ git branch -vv
|
||||||
* feature/1 42d894a [rad/patches/37f53b4104edaafcf6beb65e7292147711a06ad0] Add things
|
* feature/1 42d894a [rad/patches/2647168c23e7c2b2c1936d695443944e143bc3f7] Add things
|
||||||
master f2de534 [rad/master] Second commit
|
master f2de534 [rad/master] Second commit
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -45,7 +47,7 @@ Let's check that it's up to date with our local head:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git status --short --branch
|
$ git status --short --branch
|
||||||
## feature/1...rad/patches/37f53b4104edaafcf6beb65e7292147711a06ad0
|
## feature/1...rad/patches/2647168c23e7c2b2c1936d695443944e143bc3f7
|
||||||
$ git fetch
|
$ git fetch
|
||||||
$ git push
|
$ git push
|
||||||
```
|
```
|
||||||
|
|
@ -57,13 +59,13 @@ $ git show-ref
|
||||||
42d894a83c9c356552a57af09ccdbd5587a99045 refs/heads/feature/1
|
42d894a83c9c356552a57af09ccdbd5587a99045 refs/heads/feature/1
|
||||||
f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354 refs/heads/master
|
f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354 refs/heads/master
|
||||||
f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354 refs/remotes/rad/master
|
f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354 refs/remotes/rad/master
|
||||||
42d894a83c9c356552a57af09ccdbd5587a99045 refs/remotes/rad/patches/37f53b4104edaafcf6beb65e7292147711a06ad0
|
42d894a83c9c356552a57af09ccdbd5587a99045 refs/remotes/rad/patches/2647168c23e7c2b2c1936d695443944e143bc3f7
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
$ git ls-remote rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi 'refs/heads/patches/*'
|
$ git ls-remote rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi 'refs/heads/patches/*'
|
||||||
42d894a83c9c356552a57af09ccdbd5587a99045 refs/heads/patches/37f53b4104edaafcf6beb65e7292147711a06ad0
|
42d894a83c9c356552a57af09ccdbd5587a99045 refs/heads/patches/2647168c23e7c2b2c1936d695443944e143bc3f7
|
||||||
$ git ls-remote rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi 'refs/cobs/*'
|
$ git ls-remote rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi 'refs/cobs/*'
|
||||||
37f53b4104edaafcf6beb65e7292147711a06ad0 refs/cobs/xyz.radicle.patch/37f53b4104edaafcf6beb65e7292147711a06ad0
|
2647168c23e7c2b2c1936d695443944e143bc3f7 refs/cobs/xyz.radicle.patch/2647168c23e7c2b2c1936d695443944e143bc3f7
|
||||||
```
|
```
|
||||||
|
|
||||||
We can also create patches by pushing to the `rad/patches` remote. It's a bit
|
We can also create patches by pushing to the `rad/patches` remote. It's a bit
|
||||||
|
|
@ -82,7 +84,7 @@ We see both branches with upstreams now:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git branch -vv
|
$ git branch -vv
|
||||||
feature/1 42d894a [rad/patches/37f53b4104edaafcf6beb65e7292147711a06ad0] Add things
|
feature/1 42d894a [rad/patches/2647168c23e7c2b2c1936d695443944e143bc3f7] Add things
|
||||||
* feature/2 b94a835 [rad/patches/2af090f48003d86f735163794bfffdb2691f369e] Add more things
|
* feature/2 b94a835 [rad/patches/2af090f48003d86f735163794bfffdb2691f369e] Add more things
|
||||||
master f2de534 [rad/master] Second commit
|
master f2de534 [rad/master] Second commit
|
||||||
```
|
```
|
||||||
|
|
@ -94,8 +96,8 @@ $ rad patch
|
||||||
╭────────────────────────────────────────────────────────────────────────────────────╮
|
╭────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ ● ID Title Author Head + - Updated │
|
│ ● ID Title Author Head + - Updated │
|
||||||
├────────────────────────────────────────────────────────────────────────────────────┤
|
├────────────────────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ ● 2647168 Add things #1 z6MknSL…StBU8Vi (you) 42d894a +0 -0 [ ... ] │
|
||||||
│ ● 2af090f Add more things z6MknSL…StBU8Vi (you) b94a835 +0 -0 [ ... ] │
|
│ ● 2af090f Add more things z6MknSL…StBU8Vi (you) b94a835 +0 -0 [ ... ] │
|
||||||
│ ● 37f53b4 Add things z6MknSL…StBU8Vi (you) 42d894a +0 -0 [ ... ] │
|
|
||||||
╰────────────────────────────────────────────────────────────────────────────────────╯
|
╰────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ use thiserror::Error;
|
||||||
use radicle::git;
|
use radicle::git;
|
||||||
use radicle::storage::git::transport::local::{Url, UrlError};
|
use radicle::storage::git::transport::local::{Url, UrlError};
|
||||||
use radicle::storage::{ReadRepository, WriteStorage};
|
use radicle::storage::{ReadRepository, WriteStorage};
|
||||||
|
use radicle_cli::terminal as cli;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
|
@ -57,6 +58,8 @@ pub enum Error {
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
/// Don't sync after push.
|
/// Don't sync after push.
|
||||||
no_sync: bool,
|
no_sync: bool,
|
||||||
|
/// Patch message.
|
||||||
|
message: cli::patch::Message,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the radicle remote helper using the given profile.
|
/// Run the radicle remote helper using the given profile.
|
||||||
|
|
@ -101,15 +104,23 @@ pub fn run(profile: radicle::Profile) -> Result<(), Error> {
|
||||||
["option", "verbosity"] => {
|
["option", "verbosity"] => {
|
||||||
println!("ok");
|
println!("ok");
|
||||||
}
|
}
|
||||||
["option", "push-option", opt] => {
|
["option", "push-option", args @ ..] => {
|
||||||
match *opt {
|
match *args {
|
||||||
"sync" => opts.no_sync = false,
|
["sync"] => opts.no_sync = false,
|
||||||
"no-sync" => opts.no_sync = true,
|
["no-sync"] => opts.no_sync = true,
|
||||||
_ => {
|
_ => {
|
||||||
|
let args = args.join(" ");
|
||||||
|
|
||||||
|
if let Some((key, val)) = args.split_once('=') {
|
||||||
|
if key == "patch.message" {
|
||||||
|
opts.message.append(val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
println!("unsupported");
|
println!("unsupported");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
println!("ok");
|
println!("ok");
|
||||||
}
|
}
|
||||||
["option", "progress", ..] => {
|
["option", "progress", ..] => {
|
||||||
|
|
@ -130,7 +141,7 @@ pub fn run(profile: radicle::Profile) -> Result<(), Error> {
|
||||||
&stored,
|
&stored,
|
||||||
&profile,
|
&profile,
|
||||||
&stdin,
|
&stdin,
|
||||||
&opts,
|
opts,
|
||||||
)
|
)
|
||||||
.map_err(Error::from);
|
.map_err(Error::from);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ pub fn run(
|
||||||
stored: &storage::git::Repository,
|
stored: &storage::git::Repository,
|
||||||
profile: &Profile,
|
profile: &Profile,
|
||||||
stdin: &io::Stdin,
|
stdin: &io::Stdin,
|
||||||
opts: &Options,
|
opts: Options,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// Don't allow push if either of these conditions is true:
|
// Don't allow push if either of these conditions is true:
|
||||||
//
|
//
|
||||||
|
|
@ -172,7 +172,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(src, &nid, &working, stored, &signer)
|
patch_open(opts.message.clone(), src, &nid, &working, stored, &signer)
|
||||||
} 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()))?;
|
||||||
|
|
@ -180,7 +180,17 @@ pub fn run(
|
||||||
if let Some(oid) = dst.strip_prefix(git::refname!("refs/heads/patches")) {
|
if let Some(oid) = dst.strip_prefix(git::refname!("refs/heads/patches")) {
|
||||||
let oid = git::Oid::from_str(oid)?;
|
let oid = git::Oid::from_str(oid)?;
|
||||||
|
|
||||||
patch_update(src, &dst, *force, &oid, &nid, &working, stored, &signer)
|
patch_update(
|
||||||
|
opts.message.clone(),
|
||||||
|
src,
|
||||||
|
&dst,
|
||||||
|
*force,
|
||||||
|
&oid,
|
||||||
|
&nid,
|
||||||
|
&working,
|
||||||
|
stored,
|
||||||
|
&signer,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
push(src, &dst, *force, &nid, &working, stored, &signer)
|
push(src, &dst, *force, &nid, &working, stored, &signer)
|
||||||
}
|
}
|
||||||
|
|
@ -224,6 +234,7 @@ 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,
|
||||||
|
|
@ -244,8 +255,8 @@ fn patch_open<G: Signer>(
|
||||||
push_ref(src, &dst, false, working, stored.raw())?;
|
push_ref(src, &dst, false, working, stored.raw())?;
|
||||||
|
|
||||||
let mut patches = patch::Patches::open(stored)?;
|
let mut patches = patch::Patches::open(stored)?;
|
||||||
let message = commit.message().unwrap_or_default();
|
let fallback = commit.message().unwrap_or_default();
|
||||||
let (title, description) = cli::patch::get_message(cli::patch::Message::Edit, message)?;
|
let (title, description) = cli::patch::get_message(msg, fallback)?;
|
||||||
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 result = match patches.create(
|
let result = match patches.create(
|
||||||
|
|
@ -324,6 +335,7 @@ 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,
|
||||||
|
|
@ -349,7 +361,7 @@ fn patch_update<G: Signer>(
|
||||||
if patch.revisions().any(|(_, r)| *r.head() == commit.id()) {
|
if patch.revisions().any(|(_, r)| *r.head() == commit.id()) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let message = cli::patch::get_update_message(cli::patch::Message::Edit)?;
|
let message = cli::patch::get_update_message(msg)?;
|
||||||
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 revision = patch.update(message, base, commit.id(), signer)?;
|
let revision = patch.update(message, base, commit.id(), signer)?;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue