From: Junio C Hamano Date: Mon, 7 Sep 2009 22:24:53 +0000 (-0700) Subject: Merge branch 'jk/clone-b' X-Git-Tag: v1.6.5-rc0~3 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/2da9f8e370b08d4786e33ec95a07a4d6104eb83a?ds=inline;hp=-c Merge branch 'jk/clone-b' * jk/clone-b: clone: add --branch option to select a different HEAD --- 2da9f8e370b08d4786e33ec95a07a4d6104eb83a diff --combined Documentation/git-clone.txt index 2e0785e1de,1cd1ecc746..f23100e509 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@@ -12,7 -12,7 +12,7 @@@ SYNOPSI 'git clone' [--template=] [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror] [-o ] [-u ] [--reference ] - [--depth ] [--] [] + [--depth ] [--recursive] [--] [] DESCRIPTION ----------- @@@ -84,7 -84,7 +84,7 @@@ its source repository, you can simply r objects from the source repository into a pack in the cloned repository. --reference :: - If the reference repository is on the local machine + If the reference repository is on the local machine, automatically setup .git/objects/info/alternates to obtain objects from the reference repository. Using an already existing repository as an alternate will @@@ -127,6 -127,13 +127,13 @@@ Instead of using the remote name 'origin' to keep track of the upstream repository, use . + --branch :: + -b :: + Instead of pointing the newly created HEAD to the branch pointed + to by the cloned repositoroy's HEAD, point to branch + instead. In a non-bare repository, this is the branch that will + be checked out. + --upload-pack :: -u :: When given, and the repository to clone from is accessed @@@ -147,14 -154,6 +154,14 @@@ with a long history, and would want to send in fixes as patches. +--recursive:: + After the clone is created, initialize all submodules within, + using their default settings. This is equivalent to running + 'git submodule update --init --recursive' immediately after + the clone is finished. This option is ignored if the cloned + repository does not have a worktree/checkout (i.e. if any of + `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) + :: The (possibly remote) repository to clone from. See the <> section below for more information on specifying diff --combined builtin-clone.c index 0f231d8af5,9d79301b8e..ad048085f3 --- a/builtin-clone.c +++ b/builtin-clone.c @@@ -38,9 -38,10 +38,10 @@@ static const char * const builtin_clone }; static int option_quiet, option_no_checkout, option_bare, option_mirror; -static int option_local, option_no_hardlinks, option_shared; +static int option_local, option_no_hardlinks, option_shared, option_recursive; static char *option_template, *option_reference, *option_depth; static char *option_origin = NULL; + static char *option_branch = NULL; static char *option_upload_pack = "git-upload-pack"; static int option_verbose; @@@ -59,14 -60,14 +60,16 @@@ static struct option builtin_clone_opti "don't use local hardlinks, always copy"), OPT_BOOLEAN('s', "shared", &option_shared, "setup as shared repository"), + OPT_BOOLEAN(0, "recursive", &option_recursive, + "setup as shared repository"), OPT_STRING(0, "template", &option_template, "path", "path the template repository"), OPT_STRING(0, "reference", &option_reference, "repo", "reference repository"), OPT_STRING('o', "origin", &option_origin, "branch", "use instead of 'origin' to track upstream"), + OPT_STRING('b', "branch", &option_branch, "branch", + "checkout instead of the remote's HEAD"), OPT_STRING('u', "upload-pack", &option_upload_pack, "path", "path to git-upload-pack on the remote"), OPT_STRING(0, "depth", &option_depth, "depth", @@@ -75,10 -76,6 +78,10 @@@ OPT_END() }; +static const char *argv_submodule[] = { + "submodule", "update", "--init", "--recursive", NULL +}; + static char *get_repo_path(const char *repo, int *is_bundle) { static char *suffix[] = { "/.git", ".git", "" }; @@@ -353,7 -350,9 +356,9 @@@ int cmd_clone(int argc, const char **ar const char *repo_name, *repo, *work_tree, *git_dir; char *path, *dir; int dest_exists; - const struct ref *refs, *head_points_at, *remote_head, *mapped_refs; + const struct ref *refs, *remote_head, *mapped_refs; + const struct ref *remote_head_points_at; + const struct ref *our_head_points_at; struct strbuf key = STRBUF_INIT, value = STRBUF_INIT; struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT; struct transport *transport = NULL; @@@ -515,7 -514,7 +520,7 @@@ option_upload_pack); refs = transport_get_remote_refs(transport); - if(refs) + if (refs) transport_fetch_refs(transport, refs); } @@@ -525,11 -524,31 +530,31 @@@ mapped_refs = write_remote_refs(refs, refspec, reflog_msg.buf); remote_head = find_ref_by_name(refs, "HEAD"); - head_points_at = guess_remote_head(remote_head, mapped_refs, 0); + remote_head_points_at = + guess_remote_head(remote_head, mapped_refs, 0); + + if (option_branch) { + struct strbuf head = STRBUF_INIT; + strbuf_addstr(&head, src_ref_prefix); + strbuf_addstr(&head, option_branch); + our_head_points_at = + find_ref_by_name(mapped_refs, head.buf); + strbuf_release(&head); + + if (!our_head_points_at) { + warning("Remote branch %s not found in " + "upstream %s, using HEAD instead", + option_branch, option_origin); + our_head_points_at = remote_head_points_at; + } + } + else + our_head_points_at = remote_head_points_at; } else { warning("You appear to have cloned an empty repository."); - head_points_at = NULL; + our_head_points_at = NULL; + remote_head_points_at = NULL; remote_head = NULL; option_no_checkout = 1; if (!option_bare) @@@ -537,41 -556,35 +562,35 @@@ "refs/heads/master"); } - if (head_points_at) { - /* Local default branch link */ - create_symref("HEAD", head_points_at->name, NULL); + if (remote_head_points_at && !option_bare) { + struct strbuf head_ref = STRBUF_INIT; + strbuf_addstr(&head_ref, branch_top.buf); + strbuf_addstr(&head_ref, "HEAD"); + create_symref(head_ref.buf, + remote_head_points_at->peer_ref->name, + reflog_msg.buf); + } + if (our_head_points_at) { + /* Local default branch link */ + create_symref("HEAD", our_head_points_at->name, NULL); if (!option_bare) { - struct strbuf head_ref = STRBUF_INIT; - const char *head = head_points_at->name; - - if (!prefixcmp(head, "refs/heads/")) - head += 11; - - /* Set up the initial local branch */ - - /* Local branch initial value */ + const char *head = skip_prefix(our_head_points_at->name, + "refs/heads/"); update_ref(reflog_msg.buf, "HEAD", - head_points_at->old_sha1, + our_head_points_at->old_sha1, NULL, 0, DIE_ON_ERR); - - strbuf_addstr(&head_ref, branch_top.buf); - strbuf_addstr(&head_ref, "HEAD"); - - /* Remote branch link */ - create_symref(head_ref.buf, - head_points_at->peer_ref->name, - reflog_msg.buf); - install_branch_config(0, head, option_origin, - head_points_at->name); + our_head_points_at->name); } } else if (remote_head) { /* Source had detached HEAD pointing somewhere. */ - if (!option_bare) + if (!option_bare) { 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) @@@ -580,10 -593,8 +599,10 @@@ option_no_checkout = 1; } - if (transport) + if (transport) { transport_unlock_pack(transport); + transport_disconnect(transport); + } if (!option_no_checkout) { struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); @@@ -605,7 -616,7 +624,7 @@@ opts.src_index = &the_index; opts.dst_index = &the_index; - tree = parse_tree_indirect(remote_head->old_sha1); + 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); @@@ -616,9 -627,6 +635,9 @@@ err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1), sha1_to_hex(remote_head->old_sha1), "1", NULL); + + if (!err && option_recursive) + err = run_command_v_opt(argv_submodule, RUN_GIT_CMD); } strbuf_release(&reflog_msg);