JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Move towards having GitBackend split into files

Emilia - ⁨1⁩ year ago

parent: tbd commit: ⁨e55da0e

⁨giterated-daemon/src/backend/git/commit.rs⁩ - ⁨4516⁩ bytes
Raw
1 use anyhow::Error;
2 use giterated_models::{
3 object::Object,
4 repository::{
5 Commit, DefaultBranch, Repository, RepositoryCommitBeforeRequest,
6 RepositoryCommitFromIdRequest,
7 },
8 };
9 use giterated_stack::{AuthenticatedUser, GiteratedStack, OperationState, StackOperationState};
10
11 use super::{GitBackend, GitBackendError};
12
13 impl GitBackend {
14 /// Gets the total amount of commits using revwalk
15 pub fn get_total_commit_count(
16 git: &git2::Repository,
17 start_commit: &git2::Commit,
18 ) -> anyhow::Result<usize> {
19 // TODO: There must be a better way
20 let mut revwalk = git.revwalk()?;
21 revwalk.set_sorting(git2::Sort::TIME)?;
22 revwalk.push(start_commit.id())?;
23
24 Ok(revwalk.count())
25 }
26
27 /// Gets the last commit in a rev
28 pub fn get_last_commit_in_rev(
29 git: &git2::Repository,
30 rev: &str,
31 default_branch: &DefaultBranch,
32 ) -> anyhow::Result<Commit> {
33 let oid = Self::get_oid_from_reference(git, Some(rev), default_branch)?;
34
35 // Walk through the repository commit graph starting at our rev
36 let mut revwalk = git.revwalk()?;
37 revwalk.set_sorting(git2::Sort::TIME)?;
38 revwalk.push(oid)?;
39
40 if let Some(Ok(commit_oid)) = revwalk.next() {
41 if let Ok(commit) = git
42 .find_commit(commit_oid)
43 .map_err(|_| GitBackendError::CommitNotFound(commit_oid.to_string()))
44 {
45 return Ok(Commit::from(commit));
46 }
47 }
48
49 Err(GitBackendError::RefNotFound(oid.to_string()).into())
50 }
51
52 pub async fn handle_repository_commit_from_id(
53 &mut self,
54 requester: &Option<AuthenticatedUser>,
55 repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>,
56 OperationState(_operation_state): OperationState<StackOperationState>,
57 request: &RepositoryCommitFromIdRequest,
58 ) -> Result<Commit, Error> {
59 let repository = repository_object.object();
60 let git = self
61 .open_repository_and_check_permissions(&repository.owner, &repository.name, requester)
62 .await?;
63
64 // Parse the passed object ids
65 let oid = git2::Oid::from_str(request.0.as_str())
66 .map_err(|_| GitBackendError::InvalidObjectId(request.0.clone()))?;
67
68 // Get the commit from the oid
69 let commit = git
70 .find_commit(oid)
71 .map_err(|_| GitBackendError::CommitNotFound(oid.to_string()))?;
72
73 Ok(Commit::from(commit))
74 }
75
76 pub async fn handle_repository_commit_before(
77 &mut self,
78 requester: &Option<AuthenticatedUser>,
79 repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>,
80 OperationState(_operation_state): OperationState<StackOperationState>,
81 request: &RepositoryCommitBeforeRequest,
82 ) -> Result<Commit, Error> {
83 let repository = repository_object.object();
84 let git = self
85 .open_repository_and_check_permissions(&repository.owner, &repository.name, requester)
86 .await?;
87
88 // Parse the passed object id
89 let oid = match git2::Oid::from_str(request.0.as_str()) {
90 Ok(oid) => oid,
91 Err(_) => {
92 return Err(Box::new(GitBackendError::InvalidObjectId(request.0.clone())).into())
93 }
94 };
95
96 // Find the commit using the parsed oid
97 let commit = match git.find_commit(oid) {
98 Ok(commit) => commit,
99 Err(_) => return Err(Box::new(GitBackendError::CommitNotFound(oid.to_string())).into()),
100 };
101
102 // Get the first parent it has
103 let parent = commit.parent(0);
104 if let Ok(parent) = parent {
105 return Ok(Commit::from(parent));
106 } else {
107 // TODO: See if can be done better
108 // Walk through the repository commit graph starting at our current commit
109 let mut revwalk = git.revwalk()?;
110 revwalk.set_sorting(git2::Sort::TIME)?;
111 revwalk.push(commit.id())?;
112
113 if let Some(Ok(before_commit_oid)) = revwalk.next() {
114 // Find the commit using the parsed oid
115 if let Ok(before_commit) = git.find_commit(before_commit_oid) {
116 return Ok(Commit::from(before_commit));
117 }
118 }
119
120 Err(Box::new(GitBackendError::CommitParentNotFound(oid.to_string())).into())
121 }
122 }
123 }
124