mirror of
https://github.com/git/git.git
synced 2024-11-27 03:53:55 +08:00
Merge branch 'tb/commit-graph-no-check-oids'
Clean-up the commit-graph codepath. * tb/commit-graph-no-check-oids: commit-graph: drop COMMIT_GRAPH_WRITE_CHECK_OIDS flag t5318: reorder test below 'graph_read_expect' commit-graph.c: simplify 'fill_oids_from_commits' builtin/commit-graph.c: dereference tags in builtin builtin/commit-graph.c: extract 'read_one_commit()' commit-graph.c: peel refs in 'add_ref_to_set' commit-graph.c: show progress of finding reachable commits commit-graph.c: extract 'refs_cb_data'
This commit is contained in:
commit
dc57a9be5e
@ -47,8 +47,10 @@ with `--stdin-commits` or `--reachable`.)
|
||||
+
|
||||
With the `--stdin-commits` option, generate the new commit graph by
|
||||
walking commits starting at the commits specified in stdin as a list
|
||||
of OIDs in hex, one OID per line. (Cannot be combined with
|
||||
`--stdin-packs` or `--reachable`.)
|
||||
of OIDs in hex, one OID per line. OIDs that resolve to non-commits
|
||||
(either directly, or by peeling tags) are silently ignored. OIDs that
|
||||
are malformed, or do not exist generate an error. (Cannot be combined
|
||||
with `--stdin-packs` or `--reachable`.)
|
||||
+
|
||||
With the `--reachable` option, generate the new commit graph by walking
|
||||
commits starting at all refs. (Cannot be combined with `--stdin-commits`
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "repository.h"
|
||||
#include "commit-graph.h"
|
||||
#include "object-store.h"
|
||||
#include "progress.h"
|
||||
#include "tag.h"
|
||||
|
||||
static char const * const builtin_commit_graph_usage[] = {
|
||||
N_("git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"),
|
||||
@ -138,14 +140,37 @@ static int write_option_parse_split(const struct option *opt, const char *arg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_one_commit(struct oidset *commits, struct progress *progress,
|
||||
const char *hash)
|
||||
{
|
||||
struct object *result;
|
||||
struct object_id oid;
|
||||
const char *end;
|
||||
|
||||
if (parse_oid_hex(hash, &oid, &end))
|
||||
return error(_("unexpected non-hex object ID: %s"), hash);
|
||||
|
||||
result = deref_tag(the_repository, parse_object(the_repository, &oid),
|
||||
NULL, 0);
|
||||
if (!result)
|
||||
return error(_("invalid object: %s"), hash);
|
||||
else if (object_as_type(the_repository, result, OBJ_COMMIT, 1))
|
||||
oidset_insert(commits, &result->oid);
|
||||
|
||||
display_progress(progress, oidset_size(commits));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int graph_write(int argc, const char **argv)
|
||||
{
|
||||
struct string_list *pack_indexes = NULL;
|
||||
struct string_list pack_indexes = STRING_LIST_INIT_NODUP;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct oidset commits = OIDSET_INIT;
|
||||
struct object_directory *odb = NULL;
|
||||
struct string_list lines;
|
||||
int result = 0;
|
||||
enum commit_graph_write_flags flags = 0;
|
||||
struct progress *progress = NULL;
|
||||
|
||||
static struct option builtin_commit_graph_write_options[] = {
|
||||
OPT_STRING(0, "object-dir", &opts.obj_dir,
|
||||
@ -209,44 +234,38 @@ static int graph_write(int argc, const char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
string_list_init(&lines, 0);
|
||||
if (opts.stdin_packs || opts.stdin_commits) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
if (opts.stdin_packs) {
|
||||
while (strbuf_getline(&buf, stdin) != EOF)
|
||||
string_list_append(&lines, strbuf_detach(&buf, NULL));
|
||||
string_list_append(&pack_indexes,
|
||||
strbuf_detach(&buf, NULL));
|
||||
} else if (opts.stdin_commits) {
|
||||
oidset_init(&commits, 0);
|
||||
if (opts.progress)
|
||||
progress = start_delayed_progress(
|
||||
_("Collecting commits from input"), 0);
|
||||
|
||||
if (opts.stdin_packs)
|
||||
pack_indexes = &lines;
|
||||
if (opts.stdin_commits) {
|
||||
struct string_list_item *item;
|
||||
oidset_init(&commits, lines.nr);
|
||||
for_each_string_list_item(item, &lines) {
|
||||
struct object_id oid;
|
||||
const char *end;
|
||||
|
||||
if (parse_oid_hex(item->string, &oid, &end)) {
|
||||
error(_("unexpected non-hex object ID: "
|
||||
"%s"), item->string);
|
||||
return 1;
|
||||
}
|
||||
|
||||
oidset_insert(&commits, &oid);
|
||||
while (strbuf_getline(&buf, stdin) != EOF) {
|
||||
if (read_one_commit(&commits, progress, buf.buf)) {
|
||||
result = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
flags |= COMMIT_GRAPH_WRITE_CHECK_OIDS;
|
||||
}
|
||||
|
||||
UNLEAK(buf);
|
||||
|
||||
}
|
||||
|
||||
if (write_commit_graph(odb,
|
||||
pack_indexes,
|
||||
opts.stdin_packs ? &pack_indexes : NULL,
|
||||
opts.stdin_commits ? &commits : NULL,
|
||||
flags,
|
||||
&split_opts))
|
||||
result = 1;
|
||||
|
||||
UNLEAK(lines);
|
||||
cleanup:
|
||||
string_list_clear(&pack_indexes, 0);
|
||||
strbuf_release(&buf);
|
||||
if (progress)
|
||||
stop_progress(&progress);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -881,7 +881,6 @@ struct write_commit_graph_context {
|
||||
unsigned append:1,
|
||||
report_progress:1,
|
||||
split:1,
|
||||
check_oids:1,
|
||||
changed_paths:1,
|
||||
order_by_pack:1;
|
||||
|
||||
@ -1319,13 +1318,25 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx)
|
||||
stop_progress(&progress);
|
||||
}
|
||||
|
||||
struct refs_cb_data {
|
||||
struct oidset *commits;
|
||||
struct progress *progress;
|
||||
};
|
||||
|
||||
static int add_ref_to_set(const char *refname,
|
||||
const struct object_id *oid,
|
||||
int flags, void *cb_data)
|
||||
{
|
||||
struct oidset *commits = (struct oidset *)cb_data;
|
||||
struct object_id peeled;
|
||||
struct refs_cb_data *data = (struct refs_cb_data *)cb_data;
|
||||
|
||||
if (!peel_ref(refname, &peeled))
|
||||
oid = &peeled;
|
||||
if (oid_object_info(the_repository, oid, NULL) == OBJ_COMMIT)
|
||||
oidset_insert(data->commits, oid);
|
||||
|
||||
display_progress(data->progress, oidset_size(data->commits));
|
||||
|
||||
oidset_insert(commits, oid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1334,13 +1345,22 @@ int write_commit_graph_reachable(struct object_directory *odb,
|
||||
const struct split_commit_graph_opts *split_opts)
|
||||
{
|
||||
struct oidset commits = OIDSET_INIT;
|
||||
struct refs_cb_data data;
|
||||
int result;
|
||||
|
||||
for_each_ref(add_ref_to_set, &commits);
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.commits = &commits;
|
||||
if (flags & COMMIT_GRAPH_WRITE_PROGRESS)
|
||||
data.progress = start_delayed_progress(
|
||||
_("Collecting referenced commits"), 0);
|
||||
|
||||
for_each_ref(add_ref_to_set, &data);
|
||||
result = write_commit_graph(odb, NULL, &commits,
|
||||
flags, split_opts);
|
||||
|
||||
oidset_clear(&commits);
|
||||
if (data.progress)
|
||||
stop_progress(&data.progress);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1392,46 +1412,19 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
|
||||
static int fill_oids_from_commits(struct write_commit_graph_context *ctx,
|
||||
struct oidset *commits)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
struct strbuf progress_title = STRBUF_INIT;
|
||||
struct oidset_iter iter;
|
||||
struct object_id *oid;
|
||||
|
||||
if (!oidset_size(commits))
|
||||
return 0;
|
||||
|
||||
if (ctx->report_progress) {
|
||||
strbuf_addf(&progress_title,
|
||||
Q_("Finding commits for commit graph from %d ref",
|
||||
"Finding commits for commit graph from %d refs",
|
||||
oidset_size(commits)),
|
||||
oidset_size(commits));
|
||||
ctx->progress = start_delayed_progress(
|
||||
progress_title.buf,
|
||||
oidset_size(commits));
|
||||
}
|
||||
|
||||
oidset_iter_init(commits, &iter);
|
||||
while ((oid = oidset_iter_next(&iter))) {
|
||||
struct commit *result;
|
||||
|
||||
display_progress(ctx->progress, ++i);
|
||||
|
||||
result = lookup_commit_reference_gently(ctx->r, oid, 1);
|
||||
if (result) {
|
||||
ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc);
|
||||
oidcpy(&ctx->oids.list[ctx->oids.nr], &(result->object.oid));
|
||||
ctx->oids.nr++;
|
||||
} else if (ctx->check_oids) {
|
||||
error(_("invalid commit object id: %s"),
|
||||
oid_to_hex(oid));
|
||||
return -1;
|
||||
}
|
||||
ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc);
|
||||
oidcpy(&ctx->oids.list[ctx->oids.nr], oid);
|
||||
ctx->oids.nr++;
|
||||
}
|
||||
|
||||
stop_progress(&ctx->progress);
|
||||
strbuf_release(&progress_title);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2017,7 +2010,6 @@ int write_commit_graph(struct object_directory *odb,
|
||||
ctx->append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0;
|
||||
ctx->report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0;
|
||||
ctx->split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0;
|
||||
ctx->check_oids = flags & COMMIT_GRAPH_WRITE_CHECK_OIDS ? 1 : 0;
|
||||
ctx->split_opts = split_opts;
|
||||
ctx->changed_paths = flags & COMMIT_GRAPH_WRITE_BLOOM_FILTERS ? 1 : 0;
|
||||
ctx->total_bloom_filter_data_size = 0;
|
||||
|
@ -91,9 +91,7 @@ enum commit_graph_write_flags {
|
||||
COMMIT_GRAPH_WRITE_APPEND = (1 << 0),
|
||||
COMMIT_GRAPH_WRITE_PROGRESS = (1 << 1),
|
||||
COMMIT_GRAPH_WRITE_SPLIT = (1 << 2),
|
||||
/* Make sure that each OID in the input is a valid commit OID. */
|
||||
COMMIT_GRAPH_WRITE_CHECK_OIDS = (1 << 3),
|
||||
COMMIT_GRAPH_WRITE_BLOOM_FILTERS = (1 << 4),
|
||||
COMMIT_GRAPH_WRITE_BLOOM_FILTERS = (1 << 3),
|
||||
};
|
||||
|
||||
enum commit_graph_split_flags {
|
||||
|
@ -46,15 +46,6 @@ test_expect_success 'create commits and repack' '
|
||||
git repack
|
||||
'
|
||||
|
||||
test_expect_success 'exit with correct error on bad input to --stdin-commits' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
echo HEAD | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr &&
|
||||
test_i18ngrep "unexpected non-hex object ID: HEAD" stderr &&
|
||||
# valid tree OID, but not a commit OID
|
||||
git rev-parse HEAD^{tree} | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr &&
|
||||
test_i18ngrep "invalid commit object id" stderr
|
||||
'
|
||||
|
||||
graph_git_two_modes() {
|
||||
git -c core.commitGraph=true $1 >output
|
||||
git -c core.commitGraph=false $1 >expect
|
||||
@ -95,6 +86,22 @@ graph_read_expect() {
|
||||
test_cmp expect output
|
||||
}
|
||||
|
||||
test_expect_success 'exit with correct error on bad input to --stdin-commits' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
# invalid, non-hex OID
|
||||
echo HEAD >in &&
|
||||
test_expect_code 1 git commit-graph write --stdin-commits <in 2>stderr &&
|
||||
test_i18ngrep "unexpected non-hex object ID: HEAD" stderr &&
|
||||
# non-existent OID
|
||||
echo $ZERO_OID >in &&
|
||||
test_expect_code 1 git commit-graph write --stdin-commits <in 2>stderr &&
|
||||
test_i18ngrep "invalid object" stderr &&
|
||||
# valid commit and tree OID
|
||||
git rev-parse HEAD HEAD^{tree} >in &&
|
||||
git commit-graph write --stdin-commits <in &&
|
||||
graph_read_expect 3
|
||||
'
|
||||
|
||||
test_expect_success 'write graph' '
|
||||
cd "$TRASH_DIRECTORY/full" &&
|
||||
git commit-graph write &&
|
||||
|
Loading…
Reference in New Issue
Block a user