1
1
use anyhow:: bail;
2
- use std:: path:: Path ;
2
+ use std:: path:: { Path , PathBuf } ;
3
3
4
4
use git_repository as git;
5
- use git_repository:: Progress ;
5
+ use git_repository:: { odb :: FindExt , Progress } ;
6
6
7
7
pub struct Options {
8
8
pub object_hash : git:: hash:: Kind ,
@@ -104,9 +104,14 @@ fn parse_file(index_path: impl AsRef<Path>, object_hash: git::hash::Kind) -> any
104
104
pub fn checkout_exclusive (
105
105
index_path : impl AsRef < Path > ,
106
106
dest_directory : impl AsRef < Path > ,
107
+ repo : Option < PathBuf > ,
107
108
mut progress : impl Progress ,
108
109
Options { object_hash, .. } : Options ,
109
110
) -> anyhow:: Result < ( ) > {
111
+ let repo = repo
112
+ . map ( |dir| git_repository:: discover ( dir) . map ( |r| r. apply_environment ( ) ) )
113
+ . transpose ( ) ?;
114
+
110
115
let dest_directory = dest_directory. as_ref ( ) ;
111
116
if dest_directory. exists ( ) {
112
117
bail ! (
@@ -119,9 +124,14 @@ pub fn checkout_exclusive(
119
124
let mut index = parse_file ( index_path, object_hash) ?;
120
125
121
126
let mut num_skipped = 0 ;
127
+ let maybe_symlink_mode = if repo. is_some ( ) {
128
+ git:: index:: entry:: Mode :: DIR
129
+ } else {
130
+ git:: index:: entry:: Mode :: SYMLINK
131
+ } ;
122
132
for entry in index. entries_mut ( ) . iter_mut ( ) . filter ( |e| {
123
133
e. mode
124
- . contains ( git :: index :: entry :: Mode :: DIR | git:: index:: entry:: Mode :: SYMLINK | git:: index:: entry:: Mode :: COMMIT )
134
+ . contains ( maybe_symlink_mode | git:: index:: entry:: Mode :: DIR | git:: index:: entry:: Mode :: COMMIT )
125
135
} ) {
126
136
entry. flags . insert ( git:: index:: entry:: Flags :: SKIP_WORKTREE ) ;
127
137
num_skipped += 1 ;
@@ -147,21 +157,35 @@ pub fn checkout_exclusive(
147
157
bytes. init ( Some ( entries_for_checkout) , git:: progress:: bytes ( ) ) ;
148
158
149
159
let start = std:: time:: Instant :: now ( ) ;
150
- git:: worktree:: index:: checkout (
151
- & mut index,
152
- dest_directory,
153
- |_, buf| {
154
- buf. clear ( ) ;
155
- Some ( git:: objs:: BlobRef { data : buf } )
156
- } ,
157
- & mut files,
158
- & mut bytes,
159
- opts,
160
- ) ?;
160
+ match & repo {
161
+ Some ( repo) => git:: worktree:: index:: checkout (
162
+ & mut index,
163
+ dest_directory,
164
+ |oid, buf| repo. objects . find_blob ( oid, buf) . ok ( ) ,
165
+ & mut files,
166
+ & mut bytes,
167
+ opts,
168
+ ) ,
169
+ None => git:: worktree:: index:: checkout (
170
+ & mut index,
171
+ dest_directory,
172
+ |_, buf| {
173
+ buf. clear ( ) ;
174
+ Some ( git:: objs:: BlobRef { data : buf } )
175
+ } ,
176
+ & mut files,
177
+ & mut bytes,
178
+ opts,
179
+ ) ,
180
+ } ?;
161
181
162
182
files. show_throughput ( start) ;
163
183
bytes. show_throughput ( start) ;
164
184
165
- progress. done ( format ! ( "Created {} empty files" , entries_for_checkout) ) ;
185
+ progress. done ( format ! (
186
+ "Created {} {} files" ,
187
+ entries_for_checkout,
188
+ repo. is_none( ) . then( || "empty" ) . unwrap_or_default( )
189
+ ) ) ;
166
190
Ok ( ( ) )
167
191
}
0 commit comments