@@ -32,6 +32,12 @@ actor! {
3232        /// The formats used to compress the tarball. 
3333         #[ arg( value_name = "FORMAT" ,  default_value_t) ] 
3434        compression_formats:  CompressionFormats , 
35+ 
36+         /// Modification time that will be set for all files added to the archive. 
37+          /// The default is the date of the first Rust commit from 2006. 
38+          /// This serves for better reproducibility of the archives. 
39+          #[ arg( value_name = "FILE_MTIME" ,  default_value_t = 1153704088 ) ] 
40+         override_file_mtime:  u64 , 
3541    } 
3642} 
3743
@@ -65,6 +71,8 @@ impl Tarballer {
6571        let  buf = BufWriter :: with_capacity ( 1024  *  1024 ,  encoder) ; 
6672        let  mut  builder = Builder :: new ( buf) ; 
6773        // Make uid, gid and mtime deterministic to improve reproducibility 
74+         // The modification time of directories will be set to the date of the first Rust commit 
75+         // The modification time of files will be set to `override_file_mtime` (see `append_path`). 
6876        builder. mode ( HeaderMode :: Deterministic ) ; 
6977
7078        let  pool = rayon:: ThreadPoolBuilder :: new ( ) . num_threads ( 2 ) . build ( ) . unwrap ( ) ; 
@@ -77,7 +85,7 @@ impl Tarballer {
7785            } 
7886            for  path in  files { 
7987                let  src = Path :: new ( & self . work_dir ) . join ( & path) ; 
80-                 append_path ( & mut  builder,  & src,  & path) 
88+                 append_path ( & mut  builder,  & src,  & path,   self . override_file_mtime ) 
8189                    . with_context ( || format ! ( "failed to tar file '{}'" ,  src. display( ) ) ) ?; 
8290            } 
8391            builder
@@ -93,10 +101,16 @@ impl Tarballer {
93101    } 
94102} 
95103
96- fn  append_path < W :  Write > ( builder :  & mut  Builder < W > ,  src :  & Path ,  path :  & String )  -> Result < ( ) >  { 
104+ fn  append_path < W :  Write > ( 
105+     builder :  & mut  Builder < W > , 
106+     src :  & Path , 
107+     path :  & String , 
108+     override_file_mtime :  u64 , 
109+ )  -> Result < ( ) >  { 
97110    let  stat = symlink_metadata ( src) ?; 
98111    let  mut  header = Header :: new_gnu ( ) ; 
99112    header. set_metadata_in_mode ( & stat,  HeaderMode :: Deterministic ) ; 
113+     header. set_mtime ( override_file_mtime) ; 
100114
101115    if  stat. file_type ( ) . is_symlink ( )  { 
102116        let  link = read_link ( src) ?; 
0 commit comments