Build a commit message with Atomic provenance trailers. Only the changes in `new_history` (those new since the last push) are referenced in the body and the `Atomic-Changes` trailer. The `Atomic-State` trailer always carries the latest view state so the next push can find this commit as its starting point.
(
&self,
new_history: &[HistoryEntry],
latest_state: &Merkle,
view: &str,
)
| 259 | /// `Atomic-State` trailer always carries the latest view state so the |
| 260 | /// next push can find this commit as its starting point. |
| 261 | fn build_commit_message( |
| 262 | &self, |
| 263 | new_history: &[HistoryEntry], |
| 264 | latest_state: &Merkle, |
| 265 | view: &str, |
| 266 | ) -> CliResult<String> { |
| 267 | // Use custom message, synthesize from new change messages, or fall |
| 268 | // back to a generic label when there are no new atomic changes (e.g. |
| 269 | // manual working-copy edits). |
| 270 | let body = if let Some(ref msg) = self.message { |
| 271 | msg.clone() |
| 272 | } else if new_history.is_empty() { |
| 273 | "Working copy changes".to_string() |
| 274 | } else { |
| 275 | self.synthesize_message(new_history) |
| 276 | }; |
| 277 | |
| 278 | let mut msg = body; |
| 279 | msg.push_str("\n\n"); |
| 280 | msg.push_str(&format!("Atomic-View: {}\n", view)); |
| 281 | msg.push_str(&format!("Atomic-State: {}\n", latest_state.to_base32())); |
| 282 | |
| 283 | let change_hashes: Vec<String> = new_history.iter().map(|e| e.hash.to_base32()).collect(); |
| 284 | |
| 285 | if !change_hashes.is_empty() { |
| 286 | msg.push_str(&format!("Atomic-Changes: {}\n", change_hashes.join(", "))); |
| 287 | } |
| 288 | |
| 289 | Ok(msg) |
| 290 | } |
| 291 | |
| 292 | /// Synthesize a commit message from the new Atomic change messages. |
| 293 | /// |