@@ -296,6 +296,70 @@ static int fsck_dir(int i, char *path)
296
296
return 0 ;
297
297
}
298
298
299
+ static void read_sha1_reference (const char * path )
300
+ {
301
+ char hexname [60 ];
302
+ unsigned char sha1 [20 ];
303
+ int fd = open (path , O_RDONLY ), len ;
304
+ struct object * obj ;
305
+
306
+ if (fd < 0 )
307
+ return ;
308
+
309
+ len = read (fd , hexname , sizeof (hexname ));
310
+ close (fd );
311
+ if (len < 40 )
312
+ return ;
313
+
314
+ if (get_sha1_hex (hexname , sha1 ) < 0 )
315
+ return ;
316
+
317
+ obj = lookup_object (sha1 );
318
+ obj -> used = 1 ;
319
+ mark_reachable (obj , REACHABLE );
320
+ }
321
+
322
+ static void find_file_objects (const char * base , const char * name )
323
+ {
324
+ int baselen = strlen (base );
325
+ int namelen = strlen (name );
326
+ char * path = xmalloc (baselen + namelen + 2 );
327
+ struct stat st ;
328
+
329
+ memcpy (path , base , baselen );
330
+ path [baselen ] = '/' ;
331
+ memcpy (path + baselen + 1 , name , namelen + 1 );
332
+ if (stat (path , & st ) < 0 )
333
+ return ;
334
+
335
+ /*
336
+ * Recurse into directories
337
+ */
338
+ if (S_ISDIR (st .st_mode )) {
339
+ DIR * dir = opendir (path );
340
+ if (dir ) {
341
+ struct dirent * de ;
342
+ while ((de = readdir (dir )) != NULL ) {
343
+ if (de -> d_name [0 ] == '.' )
344
+ continue ;
345
+ find_file_objects (path , de -> d_name );
346
+ }
347
+ closedir (dir );
348
+ }
349
+ return ;
350
+ }
351
+ if (S_ISREG (st .st_mode )) {
352
+ read_sha1_reference (path );
353
+ return ;
354
+ }
355
+ }
356
+
357
+ static void get_default_heads (void )
358
+ {
359
+ char * git_dir = gitenv (GIT_DIR_ENVIRONMENT ) ? : DEFAULT_GIT_DIR_ENVIRONMENT ;
360
+ find_file_objects (git_dir , "refs" );
361
+ }
362
+
299
363
int main (int argc , char * * argv )
300
364
{
301
365
int i , heads ;
@@ -354,6 +418,16 @@ int main(int argc, char **argv)
354
418
error ("expected sha1, got %s" , arg );
355
419
}
356
420
421
+ /*
422
+ * If we've been asked to do reachability without any explicit
423
+ * head information, do the default ones from .git/refs. We also
424
+ * consider the index file in this case (ie this implies --cache).
425
+ */
426
+ if (show_unreachable && !heads ) {
427
+ get_default_heads ();
428
+ keep_cache_objects = 1 ;
429
+ }
430
+
357
431
if (keep_cache_objects ) {
358
432
int i ;
359
433
read_cache ();
@@ -368,15 +442,6 @@ int main(int argc, char **argv)
368
442
}
369
443
}
370
444
371
- if (!heads && !keep_cache_objects ) {
372
- if (show_unreachable ) {
373
- fprintf (stderr , "unable to do reachability without a head nor --cache\n" );
374
- show_unreachable = 0 ;
375
- }
376
- if (!heads )
377
- fprintf (stderr , "expect dangling commits - potential heads - due to lack of head information\n" );
378
- }
379
-
380
445
check_connectivity ();
381
446
return 0 ;
382
447
}
0 commit comments