@@ -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,36 @@ 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
+ 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
+
119
150
pub fn file (
120
151
mut repo : gix:: Repository ,
121
152
out : & mut dyn std:: io:: Write ,
@@ -125,39 +156,27 @@ pub fn file(
125
156
repo. object_cache_size_if_unset ( repo. compute_object_cache_size_for_tree_diffs ( & * * repo. index_or_empty ( ) ?) ) ;
126
157
repo. objects . refresh = RefreshMode :: Never ;
127
158
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) ?;
137
161
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 } ;
144
163
145
164
let mut resource_cache = repo. diff_resource_cache (
146
165
gix:: diff:: blob:: pipeline:: Mode :: ToGitUnlessBinaryToTextIsPresent ,
147
- Default :: default ( ) ,
166
+ worktree_roots ,
148
167
) ?;
149
168
150
169
resource_cache. set_resource (
151
- old_blob_id. into ( ) ,
170
+ old_blob_id,
152
171
gix:: object:: tree:: EntryKind :: Blob ,
153
- old_path,
172
+ old_path. as_ref ( ) ,
154
173
gix:: diff:: blob:: ResourceKind :: OldOrSource ,
155
174
& repo. objects ,
156
175
) ?;
157
176
resource_cache. set_resource (
158
- new_blob_id. into ( ) ,
177
+ new_blob_id,
159
178
gix:: object:: tree:: EntryKind :: Blob ,
160
- new_path,
179
+ new_path. as_ref ( ) ,
161
180
gix:: diff:: blob:: ResourceKind :: NewOrDestination ,
162
181
& repo. objects ,
163
182
) ?;
0 commit comments