]> git.ipfire.org Git - thirdparty/git.git/commitdiff
shallow: reset commit grafts when shallow is reset
authorJonathan Tan <jonathantanmy@google.com>
Thu, 17 Mar 2022 18:24:47 +0000 (11:24 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 18 Mar 2022 00:44:38 +0000 (17:44 -0700)
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>
commit.c
commit.h
shallow.c
submodule.c
t/t5537-fetch-shallow.sh

index 98b2e556653e6002d5f4afe31cc013d82e0da042..ffcc4a97cd1163491c821d88c285aec447ed47d3 100644 (file)
--- 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;
index 3b174135bcff3e720139e687aadacf733e414bb6..21e4d25ce7878ab6463110b6b3104c7b99d159cb 100644 (file)
--- 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);
 
index 71e5876f3776e924150cf308928262e2ff0cc16e..e158be58b05591820d645a6a44423d2da97097e1 100644 (file)
--- 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)
index 5ace18a7d94b1b55e49efe468627089c71ee29fd..7a0515913c422595d8a729cc8329fe33960c1518 100644 (file)
@@ -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;
index 11d5ea54a9c621eed86d3a7d2e5a6c40da162ee8..92948de7a0083be93284de46dfb90c75cd0e1e2b 100755 (executable)
@@ -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 &&