Calculate which changes need to be pushed to the remote. Compares local and remote changelists to determine which local changes are missing from the remote. Changes are returned in dependency order (earliest first) so they can be uploaded correctly. # Arguments `repo` - The local repository (for loading change metadata) `local_entries` - Local history entries in forward order `remote_entries` -
(
repo: &Repository,
local_entries: &[HistoryEntry],
remote_entries: &[ChangelistEntry],
graph_hashes: &HashSet<String>,
push_all: bool,
)
| 64 | /// println!("Need to push {} changes", to_push.len()); |
| 65 | /// ``` |
| 66 | pub fn calculate_push_delta( |
| 67 | repo: &Repository, |
| 68 | local_entries: &[HistoryEntry], |
| 69 | remote_entries: &[ChangelistEntry], |
| 70 | graph_hashes: &HashSet<String>, |
| 71 | push_all: bool, |
| 72 | ) -> CliResult<Vec<PushChange>> { |
| 73 | // Build set of remote hashes for quick lookup (changes already in this view) |
| 74 | let remote_hashes: HashSet<String> = remote_entries.iter().map(|e| e.hash.clone()).collect(); |
| 75 | |
| 76 | let mut to_upload = Vec::new(); |
| 77 | |
| 78 | for entry in local_entries { |
| 79 | let hash_str = entry.hash.to_base32(); |
| 80 | |
| 81 | // Skip if already on this view on the remote (unless pushing all) |
| 82 | if !push_all && remote_hashes.contains(&hash_str) { |
| 83 | continue; |
| 84 | } |
| 85 | |
| 86 | // Try to load the change header to get the message |
| 87 | let message = load_change_message(repo, &entry.hash); |
| 88 | |
| 89 | // Check if the change is already in the remote graph (via another view). |
| 90 | // If so, only view adoption is needed — no data transfer. |
| 91 | let already_in_graph = graph_hashes.contains(&hash_str); |
| 92 | |
| 93 | let push_change = PushChange::new(entry.hash, entry.sequence, entry.state) |
| 94 | .with_tagged(entry.is_tagged) |
| 95 | .with_in_graph(already_in_graph); |
| 96 | |
| 97 | let push_change = if let Some(msg) = message { |
| 98 | push_change.with_message(msg) |
| 99 | } else { |
| 100 | push_change |
| 101 | }; |
| 102 | |
| 103 | to_upload.push(push_change); |
| 104 | } |
| 105 | |
| 106 | Ok(to_upload) |
| 107 | } |
| 108 | |
| 109 | /// Load the message from a change, returning None if it fails. |
| 110 | fn load_change_message(repo: &Repository, hash: &Hash) -> Option<String> { |
no test coverage detected