git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 1/6] clone: teach --detach option

From
Philippe Blain <levraiphilippeblain@gmail.com>
Date
Aug 30, 2022, 04:02 UTC
Message-ID
<62ae295e-64ea-eaaf-646f-030e7b9028a3@gmail.com>
In-Reply-To
<936e237c716bddf3a5889829e0c907e881736336.1661806456.git.gitgitgadget@gmail.com>
Hi Glen,
Le 2022-08-29 à 16:54, Glen Choo via GitGitGadget a écrit :
Show 7 quoted lines
> From: Glen Choo <chooglen@google.com>
> 
> Teach "git clone" the "--detach" option, which leaves the cloned repo in
> detached HEAD (like "git checkout --detach"). If the clone is not bare,
> the remote's HEAD branch is also not created (bare clones always copy
> all remote branches directly to local branches, so the branch is still
> created in the bare case).

At first reading I thought you meant the 'origin/HEAD' symref, which is not the case here. I think something like this would maybe be clearer:

If the clone is not bare, skip the creation of a local branch corresponding to the branch pointed to by the remote's HEAD symref (bare clones... to local branches, so that branch ...

(OK this is very verbose but in my opinion it's clearer.)
> This is especially useful in the "submodule.propagateBranches" workflow,
> where the submodule branch names match the superproject's branch names,
> so it makes no sense to name the branches after the submodule's remote's
> branches.

We are just skipping the creation of a single branch here, so it's unclear to me which other branches are being talked about in this last paragraph. All remote-tracking branches are unaffected by this flag, no?

Show 28 quoted lines
> Signed-off-by: Glen Choo <chooglen@google.com>
> ---
>  Documentation/git-clone.txt |  7 ++++++-
>  builtin/clone.c             | 12 +++++++++---
>  t/t5601-clone.sh            | 22 ++++++++++++++++++++++
>  3 files changed, 37 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
> index 632bd1348ea..a3af90824b6 100644
> --- a/Documentation/git-clone.txt
> +++ b/Documentation/git-clone.txt
> @@ -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,11 @@ 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. In a
> +	non-bare repository, the branch will not be created.
Again, I think the wording could be improved, maybe something along those lines:

If the cloned repository's HEAD points to a branch, detach the newly created HEAD at the commit at the tip of that branch. Additionnally, in a non-bare repository, skip creating a corresponding local branch.

Show 22 quoted lines
> +
>  -u <upload-pack>::
>  --upload-pack <upload-pack>::
>  	When given, and the repository to clone from is accessed
> diff --git a/builtin/clone.c b/builtin/clone.c
> index c4ff4643ecd..1bc1807360e 100644
> --- a/builtin/clone.c
> +++ b/builtin/clone.c
> @@ -77,6 +77,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 int recurse_submodules_cb(const struct option *opt,
>  				 const char *arg, int unset)
> @@ -160,6 +161,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 branch")),
maybe "don't create any local branch" ?
Show 18 quoted lines
>  	OPT_END()
>  };
>  
> @@ -607,10 +610,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"));

OK, so the addition of that condition means that if --detach was given, we now go into the 'else if (our)' branch, as long as 'our' is non-null, which means that the remote's HEAD points to a branch or we gave --branch. This makes sense. If the remote's HEAD does not point to a branch and we did not give --branch, then we go into 'else if (remote)', as before.

