@@ -22,17 +22,43 @@ static int rerere_autoupdate;
22
22
23
23
static char * merge_rr_path ;
24
24
25
- const char * rerere_path ( const char * id , const char * file )
25
+ static void free_rerere_id ( struct string_list_item * item )
26
26
{
27
- return git_path ("rr-cache/%s/%s" , id , file );
27
+ free (item -> util );
28
+ }
29
+
30
+ static const char * rerere_id_hex (const struct rerere_id * id )
31
+ {
32
+ return id -> hex ;
33
+ }
34
+
35
+ const char * rerere_path (const struct rerere_id * id , const char * file )
36
+ {
37
+ if (!file )
38
+ return git_path ("rr-cache/%s" , rerere_id_hex (id ));
39
+
40
+ return git_path ("rr-cache/%s/%s" , rerere_id_hex (id ), file );
28
41
}
29
42
30
- static int has_rerere_resolution (const char * id )
43
+ static int has_rerere_resolution (const struct rerere_id * id )
31
44
{
32
45
struct stat st ;
46
+
33
47
return !stat (rerere_path (id , "postimage" ), & st );
34
48
}
35
49
50
+ static struct rerere_id * new_rerere_id_hex (char * hex )
51
+ {
52
+ struct rerere_id * id = xmalloc (sizeof (* id ));
53
+ strcpy (id -> hex , hex );
54
+ return id ;
55
+ }
56
+
57
+ static struct rerere_id * new_rerere_id (unsigned char * sha1 )
58
+ {
59
+ return new_rerere_id_hex (sha1_to_hex (sha1 ));
60
+ }
61
+
36
62
/*
37
63
* $GIT_DIR/MERGE_RR file is a collection of records, each of which is
38
64
* "conflict ID", a HT and pathname, terminated with a NUL, and is
@@ -50,6 +76,7 @@ static void read_rr(struct string_list *rr)
50
76
while (!strbuf_getwholeline (& buf , in , '\0' )) {
51
77
char * path ;
52
78
unsigned char sha1 [20 ];
79
+ struct rerere_id * id ;
53
80
54
81
/* There has to be the hash, tab, path and then NUL */
55
82
if (buf .len < 42 || get_sha1_hex (buf .buf , sha1 ))
@@ -59,8 +86,8 @@ static void read_rr(struct string_list *rr)
59
86
die ("corrupt MERGE_RR" );
60
87
buf .buf [40 ] = '\0' ;
61
88
path = buf .buf + 41 ;
62
-
63
- string_list_insert (rr , path )-> util = xstrdup ( buf . buf ) ;
89
+ id = new_rerere_id_hex ( buf . buf );
90
+ string_list_insert (rr , path )-> util = id ;
64
91
}
65
92
strbuf_release (& buf );
66
93
fclose (in );
@@ -73,12 +100,15 @@ static int write_rr(struct string_list *rr, int out_fd)
73
100
int i ;
74
101
for (i = 0 ; i < rr -> nr ; i ++ ) {
75
102
struct strbuf buf = STRBUF_INIT ;
103
+ struct rerere_id * id ;
76
104
77
105
assert (rr -> items [i ].util != RERERE_RESOLVED );
78
- if (!rr -> items [i ].util )
106
+
107
+ id = rr -> items [i ].util ;
108
+ if (!id )
79
109
continue ;
80
110
strbuf_addf (& buf , "%s\t%s%c" ,
81
- ( char * ) rr -> items [ i ]. util ,
111
+ rerere_id_hex ( id ) ,
82
112
rr -> items [i ].string , 0 );
83
113
if (write_in_full (out_fd , buf .buf , buf .len ) != buf .len )
84
114
die ("unable to write rerere record" );
@@ -530,7 +560,7 @@ int rerere_remaining(struct string_list *merge_rr)
530
560
struct string_list_item * it ;
531
561
it = string_list_lookup (merge_rr , (const char * )e -> name );
532
562
if (it != NULL ) {
533
- free (it -> util );
563
+ free_rerere_id (it );
534
564
it -> util = RERERE_RESOLVED ;
535
565
}
536
566
}
@@ -548,7 +578,7 @@ int rerere_remaining(struct string_list *merge_rr)
548
578
* Returns 0 for successful replay of recorded resolution, or non-zero
549
579
* for failure.
550
580
*/
551
- static int merge (const char * id , const char * path )
581
+ static int merge (const struct rerere_id * id , const char * path )
552
582
{
553
583
int ret ;
554
584
mmfile_t cur = {NULL , 0 }, base = {NULL , 0 }, other = {NULL , 0 };
@@ -582,8 +612,8 @@ static int merge(const char *id, const char *path)
582
612
*/
583
613
if (utime (rerere_path (id , "postimage" ), NULL ) < 0 )
584
614
warning ("failed utime() on %s: %s" ,
585
- rerere_path (id , "postimage" ),
586
- strerror (errno ));
615
+ rerere_path (id , "postimage" ),
616
+ strerror (errno ));
587
617
588
618
/* Update "path" with the resolution */
589
619
f = fopen (path , "w" );
@@ -640,7 +670,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
640
670
struct string_list * update )
641
671
{
642
672
const char * path = rr_item -> string ;
643
- const char * id = ( const char * ) rr_item -> util ;
673
+ const struct rerere_id * id = rr_item -> util ;
644
674
645
675
/* Is there a recorded resolution we could attempt to apply? */
646
676
if (has_rerere_resolution (id )) {
@@ -660,7 +690,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
660
690
} else {
661
691
return ;
662
692
}
663
- free (rr_item -> util );
693
+ free_rerere_id (rr_item );
664
694
rr_item -> util = NULL ;
665
695
}
666
696
@@ -679,10 +709,10 @@ static int do_plain_rerere(struct string_list *rr, int fd)
679
709
* initial run would catch all and register their preimages.
680
710
*/
681
711
for (i = 0 ; i < conflict .nr ; i ++ ) {
712
+ struct rerere_id * id ;
682
713
unsigned char sha1 [20 ];
683
- char * id ;
684
- int ret ;
685
714
const char * path = conflict .items [i ].string ;
715
+ int ret ;
686
716
687
717
if (string_list_has_string (rr , path ))
688
718
continue ;
@@ -695,7 +725,8 @@ static int do_plain_rerere(struct string_list *rr, int fd)
695
725
ret = handle_file (path , sha1 , NULL );
696
726
if (ret < 1 )
697
727
continue ;
698
- id = xstrdup (sha1_to_hex (sha1 ));
728
+
729
+ id = new_rerere_id (sha1 );
699
730
string_list_insert (rr , path )-> util = id ;
700
731
701
732
/*
@@ -706,7 +737,7 @@ static int do_plain_rerere(struct string_list *rr, int fd)
706
737
* NEEDSWORK: make sure "gc" does not remove
707
738
* preimage without removing the directory.
708
739
*/
709
- if (mkdir_in_gitdir (git_path ( "rr-cache/%s" , id )))
740
+ if (mkdir_in_gitdir (rerere_path ( id , NULL )))
710
741
continue ;
711
742
712
743
/*
@@ -788,7 +819,7 @@ int rerere(int flags)
788
819
static int rerere_forget_one_path (const char * path , struct string_list * rr )
789
820
{
790
821
const char * filename ;
791
- char * id ;
822
+ struct rerere_id * id ;
792
823
unsigned char sha1 [20 ];
793
824
int ret ;
794
825
struct string_list_item * item ;
@@ -802,7 +833,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
802
833
return error ("Could not parse conflict hunks in '%s'" , path );
803
834
804
835
/* Nuke the recorded resolution for the conflict */
805
- id = xstrdup ( sha1_to_hex ( sha1 ) );
836
+ id = new_rerere_id ( sha1 );
806
837
filename = rerere_path (id , "postimage" );
807
838
if (unlink (filename ))
808
839
return (errno == ENOENT
@@ -822,7 +853,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
822
853
* conflict when the user is done.
823
854
*/
824
855
item = string_list_insert (rr , path );
825
- free (item -> util );
856
+ free_rerere_id (item );
826
857
item -> util = id ;
827
858
fprintf (stderr , "Forgot resolution for %s\n" , path );
828
859
return 0 ;
@@ -859,22 +890,38 @@ int rerere_forget(struct pathspec *pathspec)
859
890
/*
860
891
* Garbage collection support
861
892
*/
862
- static time_t rerere_created_at (const char * id )
893
+
894
+ /*
895
+ * Note that this is not reentrant but is used only one-at-a-time
896
+ * so it does not matter right now.
897
+ */
898
+ static struct rerere_id * dirname_to_id (const char * name )
899
+ {
900
+ static struct rerere_id id ;
901
+ strcpy (id .hex , name );
902
+ return & id ;
903
+ }
904
+
905
+ static time_t rerere_created_at (const char * dir_name )
863
906
{
864
907
struct stat st ;
908
+ struct rerere_id * id = dirname_to_id (dir_name );
909
+
865
910
return stat (rerere_path (id , "preimage" ), & st ) ? (time_t ) 0 : st .st_mtime ;
866
911
}
867
912
868
- static time_t rerere_last_used_at (const char * id )
913
+ static time_t rerere_last_used_at (const char * dir_name )
869
914
{
870
915
struct stat st ;
916
+ struct rerere_id * id = dirname_to_id (dir_name );
917
+
871
918
return stat (rerere_path (id , "postimage" ), & st ) ? (time_t ) 0 : st .st_mtime ;
872
919
}
873
920
874
921
/*
875
922
* Remove the recorded resolution for a given conflict ID
876
923
*/
877
- static void unlink_rr_item (const char * id )
924
+ static void unlink_rr_item (struct rerere_id * id )
878
925
{
879
926
unlink (rerere_path (id , "thisimage" ));
880
927
unlink (rerere_path (id , "preimage" ));
@@ -884,7 +931,7 @@ static void unlink_rr_item(const char *id)
884
931
* assume that we already have preimage recorded in
885
932
* do_plain_rerere()?
886
933
*/
887
- rmdir (git_path ( "rr-cache/%s" , id ));
934
+ rmdir (rerere_path ( id , NULL ));
888
935
}
889
936
890
937
void rerere_gc (struct string_list * rr )
@@ -923,7 +970,7 @@ void rerere_gc(struct string_list *rr)
923
970
closedir (dir );
924
971
/* ... and then remove them one-by-one */
925
972
for (i = 0 ; i < to_remove .nr ; i ++ )
926
- unlink_rr_item (to_remove .items [i ].string );
973
+ unlink_rr_item (dirname_to_id ( to_remove .items [i ].string ) );
927
974
string_list_clear (& to_remove , 0 );
928
975
}
929
976
@@ -939,7 +986,7 @@ void rerere_clear(struct string_list *merge_rr)
939
986
int i ;
940
987
941
988
for (i = 0 ; i < merge_rr -> nr ; i ++ ) {
942
- const char * id = ( const char * ) merge_rr -> items [i ].util ;
989
+ struct rerere_id * id = merge_rr -> items [i ].util ;
943
990
if (!has_rerere_resolution (id ))
944
991
unlink_rr_item (id );
945
992
}
0 commit comments