///| Asynchronous Git repository metadata materialization.
///|
/// Asynchronous counterpart to `materialize_clone_to_fs`.
pub async fn[FS : @types.AsyncFileSystem + @types.AsyncRepoFileSystem] materialize_clone_to_fs_async(
store : ObjectStore,
commit_id : @object.ObjectId,
refname : String,
remote_url : String,
fs : FS,
root : String,
) -> Unit raise @object.GitError {
checkout_commit_to_fs_async(store, commit_id, fs, root)
write_git_metadata_async(store, commit_id, refname, remote_url, fs, root)
}
///|
/// Asynchronous counterpart to `write_git_metadata`.
pub async fn[FS : @types.AsyncFileSystem + @types.AsyncRepoFileSystem] write_git_metadata_async(
store : ObjectStore,
commit_id : @object.ObjectId,
refname : String,
remote_url : String,
fs : FS,
root : String,
) -> Unit raise @object.GitError {
let git_dir = join_path(root, ".git")
@types.AsyncFileSystem::mkdir_p(fs, git_dir)
@types.AsyncFileSystem::mkdir_p(fs, join_path(git_dir, "objects"))
@types.AsyncFileSystem::mkdir_p(fs, join_path(git_dir, "objects/info"))
@types.AsyncFileSystem::mkdir_p(fs, join_path(git_dir, "objects/pack"))
@types.AsyncFileSystem::mkdir_p(fs, join_path(git_dir, "refs/heads"))
@types.AsyncFileSystem::mkdir_p(fs, join_path(git_dir, "refs/tags"))
write_head_and_refs_async(fs, git_dir, refname, commit_id)
@types.AsyncFileSystem::write_string(
fs,
join_path(git_dir, "config"),
git_config_text(remote_url),
)
@types.AsyncFileSystem::write_string(
fs,
join_path(git_dir, "packed-refs"),
"# pack-refs with: peeled fully-peeled\n",
)
@types.AsyncFileSystem::write_string(
fs,
join_path(git_dir, "objects/info/alternates"),
"",
)
write_index_v2_async(store, fs, git_dir, commit_id, root)
}
///|
async fn[FS : @types.AsyncFileSystem] write_head_and_refs_async(
fs : FS,
git_dir : String,
refname : String,
commit_id : @object.ObjectId,
) -> Unit raise @object.GitError {
let head_path = join_path(git_dir, "HEAD")
if refname == "HEAD" {
@types.AsyncFileSystem::write_string(
fs,
head_path,
commit_id.to_hex() + "\n",
)
return
}
@types.AsyncFileSystem::write_string(fs, head_path, "ref: \{refname}\n")
let ref_path = join_path(git_dir, refname)
@types.AsyncFileSystem::mkdir_p(fs, parent_dir(ref_path))
@types.AsyncFileSystem::write_string(fs, ref_path, commit_id.to_hex() + "\n")
}
///|
async fn[FS : @types.AsyncFileSystem + @types.AsyncRepoFileSystem] write_index_v2_async(
store : ObjectStore,
fs : FS,
git_dir : String,
commit_id : @object.ObjectId,
root : String,
) -> Unit raise @object.GitError {
let entries = collect_commit_entries(store, commit_id)
entries.sort_by((a, b) => String::lexical_compare(a.path, b.path))
let entries_with_mtime : Array[(IndexEntryInfo, (Int, Int))] = []
for entry in entries {
let mtime = if entry.mode == 0o160000 {
(0, 0)
} else {
@types.AsyncRepoFileSystem::mtime(fs, join_path(root, entry.path))
}
entries_with_mtime.push((entry, mtime))
}
@types.AsyncFileSystem::write_file(
fs,
join_path(git_dir, "index"),
build_index_v2(entries_with_mtime),
)
}