Show 40 quoted lines
> @@ -1339,7 +1344,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
> diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
> index cf3be0584f4..1e7e5143a76 100755
> --- a/t/t5601-clone.sh
> +++ b/t/t5601-clone.sh
> @@ -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
> +	)
> +'
> +
Tests look good.
Previous: Glen Choo via GitGitGadgetNext: Glen Choo via GitGitGadget
Message 3 of 56 in “clone, submodule update: check out submodule branches”
  1. 0/6 clone, submodule update: check out submodule branchesGlen Choo via GitGitGadget, Aug 29, 2022
  2. 1/6 clone: teach --detach optionGlen Choo via GitGitGadget, Aug 29, 2022
  3. Philippe BlainAug 30, 2022
  4. 2/6 repo-settings: add submodule_propagate_branchesGlen Choo via GitGitGadget, Aug 29, 2022
  5. Philippe BlainAug 30, 2022
  6. 3/6 t5617: drop references to remote-tracking branchesGlen Choo via GitGitGadget, Aug 29, 2022
  7. Philippe BlainAug 30, 2022
  8. 4/6 submodule: return target of submodule symrefGlen Choo via GitGitGadget, Aug 29, 2022
  9. Jonathan TanSep 1, 2022
  10. Glen ChooSep 1, 2022
  11. 6/6 clone, submodule update: check out branchesGlen Choo via GitGitGadget, Aug 29, 2022
  12. Philippe BlainAug 30, 2022
  13. Glen ChooAug 30, 2022
  14. Jonathan TanSep 1, 2022
  15. 5/6 submodule--helper: refactor up-to-date criterionGlen Choo via GitGitGadget, Aug 29, 2022
  16. 0/7 clone, submodule update: check out submodule branchesGlen Choo via GitGitGadget, Oct 20, 2022
  17. 1/7 clone: teach --detach optionGlen Choo via GitGitGadget, Oct 20, 2022
  18. 2/7 repo-settings: add submodule_propagate_branchesGlen Choo via GitGitGadget, Oct 20, 2022
  19. Jonathan TanOct 25, 2022
  20. 3/7 submodule--helper clone: create named branchGlen Choo via GitGitGadget, Oct 20, 2022
  21. Jonathan TanOct 25, 2022
  22. 4/7 t5617: drop references to remote-tracking branchesGlen Choo via GitGitGadget, Oct 20, 2022
  23. 5/7 submodule: return target of submodule symrefGlen Choo via GitGitGadget, Oct 20, 2022
  24. 6/7 submodule update: refactor update targetsGlen Choo via GitGitGadget, Oct 20, 2022
  25. 7/7 clone, submodule update: create and check out branchesGlen Choo via GitGitGadget, Oct 20, 2022
  26. Jonathan TanOct 25, 2022
  27. Glen ChooOct 25, 2022
  28. Junio C HamanoOct 20, 2022
  29. Glen ChooOct 20, 2022
  30. Junio C HamanoOct 21, 2022
  31. 0/8 clone, submodule update: check out submodule branchesGlen Choo via GitGitGadget, Oct 28, 2022
  32. 1/8 clone: teach --detach optionGlen Choo via GitGitGadget, Oct 28, 2022
  33. Junio C HamanoOct 28, 2022
  34. Junio C HamanoOct 28, 2022
  35. Glen ChooOct 28, 2022
  36. Taylor BlauOct 30, 2022
  37. Glen ChooOct 31, 2022
  38. Philippe BlainNov 8, 2022
  39. 2/8 repo-settings: add submodule_propagate_branchesGlen Choo via GitGitGadget, Oct 28, 2022
  40. 3/8 submodule--helper clone: create named branchGlen Choo via GitGitGadget, Oct 28, 2022
  41. 5/8 submodule: return target of submodule symrefGlen Choo via GitGitGadget, Oct 28, 2022
  42. Junio C HamanoOct 28, 2022
  43. Glen ChooOct 28, 2022
  44. 4/8 t5617: drop references to remote-tracking branchesGlen Choo via GitGitGadget, Oct 28, 2022
  45. 8/8 clone, submodule update: create and check out branchesGlen Choo via GitGitGadget, Oct 28, 2022
  46. Philippe BlainNov 8, 2022
  47. Jonathan TanNov 15, 2022
  48. Glen ChooNov 22, 2022
  49. Jonathan TanNov 23, 2022
  50. Junio C HamanoNov 23, 2022
  51. 6/8 submodule update: refactor update targetsGlen Choo via GitGitGadget, Oct 28, 2022
  52. 7/8 submodule--helper: remove update_data.suboidGlen Choo via GitGitGadget, Oct 28, 2022
  53. Jonathan TanNov 14, 2022
  54. Taylor BlauOct 30, 2022
  55. Philippe BlainNov 8, 2022
  56. Glen ChooNov 8, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.