Skip to content

Commit

Permalink
clone: factor out checkout code
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nguyễn Thái Ngọc Duy authored and Junio C Hamano committed Jan 17, 2012
1 parent 7f08c68 commit c39852c
Showing 1 changed file with 58 additions and 43 deletions.
101 changes: 58 additions & 43 deletions builtin/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,63 @@ static void write_followtags(const struct ref *refs, const char *msg)
}
}

static int checkout(void)
{
unsigned char sha1[20];
char *head;
struct lock_file *lock_file;
struct unpack_trees_options opts;
struct tree *tree;
struct tree_desc t;
int err = 0, fd;

if (option_no_checkout)
return 0;

head = resolve_refdup("HEAD", sha1, 1, NULL);
if (!head) {
warning(_("remote HEAD refers to nonexistent ref, "
"unable to checkout.\n"));
return 0;
}
if (strcmp(head, "HEAD")) {
if (prefixcmp(head, "refs/heads/"))
die(_("HEAD not found below refs/heads!"));
}
free(head);

/* We need to be in the new work tree for the checkout */
setup_work_tree();

lock_file = xcalloc(1, sizeof(struct lock_file));
fd = hold_locked_index(lock_file, 1);

memset(&opts, 0, sizeof opts);
opts.update = 1;
opts.merge = 1;
opts.fn = oneway_merge;
opts.verbose_update = (option_verbosity > 0);
opts.src_index = &the_index;
opts.dst_index = &the_index;

tree = parse_tree_indirect(sha1);
parse_tree(tree);
init_tree_desc(&t, tree->buffer, tree->size);
unpack_trees(1, &t, &opts);

if (write_cache(fd, active_cache, active_nr) ||
commit_locked_index(lock_file))
die(_("unable to write new index file"));

err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
sha1_to_hex(sha1), "1", NULL);

if (!err && option_recursive)
err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);

return err;
}

static int write_one_config(const char *key, const char *value, void *data)
{
return git_config_set_multivar(key, value ? value : "true", "^$", 0);
Expand Down Expand Up @@ -766,56 +823,14 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
/* Source had detached HEAD pointing somewhere. */
update_ref(reflog_msg.buf, "HEAD", remote_head->old_sha1,
NULL, REF_NODEREF, DIE_ON_ERR);
our_head_points_at = remote_head;
} else {
/* Nothing to checkout out */
if (!option_no_checkout)
warning(_("remote HEAD refers to nonexistent ref, "
"unable to checkout.\n"));
option_no_checkout = 1;
}

if (transport) {
transport_unlock_pack(transport);
transport_disconnect(transport);
}

if (!option_no_checkout) {
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
struct unpack_trees_options opts;
struct tree *tree;
struct tree_desc t;
int fd;

/* We need to be in the new work tree for the checkout */
setup_work_tree();

fd = hold_locked_index(lock_file, 1);

memset(&opts, 0, sizeof opts);
opts.update = 1;
opts.merge = 1;
opts.fn = oneway_merge;
opts.verbose_update = (option_verbosity > 0);
opts.src_index = &the_index;
opts.dst_index = &the_index;

tree = parse_tree_indirect(our_head_points_at->old_sha1);
parse_tree(tree);
init_tree_desc(&t, tree->buffer, tree->size);
unpack_trees(1, &t, &opts);

if (write_cache(fd, active_cache, active_nr) ||
commit_locked_index(lock_file))
die(_("unable to write new index file"));

err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
sha1_to_hex(our_head_points_at->old_sha1), "1",
NULL);

if (!err && option_recursive)
err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
}
err = checkout();

strbuf_release(&reflog_msg);
strbuf_release(&branch_top);
Expand Down

0 comments on commit c39852c

Please sign in to comment.