OXYGENHUB

Blame from the state index, each author's name read once (refs #41) 073a2115995f

blame MAINTAINERS on the Linux tree: 0.16 s (from 0.59 s).
Author
Andy McCall @andymccall <[email protected]>
When
· 2026-09-30 22:36 UTC
Signature
✔ signed by Andy McCall
Hash
073a2115995fa07bb7e407ac76c0ac85fe77804165c9c0416a4ee27b680f28a8
Depends on
69816d688300 75167672ebcd 957fee30826e e02bf0cd0533
Depended on by
c2e1d09047db
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.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
4 atoms, 0 tree operations, 1 file

Browse the tree at this change

modified crates/oxy-core/src/repo/inspect.rs +18 −6
…
59 unchanged lines
60 60
    /// the working copy's base state (spec §27).
61 61
    pub fn blame(&self, path: &str) -> Result<Vec<BlameLine>> {
62 62
        let (_, wc) = self.working_copy()?;
63 -
        self.blame_heads(path, &wc.deps, "the working copy's base state")
63 +
        // The working copy's base is what the state index holds.
64 +
        let mut state = self.load_state_indexed(&wc.deps)?;
65 +
        let tree = state.tree().view();
66 +
        if let Some(e) = tree.entries.get(path) {
67 +
            self.load_graphs_of(&mut state, &[e.node])?;
68 +
        }
69 +
        self.blame_state(path, &state, &tree, "the working copy's base state")
64 70
    }
65 71
66 72
    /// Blame `path` in the state with these heads (hosted repositories).
…
36 unchanged lines
103 109
            return fail(format!("{path} is not a text file"));
104 110
        }
105 111
        let mut out = Vec::new();
112 +
        // Each author's name read once, not once per line.
113 +
        let mut names: HashMap<crate::hash::KeyId, String> = HashMap::new();
106 114
        for (i, ((hash, index), text)) in state.live_lines(&f.node).into_iter().enumerate() {
107 115
            let meta = state.get(&hash);
108 116
            let author = match meta {
109 -
                Some(m) if !m.author.is_zero() => self
110 -
                    .store
111 -
                    .get_identity(&m.author)
112 -
                    .map(|id| id.name)
113 -
                    .unwrap_or_else(|_| m.author.short(12)),
117 +
                Some(m) if !m.author.is_zero() => names
118 +
                    .entry(m.author)
119 +
                    .or_insert_with(|| {
120 +
                        self.store
121 +
                            .get_identity(&m.author)
122 +
                            .map(|id| id.name)
123 +
                            .unwrap_or_else(|_| m.author.short(12))
124 +
                    })
125 +
                    .clone(),
114 126
                Some(m) => m
115 127
                    .message
116 128
                    .lines()
…
351 unchanged lines