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

[PATCH 3/3] clone: always fetch remote HEAD

From
Jeff King <peff@peff.net>
Date
Jun 3, 2011, 05:18 UTC
Message-ID
<20110603051805.GC1008@sigill.intra.peff.net>
In-Reply-To
<20110603050901.GA883@sigill.intra.peff.net>

In most cases, fetching the remote HEAD explicitly is unnecessary. It's just a symref pointing to a branch which we are already fetching, so we will already ask for its sha1.

However, if the remote has a detached HEAD, things are less certain. We do not ask for HEAD's sha1, but we do try to write it into a local detached HEAD. In most cases this is fine, as the remote HEAD is pointing to some part of the history graph that we will fetch via the refs.

But if the remote HEAD points to an "orphan" commit (one which was is not an ancestor of any refs), then we will not have the object, and update_ref will complain when we try to write the detached HEAD, aborting the whole clone.

This patch makes clone always explicitly ask the remote for the sha1 of its HEAD commit. In the non-detached case, this is a no-op, as we were going to ask for that sha1 anyway. In the regular detached case, this will add an extra "want" to the protocol negotiation, but will not change the history that gets sent. And in the detached orphan case, we will fetch the orphaned history so that we can write it into our local detached HEAD.

Signed-off-by: Jeff King <peff@peff.net>
---
[+cc Sverre and Jonathan for remote-helper advice]
This fails t5800, with:
  expecting success:
        git clone "testgit::${PWD}/server" localclone &&
        test_cmp public/file localclone/file
  Cloning into localclone...
  fatal: Got feature command 'relative-marks' after data command
  fast-import: dumping crash report to ...

