summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2021-03-04 09:44:26 +0000
committerGitHub <noreply@github.com>2021-03-04 09:44:26 +0000
commitd7e65096cade21ea37f1fbd8fcd0c4e884187a8a (patch)
tree97f32b9fce4051f4c441763c94f69423f2fb6a3b
parentb99b5a81167c35471343da9050ae7d8692ba4139 (diff)
parent1a2f960907ebeeb703c85c5d2b61de8dbd69a1b5 (diff)
downloadlibgit2-d7e65096cade21ea37f1fbd8fcd0c4e884187a8a.tar.gz
Merge pull request #5764 from lhchavez/cgraph-needs-refresh
commit-graph: Introduce `git_commit_graph_needs_refresh()`
-rw-r--r--src/commit_graph.c34
-rw-r--r--src/commit_graph.h8
-rw-r--r--tests/graph/commit_graph.c1
3 files changed, 43 insertions, 0 deletions
diff --git a/src/commit_graph.c b/src/commit_graph.c
index 9740418e2..b301d3d49 100644
--- a/src/commit_graph.c
+++ b/src/commit_graph.c
@@ -333,6 +333,40 @@ static int git_commit_graph_entry_get_byindex(
return 0;
}
+bool git_commit_graph_needs_refresh(const git_commit_graph_file *cgraph, const char *path)
+{
+ git_file fd = -1;
+ struct stat st;
+ ssize_t bytes_read;
+ git_oid cgraph_checksum = {{0}};
+
+ if (path == NULL)
+ path = git_buf_cstr(&cgraph->filename);
+
+ /* TODO: properly open the file without access time using O_NOATIME */
+ fd = git_futils_open_ro(path);
+ if (fd < 0)
+ return true;
+
+ if (p_fstat(fd, &st) < 0) {
+ p_close(fd);
+ return true;
+ }
+
+ if (!S_ISREG(st.st_mode) || !git__is_sizet(st.st_size)
+ || (size_t)st.st_size != cgraph->graph_map.len) {
+ p_close(fd);
+ return true;
+ }
+
+ bytes_read = p_pread(fd, cgraph_checksum.id, GIT_OID_RAWSZ, st.st_size - GIT_OID_RAWSZ);
+ p_close(fd);
+ if (bytes_read != GIT_OID_RAWSZ)
+ return true;
+
+ return !git_oid_equal(&cgraph_checksum, &cgraph->checksum);
+}
+
int git_commit_graph_entry_find(
git_commit_graph_entry *e,
const git_commit_graph_file *cgraph,
diff --git a/src/commit_graph.h b/src/commit_graph.h
index f3a431705..f21a03769 100644
--- a/src/commit_graph.h
+++ b/src/commit_graph.h
@@ -89,6 +89,14 @@ typedef struct git_commit_graph_entry {
} git_commit_graph_entry;
int git_commit_graph_open(git_commit_graph_file **cgraph_out, const char *path);
+
+/*
+ * Returns whether the commit_graph_file needs to be reloaded since the
+ * contents of the commit-graph file have changed on disk. If `path` is NULL,
+ * the filename stored in `cgraph` will be used.
+ */
+bool git_commit_graph_needs_refresh(const git_commit_graph_file *cgraph, const char *path);
+
int git_commit_graph_entry_find(
git_commit_graph_entry *e,
const git_commit_graph_file *cgraph,
diff --git a/tests/graph/commit_graph.c b/tests/graph/commit_graph.c
index 43f566796..4c7c5a726 100644
--- a/tests/graph/commit_graph.c
+++ b/tests/graph/commit_graph.c
@@ -15,6 +15,7 @@ void test_graph_commit_graph__parse(void)
cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
cl_git_pass(git_buf_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph"));
cl_git_pass(git_commit_graph_open(&cgraph, git_buf_cstr(&commit_graph_path)));
+ cl_assert_equal_i(git_commit_graph_needs_refresh(cgraph, git_buf_cstr(&commit_graph_path)), 0);
cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5"));
cl_git_pass(git_commit_graph_entry_find(&e, cgraph, &id, GIT_OID_HEXSZ));