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,
)
| 285 | /// `Atomic-State` trailer always carries the latest view state so the |
| 286 | /// next push can find this commit as its starting point. |
| 287 | fn build_commit_message( |
| 288 | &self, |
| 289 | new_history: &[HistoryEntry], |
| 290 | latest_state: &Merkle, |
| 291 | view: &str, |
| 292 | ) -> CliResult<String> { |
| 293 | // Use custom message, synthesize from new change messages, or fall |
| 294 | // back to a generic label when there are no new atomic changes (e.g. |
| 295 | // manual working-copy edits). |
| 296 | let body = if let Some(ref msg) = self.message { |
| 297 | msg.clone() |
| 298 | } else if new_history.is_empty() { |
| 299 | "Working copy changes".to_string() |
| 300 | } else { |
| 301 | self.synthesize_message(new_history) |
| 302 | }; |
| 303 | |
| 304 | let mut msg = body; |
| 305 | msg.push_str("\n\n"); |
| 306 | msg.push_str(&format!("Atomic-View: {}\n", view)); |
| 307 | msg.push_str(&format!("Atomic-State: {}\n", latest_state.to_base32())); |
| 308 | |
| 309 | let change_hashes: Vec<String> = new_history.iter().map(|e| e.hash.to_base32()).collect(); |
| 310 | |
| 311 | if !change_hashes.is_empty() { |
| 312 | msg.push_str(&format!("Atomic-Changes: {}\n", change_hashes.join(", "))); |
| 313 | } |
| 314 | |
| 315 | Ok(msg) |
| 316 | } |
| 317 | |
| 318 | /// Synthesize a commit message from the new Atomic change messages. |
| 319 | /// |