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,
)
| 328 | /// `Atomic-State` trailer always carries the latest view state so the |
| 329 | /// next push can find this commit as its starting point. |
| 330 | fn build_commit_message( |
| 331 | &self, |
| 332 | new_history: &[HistoryEntry], |
| 333 | latest_state: &Merkle, |
| 334 | view: &str, |
| 335 | ) -> CliResult<String> { |
| 336 | // Use custom message, synthesize from new change messages, or fall |
| 337 | // back to a generic label when there are no new atomic changes (e.g. |
| 338 | // manual working-copy edits). |
| 339 | let body = if let Some(ref msg) = self.message { |
| 340 | msg.clone() |
| 341 | } else if new_history.is_empty() { |
| 342 | "Working copy changes".to_string() |
| 343 | } else { |
| 344 | self.synthesize_message(new_history) |
| 345 | }; |
| 346 | |
| 347 | let mut msg = body; |
| 348 | msg.push_str("\n\n"); |
| 349 | msg.push_str(&format!("Atomic-View: {}\n", view)); |
| 350 | msg.push_str(&format!("Atomic-State: {}\n", latest_state.to_base32())); |
| 351 | |
| 352 | let change_hashes: Vec<String> = new_history.iter().map(|e| e.hash.to_base32()).collect(); |
| 353 | |
| 354 | if !change_hashes.is_empty() { |
| 355 | msg.push_str(&format!("Atomic-Changes: {}\n", change_hashes.join(", "))); |
| 356 | } |
| 357 | |
| 358 | Ok(msg) |
| 359 | } |
| 360 | |
| 361 | /// Synthesize a commit message from the new Atomic change messages. |
| 362 | /// |