Skip to content

Commit 36d767d

Browse files
committed
Merge branch 'ab/commit-graph-progress'
Generation of (experimental) commit-graph files have so far been fairly silent, even though it takes noticeable amount of time in a meaningfully large repository. The users will now see progress output. * ab/commit-graph-progress: gc: fix regression in 7b0f229 impacting --quiet commit-graph verify: add progress output commit-graph write: add progress output
2 parents 5a0cc8a + 6b89a34 commit 36d767d

File tree

6 files changed

+87
-14
lines changed

6 files changed

+87
-14
lines changed

builtin/commit-graph.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ static int graph_write(int argc, const char **argv)
151151
opts.obj_dir = get_object_directory();
152152

153153
if (opts.reachable) {
154-
write_commit_graph_reachable(opts.obj_dir, opts.append);
154+
write_commit_graph_reachable(opts.obj_dir, opts.append, 1);
155155
return 0;
156156
}
157157

@@ -171,7 +171,8 @@ static int graph_write(int argc, const char **argv)
171171
write_commit_graph(opts.obj_dir,
172172
pack_indexes,
173173
commit_hex,
174-
opts.append);
174+
opts.append,
175+
1);
175176

176177
string_list_clear(&lines, 0);
177178
return 0;

builtin/commit.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1654,7 +1654,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
16541654
"not exceeded, and then \"git reset HEAD\" to recover."));
16551655

16561656
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
1657-
write_commit_graph_reachable(get_object_directory(), 0);
1657+
write_commit_graph_reachable(get_object_directory(), 0, 0);
16581658

16591659
rerere(0);
16601660
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);

builtin/gc.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
646646
clean_pack_garbage();
647647

648648
if (gc_write_commit_graph)
649-
write_commit_graph_reachable(get_object_directory(), 0);
649+
write_commit_graph_reachable(get_object_directory(), 0,
650+
!quiet && !daemonized);
650651

