This is a "works but is unsatisfactory from my acceptance standard" WIP for review and improvements. It tries to introduce a protocol extension that lets "git clone" discover where the HEAD points at more reliably. The current code has to guess, because the original protocol tells what object each ref points at but does not talk about which other ref a symbolic ref points at. The implication of this is that if you prepare another branch that points at your master, like this: $ git checkout -b another master and keep that other branch checked out (and in sync with 'master'), a clone made from such a repository may incorrectly have its HEAD pointing at 'master', not 'another'. Here are the five patches to remedy the problem. [PATCH 1/5] upload-pack.c: refactor receive_needs() [PATCH 2/5] get_remote_heads(): do not assume that the conversation is one-way [PATCH 3/5] clone: find the current branch more explicitly [PATCH 4/5] upload-pack: implement protocol extension "symbolic-ref" [PATCH 5/5] clone: test the new HEAD detection logic The first one is a mere clean-up and is not absolutely necessary. The second one is a preparatory step and it is needed for later steps (it by itself does not change any behaviour). The third one and the fourth one implement the receiver and and the sender end respectively. It is better to test these applying each of them independently on top of the second one and then merge the result, so that what happens during the transition period during which old client talks to new server (and vice versa) can be tested. The new feature is activated only when the updated client talks to the new server, so the test appears at the end, as a separate patch. In other words, after storing these five patches in five separate files, you would build this history (on top of 'master'): git am 1 2 3 git reset --hard HEAD^ 4---M---5 git am 4 / / git merge HEAD@{2} ---1---2---3 git am 5 The reason I say it is unsatisfactory is mostly because the protocol extension for this is very hard in the face of ls-remote which receives what the upload-pack says but disconnects without saying anything after that. The upload-pack side needs to check if the receiver wants to trigger protocol extension, but reading from the socket when talking to an old client will trigger an error message from it, although it is actually harmless. When git-clone runs locally, you can actually observe the error message arising from this issue, by running t5601 after applying 1 2 and 4 but not 3 (i.e. the state after "git am 4" in the above sequence) under "sh -x". We could trivially fix this by giving an extra parameter to packet_read_line() and safe_read() to tell them that it is Ok if the other end gives them an EOF if we wanted to, but I left the visible-but-harmless breakage as is to illustrate the issue for this round. builtin-clone.c | 24 +++++++-- builtin-fetch-pack.c | 2 +- builtin-send-pack.c | 7 ++- cache.h | 2 +- connect.c | 40 ++++++++++++++- t/t5601-clone.sh | 11 ++++ transport.c | 4 +- upload-pack.c | 140 ++++++++++++++++++++++++++++++++------------------ 8 files changed, 166 insertions(+), 64 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html