@@ -101,11 +101,7 @@ static unsigned long parse_commit_date(const char *buf)
101101 return date ;
102102}
103103
104- static struct commit_graft {
105- unsigned char sha1 [20 ];
106- int nr_parent ;
107- unsigned char parent [0 ][20 ]; /* more */
108- } * * commit_graft ;
104+ static struct commit_graft * * commit_graft ;
109105static int commit_graft_alloc , commit_graft_nr ;
110106
111107static int commit_graft_pos (const unsigned char * sha1 )
@@ -127,70 +123,98 @@ static int commit_graft_pos(const unsigned char *sha1)
127123 return - lo - 1 ;
128124}
129125
130- static void prepare_commit_graft (void )
126+ int register_commit_graft (struct commit_graft * graft , int ignore_dups )
127+ {
128+ int pos = commit_graft_pos (graft -> sha1 );
129+
130+ if (0 <= pos ) {
131+ if (ignore_dups )
132+ free (graft );
133+ else {
134+ free (commit_graft [pos ]);
135+ commit_graft [pos ] = graft ;
136+ }
137+ return 1 ;
138+ }
139+ pos = - pos - 1 ;
140+ if (commit_graft_alloc <= ++ commit_graft_nr ) {
141+ commit_graft_alloc = alloc_nr (commit_graft_alloc );
142+ commit_graft = xrealloc (commit_graft ,
143+ sizeof (* commit_graft ) *
144+ commit_graft_alloc );
145+ }
146+ if (pos < commit_graft_nr )
147+ memmove (commit_graft + pos + 1 ,
148+ commit_graft + pos ,
149+ (commit_graft_nr - pos - 1 ) *
150+ sizeof (* commit_graft ));
151+ commit_graft [pos ] = graft ;
152+ return 0 ;
153+ }
154+
155+ struct commit_graft * read_graft_line (char * buf , int len )
156+ {
157+ /* The format is just "Commit Parent1 Parent2 ...\n" */
158+ int i ;
159+ struct commit_graft * graft = NULL ;
160+
161+ if (buf [len - 1 ] == '\n' )
162+ buf [-- len ] = 0 ;
163+ if (buf [0 ] == '#' )
164+ return 0 ;
165+ if ((len + 1 ) % 41 ) {
166+ bad_graft_data :
167+ error ("bad graft data: %s" , buf );
168+ free (graft );
169+ return NULL ;
170+ }
171+ i = (len + 1 ) / 41 - 1 ;
172+ graft = xmalloc (sizeof (* graft ) + 20 * i );
173+ graft -> nr_parent = i ;
174+ if (get_sha1_hex (buf , graft -> sha1 ))
175+ goto bad_graft_data ;
176+ for (i = 40 ; i < len ; i += 41 ) {
177+ if (buf [i ] != ' ' )
178+ goto bad_graft_data ;
179+ if (get_sha1_hex (buf + i + 1 , graft -> parent [i /41 ]))
180+ goto bad_graft_data ;
181+ }
182+ return graft ;
183+ }
184+
185+ int read_graft_file (const char * graft_file )
131186{
132- char * graft_file = get_graft_file ();
133187 FILE * fp = fopen (graft_file , "r" );
134188 char buf [1024 ];
135- if (!fp ) {
136- commit_graft = (struct commit_graft * * ) "hack" ;
137- return ;
138- }
189+ if (!fp )
190+ return -1 ;
139191 while (fgets (buf , sizeof (buf ), fp )) {
140192 /* The format is just "Commit Parent1 Parent2 ...\n" */
141193 int len = strlen (buf );
142- int i ;
143- struct commit_graft * graft = NULL ;
144-
145- if (buf [len - 1 ] == '\n' )
146- buf [-- len ] = 0 ;
147- if (buf [0 ] == '#' )
148- continue ;
149- if ((len + 1 ) % 41 ) {
150- bad_graft_data :
151- error ("bad graft data: %s" , buf );
152- free (graft );
153- continue ;
154- }
155- i = (len + 1 ) / 41 - 1 ;
156- graft = xmalloc (sizeof (* graft ) + 20 * i );
157- graft -> nr_parent = i ;
158- if (get_sha1_hex (buf , graft -> sha1 ))
159- goto bad_graft_data ;
160- for (i = 40 ; i < len ; i += 41 ) {
161- if (buf [i ] != ' ' )
162- goto bad_graft_data ;
163- if (get_sha1_hex (buf + i + 1 , graft -> parent [i /41 ]))
164- goto bad_graft_data ;
165- }
166- i = commit_graft_pos (graft -> sha1 );
167- if (0 <= i ) {
194+ struct commit_graft * graft = read_graft_line (buf , len );
195+ if (register_commit_graft (graft , 1 ))
168196 error ("duplicate graft data: %s" , buf );
169- free (graft );
170- continue ;
171- }
172- i = - i - 1 ;
173- if (commit_graft_alloc <= ++ commit_graft_nr ) {
174- commit_graft_alloc = alloc_nr (commit_graft_alloc );
175- commit_graft = xrealloc (commit_graft ,
176- sizeof (* commit_graft ) *
177- commit_graft_alloc );
178- }
179- if (i < commit_graft_nr )
180- memmove (commit_graft + i + 1 ,
181- commit_graft + i ,
182- (commit_graft_nr - i - 1 ) *
183- sizeof (* commit_graft ));
184- commit_graft [i ] = graft ;
185197 }
186198 fclose (fp );
199+ return 0 ;
200+ }
201+
202+ static void prepare_commit_graft (void )
203+ {
204+ static int commit_graft_prepared ;
205+ char * graft_file ;
206+
207+ if (commit_graft_prepared )
208+ return ;
209+ graft_file = get_graft_file ();
210+ read_graft_file (graft_file );
211+ commit_graft_prepared = 1 ;
187212}
188213
189214static struct commit_graft * lookup_commit_graft (const unsigned char * sha1 )
190215{
191216 int pos ;
192- if (!commit_graft )
193- prepare_commit_graft ();
217+ prepare_commit_graft ();
194218 pos = commit_graft_pos (sha1 );
195219 if (pos < 0 )
196220 return NULL ;
0 commit comments