1
1
#![ forbid( unsafe_code, rust_2018_idioms) ]
2
2
3
3
use git_hash:: oid;
4
+ use git_index:: Entry ;
4
5
use git_object:: bstr:: ByteSlice ;
5
6
use quick_error:: quick_error;
6
- use std:: convert:: TryFrom ;
7
+ use std:: convert:: TryInto ;
7
8
use std:: fs:: { create_dir_all, OpenOptions } ;
8
9
use std:: io:: Write ;
9
10
use std:: path:: { Path , PathBuf } ;
@@ -46,13 +47,12 @@ where
46
47
{
47
48
let path = path. as_ref ( ) ;
48
49
let mut buf = Vec :: new ( ) ;
49
- let mut entry_time = Vec :: new ( ) ; // Entries whose timestamps have to be updated
50
- for ( i, entry) in index. entries ( ) . iter ( ) . enumerate ( ) {
50
+ for ( entry, entry_path) in index. entries_mut_with_paths ( ) {
51
51
if entry. flags . contains ( git_index:: entry:: Flags :: SKIP_WORKTREE ) {
52
52
continue ;
53
53
}
54
- let entry_path = entry . path ( index ) . to_path ( ) ? ;
55
- let dest = path. join ( entry_path) ;
54
+
55
+ let dest = path. join ( entry_path. to_path ( ) ? ) ; // TODO: try to use os_str_bytes to avoid UTF8 conversion. Put that into git-ref too
56
56
create_dir_all ( dest. parent ( ) . expect ( "entry paths are never empty" ) ) ?;
57
57
58
58
match entry. mode {
@@ -70,11 +70,12 @@ where
70
70
let met = file. metadata ( ) ?;
71
71
let ctime = met
72
72
. created ( )
73
- . map_or ( Ok ( Duration :: default ( ) ) , |x| x. duration_since ( std:: time:: UNIX_EPOCH ) ) ;
73
+ . map_or ( Ok ( Duration :: default ( ) ) , |x| x. duration_since ( std:: time:: UNIX_EPOCH ) ) ? ;
74
74
let mtime = met
75
75
. modified ( )
76
- . map_or ( Ok ( Duration :: default ( ) ) , |x| x. duration_since ( std:: time:: UNIX_EPOCH ) ) ;
77
- entry_time. push ( ( ctime?, mtime?, i) ) ;
76
+ . map_or ( Ok ( Duration :: default ( ) ) , |x| x. duration_since ( std:: time:: UNIX_EPOCH ) ) ?;
77
+
78
+ update_fstat ( entry, ctime, mtime) ?;
78
79
}
79
80
git_index:: entry:: Mode :: SYMLINK => {
80
81
let obj = find ( & entry. id , & mut buf) . ok_or_else ( || Error :: NotFound ( entry. id , path. to_path_buf ( ) ) ) ?;
@@ -96,25 +97,26 @@ where
96
97
let met = std:: fs:: symlink_metadata ( & dest) ?;
97
98
let ctime = met
98
99
. created ( )
99
- . map_or ( Ok ( Duration :: default ( ) ) , |x| x. duration_since ( std:: time:: UNIX_EPOCH ) ) ;
100
+ . map_or ( Ok ( Duration :: default ( ) ) , |x| x. duration_since ( std:: time:: UNIX_EPOCH ) ) ? ;
100
101
let mtime = met
101
102
. modified ( )
102
- . map_or ( Ok ( Duration :: default ( ) ) , |x| x. duration_since ( std:: time:: UNIX_EPOCH ) ) ;
103
- entry_time . push ( ( ctime? , mtime? , i ) ) ;
103
+ . map_or ( Ok ( Duration :: default ( ) ) , |x| x. duration_since ( std:: time:: UNIX_EPOCH ) ) ? ;
104
+ update_fstat ( entry , ctime , mtime ) ? ;
104
105
}
105
106
git_index:: entry:: Mode :: DIR => todo ! ( ) ,
106
107
git_index:: entry:: Mode :: COMMIT => todo ! ( ) ,
107
108
_ => unreachable ! ( ) ,
108
109
}
109
110
}
110
- let entries = index. entries_mut ( ) ;
111
- for ( ctime, mtime, i) in entry_time {
112
- let stat = & mut entries[ i] . stat ;
113
- stat. mtime . secs = u32:: try_from ( mtime. as_secs ( ) ) ?;
114
- stat. mtime . nsecs = mtime. subsec_nanos ( ) ;
115
- stat. ctime . secs = u32:: try_from ( ctime. as_secs ( ) ) ?;
116
- stat. ctime . nsecs = ctime. subsec_nanos ( ) ;
117
- }
111
+ Ok ( ( ) )
112
+ }
113
+
114
+ fn update_fstat ( entry : & mut Entry , ctime : Duration , mtime : Duration ) -> Result < ( ) , Error > {
115
+ let stat = & mut entry. stat ;
116
+ stat. mtime . secs = mtime. as_secs ( ) . try_into ( ) ?;
117
+ stat. mtime . nsecs = mtime. subsec_nanos ( ) ;
118
+ stat. ctime . secs = ctime. as_secs ( ) . try_into ( ) ?;
119
+ stat. ctime . nsecs = ctime. subsec_nanos ( ) ;
118
120
Ok ( ( ) )
119
121
}
120
122
0 commit comments