git

Форк
0
/
pack-write.c 
594 строки · 16.0 Кб
1
#define USE_THE_REPOSITORY_VARIABLE
2

3
#include "git-compat-util.h"
4
#include "environment.h"
5
#include "gettext.h"
6
#include "hex.h"
7
#include "pack.h"
8
#include "csum-file.h"
9
#include "remote.h"
10
#include "chunk-format.h"
11
#include "pack-mtimes.h"
12
#include "pack-objects.h"
13
#include "pack-revindex.h"
14
#include "path.h"
15
#include "strbuf.h"
16

17
void reset_pack_idx_option(struct pack_idx_option *opts)
18
{
19
	memset(opts, 0, sizeof(*opts));
20
	opts->version = 2;
21
	opts->off32_limit = 0x7fffffff;
22
}
23

24
static int sha1_compare(const void *_a, const void *_b)
25
{
26
	struct pack_idx_entry *a = *(struct pack_idx_entry **)_a;
27
	struct pack_idx_entry *b = *(struct pack_idx_entry **)_b;
28
	return oidcmp(&a->oid, &b->oid);
29
}
30

31
static int cmp_uint32(const void *a_, const void *b_)
32
{
33
	uint32_t a = *((uint32_t *)a_);
34
	uint32_t b = *((uint32_t *)b_);
35

36
	return (a < b) ? -1 : (a != b);
37
}
38

39
static int need_large_offset(off_t offset, const struct pack_idx_option *opts)
40
{
41
	uint32_t ofsval;
42

43
	if ((offset >> 31) || (opts->off32_limit < offset))
44
		return 1;
45
	if (!opts->anomaly_nr)
46
		return 0;
47
	ofsval = offset;
48
	return !!bsearch(&ofsval, opts->anomaly, opts->anomaly_nr,
49
			 sizeof(ofsval), cmp_uint32);
50
}
51

52
/*
53
 * The *sha1 contains the pack content SHA1 hash.
54
 * The objects array passed in will be sorted by SHA1 on exit.
55
 */
56
const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects,
57
			   int nr_objects, const struct pack_idx_option *opts,
58
			   const unsigned char *sha1)
