Coverage Report

Created: 2026-10-17 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/pack-write.c
Line
Count
Source
1
#include "git-compat-util.h"
2
#include "environment.h"
3
#include "gettext.h"
4
#include "hex.h"
5
#include "pack.h"
6
#include "csum-file.h"
7
#include "remote.h"
8
#include "chunk-format.h"
9
#include "object-file.h"
10
#include "pack-mtimes.h"
11
#include "pack-objects.h"
12
#include "pack-revindex.h"
13
#include "path.h"
14
#include "repository.h"
15
#include "strbuf.h"
16
17
void reset_pack_idx_option(struct pack_idx_option *opts)
18
0
{
19
0
  memset(opts, 0, sizeof(*opts));
20
0
  opts->version = 2;
21
0
  opts->off32_limit = 0x7fffffff;
22
0
  opts->delta_base_cache_limit = DEFAULT_DELTA_BASE_CACHE_LIMIT;
23
0
}
24
25
static int sha1_compare(const void *_a, const void *_b)
26
0
{
27
0
  struct pack_idx_entry *a = *(struct pack_idx_entry **)_a;
28
0
  struct pack_idx_entry *b = *(struct pack_idx_entry **)_b;
29
0
  return oidcmp(&a->oid, &b->oid);
30
0
}
31
32
static int cmp_uint32(const void *a_, const void *b_)
33
0
{
34
0
  uint32_t a = *((uint32_t *)a_);
35
0
  uint32_t b = *((uint32_t *)b_);
36
37
0
  return (a < b) ? -1 : (a != b);
38
0
}
39
40
static int need_large_offset(off_t offset, const struct pack_idx_option *opts)
41
0
{
42
0
  uint32_t ofsval;
43
44
0
  if ((offset >> 31) || (opts->off32_limit < offset))
45
0
    return 1;
46
0
  if (!opts->anomaly_nr)
47
0
    return 0;
48
0
  ofsval = offset;
49
0
  return !!bsearch(&ofsval, opts->anomaly, opts->anomaly_nr,
50
0
       sizeof(ofsval), cmp_uint32);
51
0
}
52
53
/*
54
 * The *sha1 contains the pack content SHA1 hash.
55
 * The objects array passed in will be sorted by SHA1 on exit.
56
 */
57
const char *write_idx_file(struct repository *repo,
58
         const char *index_name, struct pack_idx_entry **objects,
59
         int nr_objects, const struct pack_idx_option *opts,
60
         const unsigned char *sha1)
