Import commits from a branch into an Atomic repository. Commits are processed in **batches** to keep memory bounded and show progress sooner. Each batch: parse in parallel → write sequentially. Imports use a fixed 1,000-commit batch size. This keeps progress and memory behavior predictable across small and large repositories.
(
&self,
branch_name: &str,
repo: &mut Repository,
)
| 2208 | /// Imports use a fixed 1,000-commit batch size. This keeps progress and |
| 2209 | /// memory behavior predictable across small and large repositories. |
| 2210 | pub fn import_branch( |
| 2211 | &self, |
| 2212 | branch_name: &str, |
| 2213 | repo: &mut Repository, |
| 2214 | ) -> CliResult<ImportStats> { |
| 2215 | let mut stats = ImportStats::default(); |
| 2216 | |
| 2217 | // Open git repo for this thread |
| 2218 | let git_repo = self.open_git_repo()?; |
| 2219 | |
| 2220 | // Collect commit OIDs in topological order |
| 2221 | let commit_oids = self.collect_commit_oids(&git_repo, branch_name)?; |
| 2222 | stats.commits_found = commit_oids.len(); |
| 2223 | |
| 2224 | if commit_oids.is_empty() { |
| 2225 | return Ok(stats); |
| 2226 | } |
| 2227 | |
| 2228 | let total = commit_oids.len(); |
| 2229 | let batch_size = Self::batch_size_for(total); |
| 2230 | |
| 2231 | print_info(&format!( |
| 2232 | "Importing {} commits in batches of {}...", |
| 2233 | total, batch_size |
| 2234 | )); |
| 2235 | |
| 2236 | let import_start = Instant::now(); |
| 2237 | let mut commits_written = 0usize; |
| 2238 | let mut line_index = ImportLineIndex::default(); |
| 2239 | let mut all_imported_commits: Vec<ImportedCommitInfo> = Vec::new(); |
| 2240 | |
| 2241 | for (batch_idx, chunk) in commit_oids.chunks(batch_size).enumerate() { |
| 2242 | let batch_start = batch_idx * batch_size; |
| 2243 | let batch_end = (batch_start + chunk.len()).min(total); |
| 2244 | |
| 2245 | print_info(&format!( |
| 2246 | "Batch {}: parsing commits {}-{} of {}...", |
| 2247 | batch_idx + 1, |
| 2248 | batch_start, |
| 2249 | batch_end, |
| 2250 | total |
| 2251 | )); |
| 2252 | |
| 2253 | // Phase 1: Parallel git parsing for this batch |
| 2254 | let parse_start = Instant::now(); |
| 2255 | let parsed_commits = self.phase1_parse(chunk)?; |
| 2256 | let parse_elapsed = parse_start.elapsed(); |
| 2257 | |
| 2258 | stats.phase1_duration += parse_elapsed; |
| 2259 | stats.commits_parsed += parsed_commits.len(); |
| 2260 | |
| 2261 | if parsed_commits.is_empty() { |
| 2262 | continue; |
| 2263 | } |
| 2264 | |
| 2265 | // Phase 2: Sequential write for this batch |
| 2266 | let write_start = Instant::now(); |
| 2267 | let (write_stats, batch_imported) = |
nothing calls this directly
no test coverage detected