Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeeraj Singh <neerajsi@microsoft.com>2021-12-07 01:05:04 +0300
committerJunio C Hamano <gitster@pobox.com>2021-12-09 01:06:36 +0300
commitb3cecf49eac00d62e361bf6e6e81392f5a2fb571 (patch)
treeae4937eebd6d08bb828dd1967d043369c496c945 /tmp-objdir.c
parentcefe983a320c03d7843ac78e73bd513a27806845 (diff)
tmp-objdir: new API for creating temporary writable databases
The tmp_objdir API provides the ability to create temporary object directories, but was designed with the goal of having subprocesses access these object stores, followed by the main process migrating objects from it to the main object store or just deleting it. The subprocesses would view it as their primary datastore and write to it. Here we add the tmp_objdir_replace_primary_odb function that replaces the current process's writable "main" object directory with the specified one. The previous main object directory is restored in either tmp_objdir_migrate or tmp_objdir_destroy. For the --remerge-diff usecase, add a new `will_destroy` flag in `struct object_database` to mark ephemeral object databases that do not require fsync durability. Add 'git prune' support for removing temporary object databases, and make sure that they have a name starting with tmp_ and containing an operation-specific name. Based-on-patch-by: Elijah Newren <newren@gmail.com> Signed-off-by: Neeraj Singh <neerajsi@microsoft.com> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'tmp-objdir.c')
-rw-r--r--tmp-objdir.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/tmp-objdir.c b/tmp-objdir.c
index b8d880e362..3d38eeab66 100644
--- a/tmp-objdir.c
+++ b/tmp-objdir.c
@@ -1,5 +1,6 @@
#include "cache.h"
#include "tmp-objdir.h"
+#include "chdir-notify.h"
#include "dir.h"
#include "sigchain.h"
#include "string-list.h"
@@ -11,6 +12,8 @@
struct tmp_objdir {
struct strbuf path;
struct strvec env;
+ struct object_directory *prev_odb;
+ int will_destroy;
};
/*
@@ -38,6 +41,9 @@ static int tmp_objdir_destroy_1(struct tmp_objdir *t, int on_signal)
if (t == the_tmp_objdir)
the_tmp_objdir = NULL;
+ if (!on_signal && t->prev_odb)
+ restore_primary_odb(t->prev_odb, t->path.buf);
+
/*
* This may use malloc via strbuf_grow(), but we should
* have pre-grown t->path sufficiently so that this
@@ -52,6 +58,7 @@ static int tmp_objdir_destroy_1(struct tmp_objdir *t, int on_signal)
*/
if (!on_signal)
tmp_objdir_free(t);
+
return err;
}
@@ -121,7 +128,7 @@ static int setup_tmp_objdir(const char *root)
return ret;
}
-struct tmp_objdir *tmp_objdir_create(void)
+struct tmp_objdir *tmp_objdir_create(const char *prefix)
{
static int installed_handlers;
struct tmp_objdir *t;
@@ -129,11 +136,16 @@ struct tmp_objdir *tmp_objdir_create(void)
if (the_tmp_objdir)
BUG("only one tmp_objdir can be used at a time");
- t = xmalloc(sizeof(*t));
+ t = xcalloc(1, sizeof(*t));
strbuf_init(&t->path, 0);
strvec_init(&t->env);
- strbuf_addf(&t->path, "%s/incoming-XXXXXX", get_object_directory());
+ /*
+ * Use a string starting with tmp_ so that the builtin/prune.c code
+ * can recognize any stale objdirs left behind by a crash and delete
+ * them.
+ */
+ strbuf_addf(&t->path, "%s/tmp_objdir-%s-XXXXXX", get_object_directory(), prefix);
/*
* Grow the strbuf beyond any filename we expect to be placed in it.
@@ -269,6 +281,13 @@ int tmp_objdir_migrate(struct tmp_objdir *t)
if (!t)
return 0;
+ if (t->prev_odb) {
+ if (the_repository->objects->odb->will_destroy)
+ BUG("migrating an ODB that was marked for destruction");
+ restore_primary_odb(t->prev_odb, t->path.buf);
+ t->prev_odb = NULL;
+ }
+
strbuf_addbuf(&src, &t->path);
strbuf_addstr(&dst, get_object_directory());
@@ -292,3 +311,33 @@ void tmp_objdir_add_as_alternate(const struct tmp_objdir *t)
{
add_to_alternates_memory(t->path.buf);
}
+
+void tmp_objdir_replace_primary_odb(struct tmp_objdir *t, int will_destroy)
+{
+ if (t->prev_odb)
+ BUG("the primary object database is already replaced");
+ t->prev_odb = set_temporary_primary_odb(t->path.buf, will_destroy);
+ t->will_destroy = will_destroy;
+}
+
+struct tmp_objdir *tmp_objdir_unapply_primary_odb(void)
+{
+ if (!the_tmp_objdir || !the_tmp_objdir->prev_odb)
+ return NULL;
+
+ restore_primary_odb(the_tmp_objdir->prev_odb, the_tmp_objdir->path.buf);
+ the_tmp_objdir->prev_odb = NULL;
+ return the_tmp_objdir;
+}
+
+void tmp_objdir_reapply_primary_odb(struct tmp_objdir *t, const char *old_cwd,
+ const char *new_cwd)
+{
+ char *path;
+
+ path = reparent_relative_path(old_cwd, new_cwd, t->path.buf);
+ strbuf_reset(&t->path);
+ strbuf_addstr(&t->path, path);
+ free(path);
+ tmp_objdir_replace_primary_odb(t, t->will_destroy);
+}