61
0
{
62
0
  struct hashfile *f;
63
0
  struct pack_idx_entry **sorted_by_sha, **list, **last;
64
0
  off_t last_obj_offset = 0;
65
0
  int i, fd;
66
0
  uint32_t index_version;
67
68
0
  if (nr_objects) {
69
0
    sorted_by_sha = objects;
70
0
    list = sorted_by_sha;
71
0
    last = sorted_by_sha + nr_objects;
72
0
    for (i = 0; i < nr_objects; ++i) {
73
0
      if (objects[i]->offset > last_obj_offset)
74
0
        last_obj_offset = objects[i]->offset;
75
0
    }
76
0
    QSORT(sorted_by_sha, nr_objects, sha1_compare);
77
0
  }
78
0
  else
79
0
    sorted_by_sha = list = last = NULL;
80
81
0
  if (opts->flags & WRITE_IDX_VERIFY) {
82
0
    assert(index_name);
83
0
    f = hashfd_check(repo->hash_algo, index_name);
84
0
  } else {
85
0
    if (!index_name) {
86
0
      struct strbuf tmp_file = STRBUF_INIT;
87
0
      fd = odb_mkstemp(repo->objects, &tmp_file,
88
0
           "pack/tmp_idx_XXXXXX");
89
0
      index_name = strbuf_detach(&tmp_file, NULL);
90
0
    } else {
91
0
      unlink(index_name);
92
0
      fd = xopen(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
93
0
    }
94
0
    f = hashfd(repo->hash_algo, fd, index_name);
95
0
  }
96
97
  /* if last object's offset is >= 2^31 we should use index V2 */
98
0
  index_version = need_large_offset(last_obj_offset, opts) ? 2 : opts->version;
99
100
  /* index versions 2 and above need a header */
101
0
  if (index_version >= 2) {
102
0
    struct pack_idx_header hdr;
103
0
    hdr.idx_signature = htonl(PACK_IDX_SIGNATURE);
104
0
    hdr.idx_version = htonl(index_version);
105
0
    hashwrite(f, &hdr, sizeof(hdr));
106
0
  }
107
108
  /*
109
   * Write the first-level table (the list is sorted,
110
   * but we use a 256-entry lookup to be able to avoid
111
   * having to do eight extra binary search iterations).
112
   */
113
0
  for (i = 0; i < 256; i++) {
114
0
    struct pack_idx_entry **next = list;
115
0
    while (next < last) {
116
0
      struct pack_idx_entry *obj = *next;
117
0
      if (obj->oid.hash[0] != i)
118
0
        break;
119
0
      next++;
120
0
    }
121
0
    hashwrite_be32(f, next - sorted_by_sha);
122
0
    list = next;
123
0
  }
124
125
  /*
126
   * Write the actual SHA1 entries..
127
   */
128
0
  list = sorted_by_sha;
129
0
  for (i = 0; i < nr_objects; i++) {
130
0
    struct pack_idx_entry *obj = *list++;
131
0
    if (index_version < 2)
132
0
      hashwrite_be32(f, obj->offset);
133
0
    hashwrite(f, obj->oid.hash, repo->hash_algo->rawsz);
134
0
    if ((opts->flags & WRITE_IDX_STRICT) &&
135
0
        (i && oideq(&list[-2]->oid, &obj->oid)))
136
0
      die("The same object %s appears twice in the pack",
137
0
          oid_to_hex(&obj->oid));
138
0
  }
139
140
0
  if (index_version >= 2) {
141
0
    unsigned int nr_large_offset = 0;
142
143
    /* write the crc32 table */
144
0
    list = sorted_by_sha;
145
0
    for (i = 0; i < nr_objects; i++) {
146
0
      struct pack_idx_entry *obj = *list++;
147
0
      hashwrite_be32(f, obj->crc32);
148
0
    }
149
150
    /* write the 32-bit offset table */
151
0
    list = sorted_by_sha;
152
0
    for (i = 0; i < nr_objects; i++) {
153
0
      struct pack_idx_entry *obj = *list++;
154
0
      uint32_t offset;
155
156
0
      offset = (need_large_offset(obj->offset, opts)
157
0
          ? (0x80000000 | nr_large_offset++)
158
0
          : obj->offset);
159
0
      hashwrite_be32(f, offset);
160
0
    }
161
162
    /* write the large offset table */
163
0
    list = sorted_by_sha;
164
0
    while (nr_large_offset) {
165
0
      struct pack_idx_entry *obj = *list++;
166
0
      uint64_t offset = obj->offset;
167
168
0
      if (!need_large_offset(offset, opts))
169
0
        continue;
170
0
      hashwrite_be64(f, offset);
171
0
      nr_large_offset--;
172
0
    }
173
0
  }
174
175
0
  hashwrite(f, sha1, repo->hash_algo->rawsz);
176
0
  finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
177
0
        CSUM_HASH_IN_STREAM | CSUM_CLOSE |
178
0
        ((opts->flags & WRITE_IDX_VERIFY) ? 0 : CSUM_FSYNC));
179
0
  return index_name;
180
0
}
181
182
static int pack_order_cmp(const void *va, const void *vb, void *ctx)
183
0
{
184
0
  struct pack_idx_entry **objects = ctx;
185
186
0
  off_t oa = objects[*(uint32_t*)va]->offset;
187
0
  off_t ob = objects[*(uint32_t*)vb]->offset;
188
189
0
  if (oa < ob)
190
0
    return -1;
191
0
  if (oa > ob)
192
0
    return 1;
193
0
  return 0;
194
0
}
195
196
static void write_rev_header(const struct git_hash_algo *hash_algo,
197
           struct hashfile *f)
198
0
{
199
0
  hashwrite_be32(f, RIDX_SIGNATURE);
200
0
  hashwrite_be32(f, RIDX_VERSION);
201
0
  hashwrite_be32(f, oid_version(hash_algo));
202
0
}
203
204
static void write_rev_index_positions(struct hashfile *f,
205
              uint32_t *pack_order,
206
              uint32_t nr_objects)
207
0
{
208
0
  uint32_t i;
209
0
  for (i = 0; i < nr_objects; i++)
210
0
    hashwrite_be32(f, pack_order[i]);
211
0
}
212
213
static void write_rev_trailer(const struct git_hash_algo *hash_algo,
214
            struct hashfile *f, const unsigned char *hash)
