7
7
#include "commit.h"
8
8
#include "tag.h"
9
9
#include "tree.h"
10
+ #include "tree-walk.h"
10
11
#include "progress.h"
11
12
#include "decorate.h"
13
+ #include "fsck.h"
12
14
13
- static int dry_run , quiet , recover , has_errors ;
14
- static const char unpack_usage [] = "git-unpack-objects [-n] [-q] [-r] < pack-file" ;
15
+ static int dry_run , quiet , recover , has_errors , strict ;
16
+ static const char unpack_usage [] = "git-unpack-objects [-n] [-q] [-r] [--strict] < pack-file" ;
15
17
16
18
/* We always read in 4kB chunks. */
17
19
static unsigned char buffer [4096 ];
@@ -31,6 +33,16 @@ static struct obj_buffer *lookup_object_buffer(struct object *base)
31
33
return lookup_decoration (& obj_decorate , base );
32
34
}
33
35
36
+ static void add_object_buffer (struct object * object , char * buffer , unsigned long size )
37
+ {
38
+ struct obj_buffer * obj ;
39
+ obj = xcalloc (1 , sizeof (struct obj_buffer ));
40
+ obj -> buffer = buffer ;
41
+ obj -> size = size ;
42
+ if (add_decoration (& obj_decorate , object , obj ))
43
+ die ("object %s tried to add buffer twice!" , sha1_to_hex (object -> sha1 ));
44
+ }
45
+
34
46
/*
35
47
* Make sure at least "min" bytes are available in the buffer, and
36
48
* return the pointer to the buffer.
@@ -134,19 +146,95 @@ static void add_delta_to_list(unsigned nr, unsigned const char *base_sha1,
134
146
struct obj_info {
135
147
off_t offset ;
136
148
unsigned char sha1 [20 ];
149
+ struct object * obj ;
137
150
};
138
151
152
+ #define FLAG_OPEN (1u<<20)
153
+ #define FLAG_WRITTEN (1u<<21)
154
+
139
155
static struct obj_info * obj_list ;
156
+ unsigned nr_objects ;
157
+
158
+ static void write_cached_object (struct object * obj )
159
+ {
160
+ unsigned char sha1 [20 ];
161
+ struct obj_buffer * obj_buf = lookup_object_buffer (obj );
162
+ if (write_sha1_file (obj_buf -> buffer , obj_buf -> size , typename (obj -> type ), sha1 ) < 0 )
163
+ die ("failed to write object %s" , sha1_to_hex (obj -> sha1 ));
164
+ obj -> flags |= FLAG_WRITTEN ;
165
+ }
166
+
167
+ static int check_object (struct object * obj , int type , void * data )
168
+ {
169
+ if (!obj )
170
+ return 0 ;
171
+
172
+ if (obj -> flags & FLAG_WRITTEN )
173
+ return 1 ;
174
+
175
+ if (type != OBJ_ANY && obj -> type != type )
176
+ die ("object type mismatch" );
177
+
178
+ if (!(obj -> flags & FLAG_OPEN )) {
179
+ unsigned long size ;
180
+ int type = sha1_object_info (obj -> sha1 , & size );
181
+ if (type != obj -> type || type <= 0 )
182
+ die ("object of unexpected type" );
183
+ obj -> flags |= FLAG_WRITTEN ;
184
+ return 1 ;
185
+ }
186
+
187
+ if (fsck_object (obj , 1 , fsck_error_function ))
188
+ die ("Error in object" );
189
+ if (!fsck_walk (obj , check_object , 0 ))
190
+ die ("Error on reachable objects of %s" , sha1_to_hex (obj -> sha1 ));
191
+ write_cached_object (obj );
192
+ return 1 ;
193
+ }
194
+
195
+ static void write_rest (void )
196
+ {
197
+ unsigned i ;
198
+ for (i = 0 ; i < nr_objects ; i ++ )
199
+ check_object (obj_list [i ].obj , OBJ_ANY , 0 );
200
+ }
140
201
141
202
static void added_object (unsigned nr , enum object_type type ,
142
203
void * data , unsigned long size );
143
204
144
205
static void write_object (unsigned nr , enum object_type type ,
145
206
void * buf , unsigned long size )
146
207
{
147
- if (write_sha1_file (buf , size , typename (type ), obj_list [nr ].sha1 ) < 0 )
148
- die ("failed to write object" );
149
208
added_object (nr , type , buf , size );
209
+ if (!strict ) {
210
+ if (write_sha1_file (buf , size , typename (type ), obj_list [nr ].sha1 ) < 0 )
211
+ die ("failed to write object" );
212
+ free (buf );
213
+ obj_list [nr ].obj = 0 ;
214
+ } else if (type == OBJ_BLOB ) {
215
+ struct blob * blob ;
216
+ if (write_sha1_file (buf , size , typename (type ), obj_list [nr ].sha1 ) < 0 )
217
+ die ("failed to write object" );
218
+ free (buf );
219
+
220
+ blob = lookup_blob (obj_list [nr ].sha1 );
221
+ if (blob )
222
+ blob -> object .flags |= FLAG_WRITTEN ;
223
+ else
224
+ die ("invalid blob object" );
225
+ obj_list [nr ].obj = 0 ;
226
+ } else {
227
+ struct object * obj ;
228
+ int eaten ;
229
+ hash_sha1_file (buf , size , typename (type ), obj_list [nr ].sha1 );
230
+ obj = parse_object_buffer (obj_list [nr ].sha1 , type , size , buf , & eaten );
231
+ if (!obj )
232
+ die ("invalid %s" , typename (type ));
233
+ /* buf is stored via add_object_buffer and in obj, if its a tree or commit */
234
+ add_object_buffer (obj , buf , size );
235
+ obj -> flags |= FLAG_OPEN ;
236
+ obj_list [nr ].obj = obj ;
237
+ }
150
238
}
151
239
152
240
static void resolve_delta (unsigned nr , enum object_type type ,
@@ -163,7 +251,6 @@ static void resolve_delta(unsigned nr, enum object_type type,
163
251
die ("failed to apply delta" );
164
252
free (delta );
165
253
write_object (nr , type , result , result_size );
166
- free (result );
167
254
}
168
255
169
256
static void added_object (unsigned nr , enum object_type type ,
@@ -193,7 +280,8 @@ static void unpack_non_delta_entry(enum object_type type, unsigned long size,
193
280
194
281
if (!dry_run && buf )
195
282
write_object (nr , type , buf , size );
196
- free (buf );
283
+ else
284
+ free (buf );
197
285
}
198
286
199
287
static void unpack_delta_entry (enum object_type type , unsigned long delta_size ,
@@ -336,7 +424,8 @@ static void unpack_all(void)
336
424
int i ;
337
425
struct progress * progress = NULL ;
338
426
struct pack_header * hdr = fill (sizeof (struct pack_header ));
339
- unsigned nr_objects = ntohl (hdr -> hdr_entries );
427
+
428
+ nr_objects = ntohl (hdr -> hdr_entries );
340
429
341
430
if (ntohl (hdr -> hdr_signature ) != PACK_SIGNATURE )
342
431
die ("bad pack file" );
@@ -347,6 +436,7 @@ static void unpack_all(void)
347
436
if (!quiet )
348
437
progress = start_progress ("Unpacking objects" , nr_objects );
349
438
obj_list = xmalloc (nr_objects * sizeof (* obj_list ));
439
+ memset (obj_list , 0 , nr_objects * sizeof (* obj_list ));
350
440
for (i = 0 ; i < nr_objects ; i ++ ) {
351
441
unpack_one (i );
352
442
display_progress (progress , i + 1 );
@@ -382,6 +472,10 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
382
472
recover = 1 ;
383
473
continue ;
384
474
}
475
+ if (!strcmp (arg , "--strict" )) {
476
+ strict = 1 ;
477
+ continue ;
478
+ }
385
479
if (!prefixcmp (arg , "--pack_header=" )) {
386
480
struct pack_header * hdr ;
387
481
char * c ;
@@ -407,6 +501,8 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
407
501
unpack_all ();
408
502
SHA1_Update (& ctx , buffer , offset );
409
503
SHA1_Final (sha1 , & ctx );
504
+ if (strict )
505
+ write_rest ();
410
506
if (hashcmp (fill (20 ), sha1 ))
411
507
die ("final sha1 did not match" );
412
508
use (20 );
0 commit comments