@@ -6,6 +6,7 @@ use gix::diff::blob::UnifiedDiff;
6
6
use gix:: objs:: tree:: EntryMode ;
7
7
use gix:: odb:: store:: RefreshMode ;
8
8
use gix:: prelude:: ObjectIdExt ;
9
+ use gix:: ObjectId ;
9
10
10
11
pub fn tree (
11
12
mut repo : gix:: Repository ,
@@ -116,6 +117,38 @@ fn typed_location(mut location: BString, mode: EntryMode) -> BString {
116
117
location
117
118
}
118
119
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
+ use std:: os:: unix:: ffi:: OsStrExt ;
131
+
132
+ let root: Option < std:: path:: PathBuf > = repo. workdir ( ) . map ( std:: path:: Path :: to_path_buf) ;
133
+ let name: BString = BString :: new ( name. as_os_str ( ) . as_bytes ( ) . to_vec ( ) ) ;
134
+
135
+ Ok ( ( ObjectId :: null ( gix:: hash:: Kind :: Sha1 ) , root, name) )
136
+ }
137
+ Err ( err) => Err ( err. into ( ) ) ,
138
+ Ok ( resolved_revspec) => {
139
+ let blob_id = resolved_revspec
140
+ . single ( )
141
+ . context ( format ! ( "rev-spec '{revspec}' must resolve to a single object" ) ) ?;
142
+
143
+ let ( path, _) = resolved_revspec
144
+ . path_and_mode ( )
145
+ . context ( format ! ( "rev-spec '{revspec}' must contain a path" ) ) ?;
146
+
147
+ Ok ( ( blob_id. into ( ) , None , path. into ( ) ) )
148
+ }
149
+ }
150
+ }
151
+
119
152
pub fn file (
120
153
mut repo : gix:: Repository ,
121
154
out : & mut dyn std:: io:: Write ,
@@ -125,39 +158,27 @@ pub fn file(
125
158
repo. object_cache_size_if_unset ( repo. compute_object_cache_size_for_tree_diffs ( & * * repo. index_or_empty ( ) ?) ) ;
126
159
repo. objects . refresh = RefreshMode :: Never ;
127
160
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" ) ) ?;
161
+ let ( old_blob_id, old_root, old_path) = resolve_revspec ( & repo, old_revspec) ?;
162
+ let ( new_blob_id, new_root, new_path) = resolve_revspec ( & repo, new_revspec) ?;
137
163
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" ) ) ?;
164
+ let worktree_roots = gix:: diff:: blob:: pipeline:: WorktreeRoots { old_root, new_root } ;
144
165
145
166
let mut resource_cache = repo. diff_resource_cache (
146
167
gix:: diff:: blob:: pipeline:: Mode :: ToGitUnlessBinaryToTextIsPresent ,
147
- Default :: default ( ) ,
168
+ worktree_roots ,
148
169
) ?;
149
170
150
171
resource_cache. set_resource (
151
- old_blob_id. into ( ) ,
172
+ old_blob_id,
152
173
gix:: object:: tree:: EntryKind :: Blob ,
153
- old_path,
174
+ old_path. as_ref ( ) ,
154
175
gix:: diff:: blob:: ResourceKind :: OldOrSource ,
155
176
& repo. objects ,
156
177
) ?;
157
178
resource_cache. set_resource (
158
- new_blob_id. into ( ) ,
179
+ new_blob_id,
159
180
gix:: object:: tree:: EntryKind :: Blob ,
160
- new_path,
181
+ new_path. as_ref ( ) ,
161
182
gix:: diff:: blob:: ResourceKind :: NewOrDestination ,
162
183
& repo. objects ,
163
184
) ?;
0 commit comments