So I guess it doesn't like us asking for HEAD. But the fact that it sends weird data to fast-import instead of saying "hey, HEAD doesn't exist" has me confused. I'm not sure if this is something one should not be doing with remote helpers, or if the testgit helper is simply buggy or incomplete.

 builtin/clone.c           |   10 +++++++---
 t/t5707-clone-detached.sh |    6 +++---
 2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index f579794..a99f1c8 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -343,8 +343,9 @@ static void remove_junk_on_signal(int signo)
 static struct ref *wanted_peer_refs(const struct ref *refs,
 		struct refspec *refspec)
 {
-	struct ref *local_refs = NULL;
-	struct ref **tail = &local_refs;
+	struct ref *head = get_remote_ref(refs, "HEAD");
+	struct ref *local_refs = head;
+	struct ref **tail = head ? &head->next : &local_refs;
 
 	get_fetch_map(refs, refspec, &tail, 0);
 	if (!option_mirror)
@@ -357,8 +358,11 @@ static void write_remote_refs(const struct ref *local_refs)
 {
 	const struct ref *r;
 
-	for (r = local_refs; r; r = r->next)
+	for (r = local_refs; r; r = r->next) {
+		if (!r->peer_ref)
+			continue;
 		add_extra_ref(r->peer_ref->name, r->old_sha1, 0);
+	}
 
 	pack_refs(PACK_REFS_ALL);
 	clear_extra_refs();
diff --git a/t/t5707-clone-detached.sh b/t/t5707-clone-detached.sh
index db4af95..82ecbce 100755
--- a/t/t5707-clone-detached.sh
+++ b/t/t5707-clone-detached.sh
@@ -58,18 +58,18 @@ test_expect_success 'cloned HEAD is detached' '
 	head_is_detached detached-history
 '
 
-test_expect_failure 'clone repo (orphan detached HEAD)' '
+test_expect_success 'clone repo (orphan detached HEAD)' '
 	git checkout --detach master &&
 	echo four >file &&
 	git commit -a -m four &&
 	git clone "file://$PWD" detached-orphan
 '
-test_expect_failure 'cloned HEAD matches' '
+test_expect_success 'cloned HEAD matches' '
 	echo four >expect &&
 	git --git-dir=detached-orphan/.git log -1 --format=%s >actual &&
 	test_cmp expect actual
 '
-test_expect_failure 'cloned HEAD is detached' '
+test_expect_success 'cloned HEAD is detached' '
 	head_is_detached detached-orphan
 '
 
-- 
1.7.6.rc0.36.g5a0d
Previous: Jeff KingNext: Sverre Rabbelier
Message 10 of 65 in “git clone (ssh://) skips detached HEAD”
  1. Dmitry IvankovJun 1, 2011
  2. Jeff KingJun 1, 2011
  3. Dmitry IvankovJun 1, 2011
  4. Junio C HamanoJun 1, 2011
  5. Jeff KingJun 1, 2011
  6. Jeff KingJun 1, 2011
  7. Jeff KingJun 3, 2011
  8. 1/3 t: add tests for cloning remotes with detached HEADJeff King, Jun 3, 2011
  9. 2/3 consider only branches in guess_remote_headJeff King, Jun 3, 2011
  10. 3/3 clone: always fetch remote HEADJeff King, Jun 3, 2011
  11. Sverre RabbelierJun 3, 2011
  12. Jeff KingJun 3, 2011
  13. Jeff KingJun 3, 2011
  14. Junio C HamanoJun 3, 2011
  15. Jeff KingJun 3, 2011
  16. Sverre RabbelierJun 4, 2011
  17. Jeff KingJun 6, 2011
  18. Junio C HamanoJun 6, 2011
  19. Junio C HamanoJun 6, 2011
  20. Sverre RabbelierJun 6, 2011
  21. Junio C HamanoJun 6, 2011
  22. Jeff KingJun 6, 2011
  23. Sverre RabbelierJun 6, 2011
  24. Jeff KingJun 7, 2011
  25. Sverre RabbelierJun 7, 2011
  26. 0/8 minor import/export remote helper fixesJeff King, Jun 7, 2011
  27. 1/8 transport-helper: fix minor leak in push_refs_with_exportJeff King, Jun 7, 2011
  28. 2/8 git-remote-testgit: exit gracefully after pushJeff King, Jun 7, 2011
  29. Sverre RabbelierJun 7, 2011
  30. 3/8 t5800: factor out some ref testsJeff King, Jun 7, 2011
  31. Sverre RabbelierJun 7, 2011
  32. 4/8 t5800: document some non-functional parts of remote helpersJeff King, Jun 7, 2011
  33. Sverre RabbelierJun 7, 2011
  34. Jeff KingJun 7, 2011
  35. Sverre RabbelierJun 7, 2011
  36. Jeff KingJun 7, 2011
  37. Sverre RabbelierJun 7, 2011
  38. Jeff KingJun 7, 2011
  39. Junio C HamanoJun 8, 2011
  40. Jeff KingJun 9, 2011
  41. Junio C HamanoJun 9, 2011
  42. Jeff KingJun 9, 2011
  43. Sverre RabbelierJun 9, 2011
  44. 5/8 teach remote-testgit to import non-HEAD refsJeff King, Jun 7, 2011
  45. Junio C HamanoJun 8, 2011
  46. Jeff KingJun 9, 2011
  47. 6/8 teach remote-testgit to import multiple refsJeff King, Jun 7, 2011
  48. 7/8 transport-helper: don't feed bogus refs to export pushJeff King, Jun 7, 2011
  49. Sverre RabbelierJun 7, 2011
  50. 8/8 git_remote_helpers: push all refs during a non-local exportJeff King, Jun 7, 2011
  51. Sverre RabbelierJun 7, 2011
  52. Jeff KingJun 7, 2011
  53. Sverre RabbelierJun 7, 2011
  54. Junio C HamanoJun 6, 2011
  55. Jeff KingJun 6, 2011
  56. Jeff KingJun 7, 2011
  57. 1/2 make copy_ref globally availableJeff King, Jun 7, 2011
  58. 2/2 clone: always fetch remote HEADJeff King, Jun 7, 2011
  59. Junio C HamanoJun 7, 2011
  60. Junio C HamanoJun 3, 2011
  61. Jeff KingJun 3, 2011
  62. Jakub NarebskiJun 1, 2011
  63. Jeff KingJun 1, 2011
  64. Jakub NarebskiJun 2, 2011
  65. Jeff KingJun 3, 2011

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.