651652
if (auto_gc && too_many_loose_objects())
652653
warning(_("There are too many unreachable loose objects; "

commit-graph.c

+57-8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "commit-graph.h"
1414
#include "object-store.h"
1515
#include "alloc.h"
16+
#include "progress.h"
1617

1718
#define GRAPH_SIGNATURE 0x43475048 /* "CGPH" */
1819
#define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
@@ -567,6 +568,8 @@ struct packed_oid_list {
567568
struct object_id *list;
568569
int nr;
569570
int alloc;
571+
struct progress *progress;
572+
int progress_done;
570573
};
571574

572575
static int add_packed_commits(const struct object_id *oid,
@@ -579,6 +582,9 @@ static int add_packed_commits(const struct object_id *oid,
579582
off_t offset = nth_packed_object_offset(pack, pos);
580583
struct object_info oi = OBJECT_INFO_INIT;
581584

585+
if (list->progress)
586+
display_progress(list->progress, ++list->progress_done);
587+
582588
oi.typep = &type;
583589
if (packed_object_info(the_repository, pack, offset, &oi) < 0)
584590
die(_("unable to get type of object %s"), oid_to_hex(oid));
@@ -606,12 +612,18 @@ static void add_missing_parents(struct packed_oid_list *oids, struct commit *com
606612
}
607613
}
608614

609-
static void close_reachable(struct packed_oid_list *oids)
615+
static void close_reachable(struct packed_oid_list *oids, int report_progress)
610616
{
611617
int i;
612618
struct commit *commit;
619+
struct progress *progress = NULL;
620+
int j = 0;
613621

622+
if (report_progress)
623+
progress = start_delayed_progress(
624+
_("Annotating commits in commit graph"), 0);
614625
for (i = 0; i < oids->nr; i++) {
626+
display_progress(progress, ++j);
615627
commit = lookup_commit(the_repository, &oids->list[i]);
616628
if (commit)
617629
commit->object.flags |= UNINTERESTING;
@@ -623,26 +635,36 @@ static void close_reachable(struct packed_oid_list *oids)
623635
* closure.
624636
*/
625637
for (i = 0; i < oids->nr; i++) {
638+
display_progress(progress, ++j);
626639
commit = lookup_commit(the_repository, &oids->list[i]);
627640

628641
if (commit && !parse_commit(commit))
629642
add_missing_parents(oids, commit);
630643
}
631644

632645
for (i = 0; i < oids->nr; i++) {
646+
display_progress(progress, ++j);
633647
commit = lookup_commit(the_repository, &oids->list[i]);
634648

635649
if (commit)
636650
commit->object.flags &= ~UNINTERESTING;
637651
}
652+
stop_progress(&progress);
638653
}
639654

640-
static void compute_generation_numbers(struct packed_commit_list* commits)
655+
static void compute_generation_numbers(struct packed_commit_list* commits,
656+
int report_progress)
641657
{
642658
int i;
643659
struct commit_list *list = NULL;
660+
struct progress *progress = NULL;
644661

662+
if (report_progress)
663+
progress = start_progress(
664+
_("Computing commit graph generation numbers"),
665+
commits->nr);
645666
for (i = 0; i < commits->nr; i++) {
667+
display_progress(progress, i + 1);
646668
if (commits->list[i]->generation != GENERATION_NUMBER_INFINITY &&
647669
commits->list[i]->generation != GENERATION_NUMBER_ZERO)
648670
continue;
@@ -674,6 +696,7 @@ static void compute_generation_numbers(struct packed_commit_list* commits)
674696
}
675697
}
676698
}
699+
stop_progress(&progress);
677700
}
678701

679702
static int add_ref_to_list(const char *refname,
@@ -686,19 +709,20 @@ static int add_ref_to_list(const char *refname,
686709
return 0;
687710
}
688711

689-
void write_commit_graph_reachable(const char *obj_dir, int append)
712+
void write_commit_graph_reachable(const char *obj_dir, int append,
713+
int report_progress)
690714
{
691715
struct string_list list;
692716

693717
string_list_init(&list, 1);
694718
for_each_ref(add_ref_to_list, &list);
695-
write_commit_graph(obj_dir, NULL, &list, append);
719+
write_commit_graph(obj_dir, NULL, &list, append, report_progress);
696720
}
697721

698722
void write_commit_graph(const char *obj_dir,
699723
struct string_list *pack_indexes,
700724
struct string_list *commit_hex,
701-
int append)
725+
int append, int report_progress)
702726
{
703727
struct packed_oid_list oids;
704728
struct packed_commit_list commits;
@@ -711,9 +735,12 @@ void write_commit_graph(const char *obj_dir,
711735
int num_chunks;
712736
int num_extra_edges;
713737
struct commit_list *parent;
738+
struct progress *progress = NULL;
714739

715740
oids.nr = 0;
716741
oids.alloc = approximate_object_count() / 4;
742+
oids.progress = NULL;
743+
oids.progress_done = 0;
717744

718745
if (append) {
719746
prepare_commit_graph_one(the_repository, obj_dir);
@@ -740,6 +767,11 @@ void write_commit_graph(const char *obj_dir,
740767
int dirlen;
741768
strbuf_addf(&packname, "%s/pack/", obj_dir);
742769
dirlen = packname.len;
770+
if (report_progress) {
771+
oids.progress = start_delayed_progress(
772+
_("Finding commits for commit graph"), 0);
773+
oids.progress_done = 0;
774+
}
743775
for (i = 0; i < pack_indexes->nr; i++) {
744776
struct packed_git *p;
745777
strbuf_setlen(&packname, dirlen);
@@ -752,15 +784,21 @@ void write_commit_graph(const char *obj_dir,
752784
for_each_object_in_pack(p, add_packed_commits, &oids, 0);
753785
close_pack(p);
754786
}
787+
stop_progress(&oids.progress);
755788
strbuf_release(&packname);
756789
}
757790

758791
if (commit_hex) {
792+
if (report_progress)
793+
progress = start_delayed_progress(
794+
_("Finding commits for commit graph"),
795+
commit_hex->nr);
759796
for (i = 0; i < commit_hex->nr; i++) {
760797
const char *end;
761798
struct object_id oid;
762799
struct commit *result;
763800

801+
display_progress(progress, i + 1);
764802
if (commit_hex->items[i].string &&
765803
parse_oid_hex(commit_hex->items[i].string, &oid, &end))
766804
continue;
@@ -773,12 +811,18 @@ void write_commit_graph(const char *obj_dir,
773811
oids.nr++;
774812
}
775813
}
814+
stop_progress(&progress);
776815
}
777816

778-
if (!pack_indexes && !commit_hex)
817+
if (!pack_indexes && !commit_hex) {
818+
if (report_progress)
819+
oids.progress = start_delayed_progress(
820+
_("Finding commits for commit graph"), 0);
779821
for_each_packed_object(add_packed_commits, &oids, 0);
822+
stop_progress(&oids.progress);
823+
}
780824

781-
close_reachable(&oids);
825+
close_reachable(&oids, report_progress);
782826

783827
QSORT(oids.list, oids.nr, commit_compare);
784828

@@ -818,7 +862,7 @@ void write_commit_graph(const char *obj_dir,
818862
if (commits.nr >= GRAPH_PARENT_MISSING)
819863
die(_("too many commits to write graph"));
820864

821-
compute_generation_numbers(&commits);
865+
compute_generation_numbers(&commits, report_progress);
822866

823867
graph_name = get_commit_graph_filename(obj_dir);
824868
if (safe_create_leading_directories(graph_name))
@@ -897,6 +941,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)
897941
int generation_zero = 0;
898942
struct hashfile *f;
899943
int devnull;
944+
struct progress *progress = NULL;
900945

901946
if (!g) {
902947
graph_report("no commit-graph file loaded");
@@ -964,11 +1009,14 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)
9641009
if (verify_commit_graph_error & ~VERIFY_COMMIT_GRAPH_ERROR_HASH)
9651010
return verify_commit_graph_error;
9661011

1012+
progress = start_progress(_("Verifying commits in commit graph"),
1013+
g->num_commits);
9671014
for (i = 0; i < g->num_commits; i++) {
9681015
struct commit *graph_commit, *odb_commit;
9691016
struct commit_list *graph_parents, *odb_parents;
9701017
uint32_t max_generation = 0;
9711018

1019+
display_progress(progress, i + 1);
9721020
hashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i);
9731021

9741022
graph_commit = lookup_commit(r, &cur_oid);
@@ -1045,6 +1093,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)
10451093
graph_commit->date,
10461094
odb_commit->date);
10471095
}
1096+
stop_progress(&progress);
10481097

10491098
return verify_commit_graph_error;
10501099
}

commit-graph.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ struct commit_graph *load_commit_graph_one(const char *graph_file);
6060
*/
6161
int generation_numbers_enabled(struct repository *r);
6262

63-
void write_commit_graph_reachable(const char *obj_dir, int append);
63+
void write_commit_graph_reachable(const char *obj_dir, int append,
64+
int report_progress);
6465
void write_commit_graph(const char *obj_dir,
6566
struct string_list *pack_indexes,
6667
struct string_list *commit_hex,
67-
int append);
68+
int append, int report_progress);
6869

6970
int verify_commit_graph(struct repository *r, struct commit_graph *g);
7071

t/t6500-gc.sh

+21
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ test_description='basic git gc tests
44
'
55

66
. ./test-lib.sh
7+
. "$TEST_DIRECTORY"/lib-terminal.sh
78

89
test_expect_success 'setup' '
910
# do not let the amount of physical memory affects gc
@@ -99,6 +100,26 @@ test_expect_success 'auto gc with too many loose objects does not attempt to cre
99100
test_line_count = 2 new # There is one new pack and its .idx
100101
'
101102

103+
test_expect_success 'gc --no-quiet' '
104+
git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr &&
105+
test_must_be_empty stdout &&
106+
test_line_count = 1 stderr &&
107+
test_i18ngrep "Computing commit graph generation numbers" stderr
108+
'
109+
110+
test_expect_success TTY 'with TTY: gc --no-quiet' '
111+
test_terminal git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr &&
112+
test_must_be_empty stdout &&
113+
test_i18ngrep "Enumerating objects" stderr &&
114+
test_i18ngrep "Computing commit graph generation numbers" stderr
115+
'
116+
117+
test_expect_success 'gc --quiet' '
118+
git -c gc.writeCommitGraph=true gc --quiet >stdout 2>stderr &&
119+
test_must_be_empty stdout &&
120+
test_must_be_empty stderr
121+
'
122+
102123
run_and_wait_for_auto_gc () {
103124
# We read stdout from gc for the side effect of waiting until the
104125
# background gc process exits, closing its fd 9. Furthermore, the

0 commit comments

Comments
 (0)