diff --git a/odb.c b/odb.c index e5aa8deb88..86f7cf70a8 100644 --- a/odb.c +++ b/odb.c @@ -1,6 +1,5 @@ #include "git-compat-util.h" #include "abspath.h" -#include "chdir-notify.h" #include "commit-graph.h" #include "config.h" #include "dir.h" @@ -1037,38 +1036,6 @@ int odb_write_object_stream(struct object_database *odb, return odb_source_loose_write_stream(odb->sources, stream, len, oid); } -static void odb_update_commondir(const char *name UNUSED, - const char *old_cwd, - const char *new_cwd, - void *cb_data) -{ - struct object_database *odb = cb_data; - struct tmp_objdir *tmp_objdir; - struct odb_source *source; - - tmp_objdir = tmp_objdir_unapply_primary_odb(); - - /* - * In theory, we only have to do this for the primary object source, as - * alternates' paths are always resolved to an absolute path. - */ - for (source = odb->sources; source; source = source->next) { - char *path; - - if (is_absolute_path(source->path)) - continue; - - path = reparent_relative_path(old_cwd, new_cwd, - source->path); - - free(source->path); - source->path = path; - } - - if (tmp_objdir) - tmp_objdir_reapply_primary_odb(tmp_objdir, old_cwd, new_cwd); -} - struct object_database *odb_new(struct repository *repo, const char *primary_source, const char *secondary_sources) @@ -1089,8 +1056,6 @@ struct object_database *odb_new(struct repository *repo, free(to_free); - chdir_notify_register(NULL, odb_update_commondir, o); - return o; } @@ -1136,8 +1101,6 @@ void odb_free(struct object_database *o) string_list_clear(&o->submodule_source_paths, 0); - chdir_notify_unregister(NULL, odb_update_commondir, o); - free(o); } diff --git a/odb/source-files.c b/odb/source-files.c index a43a197157..df0ea9ee62 100644 --- a/odb/source-files.c +++ b/odb/source-files.c @@ -1,13 +1,28 @@ #include "git-compat-util.h" +#include "abspath.h" +#include "chdir-notify.h" #include "object-file.h" #include "odb/source.h" #include "odb/source-files.h" #include "packfile.h" +static void odb_source_files_reparent(const char *name UNUSED, + const char *old_cwd, + const char *new_cwd, + void *cb_data) +{ + struct odb_source_files *files = cb_data; + char *path = reparent_relative_path(old_cwd, new_cwd, + files->base.path); + free(files->base.path); + files->base.path = path; +} + void odb_source_files_free(struct odb_source_files *files) { if (!files) return; + chdir_notify_unregister(NULL, odb_source_files_reparent, files); odb_source_loose_free(files->loose); packfile_store_free(files->packed); odb_source_release(&files->base); @@ -25,5 +40,13 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb, files->loose = odb_source_loose_new(&files->base); files->packed = packfile_store_new(&files->base); + /* + * Ideally, we would only ever store absolute paths in the source. This + * is not (yet) possible though because we access and assume relative + * paths in the primary ODB source in some user-facing functionality. + */ + if (!is_absolute_path(path)) + chdir_notify_register(NULL, odb_source_files_reparent, files); + return files; } diff --git a/tmp-objdir.c b/tmp-objdir.c index 9f5a1788cd..e436eed07e 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -36,6 +36,21 @@ static void tmp_objdir_free(struct tmp_objdir *t) free(t); } +static void tmp_objdir_reparent(const char *name UNUSED, + const char *old_cwd, + const char *new_cwd, + void *cb_data) +{ + struct tmp_objdir *t = cb_data; + char *path; + + path = reparent_relative_path(old_cwd, new_cwd, + t->path.buf); + strbuf_reset(&t->path); + strbuf_addstr(&t->path, path); + free(path); +} + int tmp_objdir_destroy(struct tmp_objdir *t) { int err; @@ -51,6 +66,7 @@ int tmp_objdir_destroy(struct tmp_objdir *t) err = remove_dir_recursively(&t->path, 0); + chdir_notify_unregister(NULL, tmp_objdir_reparent, t); tmp_objdir_free(t); return err; @@ -137,6 +153,9 @@ struct tmp_objdir *tmp_objdir_create(struct repository *r, strbuf_addf(&t->path, "%s/tmp_objdir-%s-XXXXXX", repo_get_object_directory(r), prefix); + if (!is_absolute_path(t->path.buf)) + chdir_notify_register(NULL, tmp_objdir_reparent, t); + if (!mkdtemp(t->path.buf)) { /* free, not destroy, as we never touched the filesystem */ tmp_objdir_free(t); @@ -315,26 +334,3 @@ void tmp_objdir_replace_primary_odb(struct tmp_objdir *t, int will_destroy) 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_source) - return NULL; - - odb_restore_primary_source(the_tmp_objdir->repo->objects, - the_tmp_objdir->prev_source, the_tmp_objdir->path.buf); - the_tmp_objdir->prev_source = 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); -} diff --git a/tmp-objdir.h b/tmp-objdir.h index fceda14979..ccf800faa7 100644 --- a/tmp-objdir.h +++ b/tmp-objdir.h @@ -68,19 +68,4 @@ void tmp_objdir_add_as_alternate(const struct tmp_objdir *); */ void tmp_objdir_replace_primary_odb(struct tmp_objdir *, int will_destroy); -/* - * If the primary object database was replaced by a temporary object directory, - * restore it to its original value while keeping the directory contents around. - * Returns NULL if the primary object database was not replaced. - */ -struct tmp_objdir *tmp_objdir_unapply_primary_odb(void); - -/* - * Reapplies the former primary temporary object database, after potentially - * changing its relative path. - */ -void tmp_objdir_reapply_primary_odb(struct tmp_objdir *, const char *old_cwd, - const char *new_cwd); - - #endif /* TMP_OBJDIR_H */