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 7b0f229222
impacting --quiet
commit-graph verify: add progress output
commit-graph write: add progress output
This commit is contained in:
commit
36d767d02e
@ -151,7 +151,7 @@ static int graph_write(int argc, const char **argv)
|
|||||||
opts.obj_dir = get_object_directory();
|
opts.obj_dir = get_object_directory();
|
||||||
|
|
||||||
if (opts.reachable) {
|
if (opts.reachable) {
|
||||||
write_commit_graph_reachable(opts.obj_dir, opts.append);
|
write_commit_graph_reachable(opts.obj_dir, opts.append, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +171,8 @@ static int graph_write(int argc, const char **argv)
|
|||||||
write_commit_graph(opts.obj_dir,
|
write_commit_graph(opts.obj_dir,
|
||||||
pack_indexes,
|
pack_indexes,
|
||||||
commit_hex,
|
commit_hex,
|
||||||
opts.append);
|
opts.append,
|
||||||
|
1);
|
||||||
|
|
||||||
string_list_clear(&lines, 0);
|
string_list_clear(&lines, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1654,7 +1654,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
|||||||
"not exceeded, and then \"git reset HEAD\" to recover."));
|
"not exceeded, and then \"git reset HEAD\" to recover."));
|
||||||
|
|
||||||
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
|
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
|
||||||
write_commit_graph_reachable(get_object_directory(), 0);
|
write_commit_graph_reachable(get_object_directory(), 0, 0);
|
||||||
|
|
||||||
rerere(0);
|
rerere(0);
|
||||||
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
|
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
|
||||||
|
@ -646,7 +646,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
|
|||||||
clean_pack_garbage();
|
clean_pack_garbage();
|
||||||
|
|
||||||
if (gc_write_commit_graph)
|
if (gc_write_commit_graph)
|
||||||
write_commit_graph_reachable(get_object_directory(), 0);
|
write_commit_graph_reachable(get_object_directory(), 0,
|
||||||
|
!quiet && !daemonized);
|
||||||
|
|
||||||
if (auto_gc && too_many_loose_objects())
|
if (auto_gc && too_many_loose_objects())
|
||||||
warning(_("There are too many unreachable loose objects; "
|
warning(_("There are too many unreachable loose objects; "
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "commit-graph.h"
|
#include "commit-graph.h"
|
||||||
#include "object-store.h"
|
#include "object-store.h"
|
||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
|
#include "progress.h"
|
||||||
|
|
||||||
#define GRAPH_SIGNATURE 0x43475048 /* "CGPH" */
|
#define GRAPH_SIGNATURE 0x43475048 /* "CGPH" */
|
||||||
#define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
|
#define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
|
||||||
@ -567,6 +568,8 @@ struct packed_oid_list {
|
|||||||
struct object_id *list;
|
struct object_id *list;
|
||||||
int nr;
|
int nr;
|
||||||
int alloc;
|
int alloc;
|
||||||
|
struct progress *progress;
|
||||||
|
int progress_done;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int add_packed_commits(const struct object_id *oid,
|
static int add_packed_commits(const struct object_id *oid,
|
||||||
@ -579,6 +582,9 @@ static int add_packed_commits(const struct object_id *oid,
|
|||||||
off_t offset = nth_packed_object_offset(pack, pos);
|
off_t offset = nth_packed_object_offset(pack, pos);
|
||||||
struct object_info oi = OBJECT_INFO_INIT;
|
struct object_info oi = OBJECT_INFO_INIT;
|
||||||
|
|
||||||
|
if (list->progress)
|
||||||
|
display_progress(list->progress, ++list->progress_done);
|
||||||
|
|
||||||
oi.typep = &type;
|
oi.typep = &type;
|
||||||
if (packed_object_info(the_repository, pack, offset, &oi) < 0)
|
if (packed_object_info(the_repository, pack, offset, &oi) < 0)
|
||||||
die(_("unable to get type of object %s"), oid_to_hex(oid));
|
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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void close_reachable(struct packed_oid_list *oids)
|
static void close_reachable(struct packed_oid_list *oids, int report_progress)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
|
struct progress *progress = NULL;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
if (report_progress)
|
||||||
|
progress = start_delayed_progress(
|
||||||
|
_("Annotating commits in commit graph"), 0);
|
||||||
for (i = 0; i < oids->nr; i++) {
|
for (i = 0; i < oids->nr; i++) {
|
||||||
|
display_progress(progress, ++j);
|
||||||
commit = lookup_commit(the_repository, &oids->list[i]);
|
commit = lookup_commit(the_repository, &oids->list[i]);
|
||||||
if (commit)
|
if (commit)
|
||||||
commit->object.flags |= UNINTERESTING;
|
commit->object.flags |= UNINTERESTING;
|
||||||
@ -623,6 +635,7 @@ static void close_reachable(struct packed_oid_list *oids)
|
|||||||
* closure.
|
* closure.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < oids->nr; i++) {
|
for (i = 0; i < oids->nr; i++) {
|
||||||
|
display_progress(progress, ++j);
|
||||||
commit = lookup_commit(the_repository, &oids->list[i]);
|
commit = lookup_commit(the_repository, &oids->list[i]);
|
||||||
|
|
||||||
if (commit && !parse_commit(commit))
|
if (commit && !parse_commit(commit))
|
||||||
@ -630,19 +643,28 @@ static void close_reachable(struct packed_oid_list *oids)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < oids->nr; i++) {
|
for (i = 0; i < oids->nr; i++) {
|
||||||
|
display_progress(progress, ++j);
|
||||||
commit = lookup_commit(the_repository, &oids->list[i]);
|
commit = lookup_commit(the_repository, &oids->list[i]);
|
||||||
|
|
||||||
if (commit)
|
if (commit)
|
||||||
commit->object.flags &= ~UNINTERESTING;
|
commit->object.flags &= ~UNINTERESTING;
|
||||||
}
|
}
|
||||||
|
stop_progress(&progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compute_generation_numbers(struct packed_commit_list* commits)
|
static void compute_generation_numbers(struct packed_commit_list* commits,
|
||||||
|
int report_progress)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct commit_list *list = NULL;
|
struct commit_list *list = NULL;
|
||||||
|
struct progress *progress = NULL;
|
||||||
|
|
||||||
|
if (report_progress)
|
||||||
|
progress = start_progress(
|
||||||
|
_("Computing commit graph generation numbers"),
|
||||||
|
commits->nr);
|
||||||
for (i = 0; i < commits->nr; i++) {
|
for (i = 0; i < commits->nr; i++) {
|
||||||
|
display_progress(progress, i + 1);
|
||||||
if (commits->list[i]->generation != GENERATION_NUMBER_INFINITY &&
|
if (commits->list[i]->generation != GENERATION_NUMBER_INFINITY &&
|
||||||
commits->list[i]->generation != GENERATION_NUMBER_ZERO)
|
commits->list[i]->generation != GENERATION_NUMBER_ZERO)
|
||||||
continue;
|
continue;
|
||||||
@ -674,6 +696,7 @@ static void compute_generation_numbers(struct packed_commit_list* commits)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stop_progress(&progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_ref_to_list(const char *refname,
|
static int add_ref_to_list(const char *refname,
|
||||||
@ -686,19 +709,20 @@ static int add_ref_to_list(const char *refname,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_commit_graph_reachable(const char *obj_dir, int append)
|
void write_commit_graph_reachable(const char *obj_dir, int append,
|
||||||
|
int report_progress)
|
||||||
{
|
{
|
||||||
struct string_list list;
|
struct string_list list;
|
||||||
|
|
||||||
string_list_init(&list, 1);
|
string_list_init(&list, 1);
|
||||||
for_each_ref(add_ref_to_list, &list);
|
for_each_ref(add_ref_to_list, &list);
|
||||||
write_commit_graph(obj_dir, NULL, &list, append);
|
write_commit_graph(obj_dir, NULL, &list, append, report_progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_commit_graph(const char *obj_dir,
|
void write_commit_graph(const char *obj_dir,
|
||||||
struct string_list *pack_indexes,
|
struct string_list *pack_indexes,
|
||||||
struct string_list *commit_hex,
|
struct string_list *commit_hex,
|
||||||
int append)
|
int append, int report_progress)
|
||||||
{
|
{
|
||||||
struct packed_oid_list oids;
|
struct packed_oid_list oids;
|
||||||
struct packed_commit_list commits;
|
struct packed_commit_list commits;
|
||||||
@ -711,9 +735,12 @@ void write_commit_graph(const char *obj_dir,
|
|||||||
int num_chunks;
|
int num_chunks;
|
||||||
int num_extra_edges;
|
int num_extra_edges;
|
||||||
struct commit_list *parent;
|
struct commit_list *parent;
|
||||||
|
struct progress *progress = NULL;
|
||||||
|
|
||||||
oids.nr = 0;
|
oids.nr = 0;
|
||||||
oids.alloc = approximate_object_count() / 4;
|
oids.alloc = approximate_object_count() / 4;
|
||||||
|
oids.progress = NULL;
|
||||||
|
oids.progress_done = 0;
|
||||||
|
|
||||||
if (append) {
|
if (append) {
|
||||||
prepare_commit_graph_one(the_repository, obj_dir);
|
prepare_commit_graph_one(the_repository, obj_dir);
|
||||||
@ -740,6 +767,11 @@ void write_commit_graph(const char *obj_dir,
|
|||||||
int dirlen;
|
int dirlen;
|
||||||
strbuf_addf(&packname, "%s/pack/", obj_dir);
|
strbuf_addf(&packname, "%s/pack/", obj_dir);
|
||||||
dirlen = packname.len;
|
dirlen = packname.len;
|
||||||
|
if (report_progress) {
|
||||||
|
oids.progress = start_delayed_progress(
|
||||||
|
_("Finding commits for commit graph"), 0);
|
||||||
|
oids.progress_done = 0;
|
||||||
|
}
|
||||||
for (i = 0; i < pack_indexes->nr; i++) {
|
for (i = 0; i < pack_indexes->nr; i++) {
|
||||||
struct packed_git *p;
|
struct packed_git *p;
|
||||||
strbuf_setlen(&packname, dirlen);
|
strbuf_setlen(&packname, dirlen);
|
||||||
@ -752,15 +784,21 @@ void write_commit_graph(const char *obj_dir,
|
|||||||
for_each_object_in_pack(p, add_packed_commits, &oids, 0);
|
for_each_object_in_pack(p, add_packed_commits, &oids, 0);
|
||||||
close_pack(p);
|
close_pack(p);
|
||||||
}
|
}
|
||||||
|
stop_progress(&oids.progress);
|
||||||
strbuf_release(&packname);
|
strbuf_release(&packname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commit_hex) {
|
if (commit_hex) {
|
||||||
|
if (report_progress)
|
||||||
|
progress = start_delayed_progress(
|
||||||
|
_("Finding commits for commit graph"),
|
||||||
|
commit_hex->nr);
|
||||||
for (i = 0; i < commit_hex->nr; i++) {
|
for (i = 0; i < commit_hex->nr; i++) {
|
||||||
const char *end;
|
const char *end;
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
struct commit *result;
|
struct commit *result;
|
||||||
|
|
||||||
|
display_progress(progress, i + 1);
|
||||||
if (commit_hex->items[i].string &&
|
if (commit_hex->items[i].string &&
|
||||||
parse_oid_hex(commit_hex->items[i].string, &oid, &end))
|
parse_oid_hex(commit_hex->items[i].string, &oid, &end))
|
||||||
continue;
|
continue;
|
||||||
@ -773,12 +811,18 @@ void write_commit_graph(const char *obj_dir,
|
|||||||
oids.nr++;
|
oids.nr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stop_progress(&progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pack_indexes && !commit_hex)
|
if (!pack_indexes && !commit_hex) {
|
||||||
|
if (report_progress)
|
||||||
|
oids.progress = start_delayed_progress(
|
||||||
|
_("Finding commits for commit graph"), 0);
|
||||||
for_each_packed_object(add_packed_commits, &oids, 0);
|
for_each_packed_object(add_packed_commits, &oids, 0);
|
||||||
|
stop_progress(&oids.progress);
|
||||||
|
}
|
||||||
|
|
||||||
close_reachable(&oids);
|
close_reachable(&oids, report_progress);
|
||||||
|
|
||||||
QSORT(oids.list, oids.nr, commit_compare);
|
QSORT(oids.list, oids.nr, commit_compare);
|
||||||
|
|
||||||
@ -818,7 +862,7 @@ void write_commit_graph(const char *obj_dir,
|
|||||||
if (commits.nr >= GRAPH_PARENT_MISSING)
|
if (commits.nr >= GRAPH_PARENT_MISSING)
|
||||||
die(_("too many commits to write graph"));
|
die(_("too many commits to write graph"));
|
||||||
|
|
||||||
compute_generation_numbers(&commits);
|
compute_generation_numbers(&commits, report_progress);
|
||||||
|
|
||||||
graph_name = get_commit_graph_filename(obj_dir);
|
graph_name = get_commit_graph_filename(obj_dir);
|
||||||
if (safe_create_leading_directories(graph_name))
|
if (safe_create_leading_directories(graph_name))
|
||||||
@ -897,6 +941,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)
|
|||||||
int generation_zero = 0;
|
int generation_zero = 0;
|
||||||
struct hashfile *f;
|
struct hashfile *f;
|
||||||
int devnull;
|
int devnull;
|
||||||
|
struct progress *progress = NULL;
|
||||||
|
|
||||||
if (!g) {
|
if (!g) {
|
||||||
graph_report("no commit-graph file loaded");
|
graph_report("no commit-graph file loaded");
|
||||||
@ -964,11 +1009,14 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)
|
|||||||
if (verify_commit_graph_error & ~VERIFY_COMMIT_GRAPH_ERROR_HASH)
|
if (verify_commit_graph_error & ~VERIFY_COMMIT_GRAPH_ERROR_HASH)
|
||||||
return verify_commit_graph_error;
|
return verify_commit_graph_error;
|
||||||
|
|
||||||
|
progress = start_progress(_("Verifying commits in commit graph"),
|
||||||
|
g->num_commits);
|
||||||
for (i = 0; i < g->num_commits; i++) {
|
for (i = 0; i < g->num_commits; i++) {
|
||||||
struct commit *graph_commit, *odb_commit;
|
struct commit *graph_commit, *odb_commit;
|
||||||
struct commit_list *graph_parents, *odb_parents;
|
struct commit_list *graph_parents, *odb_parents;
|
||||||
uint32_t max_generation = 0;
|
uint32_t max_generation = 0;
|
||||||
|
|
||||||
|
display_progress(progress, i + 1);
|
||||||
hashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i);
|
hashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i);
|
||||||
|
|
||||||
graph_commit = lookup_commit(r, &cur_oid);
|
graph_commit = lookup_commit(r, &cur_oid);
|
||||||
@ -1045,6 +1093,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)
|
|||||||
graph_commit->date,
|
graph_commit->date,
|
||||||
odb_commit->date);
|
odb_commit->date);
|
||||||
}
|
}
|
||||||
|
stop_progress(&progress);
|
||||||
|
|
||||||
return verify_commit_graph_error;
|
return verify_commit_graph_error;
|
||||||
}
|
}
|
||||||
|
@ -60,11 +60,12 @@ struct commit_graph *load_commit_graph_one(const char *graph_file);
|
|||||||
*/
|
*/
|
||||||
int generation_numbers_enabled(struct repository *r);
|
int generation_numbers_enabled(struct repository *r);
|
||||||
|
|
||||||
void write_commit_graph_reachable(const char *obj_dir, int append);
|
void write_commit_graph_reachable(const char *obj_dir, int append,
|
||||||
|
int report_progress);
|
||||||
void write_commit_graph(const char *obj_dir,
|
void write_commit_graph(const char *obj_dir,
|
||||||
struct string_list *pack_indexes,
|
struct string_list *pack_indexes,
|
||||||
struct string_list *commit_hex,
|
struct string_list *commit_hex,
|
||||||
int append);
|
int append, int report_progress);
|
||||||
|
|
||||||
int verify_commit_graph(struct repository *r, struct commit_graph *g);
|
int verify_commit_graph(struct repository *r, struct commit_graph *g);
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ test_description='basic git gc tests
|
|||||||
'
|
'
|
||||||
|
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
. "$TEST_DIRECTORY"/lib-terminal.sh
|
||||||
|
|
||||||
test_expect_success 'setup' '
|
test_expect_success 'setup' '
|
||||||
# do not let the amount of physical memory affects gc
|
# 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
|
|||||||
test_line_count = 2 new # There is one new pack and its .idx
|
test_line_count = 2 new # There is one new pack and its .idx
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'gc --no-quiet' '
|
||||||
|
git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr &&
|
||||||
|
test_must_be_empty stdout &&
|
||||||
|
test_line_count = 1 stderr &&
|
||||||
|
test_i18ngrep "Computing commit graph generation numbers" stderr
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success TTY 'with TTY: gc --no-quiet' '
|
||||||
|
test_terminal git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr &&
|
||||||
|
test_must_be_empty stdout &&
|
||||||
|
test_i18ngrep "Enumerating objects" stderr &&
|
||||||
|
test_i18ngrep "Computing commit graph generation numbers" stderr
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'gc --quiet' '
|
||||||
|
git -c gc.writeCommitGraph=true gc --quiet >stdout 2>stderr &&
|
||||||
|
test_must_be_empty stdout &&
|
||||||
|
test_must_be_empty stderr
|
||||||
|
'
|
||||||
|
|
||||||
run_and_wait_for_auto_gc () {
|
run_and_wait_for_auto_gc () {
|
||||||
# We read stdout from gc for the side effect of waiting until the
|
# We read stdout from gc for the side effect of waiting until the
|
||||||
# background gc process exits, closing its fd 9. Furthermore, the
|
# background gc process exits, closing its fd 9. Furthermore, the
|
||||||
|
Loading…
Reference in New Issue
Block a user