gitdataai/libs/git/hook/sync/lfs.rs
2026-04-14 19:02:01 +08:00

90 lines
2.9 KiB
Rust

use crate::GitError;
use crate::hook::sync::HookMetaDataSync;
use db::database::AppTransaction;
use models::repos::repo_lfs_object;
use sea_orm::*;
use std::collections::HashSet;
impl HookMetaDataSync {
pub async fn sync_lfs_objects(&self, txn: &AppTransaction) -> Result<(), GitError> {
let repo_id = self.repo.id;
let existing: Vec<repo_lfs_object::Model> = repo_lfs_object::Entity::find()
.filter(repo_lfs_object::Column::Repo.eq(repo_id))
.all(txn)
.await
.map_err(|e| GitError::IoError(format!("failed to query lfs objects: {}", e)))?;
let mut existing_oids: HashSet<String> = existing.into_iter().map(|o| o.oid).collect();
let local_oids = self.domain.lfs_object_list()?;
let now = chrono::Utc::now();
let mut new_objects = Vec::new();
for oid in local_oids {
let oid_str = oid.as_str().to_string();
if existing_oids.contains(&oid_str) {
existing_oids.remove(&oid_str);
continue;
}
let path = match self.domain.lfs_object_path(&oid) {
Ok(p) => p,
Err(e) => {
slog::warn!(
self.logger,
"invalid LFS OID in local objects directory: {}",
e
);
continue;
}
};
let size = if let Ok(meta) = std::fs::metadata(&path) {
meta.len() as i64
} else {
continue;
};
let storage_path = path.to_string_lossy().to_string();
new_objects.push(repo_lfs_object::ActiveModel {
repo: Set(repo_id),
oid: Set(oid_str),
size: Set(size),
storage_path: Set(storage_path),
uploaded_by: Set(None),
uploaded_at: Set(now),
..Default::default()
});
}
if !new_objects.is_empty() {
// Insert in batches
for chunk in new_objects.chunks(100) {
repo_lfs_object::Entity::insert_many(chunk.to_vec())
.exec(txn)
.await
.map_err(|e| {
GitError::IoError(format!("failed to insert lfs objects: {}", e))
})?;
}
}
// Remove objects that no longer exist on disk
if !existing_oids.is_empty() {
repo_lfs_object::Entity::delete_many()
.filter(repo_lfs_object::Column::Repo.eq(repo_id))
.filter(repo_lfs_object::Column::Oid.is_in(existing_oids))
.exec(txn)
.await
.map_err(|e| {
GitError::IoError(format!("failed to delete stale lfs objects: {}", e))
})?;
}
Ok(())
}
}