59
{
60
	struct hashfile *f;
61
	struct pack_idx_entry **sorted_by_sha, **list, **last;
62
	off_t last_obj_offset = 0;
63
	int i, fd;
64
	uint32_t index_version;
65

66
	if (nr_objects) {
67
		sorted_by_sha = objects;
68
		list = sorted_by_sha;
69
		last = sorted_by_sha + nr_objects;
70
		for (i = 0; i < nr_objects; ++i) {
71
			if (objects[i]->offset > last_obj_offset)
72
				last_obj_offset = objects[i]->offset;
73
		}
74
		QSORT(sorted_by_sha, nr_objects, sha1_compare);
75
	}
76
	else
77
		sorted_by_sha = list = last = NULL;
78

79
	if (opts->flags & WRITE_IDX_VERIFY) {
80
		assert(index_name);
81
		f = hashfd_check(index_name);
82
	} else {
83
		if (!index_name) {
84
			struct strbuf tmp_file = STRBUF_INIT;
85
			fd = odb_mkstemp(&tmp_file, "pack/tmp_idx_XXXXXX");
86
			index_name = strbuf_detach(&tmp_file, NULL);
87
		} else {
88
			unlink(index_name);
89
			fd = xopen(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
90
		}
91
		f = hashfd(fd, index_name);
92
	}
93

94
	/* if last object's offset is >= 2^31 we should use index V2 */
95
	index_version = need_large_offset(last_obj_offset, opts) ? 2 : opts->version;
96

97
	/* index versions 2 and above need a header */
98
	if (index_version >= 2) {
99
		struct pack_idx_header hdr;
100
		hdr.idx_signature = htonl(PACK_IDX_SIGNATURE);
101
		hdr.idx_version = htonl(index_version);
102
		hashwrite(f, &hdr, sizeof(hdr));
103
	}
104

105
	/*
106
	 * Write the first-level table (the list is sorted,
107
	 * but we use a 256-entry lookup to be able to avoid
108
	 * having to do eight extra binary search iterations).
109
	 */
110
	for (i = 0; i < 256; i++) {
111
		struct pack_idx_entry **next = list;
112
		while (next < last) {
113
			struct pack_idx_entry *obj = *next;
114
			if (obj->oid.hash[0] != i)
115
				break;
116
			next++;
117
		}
118
		hashwrite_be32(f, next - sorted_by_sha);
119
		list = next;
120
	}
121

122
	/*
123
	 * Write the actual SHA1 entries..
124
	 */
125
	list = sorted_by_sha;
126
	for (i = 0; i < nr_objects; i++) {
127
		struct pack_idx_entry *obj = *list++;
128
		if (index_version < 2)
129
			hashwrite_be32(f, obj->offset);
130
		hashwrite(f, obj->oid.hash, the_hash_algo->rawsz);
131
		if ((opts->flags & WRITE_IDX_STRICT) &&
132
		    (i && oideq(&list[-2]->oid, &obj->oid)))
133
			die("The same object %s appears twice in the pack",
134
			    oid_to_hex(&obj->oid));
135
	}
136

137
	if (index_version >= 2) {
138
		unsigned int nr_large_offset = 0;
139

140
		/* write the crc32 table */
141
		list = sorted_by_sha;
142
		for (i = 0; i < nr_objects; i++) {
143
			struct pack_idx_entry *obj = *list++;
144
			hashwrite_be32(f, obj->crc32);
145
		}
146

147
		/* write the 32-bit offset table */
148
		list = sorted_by_sha;
149
		for (i = 0; i < nr_objects; i++) {
150
			struct pack_idx_entry *obj = *list++;
151
			uint32_t offset;
152

153
			offset = (need_large_offset(obj->offset, opts)
154
				  ? (0x80000000 | nr_large_offset++)
155
				  : obj->offset);
156
			hashwrite_be32(f, offset);
157
		}
158

159
		/* write the large offset table */
160
		list = sorted_by_sha;
161
		while (nr_large_offset) {
162
			struct pack_idx_entry *obj = *list++;
163
			uint64_t offset = obj->offset;
164

165
			if (!need_large_offset(offset, opts))
166
				continue;
167
			hashwrite_be64(f, offset);
168
			nr_large_offset--;
169
		}
170
	}
171

172
	hashwrite(f, sha1, the_hash_algo->rawsz);
173
	finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
174
			  CSUM_HASH_IN_STREAM | CSUM_CLOSE |
175
			  ((opts->flags & WRITE_IDX_VERIFY) ? 0 : CSUM_FSYNC));
176
	return index_name;
177
}
178

179
static int pack_order_cmp(const void *va, const void *vb, void *ctx)
180
{
181
	struct pack_idx_entry **objects = ctx;
182

183
	off_t oa = objects[*(uint32_t*)va]->offset;
184
	off_t ob = objects[*(uint32_t*)vb]->offset;
185

186
	if (oa < ob)
187
		return -1;
188
	if (oa > ob)
189
		return 1;
190
	return 0;
191
}
192

193
static void write_rev_header(struct hashfile *f)
194
{
195
	hashwrite_be32(f, RIDX_SIGNATURE);
196
	hashwrite_be32(f, RIDX_VERSION);
197
	hashwrite_be32(f, oid_version(the_hash_algo));
198
}
199

200
static void write_rev_index_positions(struct hashfile *f,
201
				      uint32_t *pack_order,
202
				      uint32_t nr_objects)
203
{
204
	uint32_t i;
205
	for (i = 0; i < nr_objects; i++)
206
		hashwrite_be32(f, pack_order[i]);
207
}
208

209
static void write_rev_trailer(struct hashfile *f, const unsigned char *hash)
210
{
211
	hashwrite(f, hash, the_hash_algo->rawsz);
212
}
213

