On Fri, Jun 03, 2011 at 09:11:19AM -0700, Junio C Hamano wrote: > An alternative would be not to checkout anything when HEAD points at an > object that does not exist, or point the HEAD at the default "master" > branch just like in the case when we cannot guess uniquely. That way, we > do not have to worry about having to fetch the orphaned detached HEAD, > which is an unlikely thing the publisher wanted to feed to its recipients > in the first place. I tend to prefer the former (i.e. resulting in no > paths in the working tree, possibly with a big warning message "the > repository does not suggest which branch to track---are you sure you > wanted to clone from there?"). Yeah, I was tempted to go the "check out nothing if we don't have the object" route. But my thinking was: 1. We have already been creating local detached HEADs to match a remote detached HEAD since at least 8434c2f (Build in clone, 2008-04-27). Should we keep doing that? If so, I think it introduces a somewhat confusing inconsistency from the user's perspective. Why is a sight-seeing detached HEAD pointing into history OK to checkout, but one with a commit on top is not OK? 2. Similar to the above, we already do have the object for a local clone, which just copies the object db whole. So now there is an inconsistency that: git clone foo bar will checkout out such a HEAD, but neither of: git clone file://$PWD/foo bar git clone git://host/foo bar does. 3. Fetching and checking it out just seems like the most friendly and the least surprising thing for the user. In 99% of cases, people are cloning bare repositories whose HEADs likely won't detach anyway (and if they did, they certainly wouldn't have made commits on them). But in the rare case that I _do_ clone a non-bare repo, what am I trying to accomplish? Most likely I'm trying to make a new workspace, either to work on the identical branch, or some other branch. In the former case, making a detached HEAD (whether it points to history or to a new commit) is what I would want. In the latter case, it doesn't really matter what we put in HEAD, as the user is going to switch it anyway. The only downside is that we may have transferred some extra objects; in practice, this is probably not a big deal due to deltas unless your detached commit is gigantic. 4. We're guessing at whether the user will want the objects on the detached HEAD or not. Which means we're going to be wrong sometimes. But I would rather err on the side of copying the extra commits than not. The few extra bytes spent are a better downside than: $ git clone git://host/foo bar $ ssh host && rm -rf foo [oops, I actually wanted the detached commit!] Though to be fair, if we printed a warning about the detached HEAD during the first command, the user would hopefully not execute the second one. > We treat the symbolic-ref on the publishing end not as the "current" > branch at all. It is used as the "suggested primary branch to track". > So allowing to fetch from a repository with detached HEAD is already a > weird setup. By that argument, we should stop checking out any detached HEAD at all. Which I agree makes sense from the point of view that clone is just "init + remote add + fetch + checkout". But I think it's probably more helpful to the user (and doesn't cost us much) to just checkout the detached HEAD than to refuse to check out anything and print a warning. If we're right, they're happy. If we're wrong, the solution in both cases is to "git checkout" what they did want. Possibly we should warn that the cloned HEAD is detached (maybe even with the regular detached HEAD warning). > I am hoping that we are not setting up origin/HEAD to point at > anything in this case, as the remote is telling us that there is no > suggested primary branch for the clients to track by having a detached > HEAD to begin with. No, we don't set up an origin/HEAD at all in that case; the handling for that and our local HEAD are separate (and I was careful to maintain this with my patch by not setting a peer_ref to store the HEAD we fetch; it stays in core until we write it to our HEAD). > Even if you are fetching your own (or your pal's) repository with a > working tree to transfer a work-in-progress, any work on detached HEAD > that is orphaned is too transitory, and it goes against my taste to > let people fetch from it. > > But people are free to have bad taste ;-). They can already fetch from it via "git fetch /your/pal HEAD". So this is really just about clone. I think it is not even bad taste if your workflow is: 1. You're in the middle of a rebase on a detached HEAD. You make an amended commit, then continue. You get a conflict which is confusing, and inspection causes you to blame your coworker. 2. You holler over the cubicle wall to your coworker, who runs "git clone ~bob/project bobs-project". They inspect your current state and try to cherry-pick the failed commit themselves. Either the merge conflicts tell them what to tell you to fix your problem, or perhaps they even resolve the conflicts themselves and let you fetch the state back. So I think it is not a matter of taste, but of "in some (rare) cases this is useful, and in many cases it is useless". I just think there is no reason not to be helpful to the people in the rare cases, as it costs so little in the other case (and remember that _without_ detached orphan commits, this is literally a no-op). -Peff -- 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