cli: Tell the user when canonical head is updated

This is useful especially in multi-delegate repos, since patches can be
merged without the head being updated.
This commit is contained in:
cloudhead 2024-01-05 12:09:30 +01:00
parent 6bc7d297a5
commit 7169e97bd5
No known key found for this signature in database
12 changed files with 52 additions and 14 deletions

View File

@ -62,6 +62,7 @@ f2de534 Second commit
```
``` ~alice RAD_SOCKET=/dev/null (stderr)
$ git push rad
✓ Canonical head updated to f6cff86594495e9beccfeda7c20173e55c1dd9fc
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
f2de534..f6cff86 master -> master
```
@ -79,6 +80,7 @@ We have to use the `allow.rollback` option:
``` ~alice RAD_SOCKET=/dev/null (stderr)
$ git push -f -o allow.rollback
✓ Canonical head updated to 319a7dc3b195368ded4b099f8c90bbb80addccd3
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+ f6cff86...319a7dc master -> master (forced update)
```

View File

@ -16,6 +16,7 @@ $ git commit --amend --allow-empty -q -m "Amended change"
$ git checkout master -q
$ git merge feature/1 -q
$ git push rad master
✓ Canonical head updated to 954bcdb5008447ce294a61a21d7eb87afbe7f4a6
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
f2de534..954bcdb master -> master
```

View File

@ -37,6 +37,7 @@ Finally, we push master and expect the patch to be merged.
``` (stderr) RAD_SOCKET=/dev/null
$ git push rad master
✓ Patch a1207f6e82700e42cc46c9c38c7786b18cbd2040 merged
✓ Canonical head updated to 737a10cfa29111afeb0d43cf3545cee386b939ec
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
f2de534..737a10c master -> master
```

View File

@ -63,6 +63,7 @@ When we push to `rad/master`, we automatically merge the patches:
$ git push rad master
✓ Patch 8357a9f1d61e80309d314491aa754969d9f47d77 merged
✓ Patch a1207f6e82700e42cc46c9c38c7786b18cbd2040 merged
✓ Canonical head updated to d6399c71702b40bae00825b3c444478d06b4e91c
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
f2de534..d6399c7 master -> master
```

View File

@ -14,6 +14,7 @@ $ git checkout master -q
$ git merge feature/1
$ git push rad master
✓ Patch cf29ac6b10141058be66b94a92a81c703b972751 merged
✓ Canonical head updated to 20aa5dde6210796c3a2f04079b42316a31d02689
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
f2de534..20aa5dd master -> master
```

View File

@ -90,6 +90,7 @@ Fast-forward
``` (stderr)
$ git push rad master
✓ Patch 3581e83ad18f5cdd806ab50fa11cfd5dd4e8ae1c merged at revision abb0360
✓ Canonical head updated to f567f695d25b4e8fb63b5f5ad2a584529826e908
✓ Synced with 1 node(s)
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
f2de534..f567f69 master -> master

View File

@ -279,8 +279,16 @@ pub fn run(
// Sign refs and sync if at least one ref pushed successfully.
if !ok.is_empty() {
stored.sign_refs(&signer)?;
stored.set_head()?;
let _ = stored.sign_refs(&signer)?;
let head = stored.set_head()?;
if head.is_updated() {
eprintln!(
"{} Canonical head updated to {}",
cli::format::positive(""),
cli::format::secondary(head.new),
);
}
if !opts.no_sync {
// Connect to local node and announce refs to the network.

View File

@ -21,7 +21,7 @@ fn main() -> anyhow::Result<()> {
radicle::Node::new(profile.socket()).announce_refs(id)?;
println!("head: {head}");
println!("head: {}", head.new);
println!("ok: {}", sigrefs.signature);
Ok(())

View File

@ -10,10 +10,10 @@ fn main() -> anyhow::Result<()> {
let repo = profile.storage.repository_mut(rid)?;
let id_oid = repo.set_identity_head()?;
let branch_oid = repo.set_head()?;
let branch = repo.set_head()?;
println!("ok: identity: {id_oid}");
println!("ok: branch: {branch_oid}");
println!("ok: branch: {}", branch.new);
Ok(())
}

View File

@ -69,6 +69,21 @@ impl FromIterator<PublicKey> for Namespaces {
}
}
/// Output of [`WriteRepository::set_head`].
pub struct SetHead {
/// Old branch head.
pub old: Option<Oid>,
/// New branch head.
pub new: Oid,
}
impl SetHead {
/// Check if the head was updated.
pub fn is_updated(&self) -> bool {
self.old != Some(self.new)
}
}
/// Repository error.
#[derive(Error, Debug)]
pub enum RepositoryError {
@ -536,7 +551,7 @@ where
pub trait WriteRepository: ReadRepository + SignRepository {
/// Set the repository head to the canonical branch.
/// This computes the head based on the delegate set.
fn set_head(&self) -> Result<Oid, RepositoryError>;
fn set_head(&self) -> Result<SetHead, RepositoryError>;
/// Set the repository 'rad/id' to the canonical commit, agreed by quorum.
fn set_identity_head(&self) -> Result<Oid, RepositoryError> {
let head = self.canonical_identity_head()?;

View File

@ -19,8 +19,8 @@ use crate::identity::{Identity, Project};
use crate::storage::refs;
use crate::storage::refs::{Refs, SignedRefs, SignedRefsAt};
use crate::storage::{
Inventory, ReadRepository, ReadStorage, Remote, Remotes, RepositoryError, SignRepository,
WriteRepository, WriteStorage,
Inventory, ReadRepository, ReadStorage, Remote, Remotes, RepositoryError, SetHead,
SignRepository, WriteRepository, WriteStorage,
};
pub use crate::git::{
@ -799,19 +799,27 @@ impl ReadRepository for Repository {
}
impl WriteRepository for Repository {
fn set_head(&self) -> Result<Oid, RepositoryError> {
fn set_head(&self) -> Result<SetHead, RepositoryError> {
let head_ref = refname!("HEAD");
let (branch_ref, head) = self.canonical_head()?;
let old = self
.raw()
.refname_to_id(&head_ref)
.ok()
.map(|oid| oid.into());
let (branch_ref, new) = self.canonical_head()?;
log::debug!(target: "storage", "Setting ref: {} -> {}", &branch_ref, head);
if old == Some(new) {
return Ok(SetHead { old, new });
}
log::debug!(target: "storage", "Setting ref: {} -> {}", &branch_ref, new);
self.raw()
.reference(&branch_ref, *head, true, "set-local-branch (radicle)")?;
.reference(&branch_ref, *new, true, "set-local-branch (radicle)")?;
log::debug!(target: "storage", "Setting ref: {} -> {}", head_ref, branch_ref);
self.raw()
.reference_symbolic(&head_ref, &branch_ref, true, "set-head (radicle)")?;
Ok(head)
Ok(SetHead { old, new })
}
fn set_identity_head_to(&self, commit: Oid) -> Result<(), RepositoryError> {

View File

@ -288,7 +288,7 @@ impl WriteRepository for MockRepository {
todo!()
}
fn set_head(&self) -> Result<Oid, RepositoryError> {
fn set_head(&self) -> Result<SetHead, RepositoryError> {
todo!()
}