215
0
{
216
0
  hashwrite(f, hash, hash_algo->rawsz);
217
0
}
218
219
char *write_rev_file(struct repository *repo,
220
         const char *rev_name,
221
         struct pack_idx_entry **objects,
222
         uint32_t nr_objects,
223
         const unsigned char *hash,
224
         unsigned flags)
225
0
{
226
0
  uint32_t *pack_order;
227
0
  uint32_t i;
228
0
  char *ret;
229
230
0
  if (!(flags & WRITE_REV) && !(flags & WRITE_REV_VERIFY))
231
0
    return NULL;
232
233
0
  ALLOC_ARRAY(pack_order, nr_objects);
234
0
  for (i = 0; i < nr_objects; i++)
235
0
    pack_order[i] = i;
236
0
  QSORT_S(pack_order, nr_objects, pack_order_cmp, objects);
237
238
0
  ret = write_rev_file_order(repo, rev_name, pack_order, nr_objects,
239
0
           hash, flags);
240
241
0
  free(pack_order);
242
243
0
  return ret;
244
0
}
245
246
char *write_rev_file_order(struct repository *repo,
247
         const char *rev_name,
248
         uint32_t *pack_order,
249
         uint32_t nr_objects,
250
         const unsigned char *hash,
251
         unsigned flags)
252
0
{
253
0
  struct hashfile *f;
254
0
  char *path;
255
0
  int fd;
256
257
0
  if ((flags & WRITE_REV) && (flags & WRITE_REV_VERIFY))
258
0
    die(_("cannot both write and verify reverse index"));
259
260
0
  if (flags & WRITE_REV) {
261
0
    if (!rev_name) {
262
0
      struct strbuf tmp_file = STRBUF_INIT;
263
0
      fd = odb_mkstemp(repo->objects, &tmp_file,
264
0
           "pack/tmp_rev_XXXXXX");
265
0
      path = strbuf_detach(&tmp_file, NULL);
266
0
    } else {
267
0
      unlink(rev_name);
268
0
      fd = xopen(rev_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
269
0
      path = xstrdup(rev_name);
270
0
    }
271
0
    f = hashfd(repo->hash_algo, fd, path);
272
0
  } else if (flags & WRITE_REV_VERIFY) {
273
0
    struct stat statbuf;
274
0
    if (stat(rev_name, &statbuf)) {
275
0
      if (errno == ENOENT) {
276
        /* .rev files are optional */
277
0
        return NULL;
278
0
      } else
279
0
        die_errno(_("could not stat: %s"), rev_name);
280
0
    }
281
0
    f = hashfd_check(repo->hash_algo, rev_name);
282
0
    path = xstrdup(rev_name);
283
0
  } else {
284
0
    return NULL;
285
0
  }
286
287
0
  write_rev_header(repo->hash_algo, f);
288
289
0
  write_rev_index_positions(f, pack_order, nr_objects);
290
0
  write_rev_trailer(repo->hash_algo, f, hash);
291
292
0
  if (adjust_shared_perm(repo, path) < 0)
293
0
    die(_("failed to make %s readable"), path);
294
295
0
  finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
296
0
        CSUM_HASH_IN_STREAM | CSUM_CLOSE |
297
0
        ((flags & WRITE_IDX_VERIFY) ? 0 : CSUM_FSYNC));
298
299
0
  return path;
300
0
}
301
302
static void write_mtimes_header(const struct git_hash_algo *hash_algo,
303
        struct hashfile *f)
304
0
{
305
0
  hashwrite_be32(f, MTIMES_SIGNATURE);
306
0
  hashwrite_be32(f, MTIMES_VERSION);
307
0
  hashwrite_be32(f, oid_version(hash_algo));
308
0
}
309
310
/*
311
 * Writes the object mtimes of "objects" for use in a .mtimes file.
312
 * Note that objects must be in lexicographic (index) order, which is
313
 * the expected ordering of these values in the .mtimes file.
314
 */
315
static void write_mtimes_objects(struct hashfile *f,
316
         struct packing_data *to_pack,
317
         struct pack_idx_entry **objects,
318
         uint32_t nr_objects)
319
0
{
320
0
  uint32_t i;
321
0
  for (i = 0; i < nr_objects; i++) {
322
0
    struct object_entry *e = (struct object_entry*)objects[i];
323
0
    hashwrite_be32(f, oe_cruft_mtime(to_pack, e));
324
0
  }
325
0
}
326
327
static void write_mtimes_trailer(const struct git_hash_algo *hash_algo,
328
         struct hashfile *f, const unsigned char *hash)
