OXYGENHUB

Remotes report stale attestations as absent but keep the last serial; remotes test expectations 4161262eeb29

Author
Andy McCall @andymccall <[email protected]>
When
· 2026-09-26 18:38 UTC
Signature
✔ signed by Andy McCall
Hash
4161262eeb292043c4081a13509f274d5fe7740f7590ea909439fbee9b48c101
Depends on
5b9c6ad45f6e ff0af1ee299d
Depended on by
f53cbe7a204e
In bookmarks
agents-in-readme bare-hashes carried-not-removed carry-identical doctor-trust identical-sides keyless-tags main merge-remote-bookmark only-help-103 paths-for-resolutions-and-amend push-notes show-stat subrepo-pin-state switch-says
In tags
v0.1.0 v0.10.0 v0.11.0 v0.2.0 v0.3.0 v0.3.1 v0.4.0 v0.4.1 v0.4.2 v0.4.3 v0.4.4 v0.4.5 v0.4.6 v0.5.0 v0.5.1 v0.6.0 v0.7.0 v0.8.0 v0.9.0
Edits
7 atoms, 0 tree operations, 2 files

Browse the tree at this change

modified crates/oxy-core/src/protocol.rs +5 −0
…
22 unchanged lines
23 23
    pub name: String,
24 24
    pub state: ObjectRef,
25 25
    pub heads: Vec<ChangeHash>,
26 +
    /// The latest attestation, only when it describes `state`. An unattested
27 +
    /// push (accepted while no trust policy exists) leaves it `None`.
26 28
    pub attestation: Option<SignedAttest>,
29 +
    /// Serial of the latest attestation ever recorded, stale or not, so the
30 +
    /// next attestation continues the sequence.
31 +
    pub last_serial: Option<u64>,
27 32
}
28 33
29 34
/// Everything needed to add a set of changes to a repository.
…
79 unchanged lines
modified crates/oxy-core/src/repo.rs +13 −14
…
522 unchanged lines
523 523
        let view = self.view()?;
524 524
        let mut out = Vec::new();
525 525
        for (name, state) in &view.bookmarks {
526 -
            out.push(RemoteRef {
527 -
                name: name.clone(),
528 -
                state: *state,
529 -
                heads: self.store.get_state(state)?.heads,
530 -
                attestation: self.latest_ref_attest(name)?.map(|(_, a)| a),
526 +
            let latest = self.latest_ref_attest(name)?.map(|(_, a)| a);
527 +
            let last_serial = latest.as_ref().and_then(|a| match a.attest.body {
528 +
                AttestBody::Ref { serial, .. } => Some(serial),
529 +
                _ => None,
531 530
            });
531 +
            let attestation = latest.filter(|a| matches!(&a.attest.body, AttestBody::Ref { new_state, .. } if new_state == state));
532 +
            out.push(RemoteRef { name: name.clone(), state: *state, heads: self.store.get_state(state)?.heads, attestation, last_serial });
532 533
        }
533 534
        Ok(out)
534 535
    }
…
353 unchanged lines
888 889
        let refs = remote.refs()?;
889 890
        let empty = self.store.put_state(&StateObject::new(vec![]))?;
890 891
        let (remote_state, remote_heads, last_serial) = match refs.iter().find(|r| r.name == bookmark) {
891 -
            Some(r) => (
892 -
                r.state,
893 -
                r.heads.clone(),
894 -
                r.attestation.as_ref().and_then(|a| match a.attest.body {
895 -
                    AttestBody::Ref { serial, .. } => Some(serial),
896 -
                    _ => None,
897 -
                }),
898 -
            ),
892 +
            Some(r) => (r.state, r.heads.clone(), r.last_serial),
899 893
            None => (empty, vec![], None),
900 894
        };
901 895
        let new_state = self.store.put_state(&StateObject::new(local_heads.clone()))?;
…
1453 unchanged lines
2355 2349
        assert!(b.push("origin", false).unwrap()[0].ok);
2356 2350
        a.pull("origin").unwrap();
2357 2351
        assert_eq!(fs::read(root.join("a/f.txt")).unwrap(), b"a\nAB\n");
2358 -
        assert_eq!(a.bookmark_heads().unwrap(), vec![hr]);
2352 +
        // The resolution depends on the conflicting edits, but nothing depends
2353 +
        // on "third" (it only added g.txt), so it stays a head beside it.
2354 +
        let mut want = vec![hr, h3];
2355 +
        want.sort();
2356 +
        assert_eq!(a.bookmark_heads().unwrap(), want);
2357 +
        assert!(!a.load_state(&want).unwrap().materialize().is_conflicted());
2359 2358
    }
2360 2359
2361 2360
    #[test]
…
156 unchanged lines