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
467467static 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
491494static 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
500507static 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
506513static 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
681696static 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 );
0 commit comments