329
0
{
330
0
  hashwrite(f, hash, hash_algo->rawsz);
331
0
}
332
333
static char *write_mtimes_file(struct repository *repo,
334
             struct packing_data *to_pack,
335
             struct pack_idx_entry **objects,
336
             uint32_t nr_objects,
337
             const unsigned char *hash)
338
0
{
339
0
  struct strbuf tmp_file = STRBUF_INIT;
340
0
  char *mtimes_name;
341
0
  struct hashfile *f;
342
0
  int fd;
343
344
0
  if (!to_pack)
345
0
    BUG("cannot call write_mtimes_file with NULL packing_data");
346
347
0
  fd = odb_mkstemp(repo->objects, &tmp_file, "pack/tmp_mtimes_XXXXXX");
348
0
  mtimes_name = strbuf_detach(&tmp_file, NULL);
349
0
  f = hashfd(repo->hash_algo, fd, mtimes_name);
350
351
0
  write_mtimes_header(repo->hash_algo, f);
352
0
  write_mtimes_objects(f, to_pack, objects, nr_objects);
353
0
  write_mtimes_trailer(repo->hash_algo, f, hash);
354
355
0
  if (adjust_shared_perm(repo, mtimes_name) < 0)
356
0
    die(_("failed to make %s readable"), mtimes_name);
357
358
0
  finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
359
0
        CSUM_HASH_IN_STREAM | CSUM_CLOSE | CSUM_FSYNC);
360
361
0
  return mtimes_name;
362
0
}
363
364
off_t write_pack_header(struct hashfile *f, uint32_t nr_entries)
365
0
{
366
0
  struct pack_header hdr;
367
368
0
  hdr.hdr_signature = htonl(PACK_SIGNATURE);
369
0
  hdr.hdr_version = htonl(PACK_VERSION);
370
0
  hdr.hdr_entries = htonl(nr_entries);
371
0
  hashwrite(f, &hdr, sizeof(hdr));
372
0
  return sizeof(hdr);
373
0
}
374
375
/*
376
 * Update pack header with object_count and compute new SHA1 for pack data
377
 * associated to pack_fd, and write that SHA1 at the end.  That new SHA1
378
 * is also returned in new_pack_sha1.
379
 *
380
 * If partial_pack_sha1 is non null, then the SHA1 of the existing pack
381
 * (without the header update) is computed and validated against the
382
 * one provided in partial_pack_sha1.  The validation is performed at
383
 * partial_pack_offset bytes in the pack file.  The SHA1 of the remaining
384
 * data (i.e. from partial_pack_offset to the end) is then computed and
385
 * returned in partial_pack_sha1.
386
 *
387
 * Note that new_pack_sha1 is updated last, so both new_pack_sha1 and
388
 * partial_pack_sha1 can refer to the same buffer if the caller is not
389
 * interested in the resulting SHA1 of pack data above partial_pack_offset.
390
 */
391
void fixup_pack_header_footer(const struct git_hash_algo *hash_algo,
392
       int pack_fd,
393
       unsigned char *new_pack_hash,
394
       const char *pack_name,
395
       uint32_t object_count,
396
       unsigned char *partial_pack_hash,
397
       off_t partial_pack_offset)
