@@ -16,7 +16,7 @@ SYNOPSIS
[--depth <depth>] [--[no-]single-branch] [--no-tags]
[--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules]
[--[no-]remote-submodules] [--jobs <n>] [--sparse] [--[no-]reject-shallow]
- [--filter=<filter> [--also-filter-submodules]] [--] <repository>
+ [--filter=<filter> [--also-filter-submodules] [--detach]] [--] <repository>
[<directory>]
DESCRIPTION
@@ -210,6 +210,12 @@ objects from the source repository into a pack in the cloned repository.
`--branch` can also take tags and detaches the HEAD at that commit
in the resulting repository.
+--detach::
+ If the cloned repository's HEAD points to a branch, point the newly
+ created HEAD to the branch's commit instead of the branch itself.
+ Additionally, in a non-bare repository, the corresponding local branch
+ will not be created.
+
-u <upload-pack>::
--upload-pack <upload-pack>::
When given, and the repository to clone from is accessed
@@ -78,6 +78,7 @@ static int option_filter_submodules = -1; /* unspecified */
static int config_filter_submodules = -1; /* unspecified */
static struct string_list server_options = STRING_LIST_INIT_NODUP;
static int option_remote_submodules;
+static int option_detach;
static const char *bundle_uri;
static int recurse_submodules_cb(const struct option *opt,
@@ -162,6 +163,8 @@ static struct option builtin_clone_options[] = {
N_("any cloned submodules will use their remote-tracking branch")),
OPT_BOOL(0, "sparse", &option_sparse_checkout,
N_("initialize sparse-checkout file to include only files at root")),
+ OPT_BOOL(0, "detach", &option_detach,
+ N_("detach HEAD and don't create a local branch")),
OPT_STRING(0, "bundle-uri", &bundle_uri,
N_("uri"), N_("a URI for downloading bundles before fetching from origin remote")),
OPT_END()
@@ -613,10 +616,12 @@ static void update_remote_refs(const struct ref *refs,
}
static void update_head(const struct ref *our, const struct ref *remote,
- const char *unborn, const char *msg)
+ const char *unborn, int should_detach,
+ const char *msg)
{
const char *head;
- if (our && skip_prefix(our->name, "refs/heads/", &head)) {
+ if (our && !should_detach &&
+ skip_prefix(our->name, "refs/heads/", &head)) {
/* Local default branch link */
if (create_symref("HEAD", our->name, NULL) < 0)
die(_("unable to update HEAD"));
@@ -1357,7 +1362,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
branch_top.buf, reflog_msg.buf, transport,
!is_local);
- update_head(our_head_points_at, remote_head, unborn_head, reflog_msg.buf);
+ update_head(our_head_points_at, remote_head, unborn_head,
+ option_detach, reflog_msg.buf);
/*
* We want to show progress for recursive submodule clones iff
@@ -333,6 +333,28 @@ test_expect_success 'clone checking out a tag' '
test_cmp fetch.expected fetch.actual
'
+test_expect_success '--detach detaches and does not create branch' '
+ test_when_finished "rm -fr dst" &&
+ git clone --detach src dst &&
+ (
+ cd dst &&
+ test_must_fail git rev-parse main &&
+ test_must_fail git symbolic-ref HEAD &&
+ test_cmp_rev HEAD refs/remotes/origin/HEAD
+ )
+'
+
+test_expect_success '--detach with --bare detaches but creates branch' '
+ test_when_finished "rm -fr dst" &&
+ git clone --bare --detach src dst &&
+ (
+ cd dst &&
+ git rev-parse main &&
+ test_must_fail git symbolic-ref HEAD &&
+ test_cmp_rev HEAD refs/heads/main
+ )
+'
+
test_expect_success 'set up ssh wrapper' '
cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" \
"$TRASH_DIRECTORY/ssh$X" &&