Skip to content

Commit e5eac57

Browse files
committed
Merge branch 'ab/commit-graph-write-progress'
The codepath to show progress meter while writing out commit-graph file has been improved. * ab/commit-graph-write-progress: commit-graph write: emit a percentage for all progress commit-graph write: add itermediate progress commit-graph write: remove empty line for readability commit-graph write: add more descriptive progress output commit-graph write: show progress for object search commit-graph write: more descriptive "writing out" output commit-graph write: add "Writing out" progress output commit-graph: don't call write_graph_chunk_extra_edges() unnecessarily commit-graph: rename "large edges" to "extra edges"
2 parents 04d67b6 + 49bbc57 commit e5eac57

File tree

5 files changed

+106
-48
lines changed

5 files changed

+106
-48
lines changed

Documentation/technical/commit-graph-format.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ CHUNK DATA:
7676
of the ith commit. Stores value 0x7000000 if no parent in that
7777
position. If there are more than two parents, the second value
7878
has its most-significant bit on and the other bits store an array
79-
position into the Large Edge List chunk.
79+
position into the Extra Edge List chunk.
8080
* The next 8 bytes store the generation number of the commit and
8181
the commit time in seconds since EPOCH. The generation number
8282
uses the higher 30 bits of the first 4 bytes, while the commit
8383
time uses the 32 bits of the second 4 bytes, along with the lowest
8484
2 bits of the lowest byte, storing the 33rd and 34th bit of the
8585
commit time.
8686

87-
Large Edge List (ID: {'E', 'D', 'G', 'E'}) [Optional]
87+
Extra Edge List (ID: {'E', 'D', 'G', 'E'}) [Optional]
8888
This list of 4-byte values store the second through nth parents for
8989
all octopus merges. The second parent value in the commit data stores
9090
an array position within this list along with the most-significant bit

builtin/commit-graph.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ static int graph_read(int argc, const char **argv)
110110
printf(" oid_lookup");
111111
if (graph->chunk_commit_data)
112112
printf(" commit_metadata");
113-
if (graph->chunk_large_edges)
114-
printf(" large_edges");
113+
if (graph->chunk_extra_edges)
114+
printf(" extra_edges");
115115
printf("\n");
116116

117117
UNLEAK(graph);

commit-graph.c

Lines changed: 94 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
#define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
2222
#define GRAPH_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
2323
#define GRAPH_CHUNKID_DATA 0x43444154 /* "CDAT" */
24-
#define GRAPH_CHUNKID_LARGEEDGES 0x45444745 /* "EDGE" */
24+
#define GRAPH_CHUNKID_EXTRAEDGES 0x45444745 /* "EDGE" */
2525

2626
#define GRAPH_DATA_WIDTH (the_hash_algo->rawsz + 16)
2727

2828
#define GRAPH_VERSION_1 0x1
2929
#define GRAPH_VERSION GRAPH_VERSION_1
3030

31-
#define GRAPH_OCTOPUS_EDGES_NEEDED 0x80000000
31+
#define GRAPH_EXTRA_EDGES_NEEDED 0x80000000
3232
#define GRAPH_EDGE_LAST_MASK 0x7fffffff
3333
#define GRAPH_PARENT_NONE 0x70000000
3434

@@ -209,11 +209,11 @@ struct commit_graph *parse_commit_graph(void *graph_map, int fd,
209209
graph->chunk_commit_data = data + chunk_offset;
210210
break;
211211

212-
case GRAPH_CHUNKID_LARGEEDGES:
213-
if (graph->chunk_large_edges)
212+
case GRAPH_CHUNKID_EXTRAEDGES:
213+
if (graph->chunk_extra_edges)
214214
chunk_repeated = 1;
215215
else
216-
graph->chunk_large_edges = data + chunk_offset;
216+
graph->chunk_extra_edges = data + chunk_offset;
217217
break;
218218
}
219219