214
const char *write_rev_file(const char *rev_name,
215
			   struct pack_idx_entry **objects,
216
			   uint32_t nr_objects,
217
			   const unsigned char *hash,
218
			   unsigned flags)
219
{
220
	uint32_t *pack_order;
221
	uint32_t i;
222
	const char *ret;
223

224
	if (!(flags & WRITE_REV) && !(flags & WRITE_REV_VERIFY))
225
		return NULL;
226

227
	ALLOC_ARRAY(pack_order, nr_objects);
228
	for (i = 0; i < nr_objects; i++)
229
		pack_order[i] = i;
230
	QSORT_S(pack_order, nr_objects, pack_order_cmp, objects);
231

232
	ret = write_rev_file_order(rev_name, pack_order, nr_objects, hash,
233
				   flags);
234

235
	free(pack_order);
236

237
	return ret;
238
}
239

240
const char *write_rev_file_order(const char *rev_name,
241
				 uint32_t *pack_order,
242
				 uint32_t nr_objects,
243
				 const unsigned char *hash,
244
				 unsigned flags)
245
{
246
	struct hashfile *f;
247
	int fd;
248

249
	if ((flags & WRITE_REV) && (flags & WRITE_REV_VERIFY))
250
		die(_("cannot both write and verify reverse index"));
251

252
	if (flags & WRITE_REV) {
253
		if (!rev_name) {
254
			struct strbuf tmp_file = STRBUF_INIT;
255
			fd = odb_mkstemp(&tmp_file, "pack/tmp_rev_XXXXXX");
256
			rev_name = strbuf_detach(&tmp_file, NULL);
257
		} else {
258
			unlink(rev_name);
259
			fd = xopen(rev_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
260
		}
261
		f = hashfd(fd, rev_name);
262
	} else if (flags & WRITE_REV_VERIFY) {
263
		struct stat statbuf;
264
		if (stat(rev_name, &statbuf)) {
265
			if (errno == ENOENT) {
266
				/* .rev files are optional */
267
				return NULL;
268
			} else
269
				die_errno(_("could not stat: %s"), rev_name);
270
		}
271
		f = hashfd_check(rev_name);
272
	} else
273
		return NULL;
274

275
	write_rev_header(f);
276

277
	write_rev_index_positions(f, pack_order, nr_objects);
278
	write_rev_trailer(f, hash);
279

280
	if (rev_name && adjust_shared_perm(rev_name) < 0)
281
		die(_("failed to make %s readable"), rev_name);
282

283
	finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
284
			  CSUM_HASH_IN_STREAM | CSUM_CLOSE |
285
			  ((flags & WRITE_IDX_VERIFY) ? 0 : CSUM_FSYNC));
286

287
	return rev_name;
288
}
289

290
static void write_mtimes_header(struct hashfile *f)
291
{
292
	hashwrite_be32(f, MTIMES_SIGNATURE);
293
	hashwrite_be32(f, MTIMES_VERSION);
294
	hashwrite_be32(f, oid_version(the_hash_algo));
295
}
296

297
/*
298
 * Writes the object mtimes of "objects" for use in a .mtimes file.
299
 * Note that objects must be in lexicographic (index) order, which is
300
 * the expected ordering of these values in the .mtimes file.
301
 */
302
static void write_mtimes_objects(struct hashfile *f,
303
				 struct packing_data *to_pack,
304
				 struct pack_idx_entry **objects,
305
				 uint32_t nr_objects)
306
{
307
	uint32_t i;
308
	for (i = 0; i < nr_objects; i++) {
309
		struct object_entry *e = (struct object_entry*)objects[i];
310
		hashwrite_be32(f, oe_cruft_mtime(to_pack, e));
311
	}
312
}
313

314
static void write_mtimes_trailer(struct hashfile *f, const unsigned char *hash)
315
{
316
	hashwrite(f, hash, the_hash_algo->rawsz);
317
}
318

