[RFC PATCH 3/6] commit-graph: enable replace-object and grafts
From: Derrick Stolee <hidden>
Date: 2018-05-31 17:41:29
Subsystem:
the rest · Maintainer:
Linus Torvalds
Create destroy_commit_graph() method to delete the commit-graph file when history is altered by a replace-object call. If the commit-graph is rebuilt after that, we will load the correct object while reading the commit-graph. When parsing a commit, first check if the commit was grafted. If so, then ignore the commit-graph for that commit and insted use the parents loaded by parsing the commit buffer and comparing against the graft file. Signed-off-by: Derrick Stolee <redacted> --- builtin/replace.c | 3 +++ commit-graph.c | 20 +++++++++++++++++++- commit-graph.h | 9 +++++++++ commit.c | 5 +++++ 4 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/builtin/replace.c b/builtin/replace.c
index 9f01f3fc7f..d553aadcdc 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c@@ -15,6 +15,7 @@ #include "parse-options.h" #include "run-command.h" #include "tag.h" +#include "commit-graph.h" static const char * const git_replace_usage[] = { N_("git replace [-f] <object> <replacement>"),
@@ -468,6 +469,8 @@ int cmd_replace(int argc, const char **argv, const char *prefix) usage_msg_opt("--raw only makes sense with --edit", git_replace_usage, options); + destroy_commit_graph(get_object_directory()); + switch (cmdmode) { case MODE_DELETE: if (argc < 1)
diff --git a/commit-graph.c b/commit-graph.c
index e9195dfb17..95af4ed519 100644
--- a/commit-graph.c
+++ b/commit-graph.c@@ -6,6 +6,7 @@ #include "pack.h" #include "packfile.h" #include "commit.h" +#include "dir.h" #include "object.h" #include "refs.h" #include "revision.h"
@@ -240,15 +241,22 @@ static struct commit_list **insert_parent_or_die(struct commit_graph *g, { struct commit *c; struct object_id oid; + const unsigned char *real; if (pos >= g->num_commits) die("invalid parent position %"PRIu64, pos); hashcpy(oid.hash, g->chunk_oid_lookup + g->hash_len * pos); + + real = lookup_replace_object(oid.hash); + c = lookup_commit(&oid); if (!c) die("could not find commit %s", oid_to_hex(&oid)); - c->graph_pos = pos; + + if (!hashcmp(real, oid.hash)) + c->graph_pos = pos; + return &commit_list_insert(c, pptr)->next; }
@@ -1019,3 +1027,13 @@ int verify_commit_graph(struct commit_graph *g) return verify_commit_graph_error; } + +void destroy_commit_graph(const char *obj_dir) +{ + char *graph_name; + close_commit_graph(); + + graph_name = get_commit_graph_filename(obj_dir); + remove_path(graph_name); + FREE_AND_NULL(graph_name); +}
diff --git a/commit-graph.h b/commit-graph.h
index 9a06a5f188..1d17da1582 100644
--- a/commit-graph.h
+++ b/commit-graph.h@@ -56,4 +56,13 @@ void write_commit_graph(const char *obj_dir, int verify_commit_graph(struct commit_graph *g); +/* + * Delete the commit-graph file in the given object directory. + * + * WARNING: this deletes data, so should only be used when + * performing history-altering actions like replace-object + * or grafts. + */ +void destroy_commit_graph(const char *obj_dir); + #endif
diff --git a/commit.c b/commit.c
index 6eaed0174c..2fe31cde77 100644
--- a/commit.c
+++ b/commit.c@@ -403,6 +403,11 @@ int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_com return -1; if (item->object.parsed) return 0; + + prepare_commit_graft(); + if (commit_graft_pos(item->object.oid.hash) >= 0) + use_commit_graph = 0; + if (use_commit_graph && parse_commit_in_graph(item)) return 0; buffer = read_sha1_file(item->object.oid.hash, &type, &size);
--
2.16.2.338.gcfe06ae955