summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Tan <jonathantanmy@google.com>2022-03-17 18:24:47 (GMT)
committerJunio C Hamano <gitster@pobox.com>2022-03-18 00:44:38 (GMT)
commit2a69ff09d5654de31361365e3faf9f8495f03ed7 (patch)
tree8fb41bab337ed067f76a2e75883345fde0e277dd
parent74cc1aa55f30ed76424a0e7226ab519aa6265061 (diff)
downloadgit-2a69ff09d5654de31361365e3faf9f8495f03ed7.zip
git-2a69ff09d5654de31361365e3faf9f8495f03ed7.tar.gz
git-2a69ff09d5654de31361365e3faf9f8495f03ed7.tar.bz2
shallow: reset commit grafts when shallow is reset
When reset_repository_shallow() is called, Git clears its cache of shallow information, so that if shallow information is re-requested, Git will read fresh data from disk instead of reusing its stale cached data. However, the cache of commit grafts is not likewise cleared, even though there are commit grafts created from shallow information. This means that if on-disk shallow information were to be updated and then a commit-graft-using codepath were run (for example, a revision walk), Git would be using stale commit graft information. This can be seen from the test in this patch, in which Git performs a revision walk (to check for changed submodules) after a fetch with --update-shallow. Therefore, clear the cache of commit grafts whenever reset_repository_shallow() is called. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--commit.c10
-rw-r--r--commit.h1
-rw-r--r--shallow.c1
-rw-r--r--submodule.c1
-rwxr-xr-xt/t5537-fetch-shallow.sh9
5 files changed, 22 insertions, 0 deletions
diff --git a/commit.c b/commit.c
index 98b2e55..ffcc4a9 100644
--- a/commit.c
+++ b/commit.c
@@ -249,6 +249,16 @@ int for_each_commit_graft(each_commit_graft_fn fn, void *cb_data)
return ret;
}
+void reset_commit_grafts(struct repository *r)
+{
+ int i;
+
+ for (i = 0; i < r->parsed_objects->grafts_nr; i++)
+ free(r->parsed_objects->grafts[i]);
+ r->parsed_objects->grafts_nr = 0;
+ r->parsed_objects->commit_graft_prepared = 0;
+}
+
struct commit_buffer {
void *buffer;
unsigned long size;
diff --git a/commit.h b/commit.h
index 3b17413..21e4d25 100644
--- a/commit.h
+++ b/commit.h
@@ -249,6 +249,7 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid);
int register_commit_graft(struct repository *r, struct commit_graft *, int);
void prepare_commit_graft(struct repository *r);
struct commit_graft *lookup_commit_graft(struct repository *r, const struct object_id *oid);
+void reset_commit_grafts(struct repository *r);
struct commit *get_fork_point(const char *refname, struct commit *commit);
diff --git a/shallow.c b/shallow.c
index 71e5876..e158be5 100644
--- a/shallow.c
+++ b/shallow.c
@@ -90,6 +90,7 @@ static void reset_repository_shallow(struct repository *r)
{
r->parsed_objects->is_shallow = -1;
stat_validity_clear(r->parsed_objects->shallow_stat);
+ reset_commit_grafts(r);
}
int commit_shallow_file(struct repository *r, struct shallow_lock *lk)
diff --git a/submodule.c b/submodule.c
index 5ace18a..7a05159 100644
--- a/submodule.c
+++ b/submodule.c
@@ -22,6 +22,7 @@
#include "parse-options.h"
#include "object-store.h"
#include "commit-reach.h"
+#include "shallow.h"
static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
static int initialized_fetch_ref_tips;
diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
index 11d5ea5..92948de 100755
--- a/t/t5537-fetch-shallow.sh
+++ b/t/t5537-fetch-shallow.sh
@@ -161,6 +161,15 @@ test_expect_success 'fetch --update-shallow' '
)
'
+test_expect_success 'fetch --update-shallow into a repo with submodules' '
+ git init a-submodule &&
+ test_commit -C a-submodule foo &&
+ git init repo-with-sub &&
+ git -C repo-with-sub submodule add ../a-submodule a-submodule &&
+ git -C repo-with-sub commit -m "added submodule" &&
+ git -C repo-with-sub fetch --update-shallow ../shallow/.git refs/heads/*:refs/remotes/shallow/*
+'
+
test_expect_success 'fetch --update-shallow (with fetch.writeCommitGraph)' '
(
cd shallow &&