398
0
{
399
0
  int aligned_sz, buf_sz = 8 * 1024;
400
0
  struct git_hash_ctx old_hash_ctx, new_hash_ctx;
401
0
  struct pack_header hdr;
402
0
  char *buf;
403
0
  ssize_t read_result;
404
405
0
  git_hash_init(&old_hash_ctx, hash_algo);
406
0
  git_hash_init(&new_hash_ctx, hash_algo);
407
408
0
  if (lseek(pack_fd, 0, SEEK_SET) != 0)
409
0
    die_errno("Failed seeking to start of '%s'", pack_name);
410
0
  read_result = read_in_full(pack_fd, &hdr, sizeof(hdr));
411
0
  if (read_result < 0)
412
0
    die_errno("Unable to reread header of '%s'", pack_name);
413
0
  else if (read_result != sizeof(hdr))
414
0
    die_errno("Unexpected short read for header of '%s'",
415
0
        pack_name);
416
0
  if (lseek(pack_fd, 0, SEEK_SET) != 0)
417
0
    die_errno("Failed seeking to start of '%s'", pack_name);
418
0
  git_hash_update(&old_hash_ctx, &hdr, sizeof(hdr));
419
0
  hdr.hdr_entries = htonl(object_count);
420
0
  git_hash_update(&new_hash_ctx, &hdr, sizeof(hdr));
421
0
  write_or_die(pack_fd, &hdr, sizeof(hdr));
422
0
  partial_pack_offset -= sizeof(hdr);
423
424
0
  buf = xmalloc(buf_sz);
425
0
  aligned_sz = buf_sz - sizeof(hdr);
426
0
  for (;;) {
427
0
    ssize_t m, n;
428
0
    m = (partial_pack_hash && partial_pack_offset < aligned_sz) ?
429
0
      partial_pack_offset : aligned_sz;
430
0
    n = xread(pack_fd, buf, m);
431
0
    if (!n)
432
0
      break;
433
0
    if (n < 0)
434
0
      die_errno("Failed to checksum '%s'", pack_name);
435
0
    git_hash_update(&new_hash_ctx, buf, n);
436
437
0
    aligned_sz -= n;
438
0
    if (!aligned_sz)
439
0
      aligned_sz = buf_sz;
440
441
0
    if (!partial_pack_hash)
442
0
      continue;
443
444
0
    git_hash_update(&old_hash_ctx, buf, n);
445
0
    partial_pack_offset -= n;
446
0
    if (partial_pack_offset == 0) {
447
0
      unsigned char hash[GIT_MAX_RAWSZ];
448
0
      git_hash_final(hash, &old_hash_ctx);
449
0
      if (!hasheq(hash, partial_pack_hash,
450
0
            hash_algo))
451
0
        die("Unexpected checksum for %s "
452
0
            "(disk corruption?)", pack_name);
453
      /*
454
       * Now let's compute the SHA1 of the remainder of the
455
       * pack, which also means making partial_pack_offset
456
       * big enough not to matter anymore.
457
       */
458
0
      git_hash_init(&old_hash_ctx, hash_algo);
459
0
      partial_pack_offset = ~partial_pack_offset;
460
0
      partial_pack_offset -= MSB(partial_pack_offset, 1);
461
0
    }
462
0
  }
463
0
  free(buf);
464
465
0
  if (partial_pack_hash)
466
0
    git_hash_final(partial_pack_hash, &old_hash_ctx);
467
0
  git_hash_final(new_pack_hash, &new_hash_ctx);
468
0
  write_or_die(pack_fd, new_pack_hash, hash_algo->rawsz);
469
0
  fsync_component_or_die(FSYNC_COMPONENT_PACK, pack_fd, pack_name);
470
0
}
471
472
char *index_pack_lockfile(struct odb_source *source, int ip_out,
473
        int *is_well_formed)
474
0
{
475
0
  char packname[GIT_MAX_HEXSZ + 6];
476
0
  const int len = source->odb->repo->hash_algo->hexsz + 6;
477
478
  /*
479
   * The first thing we expect from index-pack's output
480
   * is "pack\t%40s\n" or "keep\t%40s\n" (46 bytes) where
481
   * %40s is the newly created pack SHA1 name.  In the "keep"
482
   * case, we need it to remove the corresponding .keep file
483
   * later on.  If we don't get that then tough luck with it.
484
   */
485
0
  if (read_in_full(ip_out, packname, len) == len && packname[len-1] == '\n') {
486
0
    const char *name;
487
488
0
    if (is_well_formed)
489
0
      *is_well_formed = 1;
490
0
    packname[len-1] = 0;
491
0
    if (skip_prefix(packname, "keep\t", &name))
492
0
      return xstrfmt("%s/pack/pack-%s.keep",
493
0
               source->path, name);
494
0
    return NULL;
495
0
  }
496
0
  if (is_well_formed)
497
0
    *is_well_formed = 0;
498
0
  return NULL;
499
0
}
500
501
/*
502
 * The per-object header is a pretty dense thing, which is
503
 *  - first byte: low four bits are "size", then three bits of "type",
504
 *    and the high bit is "size continues".
505
 *  - each byte afterwards: low seven bits are size continuation,
506
 *    with the high bit being "size continues"
507
 */
508
int encode_in_pack_object_header(unsigned char *hdr, int hdr_len,
509
         enum object_type type, uintmax_t size)