@@ -374,12 +374,12 @@ static int fill_commit_in_graph(struct repository *r,
374374
edge_value = get_be32(commit_data + g->hash_len + 4);
375375
if (edge_value == GRAPH_PARENT_NONE)
376376
return 1;
377-
if (!(edge_value & GRAPH_OCTOPUS_EDGES_NEEDED)) {
377+
if (!(edge_value & GRAPH_EXTRA_EDGES_NEEDED)) {
378378
pptr = insert_parent_or_die(r, g, edge_value, pptr);
379379
return 1;
380380
}
381381

382-
parent_data_ptr = (uint32_t*)(g->chunk_large_edges +
382+
parent_data_ptr = (uint32_t*)(g->chunk_extra_edges +
383383
4 * (uint64_t)(edge_value & GRAPH_EDGE_LAST_MASK));
384384
do {
385385
edge_value = get_be32(parent_data_ptr);
@@ -466,7 +466,9 @@ struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit
466466

467467
static void write_graph_chunk_fanout(struct hashfile *f,
468468
struct commit **commits,
469-
int nr_commits)
469+
int nr_commits,
470+
struct progress *progress,
471+
uint64_t *progress_cnt)
470472
{
471473
int i, count = 0;
472474
struct commit **list = commits;
@@ -480,6 +482,7 @@ static void write_graph_chunk_fanout(struct hashfile *f,
480482
while (count < nr_commits) {
481483
if ((*list)->object.oid.hash[0] != i)
482484
break;
485+
display_progress(progress, ++*progress_cnt);
483486
count++;
484487
list++;
485488
}
@@ -489,12 +492,16 @@ static void write_graph_chunk_fanout(struct hashfile *f,
489492
}
490493

491494
static void write_graph_chunk_oids(struct hashfile *f, int hash_len,
492-
struct commit **commits, int nr_commits)
495+
struct commit **commits, int nr_commits,
496+
struct progress *progress,
497+
uint64_t *progress_cnt)
493498
{
494499
struct commit **list = commits;
495500
int count;
496-
for (count = 0; count < nr_commits; count++, list++)
501+
for (count = 0; count < nr_commits; count++, list++) {
502+
display_progress(progress, ++*progress_cnt);
497503
hashwrite(f, (*list)->object.oid.hash, (int)hash_len);
504+
}
498505
}
499506

500507
static const unsigned char *commit_to_sha1(size_t index, void *table)
@@ -504,7 +511,9 @@ static const unsigned char *commit_to_sha1(size_t index, void *table)
504511
}
505512

506513
static void write_graph_chunk_data(struct hashfile *f, int hash_len,
507-
struct commit **commits, int nr_commits)
514+
struct commit **commits, int nr_commits,
515+
struct progress *progress,
516+
uint64_t *progress_cnt)
508517
{
509518
struct commit **list = commits;
510519
struct commit **last = commits + nr_commits;
@@ -514,6 +523,7 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
514523
struct commit_list *parent;
515524
int edge_value;
516525
uint32_t packedDate[2];
526+
display_progress(progress, ++*progress_cnt);
517527

518528
parse_commit(*list);
519529
hashwrite(f, get_commit_tree_oid(*list)->hash, hash_len);
@@ -542,7 +552,7 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
542552
if (!parent)
543553
edge_value = GRAPH_PARENT_NONE;
544554
else if (parent->next)
545-
edge_value = GRAPH_OCTOPUS_EDGES_NEEDED | num_extra_edges;
555+
edge_value = GRAPH_EXTRA_EDGES_NEEDED | num_extra_edges;
546556
else {
547557
edge_value = sha1_pos(parent->item->object.oid.hash,
548558
commits,
@@ -556,7 +566,7 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
556566

557567
hashwrite_be32(f, edge_value);
558568

559-
if (edge_value & GRAPH_OCTOPUS_EDGES_NEEDED) {
569+
if (edge_value & GRAPH_EXTRA_EDGES_NEEDED) {
560570
do {
561571
num_extra_edges++;
562572
parent = parent->next;
@@ -577,16 +587,21 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
577587
}
578588
}
579589

580-
static void write_graph_chunk_large_edges(struct hashfile *f,
590+
static void write_graph_chunk_extra_edges(struct hashfile *f,
581591
struct commit **commits,
582-
int nr_commits)
592+
int nr_commits,
593+
struct progress *progress,
594+
uint64_t *progress_cnt)
583595
{
584596
struct commit **list = commits;
585597
struct commit **last = commits + nr_commits;
586598
struct commit_list *parent;
587599

588600
while (list < last) {
589601
int num_parents = 0;
602+
603+
display_progress(progress, ++*progress_cnt);
604+
590605
for (parent = (*list)->parents; num_parents < 3 && parent;
591606
parent = parent->next)
592607
num_parents++;
@@ -680,15 +695,15 @@ static void add_missing_parents(struct packed_oid_list *oids, struct commit *com
680695

681696
static void close_reachable(struct packed_oid_list *oids, int report_progress)
682697
{
683-
int i, j;
698+
int i;
684699
struct commit *commit;
685700
struct progress *progress = NULL;
686701

687702
if (report_progress)
688703
progress = start_delayed_progress(
689-
_("Loading known commits in commit graph"), j = 0);
704+
_("Loading known commits in commit graph"), oids->nr);
690705
for (i = 0; i < oids->nr; i++) {
691-
display_progress(progress, ++j);
706+
display_progress(progress, i + 1);
692707
commit = lookup_commit(the_repository, &oids->list[i]);
693708
if (commit)
694709
commit->object.flags |= UNINTERESTING;
@@ -702,9 +717,9 @@ static void close_reachable(struct packed_oid_list *oids, int report_progress)
702717
*/
703718
if (report_progress)
704719
progress = start_delayed_progress(
705-
_("Expanding reachable commits in commit graph"), j = 0);
720+
_("Expanding reachable commits in commit graph"), oids->nr);
706721
for (i = 0; i < oids->nr; i++) {
707-
display_progress(progress, ++j);
722+
display_progress(progress, i + 1);
708723
commit = lookup_commit(the_repository, &oids->list[i]);
709724

710725
if (commit && !parse_commit(commit))
@@ -714,9 +729,9 @@ static void close_reachable(struct packed_oid_list *oids, int report_progress)
714729

715730
if (report_progress)
716731
progress = start_delayed_progress(
717-
_("Clearing commit marks in commit graph"), j = 0);
732+
_("Clearing commit marks in commit graph"), oids->nr);
718733
for (i = 0; i < oids->nr; i++) {
719-
display_progress(progress, ++j);
734+
display_progress(progress, i + 1);
720735
commit = lookup_commit(the_repository, &oids->list[i]);
721736

722737
if (commit)
@@ -811,12 +826,16 @@ void write_commit_graph(const char *obj_dir,
811826
struct commit_list *parent;
812827
struct progress *progress = NULL;
813828
const unsigned hashsz = the_hash_algo->rawsz;
829+
uint64_t progress_cnt = 0;
830+
struct strbuf progress_title = STRBUF_INIT;
831+
unsigned long approx_nr_objects;
814832

815833
if (!commit_graph_compatible(the_repository))
816834
return;
817835

818836
oids.nr = 0;
819-
oids.alloc = approximate_object_count() / 32;
837+
approx_nr_objects = approximate_object_count();
838+
oids.alloc = approx_nr_objects / 32;
820839
oids.progress = NULL;
821840
oids.progress_done = 0;
822841

@@ -846,8 +865,12 @@ void write_commit_graph(const char *obj_dir,
846865
strbuf_addf(&packname, "%s/pack/", obj_dir);
847866
dirlen = packname.len;
848867
if (report_progress) {
849-
oids.progress = start_delayed_progress(
850-
_("Finding commits for commit graph"), 0);
868+
strbuf_addf(&progress_title,
869+
Q_("Finding commits for commit graph in %d pack",
870+
"Finding commits for commit graph in %d packs",
871+
pack_indexes->nr),
872+
pack_indexes->nr);
873+
oids.progress = start_delayed_progress(progress_title.buf, 0);
851874
oids.progress_done = 0;
852875
}
853876
for (i = 0; i < pack_indexes->nr; i++) {
@@ -865,14 +888,20 @@ void write_commit_graph(const char *obj_dir,
865888
free(p);
866889
}
867890
stop_progress(&oids.progress);
891+
strbuf_reset(&progress_title);
868892
strbuf_release(&packname);
869893
}
870894

871895
if (commit_hex) {
872-
if (report_progress)
873-
progress = start_delayed_progress(
874-
_("Finding commits for commit graph"),
875-
commit_hex->nr);
896+
if (report_progress) {
897+
strbuf_addf(&progress_title,
898+
Q_("Finding commits for commit graph from %d ref",
899+
"Finding commits for commit graph from %d refs",
900+
commit_hex->nr),
901+
commit_hex->nr);
902+
progress = start_delayed_progress(progress_title.buf,
903+
commit_hex->nr);
904+
}
876905
for (i = 0; i < commit_hex->nr; i++) {
877906
const char *end;
878907
struct object_id oid;
@@ -892,26 +921,36 @@ void write_commit_graph(const char *obj_dir,
892921
}
893922
}
894923
stop_progress(&progress);
924+
strbuf_reset(&progress_title);
895925
}
896926

897927
if (!pack_indexes && !commit_hex) {
898928
if (report_progress)
899929
oids.progress = start_delayed_progress(
900-
_("Finding commits for commit graph"), 0);
930+
_("Finding commits for commit graph among packed objects"),
931+
approx_nr_objects);
901932
for_each_packed_object(add_packed_commits, &oids,
902933
FOR_EACH_OBJECT_PACK_ORDER);
934+
if (oids.progress_done < approx_nr_objects)
935+
display_progress(oids.progress, approx_nr_objects);
903936
stop_progress(&oids.progress);
904937
}
905938

906939
close_reachable(&oids, report_progress);
907940

941+
if (report_progress)
942+
progress = start_delayed_progress(
943+
_("Counting distinct commits in commit graph"),
944+
oids.nr);
945+
display_progress(progress, 0); /* TODO: Measure QSORT() progress */
908946
QSORT(oids.list, oids.nr, commit_compare);
909-
910947
count_distinct = 1;
911948
for (i = 1; i < oids.nr; i++) {
949+
display_progress(progress, i + 1);
912950
if (!oideq(&oids.list[i - 1], &oids.list[i]))
913951
count_distinct++;
914952
}
953+
stop_progress(&progress);
915954

916955
if (count_distinct >= GRAPH_EDGE_LAST_MASK)
917956
die(_("the commit graph format cannot write %d commits"), count_distinct);
@@ -921,8 +960,13 @@ void write_commit_graph(const char *obj_dir,
921960
ALLOC_ARRAY(commits.list, commits.alloc);
922961

923962
num_extra_edges = 0;
963+
if (report_progress)
964+
progress = start_delayed_progress(
965+
_("Finding extra edges in commit graph"),
966+
oids.nr);
924967
for (i = 0; i < oids.nr; i++) {
925968
int num_parents = 0;
969+
display_progress(progress, i + 1);
926970
if (i > 0 && oideq(&oids.list[i - 1], &oids.list[i]))
927971
continue;
928972

@@ -939,6 +983,7 @@ void write_commit_graph(const char *obj_dir,
939983
commits.nr++;
940984
}
941985
num_chunks = num_extra_edges ? 4 : 3;
986+
stop_progress(&progress);
942987

943988
if (commits.nr >= GRAPH_EDGE_LAST_MASK)
944989
die(_("too many commits to write graph"));
@@ -966,7 +1011,7 @@ void write_commit_graph(const char *obj_dir,
9661011
chunk_ids[1] = GRAPH_CHUNKID_OIDLOOKUP;
9671012
chunk_ids[2] = GRAPH_CHUNKID_DATA;
9681013
if (num_extra_edges)
969-
chunk_ids[3] = GRAPH_CHUNKID_LARGEEDGES;
1014+
chunk_ids[3] = GRAPH_CHUNKID_EXTRAEDGES;
9701015
else
9711016
chunk_ids[3] = 0;
9721017
chunk_ids[4] = 0;
@@ -986,10 +1031,23 @@ void write_commit_graph(const char *obj_dir,
9861031
hashwrite(f, chunk_write, 12);
9871032
}
9881033

989-
write_graph_chunk_fanout(f, commits.list, commits.nr);
990-
write_graph_chunk_oids(f, hashsz, commits.list, commits.nr);
991-
write_graph_chunk_data(f, hashsz, commits.list, commits.nr);
992-
write_graph_chunk_large_edges(f, commits.list, commits.nr);
1034+
if (report_progress) {
1035+
strbuf_addf(&progress_title,
1036+
Q_("Writing out commit graph in %d pass",
1037+
"Writing out commit graph in %d passes",
1038+
num_chunks),
1039+
num_chunks);
1040+
progress = start_delayed_progress(
1041+
progress_title.buf,
1042+
num_chunks * commits.nr);
1043+
}
1044+
write_graph_chunk_fanout(f, commits.list, commits.nr, progress, &progress_cnt);
1045+
write_graph_chunk_oids(f, hashsz, commits.list, commits.nr, progress, &progress_cnt);
1046+
write_graph_chunk_data(f, hashsz, commits.list, commits.nr, progress, &progress_cnt);
1047+
if (num_extra_edges)
1048+
write_graph_chunk_extra_edges(f, commits.list, commits.nr, progress, &progress_cnt);
1049+
stop_progress(&progress);
1050+
strbuf_release(&progress_title);
9931051

9941052
close_commit_graph(the_repository);
9951053
finalize_hashfile(f, NULL, CSUM_HASH_IN_STREAM | CSUM_FSYNC);

commit-graph.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct commit_graph {
4949
const uint32_t *chunk_oid_fanout;
5050
const unsigned char *chunk_oid_lookup;
5151
const unsigned char *chunk_commit_data;
52-
const unsigned char *chunk_large_edges;
52+
const unsigned char *chunk_extra_edges;
5353
};
5454

5555
struct commit_graph *load_commit_graph_one(const char *graph_file);

0 commit comments

Comments
 (0)