319
static char *write_mtimes_file(struct packing_data *to_pack,
320
			       struct pack_idx_entry **objects,
321
			       uint32_t nr_objects,
322
			       const unsigned char *hash)
323
{
324
	struct strbuf tmp_file = STRBUF_INIT;
325
	char *mtimes_name;
326
	struct hashfile *f;
327
	int fd;
328

329
	if (!to_pack)
330
		BUG("cannot call write_mtimes_file with NULL packing_data");
331

332
	fd = odb_mkstemp(&tmp_file, "pack/tmp_mtimes_XXXXXX");
333
	mtimes_name = strbuf_detach(&tmp_file, NULL);
334
	f = hashfd(fd, mtimes_name);
335

336
	write_mtimes_header(f);
337
	write_mtimes_objects(f, to_pack, objects, nr_objects);
338
	write_mtimes_trailer(f, hash);
339

340
	if (adjust_shared_perm(mtimes_name) < 0)
341
		die(_("failed to make %s readable"), mtimes_name);
342

343
	finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
344
			  CSUM_HASH_IN_STREAM | CSUM_CLOSE | CSUM_FSYNC);
345

346
	return mtimes_name;
347
}
348

349
off_t write_pack_header(struct hashfile *f, uint32_t nr_entries)
350
{
351
	struct pack_header hdr;
352

353
	hdr.hdr_signature = htonl(PACK_SIGNATURE);
354
	hdr.hdr_version = htonl(PACK_VERSION);
355
	hdr.hdr_entries = htonl(nr_entries);
356
	hashwrite(f, &hdr, sizeof(hdr));
357
	return sizeof(hdr);
358
}
359

360
/*
361
 * Update pack header with object_count and compute new SHA1 for pack data
362
 * associated to pack_fd, and write that SHA1 at the end.  That new SHA1
363
 * is also returned in new_pack_sha1.
364
 *
365
 * If partial_pack_sha1 is non null, then the SHA1 of the existing pack
366
 * (without the header update) is computed and validated against the
367
 * one provided in partial_pack_sha1.  The validation is performed at
368
 * partial_pack_offset bytes in the pack file.  The SHA1 of the remaining
369
 * data (i.e. from partial_pack_offset to the end) is then computed and
370
 * returned in partial_pack_sha1.
371
 *
372
 * Note that new_pack_sha1 is updated last, so both new_pack_sha1 and
373
 * partial_pack_sha1 can refer to the same buffer if the caller is not
374
 * interested in the resulting SHA1 of pack data above partial_pack_offset.
375
 */
376
void fixup_pack_header_footer(int pack_fd,
377
			 unsigned char *new_pack_hash,
378
			 const char *pack_name,
379
			 uint32_t object_count,
380
			 unsigned char *partial_pack_hash,
381
			 off_t partial_pack_offset)
