@@ -19,7 +19,6 @@ use crate::{
1919 diff:: * ,
2020 file_system,
2121 file_system:: { directory, DirectoryContents , Label } ,
22- vcs,
2322 vcs:: git:: {
2423 error:: * ,
2524 reference:: { glob:: RefGlob , Ref , Rev } ,
@@ -35,7 +34,6 @@ use crate::{
3534 } ,
3635} ;
3736use directory:: Directory ;
38- use nonempty:: NonEmpty ;
3937use radicle_git_ext:: Oid ;
4038use std:: {
4139 collections:: { BTreeSet , HashSet } ,
@@ -51,7 +49,7 @@ pub(super) enum CommitHistory {
5149}
5250
5351/// A `History` that uses `git2::Commit` as the underlying artifact.
54- pub type History = vcs:: History < Commit > ;
52+ pub type History = crate :: vcs:: History < Commit > ;
5553
5654/// Wrapper around the `git2`'s `git2::Repository` type.
5755/// This is to to limit the functionality that we can do
@@ -142,18 +140,6 @@ impl<'a> RepositoryRef<'a> {
142140 Ok ( namespaces?. into_iter ( ) . collect ( ) )
143141 }
144142
145- pub ( super ) fn ref_history < R > ( & self , reference : R ) -> Result < History , Error >
146- where
147- R : Into < Ref > ,
148- {
149- let reference = match self . which_namespace ( ) ? {
150- None => reference. into ( ) ,
151- Some ( namespace) => reference. into ( ) . namespaced ( namespace) ,
152- }
153- . find_ref ( self ) ?;
154- self . to_history ( & reference)
155- }
156-
157143 /// Get the [`Diff`] between two commits.
158144 pub fn diff ( & self , from : & Rev , to : & Rev ) -> Result < Diff , Error > {
159145 let from_commit = self . rev_to_commit ( from) ?;
@@ -169,6 +155,19 @@ impl<'a> RepositoryRef<'a> {
169155 . and_then ( |diff| Diff :: try_from ( diff) . map_err ( Error :: from) )
170156 }
171157
158+ /// Get the diff introduced by a particlar rev.
159+ pub fn diff_of_rev ( & self , rev : & Rev ) -> Result < Diff , Error > {
160+ let oid = self . rev_oid ( rev) ?;
161+ let commit = self . get_commit ( oid) ?;
162+ match commit. parents . first ( ) {
163+ Some ( parent) => {
164+ let parent_rev = ( * parent) . into ( ) ;
165+ self . diff ( & parent_rev, rev)
166+ } ,
167+ None => self . initial_diff ( rev) ,
168+ }
169+ }
170+
172171 /// Parse an [`Oid`] from the given string.
173172 pub fn oid ( & self , oid : & str ) -> Result < Oid , Error > {
174173 Ok ( self . repo_ref . revparse_single ( oid) ?. id ( ) . into ( ) )
@@ -198,7 +197,7 @@ impl<'a> RepositoryRef<'a> {
198197 /// Gets stats of `rev`.
199198 pub fn get_stats ( & self , rev : & Rev ) -> Result < Stats , Error > {
200199 let branches = self . list_branches ( RefScope :: Local ) ?. len ( ) ;
201- let history = self . history ( rev. clone ( ) ) ?;
200+ let history = self . history ( rev) ?;
202201 let commits = history. len ( ) ;
203202
204203 let contributors = history
@@ -256,10 +255,19 @@ impl<'a> RepositoryRef<'a> {
256255 pub ( super ) fn rev_to_commit ( & self , rev : & Rev ) -> Result < git2:: Commit , Error > {
257256 match rev {
258257 Rev :: Oid ( oid) => Ok ( self . repo_ref . find_commit ( ( * oid) . into ( ) ) ?) ,
259- Rev :: Ref ( reference) => Ok ( reference . find_ref ( self ) ?. peel_to_commit ( ) ?) ,
258+ Rev :: Ref ( reference) => Ok ( self . find_git2_ref ( reference ) ?. peel_to_commit ( ) ?) ,
260259 }
261260 }
262261
262+ fn find_git2_ref ( & self , reference : & Ref ) -> Result < git2:: Reference < ' _ > , Error > {
263+ let reference = match self . which_namespace ( ) ? {
264+ None => reference. clone ( ) ,
265+ Some ( namespace) => reference. clone ( ) . namespaced ( namespace) ,
266+ } ;
267+ let git2_ref = self . repo_ref . find_reference ( & reference. to_string ( ) ) ?;
268+ Ok ( git2_ref)
269+ }
270+
263271 /// Switch to a `namespace`
264272 pub fn switch_namespace ( & self , namespace : & str ) -> Result < ( ) , Error > {
265273 Ok ( self . repo_ref . set_namespace ( namespace) ?)
@@ -271,18 +279,11 @@ impl<'a> RepositoryRef<'a> {
271279 Ok ( commit)
272280 }
273281
274- /// Turn a [`git2::Reference`] into a [`History`] by completing
275- /// a revwalk over the first commit in the reference.
276- pub ( super ) fn to_history ( & self , history : & git2:: Reference < ' a > ) -> Result < History , Error > {
277- let head = history. peel_to_commit ( ) ?;
278- self . commit_to_history ( head)
279- }
280-
281282 /// Turn a [`git2::Reference`] into a [`History`] by completing
282283 /// a revwalk over the first commit in the reference.
283284 pub ( super ) fn commit_to_history ( & self , head : git2:: Commit ) -> Result < History , Error > {
284285 let head_id = head. id ( ) ;
285- let mut commits = NonEmpty :: new ( Commit :: try_from ( head) ?) ;
286+ let mut commits = History :: new ( Commit :: try_from ( head) ?) ;
286287 let mut revwalk = self . repo_ref . revwalk ( ) ?;
287288
288289 // Set the revwalk to the head commit
@@ -302,7 +303,7 @@ impl<'a> RepositoryRef<'a> {
302303 commits. push ( commit) ;
303304 }
304305
305- Ok ( vcs :: History ( commits) )
306+ Ok ( commits)
306307 }
307308
308309 /// Extract the signature from a commit
@@ -531,14 +532,9 @@ impl<'a> RepositoryRef<'a> {
531532 }
532533
533534 /// Returns the history of `rev`.
534- pub fn history ( & self , rev : Rev ) -> Result < History , Error > {
535- match rev {
536- Rev :: Ref ( reference) => self . ref_history ( reference) ,
537- Rev :: Oid ( oid) => {
538- let commit = self . get_git2_commit ( oid) ?;
539- self . commit_to_history ( commit)
540- } ,
541- }
535+ pub fn history ( & self , rev : & Rev ) -> Result < History , Error > {
536+ let commit = self . rev_to_commit ( rev) ?;
537+ self . commit_to_history ( commit)
542538 }
543539}
544540
@@ -562,7 +558,7 @@ impl Repository {
562558
563559 /// Since our operations are read-only when it comes to surfing a repository
564560 /// we have a separate struct called [`RepositoryRef`]. This turns an owned
565- /// [`Repository`], the one returend by [`Repository::new`], into a
561+ /// [`Repository`], the one returned by [`Repository::new`], into a
566562 /// [`RepositoryRef`].
567563 pub fn as_ref ( & ' _ self ) -> RepositoryRef < ' _ > {
568564 RepositoryRef { repo_ref : & self . 0 }
0 commit comments