77#include "commit.h"
88#include "tag.h"
99#include "tree.h"
10+ #include "tree-walk.h"
1011#include "progress.h"
1112#include "decorate.h"
13+ #include "fsck.h"
1214
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" ;
1517
1618/* We always read in 4kB chunks. */
1719static unsigned char buffer [4096 ];
@@ -31,6 +33,16 @@ static struct obj_buffer *lookup_object_buffer(struct object *base)
3133 return lookup_decoration (& obj_decorate , base );
3234}
3335
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+
3446/*
3547 * Make sure at least "min" bytes are available in the buffer, and
3648 * return the pointer to the buffer.
@@ -134,19 +146,95 @@ static void add_delta_to_list(unsigned nr, unsigned const char *base_sha1,
134146struct obj_info {
135147 off_t offset ;
136148 unsigned char sha1 [20 ];
149+ struct object * obj ;
137150};
138151
152+ #define FLAG_OPEN (1u<<20)
153+ #define FLAG_WRITTEN (1u<<21)
154+
139155static 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+ }
140201
141202static void added_object (unsigned nr , enum object_type type ,
142203 void * data , unsigned long size );
143204
144205static void write_object (unsigned nr , enum object_type type ,
145206 void * buf , unsigned long size )
146207{
147- if (write_sha1_file (buf , size , typename (type ), obj_list [nr ].sha1 ) < 0 )
148- die ("failed to write object" );
149208 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+ }
150238}
151239
152240static void resolve_delta (unsigned nr , enum object_type type ,
@@ -163,7 +251,6 @@ static void resolve_delta(unsigned nr, enum object_type type,
163251 die ("failed to apply delta" );
164252 free (delta );
165253 write_object (nr , type , result , result_size );
166- free (result );
167254}
168255
169256static 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,
193280
194281 if (!dry_run && buf )
195282 write_object (nr , type , buf , size );
196- free (buf );
283+ else
284+ free (buf );
197285}
198286
199287static void unpack_delta_entry (enum object_type type , unsigned long delta_size ,
@@ -336,7 +424,8 @@ static void unpack_all(void)
336424 int i ;
337425 struct progress * progress = NULL ;
338426 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 );
340429
341430 if (ntohl (hdr -> hdr_signature ) != PACK_SIGNATURE )
342431 die ("bad pack file" );
@@ -347,6 +436,7 @@ static void unpack_all(void)
347436 if (!quiet )
348437 progress = start_progress ("Unpacking objects" , nr_objects );
349438 obj_list = xmalloc (nr_objects * sizeof (* obj_list ));
439+ memset (obj_list , 0 , nr_objects * sizeof (* obj_list ));
350440 for (i = 0 ; i < nr_objects ; i ++ ) {
351441 unpack_one (i );
352442 display_progress (progress , i + 1 );
@@ -382,6 +472,10 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
382472 recover = 1 ;
383473 continue ;
384474 }
475+ if (!strcmp (arg , "--strict" )) {
476+ strict = 1 ;
477+ continue ;
478+ }
385479 if (!prefixcmp (arg , "--pack_header=" )) {
386480 struct pack_header * hdr ;
387481 char * c ;
@@ -407,6 +501,8 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
407501 unpack_all ();
408502 SHA1_Update (& ctx , buffer , offset );
409503 SHA1_Final (sha1 , & ctx );
504+ if (strict )
505+ write_rest ();
410506 if (hashcmp (fill (20 ), sha1 ))
411507 die ("final sha1 did not match" );
412508 use (20 );
0 commit comments