33#include "csum-file.h"
44#include "remote.h"
55#include "chunk-format.h"
6+ #include "pack-mtimes.h"
7+ #include "oidmap.h"
8+ #include "chunk-format.h"
9+ #include "pack-objects.h"
610
711void reset_pack_idx_option (struct pack_idx_option * opts )
812{
@@ -276,6 +280,70 @@ const char *write_rev_file_order(const char *rev_name,
276280 return rev_name ;
277281}
278282
283+ static void write_mtimes_header (struct hashfile * f )
284+ {
285+ hashwrite_be32 (f , MTIMES_SIGNATURE );
286+ hashwrite_be32 (f , MTIMES_VERSION );
287+ hashwrite_be32 (f , oid_version (the_hash_algo ));
288+ }
289+
290+ /*
291+ * Writes the object mtimes of "objects" for use in a .mtimes file.
292+ * Note that objects must be in lexicographic (index) order, which is
293+ * the expected ordering of these values in the .mtimes file.
294+ */
295+ static void write_mtimes_objects (struct hashfile * f ,
296+ struct packing_data * to_pack ,
297+ struct pack_idx_entry * * objects ,
298+ uint32_t nr_objects )
299+ {
300+ uint32_t i ;
301+ for (i = 0 ; i < nr_objects ; i ++ ) {
302+ struct object_entry * e = (struct object_entry * )objects [i ];
303+ hashwrite_be32 (f , oe_cruft_mtime (to_pack , e ));
304+ }
305+ }
306+
307+ static void write_mtimes_trailer (struct hashfile * f , const unsigned char * hash )
308+ {
309+ hashwrite (f , hash , the_hash_algo -> rawsz );
310+ }
311+
312+ static const char * write_mtimes_file (const char * mtimes_name ,
313+ struct packing_data * to_pack ,
314+ struct pack_idx_entry * * objects ,
315+ uint32_t nr_objects ,
316+ const unsigned char * hash )
317+ {
318+ struct hashfile * f ;
319+ int fd ;
320+
321+ if (!to_pack )
322+ BUG ("cannot call write_mtimes_file with NULL packing_data" );
323+
324+ if (!mtimes_name ) {
325+ struct strbuf tmp_file = STRBUF_INIT ;
326+ fd = odb_mkstemp (& tmp_file , "pack/tmp_mtimes_XXXXXX" );
327+ mtimes_name = strbuf_detach (& tmp_file , NULL );
328+ } else {
329+ unlink (mtimes_name );
330+ fd = xopen (mtimes_name , O_CREAT |O_EXCL |O_WRONLY , 0600 );
331+ }
332+ f = hashfd (fd , mtimes_name );
333+
334+ write_mtimes_header (f );
335+ write_mtimes_objects (f , to_pack , objects , nr_objects );
336+ write_mtimes_trailer (f , hash );
337+
338+ if (adjust_shared_perm (mtimes_name ) < 0 )
339+ die (_ ("failed to make %s readable" ), mtimes_name );
340+
341+ finalize_hashfile (f , NULL ,
342+ CSUM_HASH_IN_STREAM | CSUM_CLOSE | CSUM_FSYNC );
343+
344+ return mtimes_name ;
345+ }
346+
279347off_t write_pack_header (struct hashfile * f , uint32_t nr_entries )
280348{
281349 struct pack_header hdr ;
@@ -478,6 +546,7 @@ void stage_tmp_packfiles(struct strbuf *name_buffer,
478546 char * * idx_tmp_name )
479547{
480548 const char * rev_tmp_name = NULL ;
549+ const char * mtimes_tmp_name = NULL ;
481550
482551 if (adjust_shared_perm (pack_tmp_name ))
483552 die_errno ("unable to make temporary pack file readable" );
@@ -490,9 +559,17 @@ void stage_tmp_packfiles(struct strbuf *name_buffer,
490559 rev_tmp_name = write_rev_file (NULL , written_list , nr_written , hash ,
491560 pack_idx_opts -> flags );
492561
562+ if (pack_idx_opts -> flags & WRITE_MTIMES ) {
563+ mtimes_tmp_name = write_mtimes_file (NULL , to_pack , written_list ,
564+ nr_written ,
565+ hash );
566+ }
567+
493568 rename_tmp_packfile (name_buffer , pack_tmp_name , "pack" );
494569 if (rev_tmp_name )
495570 rename_tmp_packfile (name_buffer , rev_tmp_name , "rev" );
571+ if (mtimes_tmp_name )
572+ rename_tmp_packfile (name_buffer , mtimes_tmp_name , "mtimes" );
496573}
497574
498575void write_promisor_file (const char * promisor_name , struct ref * * sought , int nr_sought )
0 commit comments