510
0
{
511
0
  int n = 1;
512
0
  unsigned char c;
513
514
0
  if (type < OBJ_COMMIT || type > OBJ_REF_DELTA)
515
0
    die("bad type %d", type);
516
517
0
  c = (type << 4) | (size & 15);
518
0
  size >>= 4;
519
0
  while (size) {
520
0
    if (n == hdr_len)
521
0
      die("object size is too enormous to format");
522
0
    *hdr++ = c | 0x80;
523
0
    c = size & 0x7f;
524
0
    size >>= 7;
525
0
    n++;
526
0
  }
527
0
  *hdr = c;
528
0
  return n;
529
0
}
530
531
struct hashfile *create_tmp_packfile(struct repository *repo,
532
             char **pack_tmp_name)
533
0
{
534
0
  struct strbuf tmpname = STRBUF_INIT;
535
0
  int fd;
536
537
0
  fd = odb_mkstemp(repo->objects, &tmpname, "pack/tmp_pack_XXXXXX");
538
0
  *pack_tmp_name = strbuf_detach(&tmpname, NULL);
539
0
  return hashfd(repo->hash_algo, fd, *pack_tmp_name);
540
0
}
541
542
static void rename_tmp_packfile(struct repository *repo,
543
        struct strbuf *name_prefix, const char *source,
544
        const char *ext)
545
0
{
546
0
  size_t name_prefix_len = name_prefix->len;
547
548
0
  strbuf_addstr(name_prefix, ext);
549
0
  if (finalize_object_file(repo, source, name_prefix->buf))
550
0
    die("unable to rename temporary file to '%s'",
551
0
        name_prefix->buf);
552
0
  strbuf_setlen(name_prefix, name_prefix_len);
553
0
}
554
555
void rename_tmp_packfile_idx(struct repository *repo,
556
           struct strbuf *name_buffer,
557
           char **idx_tmp_name)
558
0
{
559
0
  rename_tmp_packfile(repo, name_buffer, *idx_tmp_name, "idx");
560
0
}
561
562
void stage_tmp_packfiles(struct repository *repo,
563
       struct strbuf *name_buffer,
564
       const char *pack_tmp_name,
565
       struct pack_idx_entry **written_list,
566
       uint32_t nr_written,
567
       struct packing_data *to_pack,
568
       struct pack_idx_option *pack_idx_opts,
569
       unsigned char hash[],
570
       char **idx_tmp_name)
571
0
{
572
0
  char *rev_tmp_name = NULL;
573
0
  char *mtimes_tmp_name = NULL;
574
575
0
  if (adjust_shared_perm(repo, pack_tmp_name))
576
0
    die_errno("unable to make temporary pack file readable");
577
578
0
  *idx_tmp_name = (char *)write_idx_file(repo, NULL, written_list,
579
0
                 nr_written, pack_idx_opts, hash);
580
0
  if (adjust_shared_perm(repo, *idx_tmp_name))
581
0
    die_errno("unable to make temporary index file readable");
582
583
0
  rev_tmp_name = write_rev_file(repo, NULL, written_list, nr_written,
584
0
              hash, pack_idx_opts->flags);
585
586
0
  if (pack_idx_opts->flags & WRITE_MTIMES) {
587
0
    mtimes_tmp_name = write_mtimes_file(repo, to_pack,
588
0
                written_list, nr_written,
589
0
                hash);
590
0
  }
591
592
0
  rename_tmp_packfile(repo, name_buffer, pack_tmp_name, "pack");
593
0
  if (rev_tmp_name)
594
0
    rename_tmp_packfile(repo, name_buffer, rev_tmp_name, "rev");
595
0
  if (mtimes_tmp_name)
596
0
    rename_tmp_packfile(repo, name_buffer, mtimes_tmp_name, "mtimes");
597
598
0
  free(rev_tmp_name);
599
0
  free(mtimes_tmp_name);
600
0
}
601
602
void write_promisor_file(const char *promisor_name, struct ref **sought, int nr_sought)
603
0
{
604
0
  int i, err;
605
0
  FILE *output = xfopen(promisor_name, "w");
606
607
0
  for (i = 0; i < nr_sought; i++)
608
0
    fprintf(output, "%s %s\n", oid_to_hex(&sought[i]->old_oid),
609
0
      sought[i]->name);
610
611
0
  err = ferror(output);
612
0
  err |= fclose(output);
613
0
  if (err)
614
0
    die(_("could not write '%s' promisor file"), promisor_name);
615
0
}