@@ -68,6 +68,13 @@ struct packed_ref_store {
68
68
* thus the enclosing `packed_ref_store`) must not be freed.
69
69
*/
70
70
struct lock_file lock ;
71
+
72
+ /*
73
+ * Temporary file used when rewriting new contents to the
74
+ * "packed-refs" file. Note that this (and thus the enclosing
75
+ * `packed_ref_store`) must not be freed.
76
+ */
77
+ struct tempfile tempfile ;
71
78
};
72
79
73
80
struct ref_store * packed_ref_store_create (const char * path ,
@@ -522,10 +529,16 @@ int lock_packed_refs(struct ref_store *ref_store, int flags)
522
529
timeout_configured = 1 ;
523
530
}
524
531
532
+ /*
533
+ * Note that we close the lockfile immediately because we
534
+ * don't write new content to it, but rather to a separate
535
+ * tempfile.
536
+ */
525
537
if (hold_lock_file_for_update_timeout (
526
538
& refs -> lock ,
527
539
refs -> path ,
528
- flags , timeout_value ) < 0 )
540
+ flags , timeout_value ) < 0 ||
541
+ close_lock_file (& refs -> lock ))
529
542
return -1 ;
530
543
531
544
/*
@@ -567,13 +580,23 @@ int commit_packed_refs(struct ref_store *ref_store, struct strbuf *err)
567
580
get_packed_ref_cache (refs );
568
581
int ok ;
569
582
int ret = -1 ;
583
+ struct strbuf sb = STRBUF_INIT ;
570
584
FILE * out ;
571
585
struct ref_iterator * iter ;
572
586
573
587
if (!is_lock_file_locked (& refs -> lock ))
574
588
die ("BUG: commit_packed_refs() called when unlocked" );
575
589
576
- out = fdopen_lock_file (& refs -> lock , "w" );
590
+ strbuf_addf (& sb , "%s.new" , refs -> path );
591
+ if (create_tempfile (& refs -> tempfile , sb .buf ) < 0 ) {
592
+ strbuf_addf (err , "unable to create file %s: %s" ,
593
+ sb .buf , strerror (errno ));
594
+ strbuf_release (& sb );
595
+ goto out ;
596
+ }
597
+ strbuf_release (& sb );
598
+
599
+ out = fdopen_tempfile (& refs -> tempfile , "w" );
577
600
if (!out ) {
578
601
strbuf_addf (err , "unable to fdopen packed-refs tempfile: %s" ,
579
602
strerror (errno ));
@@ -582,7 +605,7 @@ int commit_packed_refs(struct ref_store *ref_store, struct strbuf *err)
582
605
583
606
if (fprintf (out , "%s" , PACKED_REFS_HEADER ) < 0 ) {
584
607
strbuf_addf (err , "error writing to %s: %s" ,
585
- get_lock_file_path (& refs -> lock ), strerror (errno ));
608
+ get_tempfile_path (& refs -> tempfile ), strerror (errno ));
586
609
goto error ;
587
610
}
588
611
@@ -594,21 +617,21 @@ int commit_packed_refs(struct ref_store *ref_store, struct strbuf *err)
594
617
if (write_packed_entry (out , iter -> refname , iter -> oid -> hash ,
595
618
peel_error ? NULL : peeled .hash )) {
596
619
strbuf_addf (err , "error writing to %s: %s" ,
597
- get_lock_file_path (& refs -> lock ),
620
+ get_tempfile_path (& refs -> tempfile ),
598
621
strerror (errno ));
599
622
ref_iterator_abort (iter );
600
623
goto error ;
601
624
}
602
625
}
603
626
604
627
if (ok != ITER_DONE ) {
605
- strbuf_addf (err , "unable to write packed-refs file: "
628
+ strbuf_addf (err , "unable to rewrite packed-refs file: "
606
629
"error iterating over old contents" );
607
630
goto error ;
608
631
}
609
632
610
- if (commit_lock_file (& refs -> lock )) {
611
- strbuf_addf (err , "error overwriting %s: %s" ,
633
+ if (rename_tempfile (& refs -> tempfile , refs -> path )) {
634
+ strbuf_addf (err , "error replacing %s: %s" ,
612
635
refs -> path , strerror (errno ));
613
636
goto out ;
614
637
}
@@ -617,9 +640,10 @@ int commit_packed_refs(struct ref_store *ref_store, struct strbuf *err)
617
640
goto out ;
618
641
619
642
error :
620
- rollback_lock_file (& refs -> lock );
643
+ delete_tempfile (& refs -> tempfile );
621
644
622
645
out :
646
+ rollback_lock_file (& refs -> lock );
623
647
release_packed_ref_cache (packed_ref_cache );
624
648
return ret ;
625
649
}
0 commit comments