提交 dea6737b 编写于 作者: J Junio C Hamano

Merge branch 'ds/close-object-store' into maint

The commit-graph file is now part of the "files that the runtime
may keep open file descriptors on, all of which would need to be
closed when done with the object store", and the file descriptor to
an existing commit-graph file now is closed before "gc" finalizes a
new instance to replace it.

* ds/close-object-store:
  packfile: rename close_all_packs to close_object_store
  packfile: close commit-graph in close_all_packs
  commit-graph: use raw_object_store when closing
  commit-graph: extract write_commit_graph_file()
  commit-graph: extract copy_oids_to_commits()
  commit-graph: extract count_distinct_commits()
  commit-graph: extract fill_oids_from_all_packs()
  commit-graph: extract fill_oids_from_commit_hex()
  commit-graph: extract fill_oids_from_packs()
  commit-graph: create write_commit_graph_context
  commit-graph: remove Future Work section
  commit-graph: collapse parameters into flags
  commit-graph: return with errors during write
  commit-graph: fix the_repository reference
......@@ -127,23 +127,6 @@ Design Details
helpful for these clones, anyway. The commit-graph will not be read or
written when shallow commits are present.
Future Work
-----------
- After computing and storing generation numbers, we must make graph
walks aware of generation numbers to gain the performance benefits they
enable. This will mostly be accomplished by swapping a commit-date-ordered
priority queue with one ordered by generation number. The following
operations are important candidates:
- 'log --topo-order'
- 'tag --merged'
- A server could provide a commit-graph file as part of the network protocol
to avoid extra calculations by clients. This feature is only of benefit if
the user is willing to trust the file, because verifying the file is correct
is as hard as computing it from scratch.
Related Links
-------------
[0] https://bugs.chromium.org/p/git/issues/detail?id=8
......
......@@ -1801,7 +1801,7 @@ static void am_run(struct am_state *state, int resume)
*/
if (!state->rebasing) {
am_destroy(state);
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
}
}
......
......@@ -1245,7 +1245,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
transport_disconnect(transport);
if (option_dissociate) {
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
dissociate_from_references();
}
......
......@@ -141,6 +141,8 @@ static int graph_write(int argc, const char **argv)
struct string_list *pack_indexes = NULL;
struct string_list *commit_hex = NULL;
struct string_list lines;
int result = 0;
unsigned int flags = COMMIT_GRAPH_PROGRESS;
static struct option builtin_commit_graph_write_options[] = {
OPT_STRING(0, "object-dir", &opts.obj_dir,
......@@ -165,13 +167,13 @@ static int graph_write(int argc, const char **argv)
die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs"));
if (!opts.obj_dir)
opts.obj_dir = get_object_directory();
if (opts.append)
flags |= COMMIT_GRAPH_APPEND;
read_replace_refs = 0;
if (opts.reachable) {
write_commit_graph_reachable(opts.obj_dir, opts.append, 1);
return 0;
}
if (opts.reachable)
return write_commit_graph_reachable(opts.obj_dir, flags);
string_list_init(&lines, 0);
if (opts.stdin_packs || opts.stdin_commits) {
......@@ -188,14 +190,14 @@ static int graph_write(int argc, const char **argv)
UNLEAK(buf);
}
write_commit_graph(opts.obj_dir,
pack_indexes,
commit_hex,
opts.append,
1);
if (write_commit_graph(opts.obj_dir,
pack_indexes,
commit_hex,
flags))
result = 1;
UNLEAK(lines);
return 0;
return result;
}
int cmd_commit_graph(int argc, const char **argv, const char *prefix)
......
......@@ -1669,8 +1669,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
"new_index file. Check that disk is not full and quota is\n"
"not exceeded, and then \"git reset HEAD\" to recover."));
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
write_commit_graph_reachable(get_object_directory(), 0, 0);
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
write_commit_graph_reachable(get_object_directory(), 0))
return 1;
repo_rerere(the_repository, 0);
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
......
......@@ -1672,7 +1672,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
string_list_clear(&list, 0);
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL);
if (verbosity < 0)
......
......@@ -653,7 +653,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
gc_before_repack();
if (!repository_format_precious_objects) {
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
if (run_command_v_opt(repack.argv, RUN_GIT_CMD))
die(FAILED_RUN, repack.argv[0]);
......@@ -681,13 +681,14 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
report_garbage = report_pack_garbage;
reprepare_packed_git(the_repository);
if (pack_garbage.nr > 0) {
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
clean_pack_garbage();
}
if (gc_write_commit_graph)
write_commit_graph_reachable(get_object_directory(), 0,
!quiet && !daemonized);
if (gc_write_commit_graph &&
write_commit_graph_reachable(get_object_directory(),
!quiet && !daemonized ? COMMIT_GRAPH_PROGRESS : 0))
return 1;
if (auto_gc && too_many_loose_objects())
warning(_("There are too many unreachable loose objects; "
......
......@@ -457,7 +457,7 @@ static void finish(struct commit *head_commit,
* We ignore errors in 'gc --auto', since the
* user should see them.
*/
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
}
}
......
......@@ -742,7 +742,7 @@ static int finish_rebase(struct rebase_options *opts)
delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
apply_autostash(opts);
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
/*
* We ignore errors in 'gc --auto', since the
* user should see them.
......
......@@ -2043,7 +2043,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
proc.git_cmd = 1;
proc.argv = argv_gc_auto;
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
if (!start_command(&proc)) {
if (use_sideband)
copy_to_sideband(proc.err, -1, NULL);
......
......@@ -422,7 +422,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (!names.nr && !po_args.quiet)
printf_ln(_("Nothing new to pack."));
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
/*
* Ok we have prepared all new packfiles.
......
此差异已折叠。
......@@ -65,16 +65,24 @@ struct commit_graph *parse_commit_graph(void *graph_map, int fd,
*/
int generation_numbers_enabled(struct repository *r);
void write_commit_graph_reachable(const char *obj_dir, int append,
int report_progress);
void write_commit_graph(const char *obj_dir,
struct string_list *pack_indexes,
struct string_list *commit_hex,
int append, int report_progress);
#define COMMIT_GRAPH_APPEND (1 << 0)
#define COMMIT_GRAPH_PROGRESS (1 << 1)
/*
* The write_commit_graph* methods return zero on success
* and a negative value on failure. Note that if the repository
* is not compatible with the commit-graph feature, then the
* methods will return 0 without writing a commit-graph.
*/
int write_commit_graph_reachable(const char *obj_dir, unsigned int flags);
int write_commit_graph(const char *obj_dir,
struct string_list *pack_indexes,
struct string_list *commit_hex,
unsigned int flags);
int verify_commit_graph(struct repository *r, struct commit_graph *g);
void close_commit_graph(struct repository *);
void close_commit_graph(struct raw_object_store *);
void free_commit_graph(struct commit_graph *);
#endif
......@@ -449,7 +449,7 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
item->date = parse_commit_date(bufptr, tail);
if (check_graph)
load_commit_graph_info(the_repository, item);
load_commit_graph_info(r, item);
return 0;
}
......
......@@ -517,7 +517,7 @@ void raw_object_store_clear(struct raw_object_store *o)
o->loaded_alternates = 0;
INIT_LIST_HEAD(&o->packed_git_mru);
close_all_packs(o);
close_object_store(o);
o->packed_git = NULL;
}
......
......@@ -16,6 +16,7 @@
#include "tree.h"
#include "object-store.h"
#include "midx.h"
#include "commit-graph.h"
char *odb_pack_name(struct strbuf *buf,
const unsigned char *sha1,
......@@ -336,7 +337,7 @@ void close_pack(struct packed_git *p)
close_pack_index(p);
}
void close_all_packs(struct raw_object_store *o)
void close_object_store(struct raw_object_store *o)
{
struct packed_git *p;
......@@ -350,6 +351,8 @@ void close_all_packs(struct raw_object_store *o)
close_midx(o->multi_pack_index);
o->multi_pack_index = NULL;
}
close_commit_graph(o);
}
/*
......
......@@ -90,7 +90,7 @@ uint32_t get_pack_fanout(struct packed_git *p, uint32_t value);
unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);
void close_pack_windows(struct packed_git *);
void close_pack(struct packed_git *);
void close_all_packs(struct raw_object_store *o);
void close_object_store(struct raw_object_store *o);
void unuse_pack(struct pack_window **);
void clear_delta_base_cache(void);
struct packed_git *add_packed_git(const char *path, size_t path_len, int local);
......
......@@ -23,6 +23,14 @@ test_expect_success 'write graph with no packs' '
test_path_is_file info/commit-graph
'
test_expect_success 'close with correct error on bad input' '
cd "$TRASH_DIRECTORY/full" &&
echo doesnotexist >in &&
{ git commit-graph write --stdin-packs <in 2>stderr; ret=$?; } &&
test "$ret" = 1 &&
test_i18ngrep "error adding pack" stderr
'
test_expect_success 'create commits and repack' '
cd "$TRASH_DIRECTORY/full" &&
for i in $(test_seq 3)
......
......@@ -722,7 +722,7 @@ static void deepen_by_rev_list(struct packet_writer *writer, int ac,
{
struct commit_list *result;
close_commit_graph(the_repository);
close_commit_graph(the_repository->objects);
result = get_shallow_commits_by_rev_list(ac, av, SHALLOW, NOT_SHALLOW);
send_shallow(writer, result);
free_commit_list(result);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册