summaryrefslogtreecommitdiff
path: root/object-file.c
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2022-01-03 16:24:14 -0800
committerLibravatar Junio C Hamano <gitster@pobox.com>2022-01-03 16:24:15 -0800
commit0dc90d954db852c6604796b8d817365f94e92a16 (patch)
tree9d4cf45af85370e4e7c89e74ff6ba74b39a28579 /object-file.c
parentMerge branch 'jc/unleak-log' (diff)
parenttmp-objdir: disable ref updates when replacing the primary odb (diff)
downloadtgif-0dc90d954db852c6604796b8d817365f94e92a16.tar.xz
Merge branch 'ns/tmp-objdir'
New interface into the tmp-objdir API to help in-core use of the quarantine feature. * ns/tmp-objdir: tmp-objdir: disable ref updates when replacing the primary odb tmp-objdir: new API for creating temporary writable databases
Diffstat (limited to 'object-file.c')
-rw-r--r--object-file.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/object-file.c b/object-file.c
index eb1426f98c..8be57f48de 100644
--- a/object-file.c
+++ b/object-file.c
@@ -680,6 +680,49 @@ void add_to_alternates_memory(const char *reference)
'\n', NULL, 0);
}
+struct object_directory *set_temporary_primary_odb(const char *dir, int will_destroy)
+{
+ struct object_directory *new_odb;
+
+ /*
+ * Make sure alternates are initialized, or else our entry may be
+ * overwritten when they are.
+ */
+ prepare_alt_odb(the_repository);
+
+ /*
+ * Make a new primary odb and link the old primary ODB in as an
+ * alternate
+ */
+ new_odb = xcalloc(1, sizeof(*new_odb));
+ new_odb->path = xstrdup(dir);
+
+ /*
+ * Disable ref updates while a temporary odb is active, since
+ * the objects in the database may roll back.
+ */
+ new_odb->disable_ref_updates = 1;
+ new_odb->will_destroy = will_destroy;
+ new_odb->next = the_repository->objects->odb;
+ the_repository->objects->odb = new_odb;
+ return new_odb->next;
+}
+
+void restore_primary_odb(struct object_directory *restore_odb, const char *old_path)
+{
+ struct object_directory *cur_odb = the_repository->objects->odb;
+
+ if (strcmp(old_path, cur_odb->path))
+ BUG("expected %s as primary object store; found %s",
+ old_path, cur_odb->path);
+
+ if (cur_odb->next != restore_odb)
+ BUG("we expect the old primary object store to be the first alternate");
+
+ the_repository->objects->odb = restore_odb;
+ free_object_directory(cur_odb);
+}
+
/*
* Compute the exact path an alternate is at and returns it. In case of
* error NULL is returned and the human readable error is added to `err`
@@ -1806,8 +1849,11 @@ int hash_object_file(const struct git_hash_algo *algo, const void *buf,
/* Finalize a file on disk, and close it. */
static void close_loose_object(int fd)
{
- if (fsync_object_files)
- fsync_or_die(fd, "loose object file");
+ if (!the_repository->objects->odb->will_destroy) {
+ if (fsync_object_files)
+ fsync_or_die(fd, "loose object file");
+ }
+
if (close(fd) != 0)
die_errno(_("error when closing loose object file"));
}