Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
remote-helper: allow patch creation from detached HEAD
Merged fintohaps opened 1 year ago

The patch creation flow would be partially interrupted when creating a patch via a detached HEAD state. The creation of an upstream branch would fail since there is no branch to set an upstream for. It would result in the following error:

✓ Patch 6035d2f582afbe01ff23ea87528ae523d76875b6 opened
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
 ! [remote rejected] HEAD -> refs/patches (git: reference 'HEAD' is neither a local nor a remote branch.; class=Invalid (3))
error: failed to push some refs to 'rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi'

To fix this, the reference that’s resolved is checked to see if it a local branch. If not, it will return early.

The behaviour is tested in the rad-patch-detached-head example.

3 files changed +66 -0 1c46f195 dc34eafd
added radicle-cli/examples/rad-patch-detached-head.md
@@ -0,0 +1,41 @@
+
To ensure that we can handle diverse workflows, we also allow patches to be
+
opened when we're in the infamous 'detached HEAD' state.
+

+
First, we will enter this state by using `git checkout` on a commit object:
+

+
``` (stderr) RAD_HINT=1
+
$ git checkout f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354
+
Note: switching to 'f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354'.
+

+
You are in 'detached HEAD' state. You can look around, make experimental
+
changes and commit them, and you can discard any commits you make in this
+
state without impacting any branches by switching back to a branch.
+

+
If you want to create a new branch to retain commits you create, you may
+
do so (now or later) by using -c with the switch command. Example:
+

+
  git switch -c <new-branch-name>
+

+
Or undo this operation with:
+

+
  git switch -
+

+
Turn off this advice by setting config variable advice.detachedHead to false
+

+
HEAD is now at f2de534 Second commit
+
```
+

+
Now, we can create a commit on top of this and create a patch, as usual:
+

+
``` (stderr) RAD_HINT=1
+
$ git commit -a -m "Add things" -q --allow-empty
+
$ git push -o patch.message="Add things #1" -o patch.message="See commits for details." rad HEAD:refs/patches
+
✓ Patch 6035d2f582afbe01ff23ea87528ae523d76875b6 opened
+
hint: offline push, your node is not running
+
hint: to sync with the network, run `rad node start`
+
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
 * [new reference]   HEAD -> refs/patches
+
```
+

+
Note that there will be no upstream branch, since we did not have a branch to
+
set an upstream for in the first place!
modified radicle-cli/tests/commands.rs
@@ -1045,6 +1045,26 @@ fn rad_patch_via_push() {
}

#[test]
+
fn rad_patch_detached_head() {
+
    let mut environment = Environment::new();
+
    let profile = environment.profile(config::profile("alice"));
+
    let working = tempfile::tempdir().unwrap();
+
    let home = &profile.home;
+

+
    // Setup a test repository.
+
    fixtures::repository(working.path());
+

+
    test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
+
    test(
+
        "examples/rad-patch-detached-head.md",
+
        working.path(),
+
        Some(home),
+
        [],
+
    )
+
    .unwrap();
+
}
+

+
#[test]
fn rad_patch_merge_draft() {
    let mut environment = Environment::new();
    let profile = environment.profile(config::profile("alice"));
modified radicle/src/rad.rs
@@ -353,6 +353,11 @@ pub fn setup_patch_upstream<'a>(
        return Ok(None);
    };

+
    // Can't set an upstream for something that's not a branch
+
    if !r.is_branch() {
+
        return Ok(None);
+
    }
+

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

    // Only set the upstream if it's missing or `force` is `true`