382
{
383
	int aligned_sz, buf_sz = 8 * 1024;
384
	git_hash_ctx old_hash_ctx, new_hash_ctx;
385
	struct pack_header hdr;
386
	char *buf;
387
	ssize_t read_result;
388

389
	the_hash_algo->init_fn(&old_hash_ctx);
390
	the_hash_algo->init_fn(&new_hash_ctx);
391

392
	if (lseek(pack_fd, 0, SEEK_SET) != 0)
393
		die_errno("Failed seeking to start of '%s'", pack_name);
394
	read_result = read_in_full(pack_fd, &hdr, sizeof(hdr));
395
	if (read_result < 0)
396
		die_errno("Unable to reread header of '%s'", pack_name);
397
	else if (read_result != sizeof(hdr))
398
		die_errno("Unexpected short read for header of '%s'",
399
			  pack_name);
400
	if (lseek(pack_fd, 0, SEEK_SET) != 0)
401
		die_errno("Failed seeking to start of '%s'", pack_name);
402
	the_hash_algo->update_fn(&old_hash_ctx, &hdr, sizeof(hdr));
403
	hdr.hdr_entries = htonl(object_count);
404
	the_hash_algo->update_fn(&new_hash_ctx, &hdr, sizeof(hdr));
405
	write_or_die(pack_fd, &hdr, sizeof(hdr));
406
	partial_pack_offset -= sizeof(hdr);
407

408
	buf = xmalloc(buf_sz);
409
	aligned_sz = buf_sz - sizeof(hdr);
410
	for (;;) {
411
		ssize_t m, n;
412
		m = (partial_pack_hash && partial_pack_offset < aligned_sz) ?
413
			partial_pack_offset : aligned_sz;
414
		n = xread(pack_fd, buf, m);
415
		if (!n)
416
			break;
417
		if (n < 0)
418
			die_errno("Failed to checksum '%s'", pack_name);
419
		the_hash_algo->update_fn(&new_hash_ctx, buf, n);
420

421
		aligned_sz -= n;
422
		if (!aligned_sz)
423
			aligned_sz = buf_sz;
424

425
		if (!partial_pack_hash)
426
			continue;
427

428
		the_hash_algo->update_fn(&old_hash_ctx, buf, n);
429
		partial_pack_offset -= n;
430
		if (partial_pack_offset == 0) {
431
			unsigned char hash[GIT_MAX_RAWSZ];
432
			the_hash_algo->final_fn(hash, &old_hash_ctx);
433
			if (!hasheq(hash, partial_pack_hash,
434
				    the_repository->hash_algo))
435
				die("Unexpected checksum for %s "
436
				    "(disk corruption?)", pack_name);
437
			/*
438
			 * Now let's compute the SHA1 of the remainder of the
439
			 * pack, which also means making partial_pack_offset
440
			 * big enough not to matter anymore.
441
			 */
442
			the_hash_algo->init_fn(&old_hash_ctx);
443
			partial_pack_offset = ~partial_pack_offset;
444
			partial_pack_offset -= MSB(partial_pack_offset, 1);
445
		}
446
	}
447
	free(buf);
448

449
	if (partial_pack_hash)
450
		the_hash_algo->final_fn(partial_pack_hash, &old_hash_ctx);
451
	the_hash_algo->final_fn(new_pack_hash, &new_hash_ctx);
452
	write_or_die(pack_fd, new_pack_hash, the_hash_algo->rawsz);
453
	fsync_component_or_die(FSYNC_COMPONENT_PACK, pack_fd, pack_name);
454
}
455

456
char *index_pack_lockfile(int ip_out, int *is_well_formed)
457
{
458
	char packname[GIT_MAX_HEXSZ + 6];
459
	const int len = the_hash_algo->hexsz + 6;
460

461
	/*
462
	 * The first thing we expect from index-pack's output
463
	 * is "pack\t%40s\n" or "keep\t%40s\n" (46 bytes) where
464
	 * %40s is the newly created pack SHA1 name.  In the "keep"
465
	 * case, we need it to remove the corresponding .keep file
466
	 * later on.  If we don't get that then tough luck with it.
467
	 */
468
	if (read_in_full(ip_out, packname, len) == len && packname[len-1] == '\n') {
469
		const char *name;
470

471
		if (is_well_formed)
472
			*is_well_formed = 1;
473
		packname[len-1] = 0;
474
		if (skip_prefix(packname, "keep\t", &name))
475
			return xstrfmt("%s/pack/pack-%s.keep",
476
				       get_object_directory(), name);
477
		return NULL;
478
	}
479
	if (is_well_formed)
480
		*is_well_formed = 0;
481
	return NULL;
482
}
483

484
/*
485
 * The per-object header is a pretty dense thing, which is
486
 *  - first byte: low four bits are "size", then three bits of "type",
487
 *    and the high bit is "size continues".
488
 *  - each byte afterwards: low seven bits are size continuation,
489
 *    with the high bit being "size continues"
490
 */
491
int encode_in_pack_object_header(unsigned char *hdr, int hdr_len,
492
				 enum object_type type, uintmax_t size)
