8
8
#include "strbuf.h"
9
9
#include "string-list.h"
10
10
#include "argv-array.h"
11
+ #include "packfile.h"
12
+ #include "object-store.h"
11
13
12
14
static int delta_base_offset = 1 ;
13
15
static int pack_kept_objects = -1 ;
@@ -83,7 +85,7 @@ static void remove_pack_on_signal(int signo)
83
85
84
86
/*
85
87
* Adds all packs hex strings to the fname list, which do not
86
- * have a corresponding .keep or .promisor file. These packs are not to
88
+ * have a corresponding .keep file. These packs are not to
87
89
* be kept if we are going to pack everything into one file.
88
90
*/
89
91
static void get_non_kept_pack_filenames (struct string_list * fname_list ,
@@ -111,8 +113,7 @@ static void get_non_kept_pack_filenames(struct string_list *fname_list,
111
113
112
114
fname = xmemdupz (e -> d_name , len );
113
115
114
- if (!file_exists (mkpath ("%s/%s.keep" , packdir , fname )) &&
115
- !file_exists (mkpath ("%s/%s.promisor" , packdir , fname )))
116
+ if (!file_exists (mkpath ("%s/%s.keep" , packdir , fname )))
116
117
string_list_append_nodup (fname_list , fname );
117
118
else
118
119
free (fname );
@@ -122,7 +123,7 @@ static void get_non_kept_pack_filenames(struct string_list *fname_list,
122
123
123
124
static void remove_redundant_pack (const char * dir_name , const char * base_name )
124
125
{
125
- const char * exts [] = {".pack" , ".idx" , ".keep" , ".bitmap" };
126
+ const char * exts [] = {".pack" , ".idx" , ".keep" , ".bitmap" , ".promisor" };
126
127
int i ;
127
128
struct strbuf buf = STRBUF_INIT ;
128
129
size_t plen ;
@@ -138,6 +139,117 @@ static void remove_redundant_pack(const char *dir_name, const char *base_name)
138
139
strbuf_release (& buf );
139
140
}
140
141
142
+ struct pack_objects_args {
143
+ const char * window ;
144
+ const char * window_memory ;
145
+ const char * depth ;
146
+ const char * threads ;
147
+ const char * max_pack_size ;
148
+ int no_reuse_delta ;
149
+ int no_reuse_object ;
150
+ int quiet ;
151
+ int local ;
152
+ };
153
+
154
+ static void prepare_pack_objects (struct child_process * cmd ,
155
+ const struct pack_objects_args * args )
156
+ {
157
+ argv_array_push (& cmd -> args , "pack-objects" );
158
+ if (args -> window )
159
+ argv_array_pushf (& cmd -> args , "--window=%s" , args -> window );
160
+ if (args -> window_memory )
161
+ argv_array_pushf (& cmd -> args , "--window-memory=%s" , args -> window_memory );
162
+ if (args -> depth )
163
+ argv_array_pushf (& cmd -> args , "--depth=%s" , args -> depth );
164
+ if (args -> threads )
165
+ argv_array_pushf (& cmd -> args , "--threads=%s" , args -> threads );
166
+ if (args -> max_pack_size )
167
+ argv_array_pushf (& cmd -> args , "--max-pack-size=%s" , args -> max_pack_size );
168
+ if (args -> no_reuse_delta )
169
+ argv_array_pushf (& cmd -> args , "--no-reuse-delta" );
170
+ if (args -> no_reuse_object )
171
+ argv_array_pushf (& cmd -> args , "--no-reuse-object" );
172
+ if (args -> local )
173
+ argv_array_push (& cmd -> args , "--local" );
174
+ if (args -> quiet )
175
+ argv_array_push (& cmd -> args , "--quiet" );
176
+ if (delta_base_offset )
177
+ argv_array_push (& cmd -> args , "--delta-base-offset" );
178
+ argv_array_push (& cmd -> args , packtmp );
179
+ cmd -> git_cmd = 1 ;
180
+ cmd -> out = -1 ;
181
+ }
182
+
183
+ /*
184
+ * Write oid to the given struct child_process's stdin, starting it first if
185
+ * necessary.
186
+ */
187
+ static int write_oid (const struct object_id * oid , struct packed_git * pack ,
188
+ uint32_t pos , void * data )
189
+ {
190
+ struct child_process * cmd = data ;
191
+
192
+ if (cmd -> in == -1 ) {
193
+ if (start_command (cmd ))
194
+ die ("Could not start pack-objects to repack promisor objects" );
195
+ }
196
+
197
+ xwrite (cmd -> in , oid_to_hex (oid ), GIT_SHA1_HEXSZ );
198
+ xwrite (cmd -> in , "\n" , 1 );
199
+ return 0 ;
200
+ }
201
+
202
+ static void repack_promisor_objects (const struct pack_objects_args * args ,
203
+ struct string_list * names )
204
+ {
205
+ struct child_process cmd = CHILD_PROCESS_INIT ;
206
+ FILE * out ;
207
+ struct strbuf line = STRBUF_INIT ;
208
+
209
+ prepare_pack_objects (& cmd , args );
210
+ cmd .in = -1 ;
211
+
212
+ /*
213
+ * NEEDSWORK: Giving pack-objects only the OIDs without any ordering
214
+ * hints may result in suboptimal deltas in the resulting pack. See if
215
+ * the OIDs can be sent with fake paths such that pack-objects can use a
216
+ * {type -> existing pack order} ordering when computing deltas instead
217
+ * of a {type -> size} ordering, which may produce better deltas.
218
+ */
219
+ for_each_packed_object (write_oid , & cmd ,
220
+ FOR_EACH_OBJECT_PROMISOR_ONLY );
221
+
222
+ if (cmd .in == -1 )
223
+ /* No packed objects; cmd was never started */
224
+ return ;
225
+
226
+ close (cmd .in );
227
+
228
+ out = xfdopen (cmd .out , "r" );
229
+ while (strbuf_getline_lf (& line , out ) != EOF ) {
230
+ char * promisor_name ;
231
+ int fd ;
232
+ if (line .len != 40 )
233
+ die ("repack: Expecting 40 character sha1 lines only from pack-objects." );
234
+ string_list_append (names , line .buf );
235
+
236
+ /*
237
+ * pack-objects creates the .pack and .idx files, but not the
238
+ * .promisor file. Create the .promisor file, which is empty.
239
+ */
240
+ promisor_name = mkpathdup ("%s-%s.promisor" , packtmp ,
241
+ line .buf );
242
+ fd = open (promisor_name , O_CREAT |O_EXCL |O_WRONLY , 0600 );
243
+ if (fd < 0 )
244
+ die_errno ("unable to create '%s'" , promisor_name );
245
+ close (fd );
246
+ free (promisor_name );
247
+ }
248
+ fclose (out );
249
+ if (finish_command (& cmd ))
250
+ die ("Could not finish pack-objects to repack promisor objects" );
251
+ }
252
+
141
253
#define ALL_INTO_ONE 1
142
254
#define LOOSEN_UNREACHABLE 2
143
255
@@ -150,6 +262,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
150
262
{".pack" },
151
263
{".idx" },
152
264
{".bitmap" , 1 },
265
+ {".promisor" , 1 },
153
266
};
154
267
struct child_process cmd = CHILD_PROCESS_INIT ;
155
268
struct string_list_item * item ;
@@ -165,15 +278,9 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
165
278
int delete_redundant = 0 ;
166
279
const char * unpack_unreachable = NULL ;
167
280
int keep_unreachable = 0 ;
168
- const char * window = NULL , * window_memory = NULL ;
169
- const char * depth = NULL ;
170
- const char * threads = NULL ;
171
- const char * max_pack_size = NULL ;
172
281
struct string_list keep_pack_list = STRING_LIST_INIT_NODUP ;
173
- int no_reuse_delta = 0 , no_reuse_object = 0 ;
174
282
int no_update_server_info = 0 ;
175
- int quiet = 0 ;
176
- int local = 0 ;
283
+ struct pack_objects_args po_args = {NULL };
177
284
178
285
struct option builtin_repack_options [] = {
179
286
OPT_BIT ('a' , NULL , & pack_everything ,
@@ -183,30 +290,30 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
183
290
LOOSEN_UNREACHABLE | ALL_INTO_ONE ),
184
291
OPT_BOOL ('d' , NULL , & delete_redundant ,
185
292
N_ ("remove redundant packs, and run git-prune-packed" )),
186
- OPT_BOOL ('f' , NULL , & no_reuse_delta ,
293
+ OPT_BOOL ('f' , NULL , & po_args . no_reuse_delta ,
187
294
N_ ("pass --no-reuse-delta to git-pack-objects" )),
188
- OPT_BOOL ('F' , NULL , & no_reuse_object ,
295
+ OPT_BOOL ('F' , NULL , & po_args . no_reuse_object ,
189
296
N_ ("pass --no-reuse-object to git-pack-objects" )),
190
297
OPT_BOOL ('n' , NULL , & no_update_server_info ,
191
298
N_ ("do not run git-update-server-info" )),
192
- OPT__QUIET (& quiet , N_ ("be quiet" )),
193
- OPT_BOOL ('l' , "local" , & local ,
299
+ OPT__QUIET (& po_args . quiet , N_ ("be quiet" )),
300
+ OPT_BOOL ('l' , "local" , & po_args . local ,
194
301
N_ ("pass --local to git-pack-objects" )),
195
302
OPT_BOOL ('b' , "write-bitmap-index" , & write_bitmaps ,
196
303
N_ ("write bitmap index" )),
197
304
OPT_STRING (0 , "unpack-unreachable" , & unpack_unreachable , N_ ("approxidate" ),
198
305
N_ ("with -A, do not loosen objects older than this" )),
199
306
OPT_BOOL ('k' , "keep-unreachable" , & keep_unreachable ,
200
307
N_ ("with -a, repack unreachable objects" )),
201
- OPT_STRING (0 , "window" , & window , N_ ("n" ),
308
+ OPT_STRING (0 , "window" , & po_args . window , N_ ("n" ),
202
309
N_ ("size of the window used for delta compression" )),
203
- OPT_STRING (0 , "window-memory" , & window_memory , N_ ("bytes" ),
310
+ OPT_STRING (0 , "window-memory" , & po_args . window_memory , N_ ("bytes" ),
204
311
N_ ("same as the above, but limit memory size instead of entries count" )),
205
- OPT_STRING (0 , "depth" , & depth , N_ ("n" ),
312
+ OPT_STRING (0 , "depth" , & po_args . depth , N_ ("n" ),
206
313
N_ ("limits the maximum delta depth" )),
207
- OPT_STRING (0 , "threads" , & threads , N_ ("n" ),
314
+ OPT_STRING (0 , "threads" , & po_args . threads , N_ ("n" ),
208
315
N_ ("limits the maximum number of threads" )),
209
- OPT_STRING (0 , "max-pack-size" , & max_pack_size , N_ ("bytes" ),
316
+ OPT_STRING (0 , "max-pack-size" , & po_args . max_pack_size , N_ ("bytes" ),
210
317
N_ ("maximum size of each packfile" )),
211
318
OPT_BOOL (0 , "pack-kept-objects" , & pack_kept_objects ,
212
319
N_ ("repack objects in packs marked with .keep" )),
@@ -238,7 +345,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
238
345
239
346
sigchain_push_common (remove_pack_on_signal );
240
347
241
- argv_array_push (& cmd .args , "pack-objects" );
348
+ prepare_pack_objects (& cmd , & po_args );
349
+
242
350
argv_array_push (& cmd .args , "--keep-true-parents" );
243
351
if (!pack_kept_objects )
244
352
argv_array_push (& cmd .args , "--honor-pack-keep" );
@@ -251,26 +359,14 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
251
359
argv_array_push (& cmd .args , "--indexed-objects" );
252
360
if (repository_format_partial_clone )
253
361
argv_array_push (& cmd .args , "--exclude-promisor-objects" );
254
- if (window )
255
- argv_array_pushf (& cmd .args , "--window=%s" , window );
256
- if (window_memory )
257
- argv_array_pushf (& cmd .args , "--window-memory=%s" , window_memory );
258
- if (depth )
259
- argv_array_pushf (& cmd .args , "--depth=%s" , depth );
260
- if (threads )
261
- argv_array_pushf (& cmd .args , "--threads=%s" , threads );
262
- if (max_pack_size )
263
- argv_array_pushf (& cmd .args , "--max-pack-size=%s" , max_pack_size );
264
- if (no_reuse_delta )
265
- argv_array_pushf (& cmd .args , "--no-reuse-delta" );
266
- if (no_reuse_object )
267
- argv_array_pushf (& cmd .args , "--no-reuse-object" );
268
362
if (write_bitmaps )
269
363
argv_array_push (& cmd .args , "--write-bitmap-index" );
270
364
271
365
if (pack_everything & ALL_INTO_ONE ) {
272
366
get_non_kept_pack_filenames (& existing_packs , & keep_pack_list );
273
367
368
+ repack_promisor_objects (& po_args , & names );
369
+
274
370
if (existing_packs .nr && delete_redundant ) {
275
371
if (unpack_unreachable ) {
276
372
argv_array_pushf (& cmd .args ,
@@ -292,17 +388,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
292
388
argv_array_push (& cmd .args , "--incremental" );
293
389
}
294
390
295
- if (local )
296
- argv_array_push (& cmd .args , "--local" );
297
- if (quiet )
298
- argv_array_push (& cmd .args , "--quiet" );
299
- if (delta_base_offset )
300
- argv_array_push (& cmd .args , "--delta-base-offset" );
301
-
302
- argv_array_push (& cmd .args , packtmp );
303
-
304
- cmd .git_cmd = 1 ;
305
- cmd .out = -1 ;
306
391
cmd .no_stdin = 1 ;
307
392
308
393
ret = start_command (& cmd );
@@ -320,7 +405,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
320
405
if (ret )
321
406
return ret ;
322
407
323
- if (!names .nr && !quiet )
408
+ if (!names .nr && !po_args . quiet )
324
409
printf ("Nothing new to pack.\n" );
325
410
326
411
/*
@@ -429,6 +514,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
429
514
430
515
/* End of pack replacement. */
431
516
517
+ reprepare_packed_git (the_repository );
518
+
432
519
if (delete_redundant ) {
433
520
int opts = 0 ;
434
521
string_list_sort (& names );
@@ -441,7 +528,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
441
528
if (!string_list_has_string (& names , sha1 ))
442
529
remove_redundant_pack (packdir , item -> string );
443
530
}
444
- if (!quiet && isatty (2 ))
531
+ if (!po_args . quiet && isatty (2 ))
445
532
opts |= PRUNE_PACKED_VERBOSE ;
446
533
prune_packed_objects (opts );
447
534
}
0 commit comments