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 |