1
1
#include "cache.h"
2
2
#include "config.h"
3
+ #include "dir.h"
3
4
#include "git-compat-util.h"
4
5
#include "lockfile.h"
5
6
#include "pack.h"
@@ -248,6 +249,13 @@ static struct commit_list **insert_parent_or_die(struct commit_graph *g,
248
249
return & commit_list_insert (c , pptr )-> next ;
249
250
}
250
251
252
+ static void fill_commit_graph_info (struct commit * item , struct commit_graph * g , uint32_t pos )
253
+ {
254
+ const unsigned char * commit_data = g -> chunk_commit_data + GRAPH_DATA_WIDTH * pos ;
255
+ item -> graph_pos = pos ;
256
+ item -> generation = get_be32 (commit_data + g -> hash_len + 8 ) >> 2 ;
257
+ }
258
+
251
259
static int fill_commit_in_graph (struct commit * item , struct commit_graph * g , uint32_t pos )
252
260
{
253
261
uint32_t edge_value ;
@@ -265,6 +273,8 @@ static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uin
265
273
date_low = get_be32 (commit_data + g -> hash_len + 12 );
266
274
item -> date = (timestamp_t )((date_high << 32 ) | date_low );
267
275
276
+ item -> generation = get_be32 (commit_data + g -> hash_len + 8 ) >> 2 ;
277
+
268
278
pptr = & item -> parents ;
269
279
270
280
edge_value = get_be32 (commit_data + g -> hash_len );
@@ -293,31 +303,40 @@ static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uin
293
303
return 1 ;
294
304
}
295
305
306
+ static int find_commit_in_graph (struct commit * item , struct commit_graph * g , uint32_t * pos )
307
+ {
308
+ if (item -> graph_pos != COMMIT_NOT_FROM_GRAPH ) {
309
+ * pos = item -> graph_pos ;
310
+ return 1 ;
311
+ } else {
312
+ return bsearch_graph (g , & (item -> object .oid ), pos );
313
+ }
314
+ }
315
+
296
316
int parse_commit_in_graph (struct commit * item )
297
317
{
318
+ uint32_t pos ;
319
+
298
320
if (!core_commit_graph )
299
321
return 0 ;
300
322
if (item -> object .parsed )
301
323
return 1 ;
302
-
303
324
prepare_commit_graph ();
304
- if (commit_graph ) {
305
- uint32_t pos ;
306
- int found ;
307
- if (item -> graph_pos != COMMIT_NOT_FROM_GRAPH ) {
308
- pos = item -> graph_pos ;
309
- found = 1 ;
310
- } else {
311
- found = bsearch_graph (commit_graph , & (item -> object .oid ), & pos );
312
- }
313
-
314
- if (found )
315
- return fill_commit_in_graph (item , commit_graph , pos );
316
- }
317
-
325
+ if (commit_graph && find_commit_in_graph (item , commit_graph , & pos ))
326
+ return fill_commit_in_graph (item , commit_graph , pos );
318
327
return 0 ;
319
328
}
320
329
330
+ void load_commit_graph_info (struct commit * item )
331
+ {
332
+ uint32_t pos ;
333
+ if (!core_commit_graph )
334
+ return ;
335
+ prepare_commit_graph ();
336
+ if (commit_graph && find_commit_in_graph (item , commit_graph , & pos ))
337
+ fill_commit_graph_info (item , commit_graph , pos );
338
+ }
339
+
321
340
static struct tree * load_tree_for_commit (struct commit_graph * g , struct commit * c )
322
341
{
323
342
struct object_id oid ;
@@ -440,6 +459,8 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
440
459
else
441
460
packedDate [0 ] = 0 ;
442
461
462
+ packedDate [0 ] |= htonl ((* list )-> generation << 2 );
463
+
443
464
packedDate [1 ] = htonl ((* list )-> date );
444
465
hashwrite (f , packedDate , 8 );
445
466
@@ -572,6 +593,45 @@ static void close_reachable(struct packed_oid_list *oids)
572
593
}
573
594
}
574
595
596
+ static void compute_generation_numbers (struct packed_commit_list * commits )
597
+ {
598
+ int i ;
599
+ struct commit_list * list = NULL ;
600
+
601
+ for (i = 0 ; i < commits -> nr ; i ++ ) {
602
+ if (commits -> list [i ]-> generation != GENERATION_NUMBER_INFINITY &&
603
+ commits -> list [i ]-> generation != GENERATION_NUMBER_ZERO )
604
+ continue ;
605
+
606
+ commit_list_insert (commits -> list [i ], & list );
607
+ while (list ) {
608
+ struct commit * current = list -> item ;
609
+ struct commit_list * parent ;
610
+ int all_parents_computed = 1 ;
611
+ uint32_t max_generation = 0 ;
612
+
613
+ for (parent = current -> parents ; parent ; parent = parent -> next ) {
614
+ if (parent -> item -> generation == GENERATION_NUMBER_INFINITY ||
615
+ parent -> item -> generation == GENERATION_NUMBER_ZERO ) {
616
+ all_parents_computed = 0 ;
617
+ commit_list_insert (parent -> item , & list );
618
+ break ;
619
+ } else if (parent -> item -> generation > max_generation ) {
620
+ max_generation = parent -> item -> generation ;
621
+ }
622
+ }
623
+
624
+ if (all_parents_computed ) {
625
+ current -> generation = max_generation + 1 ;
626
+ pop_commit (& list );
627
+
628
+ if (current -> generation > GENERATION_NUMBER_MAX )
629
+ current -> generation = GENERATION_NUMBER_MAX ;
630
+ }
631
+ }
632
+ }
633
+ }
634
+
575
635
void write_commit_graph (const char * obj_dir ,
576
636
const char * * pack_indexes ,
577
637
int nr_packs ,
@@ -584,7 +644,6 @@ void write_commit_graph(const char *obj_dir,
584
644
struct hashfile * f ;
585
645
uint32_t i , count_distinct = 0 ;
586
646
char * graph_name ;
587
- int fd ;
588
647
struct lock_file lk = LOCK_INIT ;
589
648
uint32_t chunk_ids [5 ];
590
649
uint64_t chunk_offsets [5 ];
@@ -695,24 +754,14 @@ void write_commit_graph(const char *obj_dir,
695
754
if (commits .nr >= GRAPH_PARENT_MISSING )
696
755
die (_ ("too many commits to write graph" ));
697
756
698
- graph_name = get_commit_graph_filename (obj_dir );
699
- fd = hold_lock_file_for_update (& lk , graph_name , 0 );
700
-
701
- if (fd < 0 ) {
702
- struct strbuf folder = STRBUF_INIT ;
703
- strbuf_addstr (& folder , graph_name );
704
- strbuf_setlen (& folder , strrchr (folder .buf , '/' ) - folder .buf );
705
-
706
- if (mkdir (folder .buf , 0777 ) < 0 )
707
- die_errno (_ ("cannot mkdir %s" ), folder .buf );
708
- strbuf_release (& folder );
709
-
710
- fd = hold_lock_file_for_update (& lk , graph_name , LOCK_DIE_ON_ERROR );
757
+ compute_generation_numbers (& commits );
711
758
712
- if (fd < 0 )
713
- die_errno ("unable to create '%s'" , graph_name );
714
- }
759
+ graph_name = get_commit_graph_filename (obj_dir );
760
+ if (safe_create_leading_directories (graph_name ))
761
+ die_errno (_ ("unable to create leading directories of %s" ),
762
+ graph_name );
715
763
764
+ hold_lock_file_for_update (& lk , graph_name , LOCK_DIE_ON_ERROR );
716
765
f = hashfd (lk .tempfile -> fd , lk .tempfile -> filename .buf );
717
766
718
767
hashwrite_be32 (f , GRAPH_SIGNATURE );
0 commit comments