Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Allow setting a different patch base on push
Alexis Sellier committed 2 years ago
commit cb576cf8c33974e8acd59271f84af5aed3b3aded
parent a6782ac2d67062729861ae7bad06d0d5c946e3a2
4 files changed +72 -19
modified radicle-cli/examples/rad-patch-ahead-behind.md
@@ -115,6 +115,40 @@ $ rad patch show -v 57cb9b2758518e547de324456ac967fda456c6c1
│ 7f63fcb Add Mel                                                    │
│ 5c88a79 Add Alan                                                   │
├────────────────────────────────────────────────────────────────────┤
-
│ ● opened by (you) (z6MknSL…StBU8Vi) 5 months ago                   │
+
│ ● opened by (you) (z6MknSL…StBU8Vi) [            ...             ] │
+
╰────────────────────────────────────────────────────────────────────╯
+
```
+

+
If we want to instead create a "stacked" patch, we can do so with the
+
`patch.base` push option:
+

+
``` (stderr)
+
$ git push -o patch.message="Add Mel #2" -o patch.base=5c88a79d75f5c2b4cc51ee6f163d2db91ee198d7 rad HEAD:refs/patches
+
✓ Patch 395221c5b75fa9bc2de7909d03e69dfd606611c6 opened
+
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
 * [new reference]   HEAD -> refs/patches
+
```
+

+
As you'll notice, using the previous patch as the base, we only see commit
+
`7f63fcb` listed for this new patch.
+

+
However, since the patch is still intended to be merged into `master`, we see
+
that it is still two commits ahead and one behind from `master`.
+

+
```
+
$ rad patch show -v 395221c5b75fa9bc2de7909d03e69dfd606611c6
+
╭────────────────────────────────────────────────────────────────────╮
+
│ Title     Add Mel #2                                               │
+
│ Patch     395221c5b75fa9bc2de7909d03e69dfd606611c6                 │
+
│ Author    did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi │
+
│ Head      7f63fcbcf23fc39eea784c091ad3d20d7e4bd005                 │
+
│ Base      5c88a79d75f5c2b4cc51ee6f163d2db91ee198d7                 │
+
│ Branches  feature/2                                                │
+
│ Commits   ahead 2, behind 1                                        │
+
│ Status    open                                                     │
+
├────────────────────────────────────────────────────────────────────┤
+
│ 7f63fcb Add Mel                                                    │
+
├────────────────────────────────────────────────────────────────────┤
+
│ ● opened by (you) (z6MknSL…StBU8Vi) [            ...             ] │
╰────────────────────────────────────────────────────────────────────╯
```
modified radicle-remote-helper/src/lib.rs
@@ -60,6 +60,8 @@ pub struct Options {
    no_sync: bool,
    /// Open patch in draft mode.
    draft: bool,
+
    /// Patch base to use, when opening or updating a patch.
+
    base: Option<git::Oid>,
    /// Patch message.
    message: cli::patch::Message,
}
@@ -115,8 +117,18 @@ pub fn run(profile: radicle::Profile) -> Result<(), Error> {
                        let args = args.join(" ");

                        if let Some((key, val)) = args.split_once('=') {
-
                            if key == "patch.message" {
-
                                opts.message.append(val);
+
                            match key {
+
                                "patch.message" => {
+
                                    opts.message.append(val);
+
                                }
+
                                "patch.base" => {
+
                                    let base = val.parse()?;
+
                                    opts.base = Some(base);
+
                                }
+
                                _ => {
+
                                    println!("unsupported");
+
                                    continue;
+
                                }
                            }
                        } else {
                            println!("unsupported");
modified radicle-remote-helper/src/push.rs
@@ -50,6 +50,9 @@ pub enum Error {
    /// Git error.
    #[error("git: {0}")]
    Git(#[from] git::raw::Error),
+
    /// Git extension error.
+
    #[error("git: {0}")]
+
    GitExt(#[from] git::ext::Error),
    /// Storage error.
    #[error(transparent)]
    Storage(#[from] radicle::storage::Error),
@@ -261,16 +264,17 @@ fn patch_open<G: Signer>(
    push_ref(src, &dst, false, working, stored.raw())?;

    let (_, target) = stored.canonical_head()?;
-
    let base = stored.backend.merge_base(*target, commit.id())?;
-
    if base == commit.id() {
+
    let head = commit.id().into();
+
    let base = if let Some(base) = opts.base {
+
        base
+
    } else {
+
        stored.merge_base(&target, &head)?
+
    };
+
    if base == head {
        return Err(Error::EmptyPatch);
    }
-
    let (title, description) = cli::patch::get_create_message(
-
        opts.message,
-
        &stored.backend,
-
        &base.into(),
-
        &commit.id().into(),
-
    )?;
+
    let (title, description) =
+
        cli::patch::get_create_message(opts.message, &stored.backend, &base, &head)?;

    let mut patches = patch::Patches::open(stored)?;
    let patch = if opts.draft {
@@ -401,8 +405,16 @@ fn patch_update<G: Signer>(
    )?;

    let (_, target) = stored.canonical_head()?;
-
    let base = stored.backend.merge_base(*target, commit.id())?;
-
    let revision = patch.update(message, base, commit.id(), signer)?;
+
    let head: git::Oid = commit.id().into();
+
    let base = if let Some(base) = opts.base {
+
        base
+
    } else {
+
        stored.merge_base(&target, &head)?
+
    };
+
    if base == head {
+
        return Err(Error::EmptyPatch);
+
    }
+
    let revision = patch.update(message, base, head, signer)?;

    eprintln!(
        "{} Patch {} updated to {}",
modified radicle/src/cob/patch.rs
@@ -305,12 +305,7 @@ impl Patch {

    /// Get the merge base of this patch.
    pub fn merge_base<R: ReadRepository>(&self, repo: &R) -> Result<git::Oid, git::ext::Error> {
-
        let target = self.target().head(repo).map_err(|_| {
-
            git::ext::Error::NotFound(git::ext::NotFound::NoSuchBranch(String::from("HEAD")))
-
        })?;
-
        let base = repo.merge_base(&target, self.head())?;
-

-
        Ok(base)
+
        repo.merge_base(self.base(), self.head())
    }

    /// Get the commit range of this patch.