Diffusion: a bump pins the upstream's default bookmark, not the old pin's (closes #332) 3e868a1f94e1
- Author
- Andy McCall @andymccall <[email protected]>
- via
- agent
agent:claude@andymccall <[email protected]> · keyless, under your grant for changes,refs,seal · key ce8a0aaaaeaa
- When
- · 2026-10-26 17:29 UTC
- Signature
- ◈ sealed by agent:claude@andymccall
- Hash
3e868a1f94e111eb69563ebe52a76d3c20bfe1857f6cc65986a189b6119dd75f- Depends on
- 1d634f698ecd 34388e612963 62cdf34daec1 7a14bdaeb857 a7e6e8e6094c b5668108487f e71583501b1d f677d6270298
- Depended on by
- 4b49c41599f3
- In bookmarks
- diffusion-pin-bookmark main
- In tags
- v0.9.11 v0.9.15 v0.9.16 v0.9.19 v0.9.20 v0.9.21 v0.9.22 v0.9.23 v0.9.24 v0.9.7 v0.9.8 v0.9.9
- Edits
- 6 atoms, 0 tree operations, 2 files
Browse the tree at this change
modified CHANGELOG.md +1 −0
| … | 3 unchanged lines |
||
| 4 | 4 | ||
| 5 | 5 | ## Unreleased |
|
| 6 | 6 | ||
| 7 | + | - **A Diffusion bump pins the upstream's default bookmark (#332).** A bump kept the bookmark name of the pin it replaced, so a subrepo first pinned at an upstream proposal's bookmark still named it after the proposal landed and Diffusion moved the pin to the default bookmark's state; a checkout then counted the subrepo as on another bookmark. A bump now names the upstream's default bookmark, unless it keeps pinned changes that bookmark lacks. |
|
| 7 | 8 | - **The API refuses a field an edit does not take (#330).** `PATCH` on an issue, proposal, project, milestone, release or drop answered 200 to a field it does not know and changed nothing (`{"ready": true}` on a draft proposal, say), which looked like success. It now answers 422 naming the field and the ones it takes. |
|
| 8 | 9 | - **Mail reads `[OxygenHub]`, in a wider message (#334).** A notification's subject was tagged with the site's name (`[Oxygenhub on Earth]`); mail now goes by the From address's display name (`OxygenHub <noreply@…>`) in the subject and the footer, falling back to the site's name, so the site keeps its own name (which its apt repository is labelled with). The message card is 720px wide rather than 560. |
|
| 9 | 10 | - **An agent follows its owner's newest identity (oxygen#82).** A keyless certificate's answer now carries `author_chain`: the grant owner's newest linked identity and its predecessors back to the grant's key, so an agent home with `author.for` authors as the owner's current identity, not one several rotations old. |
|
| … | 349 unchanged lines |
modified crates/hub/src/diffusion.rs +36 −1
| … | 719 unchanged lines |
||
| 720 | 720 | if repo != upstream_id { |
|
| 721 | 721 | return Ok(Bumped::NoPin); |
|
| 722 | 722 | } |
|
| 723 | - | let new_heads = match plan(app, &uname, old.clone(), new_heads.clone()).await? { |
|
| 723 | + | let planned = match plan(app, &uname, old.clone(), new_heads.clone()).await? { |
|
| 724 | 724 | Plan::To(heads, _) => heads, |
|
| 725 | 725 | Plan::UpToDate => return Ok(Bumped::UpToDate), |
|
| 726 | 726 | Plan::Unknown => return Ok(Bumped::Unknown), |
|
| 727 | 727 | Plan::Conflicts => return Ok(Bumped::Conflicts), |
|
| 728 | 728 | }; |
|
| 729 | + | let bookmark = pin_bookmark(&planned, &new_heads, &upstream.default_bookmark, bookmark); |
|
| 730 | + | let new_heads = planned; |
|
| 729 | 731 | if let Some(Pin::Oxy { heads: b, .. }) = &bumped { |
|
| 730 | 732 | let (mut b, mut n) = (b.clone(), new_heads.clone()); |
|
| 731 | 733 | b.sort(); |
|
| … | 40 unchanged lines |
||
| 772 | 774 | .await |
|
| 773 | 775 | } |
|
| 774 | 776 | ||
| 777 | + | /// The bookmark a bump's pin names (#332): the upstream's default |
|
| 778 | + | /// bookmark, which `new` (its heads) are from, unless the move keeps |
|
| 779 | + | /// pinned changes that bookmark lacks (an upstream proposal not landed |
|
| 780 | + | /// yet), which are only on the bookmark the pin named, `old`. Keeping |
|
| 781 | + | /// `old` always left a pin naming a proposal's bookmark after the |
|
| 782 | + | /// proposal had landed, and a checkout then counted the subrepo as on |
|
| 783 | + | /// another bookmark. |
|
| 784 | + | fn pin_bookmark(planned: &[ChangeHash], new: &[ChangeHash], default: &str, old: String) -> String { |
|
| 785 | + | if heads_key(planned) == heads_key(new) { |
|
| 786 | + | default.to_string() |
|
| 787 | + | } else { |
|
| 788 | + | old |
|
| 789 | + | } |
|
| 790 | + | } |
|
| 791 | + | ||
| 775 | 792 | /// The account Diffusion's proposals are opened as. |
|
| 776 | 793 | pub const ACCOUNT: &str = "diffusion"; |
|
| 777 | 794 | ||
| … | 783 unchanged lines |
||
| 1561 | 1578 | assert_eq!(title, "Diffusion: move rstar-api to doomsdayone/rstar-api 00a6c9d4746a (+19 heads)"); |
|
| 1562 | 1579 | assert_eq!(body, format!("Pins doomsdayone/rstar-api at {}", heads.join("+"))); |
|
| 1563 | 1580 | assert_eq!(bump_message("api", "andy/api", &heads[..1]), "Diffusion: move api to andy/api 00a6c9d4746a"); |
|
| 1581 | + | } |
|
| 1582 | + | } |
|
| 1583 | + | ||
| 1584 | + | #[cfg(test)] |
|
| 1585 | + | mod pin_tests { |
|
| 1586 | + | use super::pin_bookmark; |
|
| 1587 | + | use oxy_core::hash::ObjectRef; |
|
| 1588 | + | ||
| 1589 | + | #[test] |
|
| 1590 | + | fn a_bump_pins_the_upstreams_default_bookmark_unless_it_keeps_other_changes() { |
|
| 1591 | + | let (a, b) = (ObjectRef([1; 32]), ObjectRef([2; 32])); |
|
| 1592 | + | // R*'s proposal had landed on main: the move is to main's heads, |
|
| 1593 | + | // so the pin names main, not the proposal's bookmark (#332). |
|
| 1594 | + | assert_eq!(pin_bookmark(&[a], &[a], "main", "x16-tilemap-double".into()), "main"); |
|
| 1595 | + | assert_eq!(pin_bookmark(&[b, a], &[a, b], "main", "feature".into()), "main", "in any order"); |
|
| 1596 | + | // The pin's own changes are kept beside main's: still the bookmark |
|
| 1597 | + | // that has them. |
|
| 1598 | + | assert_eq!(pin_bookmark(&[a, b], &[a], "main", "feature".into()), "feature"); |
|
| 1564 | 1599 | } |
|
| 1565 | 1600 | } |