Skip to content

Commit 5272f75

Browse files
pcloudsgitster
authored andcommitted
index-pack: restructure pack processing into three main functions
The second pass in parse_pack_objects() are split into resolve_deltas(). The final phase, fixing thin pack or just seal the pack, is now in conclude_pack() function. Main pack processing is now a sequence of these functions: - parse_pack_objects() reads through the input pack - resolve_deltas() makes sure all deltas can be resolved - conclude_pack() seals the output pack - write_idx_file() writes companion index file - final() moves the pack/index to proper place Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 9ba604a commit 5272f75

1 file changed

Lines changed: 75 additions & 53 deletions

File tree

builtin/index-pack.c

Lines changed: 75 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -682,19 +682,26 @@ static int compare_delta_entry(const void *a, const void *b)
682682
objects[delta_b->obj_no].type);
683683
}
684684

685-
/* Parse all objects and return the pack content SHA1 hash */
685+
static void resolve_base(struct object_entry *obj)
686+
{
687+
struct base_data *base_obj = alloc_base_data();
688+
base_obj->obj = obj;
689+
base_obj->data = NULL;
690+
find_unresolved_deltas(base_obj);
691+
}
692+
693+
/*
694+
* First pass:
695+
* - find locations of all objects;
696+
* - calculate SHA1 of all non-delta objects;
697+
* - remember base (SHA1 or offset) for all deltas.
698+
*/
686699
static void parse_pack_objects(unsigned char *sha1)
687700
{
688701
int i;
689702
struct delta_entry *delta = deltas;
690703
struct stat st;
691704

692-
/*
693-
* First pass:
694-
* - find locations of all objects;
695-
* - calculate SHA1 of all non-delta objects;
696-
* - remember base (SHA1 or offset) for all deltas.
697-
*/
698705
if (verbose)
699706
progress = start_progress(
700707
from_stdin ? "Receiving objects" : "Indexing objects",
@@ -728,6 +735,19 @@ static void parse_pack_objects(unsigned char *sha1)
728735
if (S_ISREG(st.st_mode) &&
729736
lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size)
730737
die("pack has junk at the end");
738+
}
739+
740+
/*
741+
* Second pass:
742+
* - for all non-delta objects, look if it is used as a base for
743+
* deltas;
744+
* - if used as a base, uncompress the object and apply all deltas,
745+
* recursively checking if the resulting object is used as a base
746+
* for some more deltas.
747+
*/
748+
static void resolve_deltas(void)
749+
{
750+
int i;
731751

732752
if (!nr_deltas)
733753
return;
@@ -736,29 +756,63 @@ static void parse_pack_objects(unsigned char *sha1)
736756
qsort(deltas, nr_deltas, sizeof(struct delta_entry),
737757
compare_delta_entry);
738758

739-
/*
740-
* Second pass:
741-
* - for all non-delta objects, look if it is used as a base for
742-
* deltas;
743-
* - if used as a base, uncompress the object and apply all deltas,
744-
* recursively checking if the resulting object is used as a base
745-
* for some more deltas.
746-
*/
747759
if (verbose)
748760
progress = start_progress("Resolving deltas", nr_deltas);
749761
for (i = 0; i < nr_objects; i++) {
750762
struct object_entry *obj = &objects[i];
751-
struct base_data *base_obj = alloc_base_data();
752763

753764
if (is_delta_type(obj->type))
754765
continue;
755-
base_obj->obj = obj;
756-
base_obj->data = NULL;
757-
find_unresolved_deltas(base_obj);
766+
resolve_base(obj);
758767
display_progress(progress, nr_resolved_deltas);
759768
}
760769
}
761770

771+
/*
772+
* Third pass:
773+
* - append objects to convert thin pack to full pack if required
774+
* - write the final 20-byte SHA-1
775+
*/
776+
static void fix_unresolved_deltas(struct sha1file *f, int nr_unresolved);
777+
static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned char *pack_sha1)
778+
{
779+
if (nr_deltas == nr_resolved_deltas) {
780+
stop_progress(&progress);
781+
/* Flush remaining pack final 20-byte SHA1. */
782+
flush();
783+
return;
784+
}
785+
786+
if (fix_thin_pack) {
787+
struct sha1file *f;
788+
unsigned char read_sha1[20], tail_sha1[20];
789+
char msg[48];
790+
int nr_unresolved = nr_deltas - nr_resolved_deltas;
791+
int nr_objects_initial = nr_objects;
792+
if (nr_unresolved <= 0)
793+
die("confusion beyond insanity");
794+
objects = xrealloc(objects,
795+
(nr_objects + nr_unresolved + 1)
796+
* sizeof(*objects));
797+
f = sha1fd(output_fd, curr_pack);
798+
fix_unresolved_deltas(f, nr_unresolved);
799+
sprintf(msg, "completed with %d local objects",
800+
nr_objects - nr_objects_initial);
801+
stop_progress_msg(&progress, msg);
802+
sha1close(f, tail_sha1, 0);
803+
hashcpy(read_sha1, pack_sha1);
804+
fixup_pack_header_footer(output_fd, pack_sha1,
805+
curr_pack, nr_objects,
806+
read_sha1, consumed_bytes-20);
807+
if (hashcmp(read_sha1, tail_sha1) != 0)
808+
die("Unexpected tail checksum for %s "
809+
"(disk corruption?)", curr_pack);
810+
}
811+
if (nr_deltas != nr_resolved_deltas)
812+
die("pack has %d unresolved deltas",
813+
nr_deltas - nr_resolved_deltas);
814+
}
815+
762816
static int write_compressed(struct sha1file *f, void *in, unsigned int size)
763817
{
764818
git_zstream stream;
@@ -1196,40 +1250,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
11961250
objects = xcalloc(nr_objects + 1, sizeof(struct object_entry));
11971251
deltas = xcalloc(nr_objects, sizeof(struct delta_entry));
11981252
parse_pack_objects(pack_sha1);
1199-
if (nr_deltas == nr_resolved_deltas) {
1200-
stop_progress(&progress);
1201-
/* Flush remaining pack final 20-byte SHA1. */
1202-
flush();
1203-
} else {
1204-
if (fix_thin_pack) {
1205-
struct sha1file *f;
1206-
unsigned char read_sha1[20], tail_sha1[20];
1207-
char msg[48];
1208-
int nr_unresolved = nr_deltas - nr_resolved_deltas;
1209-
int nr_objects_initial = nr_objects;
1210-
if (nr_unresolved <= 0)
1211-
die("confusion beyond insanity");
1212-
objects = xrealloc(objects,
1213-
(nr_objects + nr_unresolved + 1)
1214-
* sizeof(*objects));
1215-
f = sha1fd(output_fd, curr_pack);
1216-
fix_unresolved_deltas(f, nr_unresolved);
1217-
sprintf(msg, "completed with %d local objects",
1218-
nr_objects - nr_objects_initial);
1219-
stop_progress_msg(&progress, msg);
1220-
sha1close(f, tail_sha1, 0);
1221-
hashcpy(read_sha1, pack_sha1);
1222-
fixup_pack_header_footer(output_fd, pack_sha1,
1223-
curr_pack, nr_objects,
1224-
read_sha1, consumed_bytes-20);
1225-
if (hashcmp(read_sha1, tail_sha1) != 0)
1226-
die("Unexpected tail checksum for %s "
1227-
"(disk corruption?)", curr_pack);
1228-
}
1229-
if (nr_deltas != nr_resolved_deltas)
1230-
die("pack has %d unresolved deltas",
1231-
nr_deltas - nr_resolved_deltas);
1232-
}
1253+
resolve_deltas();
1254+
conclude_pack(fix_thin_pack, curr_pack, pack_sha1);
12331255
free(deltas);
12341256
if (strict)
12351257
check_objects();

0 commit comments

Comments
 (0)