>(
clone_path: P,
repo: &github::Repo,
base_cgitrc: Option,
) -> anyhow::Result<()> {
git::mirror(
&repo.git_url,
&clone_path,
repo.description(),
)?;
// Copy the base cgitrc file into the newly-cloned repository.
if let Some(base_cgitrc) = base_cgitrc {
let cgitrc_path = clone_path.as_ref().join("cgitrc");
fs::copy(&base_cgitrc, &cgitrc_path)
.with_context(|| format!(
"unable to copy '{}' to '{}'",
"./cgitrc",
&cgitrc_path.display(),
))?;
}
update_mtime(&clone_path, &repo)?;
Ok(())
}
/// Update a previously-mirrored repository.
fn update>(
repo_path: P,
current_repo: &database::Repo,
updated_repo: &github::Repo,
) -> anyhow::Result<()> {
git::update(&repo_path)?;
let remote_description = updated_repo.description();
if current_repo.description() != remote_description {
git::update_description(&repo_path, remote_description)?;
}
update_mtime(&repo_path, &updated_repo)?;
Ok(())
}
/// Set the mtime of the repository to GitHub's `updated_at` time.
///
/// Used for CGit "age" sorting.
fn update_mtime>(
repo_path: P,
repo: &github::Repo,
) -> anyhow::Result<()> {
let default_branch_ref = repo_path
.as_ref()
.join("refs/heads")
.join(&repo.default_branch);
let update_time = filetime::FileTime::from_system_time(
DateTime::parse_from_rfc3339(&repo.updated_at)?.into()
);
// Try updating times on the default ref.
match filetime::set_file_times(
&default_branch_ref,
update_time,
update_time,
) {
Ok(_) => Ok(()),
Err(e) => match e.kind() {
// If the default ref file doesn't exist, update times on the
// 'packed-refs' file.
io::ErrorKind::NotFound => {
let packed_refs_path = repo_path
.as_ref()
.join("packed-refs");
Ok(
filetime::set_file_times(
&packed_refs_path,
update_time,
update_time,
)
.with_context(|| format!(
"unable to set mtime on '{}'",
&packed_refs_path.display(),
))?
)
},
_ => Err(e),
},
}
.with_context(|| format!(
"unable to set mtime on '{}'",
&default_branch_ref.display(),
))?;
Ok(())
}