Browse code

Merge branch 'rs/use-child-process-init-more'

* rs/use-child-process-init-more:
bundle: split out ref writing from bundle_create
bundle: split out a helper function to compute and write prerequisites
bundle: split out a helper function to create pack data
use child_process_init() to initialize struct child_process variables

Junio C Hamano authored on 06/11/2014 18:52:23
Showing 4 changed files
... ...
@@ -235,33 +235,50 @@ out:
235 235
 	return result;
236 236
 }
237 237
 
238
-int create_bundle(struct bundle_header *header, const char *path,
239
-		  int argc, const char **argv)
238
+static int write_pack_data(int bundle_fd, struct lock_file *lock, struct rev_info *revs)
240 239
 {
241
-	static struct lock_file lock;
242
-	int bundle_fd = -1;
243
-	int bundle_to_stdout;
244
-	int i, ref_count = 0;
245
-	struct strbuf buf = STRBUF_INIT;
246
-	struct rev_info revs;
247
-	struct child_process rls = CHILD_PROCESS_INIT;
248
-	FILE *rls_fout;
240
+	struct child_process pack_objects = CHILD_PROCESS_INIT;
241
+	int i;
249 242
 
250
-	bundle_to_stdout = !strcmp(path, "-");
251
-	if (bundle_to_stdout)
252
-		bundle_fd = 1;
253
-	else
254
-		bundle_fd = hold_lock_file_for_update(&lock, path,
255
-						      LOCK_DIE_ON_ERROR);
243
+	argv_array_pushl(&pack_objects.args,
244
+			 "pack-objects", "--all-progress-implied",
245
+			 "--stdout", "--thin", "--delta-base-offset",
246
+			 NULL);
247
+	pack_objects.in = -1;
248
+	pack_objects.out = bundle_fd;
249
+	pack_objects.git_cmd = 1;
250
+	if (start_command(&pack_objects))
251
+		return error(_("Could not spawn pack-objects"));
256 252
 
257
-	/* write signature */
258
-	write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
253
+	/*
254
+	 * start_command closed bundle_fd if it was > 1
255
+	 * so set the lock fd to -1 so commit_lock_file()
256
+	 * won't fail trying to close it.
257
+	 */
258
+	lock->fd = -1;
259 259
 
260
-	/* init revs to list objects for pack-objects later */
261
-	save_commit_buffer = 0;
262
-	init_revisions(&revs, NULL);
260
+	for (i = 0; i < revs->pending.nr; i++) {
261
+		struct object *object = revs->pending.objects[i].item;
262
+		if (object->flags & UNINTERESTING)
263
+			write_or_die(pack_objects.in, "^", 1);
264
+		write_or_die(pack_objects.in, sha1_to_hex(object->sha1), 40);
265
+		write_or_die(pack_objects.in, "\n", 1);
266
+	}
267
+	close(pack_objects.in);
268
+	if (finish_command(&pack_objects))
269
+		return error(_("pack-objects died"));
270
+	return 0;
271
+}
272
+
273
+static int compute_and_write_prerequisites(int bundle_fd,
274
+					   struct rev_info *revs,
275
+					   int argc, const char **argv)
276
+{
277
+	struct child_process rls = CHILD_PROCESS_INIT;
278
+	struct strbuf buf = STRBUF_INIT;
279
+	FILE *rls_fout;
280
+	int i;
263 281
 
264
-	/* write prerequisites */
265 282
 	argv_array_pushl(&rls.args,
266 283
 			 "rev-list", "--boundary", "--pretty=oneline",
267 284
 			 NULL);
... ...
@@ -279,7 +296,7 @@ int create_bundle(struct bundle_header *header, const char *path,
279 279
 			if (!get_sha1_hex(buf.buf + 1, sha1)) {
280 280
 				struct object *object = parse_object_or_die(sha1, buf.buf);
281 281
 				object->flags |= UNINTERESTING;
282
-				add_pending_object(&revs, object, buf.buf);
282
+				add_pending_object(revs, object, buf.buf);
283 283
 			}
284 284
 		} else if (!get_sha1_hex(buf.buf, sha1)) {
285 285
 			struct object *object = parse_object_or_die(sha1, buf.buf);
... ...
@@ -290,17 +307,25 @@ int create_bundle(struct bundle_header *header, const char *path,
290 290
 	fclose(rls_fout);
291 291
 	if (finish_command(&rls))
292 292
 		return error(_("rev-list died"));
293
+	return 0;
294
+}
293 295
 
294
-	/* write references */
295
-	argc = setup_revisions(argc, argv, &revs, NULL);
296
-
297
-	if (argc > 1)
298
-		return error(_("unrecognized argument: %s"), argv[1]);
299
-
300
-	object_array_remove_duplicates(&revs.pending);
296
+/*
297
+ * Write out bundle refs based on the tips already
298
+ * parsed into revs.pending. As a side effect, may
299
+ * manipulate revs.pending to include additional
300
+ * necessary objects (like tags).
301
+ *
302
+ * Returns the number of refs written, or negative
303
+ * on error.
304
+ */
305
+static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
306
+{
307
+	int i;
308
+	int ref_count = 0;
301 309
 
302
-	for (i = 0; i < revs.pending.nr; i++) {
303
-		struct object_array_entry *e = revs.pending.objects + i;
310
+	for (i = 0; i < revs->pending.nr; i++) {
311
+		struct object_array_entry *e = revs->pending.objects + i;
304 312
 		unsigned char sha1[20];
305 313
 		char *ref;
306 314
 		const char *display_ref;
... ...
@@ -315,7 +340,7 @@ int create_bundle(struct bundle_header *header, const char *path,
315 315
 		display_ref = (flag & REF_ISSYMREF) ? e->name : ref;
316 316
 
317 317
 		if (e->item->type == OBJ_TAG &&
318
-				!is_tag_in_date_range(e->item, &revs)) {
318
+				!is_tag_in_date_range(e->item, revs)) {
319 319
 			e->item->flags |= UNINTERESTING;
320 320
 			continue;
321 321
 		}
... ...
@@ -361,7 +386,7 @@ int create_bundle(struct bundle_header *header, const char *path,
361 361
 				 */
362 362
 				obj = parse_object_or_die(sha1, e->name);
363 363
 				obj->flags |= SHOWN;
364
-				add_pending_object(&revs, obj, e->name);
364
+				add_pending_object(revs, obj, e->name);
365 365
 			}
366 366
 			free(ref);
367 367
 			continue;
... ...
@@ -374,41 +399,56 @@ int create_bundle(struct bundle_header *header, const char *path,
374 374
 		write_or_die(bundle_fd, "\n", 1);
375 375
 		free(ref);
376 376
 	}
377
-	if (!ref_count)
378
-		die(_("Refusing to create empty bundle."));
379 377
 
380 378
 	/* end header */
381 379
 	write_or_die(bundle_fd, "\n", 1);
380
+	return ref_count;
381
+}
382 382
 
383
-	/* write pack */
384
-	memset(&rls, 0, sizeof(rls));
385
-	argv_array_pushl(&rls.args,
386
-			 "pack-objects", "--all-progress-implied",
387
-			 "--stdout", "--thin", "--delta-base-offset",
388
-			 NULL);
389
-	rls.in = -1;
390
-	rls.out = bundle_fd;
391
-	rls.git_cmd = 1;
392
-	if (start_command(&rls))
393
-		return error(_("Could not spawn pack-objects"));
383
+int create_bundle(struct bundle_header *header, const char *path,
384
+		  int argc, const char **argv)
385
+{
386
+	static struct lock_file lock;
387
+	int bundle_fd = -1;
388
+	int bundle_to_stdout;
389
+	int ref_count = 0;
390
+	struct rev_info revs;
394 391
 
395
-	/*
396
-	 * start_command closed bundle_fd if it was > 1
397
-	 * so set the lock fd to -1 so commit_lock_file()
398
-	 * won't fail trying to close it.
399
-	 */
400
-	lock.fd = -1;
392
+	bundle_to_stdout = !strcmp(path, "-");
393
+	if (bundle_to_stdout)
394
+		bundle_fd = 1;
395
+	else
396
+		bundle_fd = hold_lock_file_for_update(&lock, path,
397
+						      LOCK_DIE_ON_ERROR);
398
+
399
+	/* write signature */
400
+	write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
401
+
402
+	/* init revs to list objects for pack-objects later */
403
+	save_commit_buffer = 0;
404
+	init_revisions(&revs, NULL);
405
+
406
+	/* write prerequisites */
407
+	if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))
408
+		return -1;
409
+
410
+	argc = setup_revisions(argc, argv, &revs, NULL);
411
+
412
+	if (argc > 1)
413
+		return error(_("unrecognized argument: %s"), argv[1]);
414
+
415
+	object_array_remove_duplicates(&revs.pending);
416
+
417
+	ref_count = write_bundle_refs(bundle_fd, &revs);
418
+	if (!ref_count)
419
+		die(_("Refusing to create empty bundle."));
420
+	else if (ref_count < 0)
421
+		return -1;
422
+
423
+	/* write pack */
424
+	if (write_pack_data(bundle_fd, &lock, &revs))
425
+		return -1;
401 426
 
402
-	for (i = 0; i < revs.pending.nr; i++) {
403
-		struct object *object = revs.pending.objects[i].item;
404
-		if (object->flags & UNINTERESTING)
405
-			write_or_die(rls.in, "^", 1);
406
-		write_or_die(rls.in, sha1_to_hex(object->sha1), 40);
407
-		write_or_die(rls.in, "\n", 1);
408
-	}
409
-	close(rls.in);
410
-	if (finish_command(&rls))
411
-		return error(_("pack-objects died"));
412 427
 	if (!bundle_to_stdout) {
413 428
 		if (commit_lock_file(&lock))
414 429
 			die_errno(_("cannot create '%s'"), path);
... ...
@@ -374,7 +374,7 @@ int run_column_filter(int colopts, const struct column_options *opts)
374 374
 	if (fd_out != -1)
375 375
 		return -1;
376 376
 
377
-	memset(&column_process, 0, sizeof(column_process));
377
+	child_process_init(&column_process);
378 378
 	argv = &column_process.args;
379 379
 
380 380
 	argv_array_push(argv, "column");
... ...
@@ -237,7 +237,7 @@ static const char *apply_command(const char *command, const char *arg)
237 237
 		strbuf_replace(&cmd, TRAILER_ARG_STRING, arg);
238 238
 
239 239
 	argv[0] = cmd.buf;
240
-	memset(&cp, 0, sizeof(cp));
240
+	child_process_init(&cp);
241 241
 	cp.argv = argv;
242 242
 	cp.env = local_repo_env;
243 243
 	cp.no_stdin = 1;
... ...
@@ -414,7 +414,7 @@ static int get_exporter(struct transport *transport,
414 414
 	struct child_process *helper = get_helper(transport);
415 415
 	int i;
416 416
 
417
-	memset(fastexport, 0, sizeof(*fastexport));
417
+	child_process_init(fastexport);
418 418
 
419 419
 	/* we need to duplicate helper->in because we want to use it after
420 420
 	 * fastexport is done with it. */