diff --git a/giterated-daemon/src/backend/git.rs b/giterated-daemon/src/backend/git.rs index 008b10e..7cb0491 100644 --- a/giterated-daemon/src/backend/git.rs +++ b/giterated-daemon/src/backend/git.rs @@ -352,21 +352,13 @@ impl GitBackend { pub fn get_oid_from_reference( git: &git2::Repository, rev: Option<&str>, + default_branch: &DefaultBranch, ) -> Result { - // TODO: Change to default branch instead of head - // If the rev is None try and get the repository head - let Some(rev) = rev else { - if let Ok(head) = git.head() { - // TODO: Fix for symbolic references - // TODO: unsafe unwrap? - return Ok(head.target().unwrap()); - } else { - // Nothing in database, render empty tree. - return Err(GitBackendError::HeadNotFound); - } - }; + // If the rev is None try and get the default branch instead + let rev = rev.unwrap_or(default_branch.0.as_str()); // TODO: This is far from ideal or speedy and would love for a better way to check this in the same order, but I can't find proper methods to do any of this. + trace!("Attempting to get ref with name {}", rev); // Try getting it as a refname (refs/heads/name) if let Ok(oid) = git.refname_to_id(rev) { @@ -377,15 +369,28 @@ impl GitBackend { Ok(branch.get().target().unwrap()) // As last resort, try revparsing (will catch short oid and tags) } else if let Ok(object) = git.revparse_single(rev) { - Ok(object.id()) + Ok(match object.kind() { + Some(git2::ObjectType::Tag) => { + if let Ok(commit) = object.peel_to_commit() { + commit.id() + } else { + object.id() + } + } + _ => object.id(), + }) } else { Err(GitBackendError::RefNotFound(rev.to_string())) } } /// Gets the last commit in a rev - pub fn get_last_commit_in_rev(git: &git2::Repository, rev: &str) -> anyhow::Result { - let oid = Self::get_oid_from_reference(git, Some(rev))?; + pub fn get_last_commit_in_rev( + git: &git2::Repository, + rev: &str, + default_branch: &DefaultBranch, + ) -> anyhow::Result { + let oid = Self::get_oid_from_reference(git, Some(rev), default_branch)?; // Walk through the repository commit graph starting at our rev let mut revwalk = git.revwalk()?; @@ -515,19 +520,25 @@ impl RepositoryBackend for GitBackend { async fn repository_file_inspect( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryFileInspectRequest, ) -> Result, Error> { + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; + let default_branch = repository_object + .get::(&operation_state) + .await?; // Try and find the tree_id/branch - let tree_id = match Self::get_oid_from_reference(&git, request.rev.as_deref()) { - Ok(oid) => oid, - Err(GitBackendError::HeadNotFound) => return Ok(vec![]), - Err(err) => return Err(err.into()), - }; + let tree_id = + match Self::get_oid_from_reference(&git, request.rev.as_deref(), &default_branch) { + Ok(oid) => oid, + Err(GitBackendError::HeadNotFound) => return Ok(vec![]), + Err(err) => return Err(err.into()), + }; // Get the commit from the oid let commit = match git.find_commit(tree_id) { @@ -620,9 +631,11 @@ impl RepositoryBackend for GitBackend { async fn repository_file_from_id( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(_operation_state): OperationState, request: &RepositoryFileFromIdRequest, ) -> Result { + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; @@ -652,14 +665,19 @@ impl RepositoryBackend for GitBackend { async fn repository_file_from_path( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryFileFromPathRequest, ) -> Result<(RepositoryFile, String), Error> { + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; - let tree_id = Self::get_oid_from_reference(&git, request.rev.as_deref())?; + let default_branch = repository_object + .get::(&operation_state) + .await?; + let tree_id = Self::get_oid_from_reference(&git, request.rev.as_deref(), &default_branch)?; // unwrap might be dangerous? // Get the commit from the oid @@ -700,9 +718,11 @@ impl RepositoryBackend for GitBackend { async fn repository_commit_from_id( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(_operation_state): OperationState, request: &RepositoryCommitFromIdRequest, ) -> Result { + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; @@ -722,9 +742,11 @@ impl RepositoryBackend for GitBackend { async fn repository_last_commit_of_file( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(_operation_state): OperationState, request: &RepositoryLastCommitOfFileRequest, ) -> Result { + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; @@ -748,17 +770,23 @@ impl RepositoryBackend for GitBackend { async fn repository_get_statistics( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryStatisticsRequest, ) -> Result { + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; - let tree_id = match Self::get_oid_from_reference(&git, request.rev.as_deref()) { - Ok(oid) => oid, - Err(_) => return Ok(RepositoryStatistics::default()), - }; + let default_branch = repository_object + .get::(&operation_state) + .await?; + let tree_id = + match Self::get_oid_from_reference(&git, request.rev.as_deref(), &default_branch) { + Ok(oid) => oid, + Err(_) => return Ok(RepositoryStatistics::default()), + }; // Count the amount of branches and tags let mut branches = 0; @@ -797,17 +825,16 @@ impl RepositoryBackend for GitBackend { OperationState(operation_state): OperationState, request: &RepositoryBranchesRequest, ) -> Result<(Vec, usize), Error> { - let repository: &Repository = repository_object.object(); + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; let default_branch_name = repository_object .get::(&operation_state) - .await? - .0; + .await?; let default_branch = git - .find_branch(&default_branch_name, BranchType::Local) + .find_branch(&default_branch_name.0, BranchType::Local) .map_err(|_| GitBackendError::DefaultNotFound)?; // Get the stale(after X seconds) setting @@ -828,9 +855,12 @@ impl RepositoryBackend for GitBackend { }; // TODO: Non UTF-8? - let Some(commit) = - GitBackend::get_last_commit_in_rev(&git, branch.get().name().unwrap()).ok() - else { + let Some(commit) = GitBackend::get_last_commit_in_rev( + &git, + branch.get().name().unwrap(), + &default_branch_name, + ) + .ok() else { return None; }; @@ -910,7 +940,7 @@ impl RepositoryBackend for GitBackend { OperationState(operation_state): OperationState, request: &RepositoryBranchRequest, ) -> Result { - let repository: &Repository = repository_object.object(); + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; @@ -919,10 +949,9 @@ impl RepositoryBackend for GitBackend { // Get the default branch to compare against let default_branch_name = repository_object .get::(&operation_state) - .await? - .0; + .await?; let default_branch = git - .find_branch(&default_branch_name, BranchType::Local) + .find_branch(&default_branch_name.0, BranchType::Local) .map_err(|_| GitBackendError::DefaultNotFound)?; // Find the requested branch @@ -938,8 +967,12 @@ impl RepositoryBackend for GitBackend { .0; // TODO: Non UTF-8? - let last_commit = - GitBackend::get_last_commit_in_rev(&git, branch.get().name().unwrap()).ok(); + let last_commit = GitBackend::get_last_commit_in_rev( + &git, + branch.get().name().unwrap(), + &default_branch_name, + ) + .ok(); let stale = if let Some(ref last_commit) = last_commit { chrono::Utc::now() @@ -981,7 +1014,7 @@ impl RepositoryBackend for GitBackend { OperationState(_operation_state): OperationState, request: &RepositoryTagsRequest, ) -> Result<(Vec, usize), Error> { - let repository: &Repository = repository_object.object(); + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; @@ -1100,9 +1133,11 @@ impl RepositoryBackend for GitBackend { async fn repository_diff( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(_operation_state): OperationState, request: &RepositoryDiffRequest, ) -> Result { + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; @@ -1229,9 +1264,11 @@ impl RepositoryBackend for GitBackend { async fn repository_diff_patch( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(_operation_state): OperationState, request: &RepositoryDiffPatchRequest, ) -> Result { + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; @@ -1284,9 +1321,11 @@ impl RepositoryBackend for GitBackend { async fn repository_commit_before( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(_operation_state): OperationState, request: &RepositoryCommitBeforeRequest, ) -> Result { + let repository = repository_object.object(); let git = self .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) .await?; diff --git a/giterated-daemon/src/backend/mod.rs b/giterated-daemon/src/backend/mod.rs index 907c363..28b3947 100644 --- a/giterated-daemon/src/backend/mod.rs +++ b/giterated-daemon/src/backend/mod.rs @@ -40,55 +40,64 @@ pub trait RepositoryBackend { async fn repository_file_inspect( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryFileInspectRequest, ) -> Result, Error>; async fn repository_file_from_id( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryFileFromIdRequest, ) -> Result; async fn repository_file_from_path( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryFileFromPathRequest, ) -> Result<(RepositoryFile, String), Error>; async fn repository_commit_from_id( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryCommitFromIdRequest, ) -> Result; async fn repository_last_commit_of_file( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryLastCommitOfFileRequest, ) -> Result; async fn repository_diff( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryDiffRequest, ) -> Result; async fn repository_diff_patch( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryDiffPatchRequest, ) -> Result; async fn repository_commit_before( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryCommitBeforeRequest, ) -> Result; async fn repository_get_statistics( &mut self, requester: &Option, - repository: &Repository, + repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>, + OperationState(operation_state): OperationState, request: &RepositoryStatisticsRequest, ) -> Result; async fn repository_get_branches( diff --git a/giterated-daemon/src/database_backend/handler.rs b/giterated-daemon/src/database_backend/handler.rs index 968791e..dbf9cca 100644 --- a/giterated-daemon/src/database_backend/handler.rs +++ b/giterated-daemon/src/database_backend/handler.rs @@ -69,7 +69,8 @@ pub async fn repository_info( let tree = repository_backend .repository_file_inspect( &requester, - object.object(), + &mut object, + OperationState(operation_state.clone()), &RepositoryFileInspectRequest { extra_metadata: operation.extra_metadata, path: operation.path.clone(), @@ -82,7 +83,8 @@ pub async fn repository_info( let statistics = repository_backend .repository_get_statistics( &requester, - object.object(), + &mut object, + OperationState(operation_state.clone()), &RepositoryStatisticsRequest { rev: operation.rev.clone(), }, @@ -121,7 +123,7 @@ pub async fn repository_get_statistics( backend: GiteratedStack, requester: Option, ) -> Result> { - let object = backend + let mut object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); @@ -130,7 +132,8 @@ pub async fn repository_get_statistics( let statistics = repository_backend .repository_get_statistics( &requester, - object.object(), + &mut object, + OperationState(operation_state), &RepositoryStatisticsRequest { rev: operation.rev.clone(), }, @@ -234,7 +237,7 @@ pub async fn repository_file_from_id( backend: GiteratedStack, requester: Option, ) -> Result> { - let object = backend + let mut object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); @@ -243,7 +246,8 @@ pub async fn repository_file_from_id( let file = repository_backend .repository_file_from_id( &requester, - object.object(), + &mut object, + OperationState(operation_state), &RepositoryFileFromIdRequest(operation.0.clone()), ) .await @@ -261,7 +265,7 @@ pub async fn repository_file_from_path( backend: GiteratedStack, requester: Option, ) -> Result<(RepositoryFile, String), OperationError> { - let object = backend + let mut object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); @@ -270,7 +274,8 @@ pub async fn repository_file_from_path( let file = repository_backend .repository_file_from_path( &requester, - object.object(), + &mut object, + OperationState(operation_state), &RepositoryFileFromPathRequest { rev: operation.rev.clone(), path: operation.path.clone(), @@ -291,7 +296,7 @@ pub async fn repository_last_commit_of_file( backend: GiteratedStack, requester: Option, ) -> Result> { - let object = backend + let mut object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); @@ -300,7 +305,8 @@ pub async fn repository_last_commit_of_file( let commit = repository_backend .repository_last_commit_of_file( &requester, - object.object(), + &mut object, + OperationState(operation_state), &RepositoryLastCommitOfFileRequest { start_commit: operation.start_commit.clone(), path: operation.path.clone(), @@ -321,7 +327,7 @@ pub async fn repository_commit_by_id( backend: GiteratedStack, requester: Option, ) -> Result> { - let object = backend + let mut object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); @@ -330,7 +336,8 @@ pub async fn repository_commit_by_id( let commit = repository_backend .repository_commit_from_id( &requester, - object.object(), + &mut object, + OperationState(operation_state), &RepositoryCommitFromIdRequest(operation.0.clone()), ) .await @@ -348,14 +355,19 @@ pub async fn repository_diff( backend: GiteratedStack, requester: Option, ) -> Result> { - let object = backend + let mut object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let diff = repository_backend - .repository_diff(&requester, object.object(), &operation) + .repository_diff( + &requester, + &mut object, + OperationState(operation_state), + &operation, + ) .await .as_internal_error()?; drop(repository_backend); @@ -371,14 +383,19 @@ pub async fn repository_diff_patch( backend: GiteratedStack, requester: Option, ) -> Result> { - let object = backend + let mut object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let patch = repository_backend - .repository_diff_patch(&requester, object.object(), &operation) + .repository_diff_patch( + &requester, + &mut object, + OperationState(operation_state), + &operation, + ) .await .as_internal_error()?; drop(repository_backend); @@ -394,14 +411,19 @@ pub async fn repository_commit_before( backend: GiteratedStack, requester: Option, ) -> Result> { - let object = backend + let mut object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let file = repository_backend - .repository_commit_before(&requester, object.object(), &operation) + .repository_commit_before( + &requester, + &mut object, + OperationState(operation_state), + &operation, + ) .await .as_internal_error()?; drop(repository_backend);