13
13
* bundle supporting git-fetch, git-pull, and git-ls-remote
14
14
*/
15
15
16
- static const char * bundle_usage = "git-bundle (-- create <bundle> <git-rev-list args> | -- verify <bundle> | -- list-heads <bundle> [refname]... | -- unbundle <bundle> [refname]... )" ;
16
+ static const char * bundle_usage = "git-bundle (create <bundle> <git-rev-list args> | verify <bundle> | list-heads <bundle> [refname]... | unbundle <bundle> [refname]... )" ;
17
17
18
18
static const char bundle_signature [] = "# v2 git bundle\n" ;
19
19
@@ -39,15 +39,16 @@ static void add_to_ref_list(const unsigned char *sha1, const char *name,
39
39
}
40
40
41
41
struct bundle_header {
42
- struct ref_list prerequisites , references ;
42
+ struct ref_list prerequisites ;
43
+ struct ref_list references ;
43
44
};
44
45
45
46
/* this function returns the length of the string */
46
47
static int read_string (int fd , char * buffer , int size )
47
48
{
48
49
int i ;
49
50
for (i = 0 ; i < size - 1 ; i ++ ) {
50
- int count = read (fd , buffer + i , 1 );
51
+ int count = xread (fd , buffer + i , 1 );
51
52
if (count < 0 )
52
53
return error ("Read error: %s" , strerror (errno ));
53
54
if (count == 0 ) {
@@ -75,18 +76,25 @@ static int read_header(const char *path, struct bundle_header *header) {
75
76
}
76
77
while (read_string (fd , buffer , sizeof (buffer )) > 0
77
78
&& buffer [0 ] != '\n' ) {
78
- int offset = buffer [0 ] == '-' ? 1 : 0 ;
79
+ int is_prereq = buffer [0 ] == '-' ;
80
+ int offset = is_prereq ? 1 : 0 ;
79
81
int len = strlen (buffer );
80
82
unsigned char sha1 [20 ];
81
- struct ref_list * list = offset ? & header -> prerequisites
83
+ struct ref_list * list = is_prereq ? & header -> prerequisites
82
84
: & header -> references ;
83
- if (get_sha1_hex (buffer + offset , sha1 )) {
84
- close (fd );
85
- return error ("invalid SHA1: %s" , buffer );
86
- }
85
+ char delim ;
86
+
87
87
if (buffer [len - 1 ] == '\n' )
88
88
buffer [len - 1 ] = '\0' ;
89
- add_to_ref_list (sha1 , buffer + 41 + offset , list );
89
+ if (get_sha1_hex (buffer + offset , sha1 )) {
90
+ warn ("unrecognized header: %s" , buffer );
91
+ continue ;
92
+ }
93
+ delim = buffer [40 + offset ];
94
+ if (!isspace (delim ) && (delim != '\0' || !is_prereq ))
95
+ die ("invalid header: %s" , buffer );
96
+ add_to_ref_list (sha1 , isspace (delim ) ?
97
+ buffer + 41 + offset : "" , list );
90
98
}
91
99
return fd ;
92
100
}
@@ -127,20 +135,28 @@ static int fork_with_pipe(const char **argv, int *in, int *out)
127
135
dup2 (fdin [0 ], 0 );
128
136
close (fdin [0 ]);
129
137
close (fdin [1 ]);
130
- } else if (in )
138
+ } else if (in ) {
131
139
dup2 (* in , 0 );
140
+ close (* in );
141
+ }
132
142
if (needs_out ) {
133
143
dup2 (fdout [1 ], 1 );
134
144
close (fdout [0 ]);
135
145
close (fdout [1 ]);
136
- } else if (out )
146
+ } else if (out ) {
137
147
dup2 (* out , 1 );
148
+ close (* out );
149
+ }
138
150
exit (execv_git_cmd (argv ));
139
151
}
140
152
if (needs_in )
141
153
close (fdin [0 ]);
154
+ else if (in )
155
+ close (* in );
142
156
if (needs_out )
143
157
close (fdout [1 ]);
158
+ else if (out )
159
+ close (* out );
144
160
return pid ;
145
161
}
146
162
@@ -151,29 +167,28 @@ static int verify_bundle(struct bundle_header *header)
151
167
* to be verbose about the errors
152
168
*/
153
169
struct ref_list * p = & header -> prerequisites ;
154
- const char * argv [ 5 ] = { "rev-list" , "--stdin" , "--not" , "--all" , NULL } ;
155
- int pid , in , out , i , ret = 0 ;
170
+ char * * argv ;
171
+ int pid , out , i , ret = 0 ;
156
172
char buffer [1024 ];
157
173
158
- in = out = -1 ;
159
- pid = fork_with_pipe (argv , & in , & out );
174
+ argv = xmalloc ((p -> nr + 4 ) * sizeof (const char * ));
175
+ argv [0 ] = "rev-list" ;
176
+ argv [1 ] = "--not" ;
177
+ argv [2 ] = "--all" ;
178
+ for (i = 0 ; i < p -> nr ; i ++ )
179
+ argv [i + 3 ] = xstrdup (sha1_to_hex (p -> list [i ].sha1 ));
180
+ argv [p -> nr + 3 ] = NULL ;
181
+ out = -1 ;
182
+ pid = fork_with_pipe ((const char * * )argv , NULL , & out );
160
183
if (pid < 0 )
161
184
return error ("Could not fork rev-list" );
162
- if (!fork ()) {
163
- for (i = 0 ; i < p -> nr ; i ++ ) {
164
- write (in , sha1_to_hex (p -> list [i ].sha1 ), 40 );
165
- write (in , "\n" , 1 );
166
- }
167
- close (in );
168
- exit (0 );
169
- }
170
- close (in );
171
- while (read_string (out , buffer , sizeof (buffer )) > 0 ) {
172
- if (ret ++ == 0 )
173
- error ("The bundle requires the following commits you lack:" );
174
- fprintf (stderr , "%s" , buffer );
175
- }
185
+ while (read_string (out , buffer , sizeof (buffer )) > 0 )
186
+ ; /* do nothing */
176
187
close (out );
188
+ for (i = 0 ; i < p -> nr ; i ++ )
189
+ free (argv [i + 3 ]);
190
+ free (argv );
191
+
177
192
while (waitpid (pid , & i , 0 ) < 0 )
178
193
if (errno != EINTR )
179
194
return -1 ;
@@ -205,8 +220,8 @@ static int list_heads(struct bundle_header *header, int argc, const char **argv)
205
220
206
221
static void show_commit (struct commit * commit )
207
222
{
208
- write (1 , sha1_to_hex (commit -> object .sha1 ), 40 );
209
- write (1 , "\n" , 1 );
223
+ write_or_die (1 , sha1_to_hex (commit -> object .sha1 ), 40 );
224
+ write_or_die (1 , "\n" , 1 );
210
225
if (commit -> parents ) {
211
226
free_commit_list (commit -> parents );
212
227
commit -> parents = NULL ;
@@ -216,15 +231,15 @@ static void show_commit(struct commit *commit)
216
231
static void show_object (struct object_array_entry * p )
217
232
{
218
233
/* An object with name "foo\n0000000..." can be used to
219
- * * confuse downstream git-pack-objects very badly.
220
- * * /
234
+ * confuse downstream git-pack-objects very badly.
235
+ */
221
236
const char * ep = strchr (p -> name , '\n' );
222
237
int len = ep ? ep - p -> name : strlen (p -> name );
223
- write (1 , sha1_to_hex (p -> item -> sha1 ), 40 );
224
- write (1 , " " , 1 );
238
+ write_or_die (1 , sha1_to_hex (p -> item -> sha1 ), 40 );
239
+ write_or_die (1 , " " , 1 );
225
240
if (len )
226
- write (1 , p -> name , len );
227
- write (1 , "\n" , 1 );
241
+ write_or_die (1 , p -> name , len );
242
+ write_or_die (1 , "\n" , 1 );
228
243
}
229
244
230
245
static int create_bundle (struct bundle_header * header , const char * path ,
@@ -243,7 +258,7 @@ static int create_bundle(struct bundle_header *header, const char *path,
243
258
return error ("Could not write to '%s'" , path );
244
259
245
260
/* write signature */
246
- write (bundle_fd , bundle_signature , strlen (bundle_signature ));
261
+ write_or_die (bundle_fd , bundle_signature , strlen (bundle_signature ));
247
262
248
263
/* write prerequisites */
249
264
memcpy (argv_boundary + 2 , argv + 1 , argc * sizeof (const char * ));
@@ -256,7 +271,7 @@ static int create_bundle(struct bundle_header *header, const char *path,
256
271
return -1 ;
257
272
while ((i = read_string (out , buffer , sizeof (buffer ))) > 0 )
258
273
if (buffer [0 ] == '-' )
259
- write (bundle_fd , buffer , i );
274
+ write_or_die (bundle_fd , buffer , i );
260
275
while ((i = waitpid (pid , & status , 0 )) < 0 )
261
276
if (errno != EINTR )
262
277
return error ("rev-list died" );
@@ -279,16 +294,16 @@ static int create_bundle(struct bundle_header *header, const char *path,
279
294
char * ref ;
280
295
if (dwim_ref (e -> name , strlen (e -> name ), sha1 , & ref ) != 1 )
281
296
continue ;
282
- write (bundle_fd , sha1_to_hex (e -> item -> sha1 ), 40 );
283
- write (bundle_fd , " " , 1 );
284
- write (bundle_fd , ref , strlen (ref ));
285
- write (bundle_fd , "\n" , 1 );
297
+ write_or_die (bundle_fd , sha1_to_hex (e -> item -> sha1 ), 40 );
298
+ write_or_die (bundle_fd , " " , 1 );
299
+ write_or_die (bundle_fd , ref , strlen (ref ));
300
+ write_or_die (bundle_fd , "\n" , 1 );
286
301
free (ref );
287
302
}
288
303
}
289
304
290
305
/* end header */
291
- write (bundle_fd , "\n" , 1 );
306
+ write_or_die (bundle_fd , "\n" , 1 );
292
307
293
308
/* write pack */
294
309
argv_pack [0 ] = "pack-objects" ;
@@ -301,7 +316,6 @@ static int create_bundle(struct bundle_header *header, const char *path,
301
316
if (pid < 0 )
302
317
return error ("Could not spawn pack-objects" );
303
318
close (1 );
304
- close (bundle_fd );
305
319
dup2 (in , 1 );
306
320
close (in );
307
321
prepare_revision_walk (& revs );
@@ -327,7 +341,6 @@ static int unbundle(struct bundle_header *header, int bundle_fd,
327
341
pid = fork_with_pipe (argv_index_pack , & bundle_fd , & dev_null );
328
342
if (pid < 0 )
329
343
return error ("Could not spawn index-pack" );
330
- close (bundle_fd );
331
344
while (waitpid (pid , & status , 0 ) < 0 )
332
345
if (errno != EINTR )
333
346
return error ("index-pack died" );
0 commit comments