@@ -6,6 +6,7 @@ use gix::diff::blob::UnifiedDiff;
66use gix:: objs:: tree:: EntryMode ;
77use gix:: odb:: store:: RefreshMode ;
88use gix:: prelude:: ObjectIdExt ;
9+ use gix:: ObjectId ;
910
1011pub fn tree (
1112 mut repo : gix:: Repository ,
@@ -116,6 +117,36 @@ fn typed_location(mut location: BString, mode: EntryMode) -> BString {
116117 location
117118}
118119
120+ fn resolve_revspec (
121+ repo : & gix:: Repository ,
122+ revspec : BString ,
123+ ) -> Result < ( ObjectId , Option < std:: path:: PathBuf > , BString ) , anyhow:: Error > {
124+ let result = repo. rev_parse ( revspec. as_bstr ( ) ) ;
125+
126+ match result {
127+ Err ( gix:: revision:: spec:: parse:: Error :: FindReference ( gix:: refs:: file:: find:: existing:: Error :: NotFound {
128+ name,
129+ } ) ) => {
130+ let root = repo. workdir ( ) . map ( ToOwned :: to_owned) ;
131+ let name = gix:: path:: os_string_into_bstring ( name. into ( ) ) ?;
132+
133+ Ok ( ( ObjectId :: null ( gix:: hash:: Kind :: Sha1 ) , root, name) )
134+ }
135+ Err ( err) => Err ( err. into ( ) ) ,
136+ Ok ( resolved_revspec) => {
137+ let blob_id = resolved_revspec
138+ . single ( )
139+ . context ( format ! ( "rev-spec '{revspec}' must resolve to a single object" ) ) ?;
140+
141+ let ( path, _) = resolved_revspec
142+ . path_and_mode ( )
143+ . context ( format ! ( "rev-spec '{revspec}' must contain a path" ) ) ?;
144+
145+ Ok ( ( blob_id. into ( ) , None , path. into ( ) ) )
146+ }
147+ }
148+ }
149+
119150pub fn file (
120151 mut repo : gix:: Repository ,
121152 out : & mut dyn std:: io:: Write ,
@@ -125,39 +156,27 @@ pub fn file(
125156 repo. object_cache_size_if_unset ( repo. compute_object_cache_size_for_tree_diffs ( & * * repo. index_or_empty ( ) ?) ) ;
126157 repo. objects . refresh = RefreshMode :: Never ;
127158
128- let old_resolved_revspec = repo. rev_parse ( old_revspec. as_bstr ( ) ) ?;
129- let new_resolved_revspec = repo. rev_parse ( new_revspec. as_bstr ( ) ) ?;
130-
131- let old_blob_id = old_resolved_revspec
132- . single ( )
133- . context ( format ! ( "rev-spec '{old_revspec}' must resolve to a single object" ) ) ?;
134- let new_blob_id = new_resolved_revspec
135- . single ( )
136- . context ( format ! ( "rev-spec '{new_revspec}' must resolve to a single object" ) ) ?;
159+ let ( old_blob_id, old_root, old_path) = resolve_revspec ( & repo, old_revspec) ?;
160+ let ( new_blob_id, new_root, new_path) = resolve_revspec ( & repo, new_revspec) ?;
137161
138- let ( old_path, _) = old_resolved_revspec
139- . path_and_mode ( )
140- . context ( format ! ( "rev-spec '{old_revspec}' must contain a path" ) ) ?;
141- let ( new_path, _) = new_resolved_revspec
142- . path_and_mode ( )
143- . context ( format ! ( "rev-spec '{new_revspec}' must contain a path" ) ) ?;
162+ let worktree_roots = gix:: diff:: blob:: pipeline:: WorktreeRoots { old_root, new_root } ;
144163
145164 let mut resource_cache = repo. diff_resource_cache (
146165 gix:: diff:: blob:: pipeline:: Mode :: ToGitUnlessBinaryToTextIsPresent ,
147- Default :: default ( ) ,
166+ worktree_roots ,
148167 ) ?;
149168
150169 resource_cache. set_resource (
151- old_blob_id. into ( ) ,
170+ old_blob_id,
152171 gix:: object:: tree:: EntryKind :: Blob ,
153- old_path,
172+ old_path. as_ref ( ) ,
154173 gix:: diff:: blob:: ResourceKind :: OldOrSource ,
155174 & repo. objects ,
156175 ) ?;
157176 resource_cache. set_resource (
158- new_blob_id. into ( ) ,
177+ new_blob_id,
159178 gix:: object:: tree:: EntryKind :: Blob ,
160- new_path,
179+ new_path. as_ref ( ) ,
161180 gix:: diff:: blob:: ResourceKind :: NewOrDestination ,
162181 & repo. objects ,
163182 ) ?;
0 commit comments