493
{
494
	int n = 1;
495
	unsigned char c;
496

497
	if (type < OBJ_COMMIT || type > OBJ_REF_DELTA)
498
		die("bad type %d", type);
499

500
	c = (type << 4) | (size & 15);
501
	size >>= 4;
502
	while (size) {
503
		if (n == hdr_len)
504
			die("object size is too enormous to format");
505
		*hdr++ = c | 0x80;
506
		c = size & 0x7f;
507
		size >>= 7;
508
		n++;
509
	}
510
	*hdr = c;
511
	return n;
512
}
513

514
struct hashfile *create_tmp_packfile(char **pack_tmp_name)
515
{
516
	struct strbuf tmpname = STRBUF_INIT;
517
	int fd;
518

519
	fd = odb_mkstemp(&tmpname, "pack/tmp_pack_XXXXXX");
520
	*pack_tmp_name = strbuf_detach(&tmpname, NULL);
521
	return hashfd(fd, *pack_tmp_name);
522
}
523

524
static void rename_tmp_packfile(struct strbuf *name_prefix, const char *source,
525
				const char *ext)
526
{
527
	size_t name_prefix_len = name_prefix->len;
528

529
	strbuf_addstr(name_prefix, ext);
530
	if (rename(source, name_prefix->buf))
531
		die_errno("unable to rename temporary file to '%s'",
532
			  name_prefix->buf);
533
	strbuf_setlen(name_prefix, name_prefix_len);
534
}
535

536
void rename_tmp_packfile_idx(struct strbuf *name_buffer,
537
			     char **idx_tmp_name)
538
{
539
	rename_tmp_packfile(name_buffer, *idx_tmp_name, "idx");
540
}
541

542
void stage_tmp_packfiles(struct strbuf *name_buffer,
543
			 const char *pack_tmp_name,
544
			 struct pack_idx_entry **written_list,
545
			 uint32_t nr_written,
546
			 struct packing_data *to_pack,
547
			 struct pack_idx_option *pack_idx_opts,
548
			 unsigned char hash[],
549
			 char **idx_tmp_name)
550
{
551
	const char *rev_tmp_name = NULL;
552
	char *mtimes_tmp_name = NULL;
553

554
	if (adjust_shared_perm(pack_tmp_name))
555
		die_errno("unable to make temporary pack file readable");
556

557
	*idx_tmp_name = (char *)write_idx_file(NULL, written_list, nr_written,
558
					       pack_idx_opts, hash);
559
	if (adjust_shared_perm(*idx_tmp_name))
560
		die_errno("unable to make temporary index file readable");
561

562
	rev_tmp_name = write_rev_file(NULL, written_list, nr_written, hash,
563
				      pack_idx_opts->flags);
564

565
	if (pack_idx_opts->flags & WRITE_MTIMES) {
566
		mtimes_tmp_name = write_mtimes_file(to_pack, written_list,
567
						    nr_written,
568
						    hash);
569
	}
570

571
	rename_tmp_packfile(name_buffer, pack_tmp_name, "pack");
572
	if (rev_tmp_name)
573
		rename_tmp_packfile(name_buffer, rev_tmp_name, "rev");
574
	if (mtimes_tmp_name)
575
		rename_tmp_packfile(name_buffer, mtimes_tmp_name, "mtimes");
576

577
	free((char *)rev_tmp_name);
578
	free(mtimes_tmp_name);
579
}
580

581
void write_promisor_file(const char *promisor_name, struct ref **sought, int nr_sought)
582
{
583
	int i, err;
584
	FILE *output = xfopen(promisor_name, "w");
585

586
	for (i = 0; i < nr_sought; i++)
587
		fprintf(output, "%s %s\n", oid_to_hex(&sought[i]->old_oid),
588
			sought[i]->name);
589

590
	err = ferror(output);
591
	err |= fclose(output);
592
	if (err)
593
		die(_("could not write '%s' promisor file"), promisor_name);
594
}
595

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.