11#include "cache.h"
22#include "tmp-objdir.h"
3+ #include "chdir-notify.h"
34#include "dir.h"
45#include "sigchain.h"
56#include "string-list.h"
1112struct tmp_objdir {
1213 struct strbuf path ;
1314 struct strvec env ;
15+ struct object_directory * prev_odb ;
16+ int will_destroy ;
1417};
1518
1619/*
@@ -38,6 +41,9 @@ static int tmp_objdir_destroy_1(struct tmp_objdir *t, int on_signal)
3841 if (t == the_tmp_objdir )
3942 the_tmp_objdir = NULL ;
4043
44+ if (!on_signal && t -> prev_odb )
45+ restore_primary_odb (t -> prev_odb , t -> path .buf );
46+
4147 /*
4248 * This may use malloc via strbuf_grow(), but we should
4349 * 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)
5258 */
5359 if (!on_signal )
5460 tmp_objdir_free (t );
61+
5562 return err ;
5663}
5764
@@ -121,19 +128,24 @@ static int setup_tmp_objdir(const char *root)
121128 return ret ;
122129}
123130
124- struct tmp_objdir * tmp_objdir_create (void )
131+ struct tmp_objdir * tmp_objdir_create (const char * prefix )
125132{
126133 static int installed_handlers ;
127134 struct tmp_objdir * t ;
128135
129136 if (the_tmp_objdir )
130137 BUG ("only one tmp_objdir can be used at a time" );
131138
132- t = xmalloc ( sizeof (* t ));
139+ t = xcalloc ( 1 , sizeof (* t ));
133140 strbuf_init (& t -> path , 0 );
134141 strvec_init (& t -> env );
135142
136- strbuf_addf (& t -> path , "%s/incoming-XXXXXX" , get_object_directory ());
143+ /*
144+ * Use a string starting with tmp_ so that the builtin/prune.c code
145+ * can recognize any stale objdirs left behind by a crash and delete
146+ * them.
147+ */
148+ strbuf_addf (& t -> path , "%s/tmp_objdir-%s-XXXXXX" , get_object_directory (), prefix );
137149
138150 /*
139151 * 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)
269281 if (!t )
270282 return 0 ;
271283
284+ if (t -> prev_odb ) {
285+ if (the_repository -> objects -> odb -> will_destroy )
286+ BUG ("migrating an ODB that was marked for destruction" );
287+ restore_primary_odb (t -> prev_odb , t -> path .buf );
288+ t -> prev_odb = NULL ;
289+ }
290+
272291 strbuf_addbuf (& src , & t -> path );
273292 strbuf_addstr (& dst , get_object_directory ());
274293
@@ -292,3 +311,33 @@ void tmp_objdir_add_as_alternate(const struct tmp_objdir *t)
292311{
293312 add_to_alternates_memory (t -> path .buf );
294313}
314+
315+ void tmp_objdir_replace_primary_odb (struct tmp_objdir * t , int will_destroy )
316+ {
317+ if (t -> prev_odb )
318+ BUG ("the primary object database is already replaced" );
319+ t -> prev_odb = set_temporary_primary_odb (t -> path .buf , will_destroy );
320+ t -> will_destroy = will_destroy ;
321+ }
322+
323+ struct tmp_objdir * tmp_objdir_unapply_primary_odb (void )
324+ {
325+ if (!the_tmp_objdir || !the_tmp_objdir -> prev_odb )
326+ return NULL ;
327+
328+ restore_primary_odb (the_tmp_objdir -> prev_odb , the_tmp_objdir -> path .buf );
329+ the_tmp_objdir -> prev_odb = NULL ;
330+ return the_tmp_objdir ;
331+ }
332+
333+ void tmp_objdir_reapply_primary_odb (struct tmp_objdir * t , const char * old_cwd ,
334+ const char * new_cwd )
335+ {
336+ char * path ;
337+
338+ path = reparent_relative_path (old_cwd , new_cwd , t -> path .buf );
339+ strbuf_reset (& t -> path );
340+ strbuf_addstr (& t -> path , path );
341+ free (path );
342+ tmp_objdir_replace_primary_odb (t , t -> will_destroy );
343+ }
0 commit comments