Jeff King <peff@xxxxxxxx> writes: > On Thu, Oct 15, 2009 at 12:52:55PM -0700, Junio C Hamano wrote: > >> I like James's suggestion to allow us to store refs other than refs/heads/ >> in HEAD to denote this state, and keep commit and reset from updating such >> a ref through updating HEAD. > > Didn't we already consider and reject this the first time around? For > example, this thread has a ton of stuff about how we shouldn't prevent > people from making commits on the wandering state: > > http://thread.gmane.org/gmane.comp.version-control.git/35777/focus=35835 > > And here's me even advocating this exact strategy (and I'm sure I didn't > think of it; it's probably discussed elsewhere, too): > > http://thread.gmane.org/gmane.comp.version-control.git/35777/focus=35858 > > Not that I am not necessarily complaining, but I just hope this decision > is "with new-found knowledge we are revisiting this decision" and not > "we totally forgot about what came before". Maybe we are reading different messages in the same message. My understanding of James's suggestion is: (1) "git checkout $token" makes HEAD point at the refname dwim_ref() expands $token to, iff dwim_ref() is happy, and otherwise detaches HEAD; (2) "git commit" (and other things like "git reset HEAD^" that updates underlying ref thru updates to HEAD when HEAD is a symref) rejects when HEAD points at a ref outside refs/heads/, but works when HEAD points at a local branch, or when HEAD is detached. As a consequence: $ git checkout v1.6.5 ;# does not detach, cannot update $ git symbolic-ref HEAD refs/tags/v1.6.5 $ git checkout origin/next ;# ditto $ git symbolic-ref HEAD refs/remotes/origin/next These are often done by sightseers, and we can add instructions to fork and record upon an attempt to "git commit". As a bonus, we get Daniel's extra information for detached HEAD for free, as we can just read HEAD and learn what it points at. We need to design what "git branch" should say in this case. This is backward incompatible, and makes what experts are used to do slightly cumbersome to spell, i.e. $ git checkout v1.6.5^0 ;# detaches and can commit $ git checkout origin/next^0 ;# ditto $ git checkout $(git merge-base master sp/smart-http) ;# ditto These detach, and I can apply the updates series to the same base as the previous round on an unnamed branch. So in other words, the semantics for detached HEAD case does not change at all. We never forbid committing or resetting while on detached HEAD, as it is meant to be an easy way to get an unnamed throw-away state that is not even worth coming up with a unique temporary branch name, and I do not think the above contradicts with what was said in 35835. We used to have only two states on HEAD: either on a local branch or detached. James is introducing another state: on a ref that is not a local branch. As that is useful for common sightseer tasks, we can afford to forbid committing or updating for safety and we do not have to worry about hurting the established usefulness of how detached HEAD works. One drawback is that you cannot be in this sightseeing state without having a ref. You can have "look-but-not-touch" checkout on origin/next or origin/master, but you cannot sightsee the parent of origin/next the same way (it would detach). I do not know if it is a big deal, though. If it is very important to support: $ git checkout --look-but-not-touch origin/next^ then James's approach would not be very useful, as we do have to detach HEAD and implement the "do not touch" logic for detached HEAD state anyway, so we might just use the same logic we would use for origin/next^ when checking out origin/next itself. -- 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