clone: factor out checkout code

Read HEAD from disk instead of relying on local variable our_head_points_at, so that if earlier code fails to make HEAD properly, it'll be detected. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Jan 16, 2012 at 16:46 UTC c39852c18dc7efa794bbe20b10ecfe7038409727
1 file changed +58 -43
builtin/clone.c
+58 -43
@@ -486,6 +486,63 @@ static void write_followtags(const struct ref *refs, const char *msg)
486 }
487 }
488
489 +static int checkout(void)
490 +{
491 + unsigned char sha1[20];
492 + char *head;
493 + struct lock_file *lock_file;
494 + struct unpack_trees_options opts;
495 + struct tree *tree;
496 + struct tree_desc t;
497 + int err = 0, fd;
498 +
499 + if (option_no_checkout)
500 + return 0;
501 +
502 + head = resolve_refdup("HEAD", sha1, 1, NULL);
503 + if (!head) {
504 + warning(_("remote HEAD refers to nonexistent ref, "
505 + "unable to checkout.\n"));
506 + return 0;
507 + }
508 + if (strcmp(head, "HEAD")) {
509 + if (prefixcmp(head, "refs/heads/"))
510 + die(_("HEAD not found below refs/heads!"));
511 + }
512 + free(head);
513 +
514 + /* We need to be in the new work tree for the checkout */
515 + setup_work_tree();
516 +
517 + lock_file = xcalloc(1, sizeof(struct lock_file));
518 + fd = hold_locked_index(lock_file, 1);
519 +
520 + memset(&opts, 0, sizeof opts);
521 + opts.update = 1;
522 + opts.merge = 1;
523 + opts.fn = oneway_merge;
524 + opts.verbose_update = (option_verbosity > 0);
525 + opts.src_index = &the_index;
526 + opts.dst_index = &the_index;
527 +
528 + tree = parse_tree_indirect(sha1);
529 + parse_tree(tree);
530 + init_tree_desc(&t, tree->buffer, tree->size);
531 + unpack_trees(1, &t, &opts);
532 +
533 + if (write_cache(fd, active_cache, active_nr) ||
534 + commit_locked_index(lock_file))
535 + die(_("unable to write new index file"));
536 +
537 + err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
538 + sha1_to_hex(sha1), "1", NULL);
539 +
540 + if (!err && option_recursive)
541 + err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
542 +
543 + return err;
544 +}
545 +
546 static int write_one_config(const char *key, const char *value, void *data)
547 {
548 return git_config_set_multivar(key, value ? value : "true", "^$", 0);
@@ -766,13 +823,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
823 /* Source had detached HEAD pointing somewhere. */
824 update_ref(reflog_msg.buf, "HEAD", remote_head->old_sha1,
825 NULL, REF_NODEREF, DIE_ON_ERR);
769 - our_head_points_at = remote_head;
770 - } else {
771 - /* Nothing to checkout out */
772 - if (!option_no_checkout)
773 - warning(_("remote HEAD refers to nonexistent ref, "
774 - "unable to checkout.\n"));
775 - option_no_checkout = 1;
826 }
827
828 if (transport) {
@@ -780,42 +830,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
830 transport_disconnect(transport);
831 }
832
783 - if (!option_no_checkout) {
784 - struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
785 - struct unpack_trees_options opts;
786 - struct tree *tree;
787 - struct tree_desc t;
788 - int fd;
789 -
790 - /* We need to be in the new work tree for the checkout */
791 - setup_work_tree();
792 -
793 - fd = hold_locked_index(lock_file, 1);
794 -
795 - memset(&opts, 0, sizeof opts);
796 - opts.update = 1;
797 - opts.merge = 1;
798 - opts.fn = oneway_merge;
799 - opts.verbose_update = (option_verbosity > 0);
800 - opts.src_index = &the_index;
801 - opts.dst_index = &the_index;
802 -
803 - tree = parse_tree_indirect(our_head_points_at->old_sha1);
804 - parse_tree(tree);
805 - init_tree_desc(&t, tree->buffer, tree->size);
806 - unpack_trees(1, &t, &opts);
807 -
808 - if (write_cache(fd, active_cache, active_nr) ||
809 - commit_locked_index(lock_file))
810 - die(_("unable to write new index file"));
811 -
812 - err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
813 - sha1_to_hex(our_head_points_at->old_sha1), "1",
814 - NULL);
815 -
816 - if (!err && option_recursive)
817 - err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
818 - }
833 + err = checkout();
834
835 strbuf_release(&reflog_msg);
836 strbuf_release(&branch_top);