in focus/operations/src/clone.rs [892:992]
fn copy_local_branches(
dense_repo: &Repository,
sparse_repo: &Repository,
branch: &str,
app: Arc<App>,
days_of_history: u64,
) -> Result<()> {
let branches = dense_repo
.branches(Some(git2::BranchType::Local))
.context("Failed to enumerate local branches in the dense repo")?;
let mut valid_local_branches = Vec::new();
for b in branches {
let (b, _branch_type) = b?;
let name = match b.name()? {
Some(name) => name,
None => {
warn!(
"Skipping branch {:?} because it is not representable as UTF-8",
b.name_bytes()
);
continue;
}
};
if name == branch {
// Skip the primary branch since it should already be configured.
continue;
}
debug!("Examining dense repo branch {}", name);
let dense_commit = b
.get()
.peel_to_commit()
.context("Failed to peel branch ref to commit")?;
let dense_commit_date = DateTime::from_utc(
NaiveDateTime::from_timestamp(dense_commit.time().seconds(), 0),
Utc,
)
.date();
let days_of_history: i64 = days_of_history.try_into()?;
let shallow_since_datestamp = focus_util::time::date_at_day_in_past(days_of_history)?;
if days_of_history > 0 {
if dense_commit_date > shallow_since_datestamp {
valid_local_branches.push((name.to_owned(), dense_commit.to_owned()));
} else {
warn!(
"Branch {} is older than the configured limit ({}). Rebase it if you would like it to be included in the new repo.",
name, shallow_since_datestamp
);
}
}
}
let branch_list_output = valid_local_branches
.iter()
.map(|(name, _)| name.to_string())
.collect::<Vec<String>>()
.join(" ");
let (mut cmd, scmd) = git_helper::git_command(app)?;
let mut args: Vec<OsString> = vec!["fetch".into(), "--no-tags".into()];
args.push("origin".into());
valid_local_branches
.iter()
.for_each(|(name, _)| args.push(name.into()));
scmd.ensure_success_or_log(
cmd.current_dir(sparse_repo.path()).args(args),
SandboxCommandOutput::Stderr,
)
.map(|_| ())
.with_context(|| {
format!(
"Failed to fetch user branches ({}) for {}",
branch_list_output,
whoami::username()
)
})?;
valid_local_branches.iter().for_each(|(name, dense_commit)| {
match sparse_repo.find_commit(dense_commit.id()) {
Ok(sparse_commit) => match sparse_repo.branch(name, &sparse_commit, false) {
Ok(_new_branch) => {
info!("Created branch {} ({})", name, sparse_commit.id());
}
Err(e) => {
error!("Could not create branch {} in the sparse repo: {}", name, e);
}
},
Err(_) => {
error!("Could not create branch {} in the sparse repo because the associated commit ({}) does not exist!",
name, dense_commit.id());
}
}
});
Ok(())
}