On 2009.10.15 14:54:18 -0700, Junio C Hamano wrote: > 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. I don't have any numbers backing this up, but my gut feeling says that most cases of "Where have my commits gone?" that I have seen on #git were due to "git checkout HEAD~2"-like actions. Either because the user assumed SVN-like behaviour (you can't commit until you do "svn up", like "git reset --merge HEAD@{1}") or thought that "git checkout <committish>" would act like "git reset --hard <committish>". For the latter I fail to envision any solution except for education (and I have no idea why the user expected checkout to work like reset). The former can be solved by the proposed extra information in HEAD, forbidding changes to HEAD that make it reference a commit that's not reachable through the head stored in the extra information[*1*] and providing some command that acts like "svn up". This seems quite different from the plain "forbid committing" or "detach and know how you get there", but more like "detach and know where you're coming from". [*1*] If certain updates to HEAD aren't forbidden, a "checkout deadbeef" (or a reset or update-ref) would possibly invalidate the extra information in HEAD, which would require implicit detaching, making the concept useless. For example: A---B---C---D---E (master) \ / F---G---H---I (foo) git checkout master git checkout master~2 # Put refs/heads/master into the extra info git reset --hard HEAD^ # Allow? git reset --hard foo~2 # Allow? Change extra info? It's also in master git checkout master git checkout foo~2 Is that checkout allowed? "foo~2" is also reachable through master. Does "checkout" do some smart parsing and puts refs/heads/foo into the extra info? Or should refs/heads/master end up there? git checkout master git checkout foo~1 Basically, same deal as above, but foo~1 is not reachable through master. And finally the pure commit id cases: git checkout master git checkout $(git rev-parse master^) Is that to be allowed? We can't derive the extra info from the argument given to checkout, but could check that it's reachable from master (currently referenced HEAD at the time of the command being run) And: git checkout master git checkout $(git rev-parse foo^) Neither can we guess what the extra info should be from the argument given to checkout, nor is the given commit reachable through master. So this should be forbidden and should require ^0? This whole thing is indeed a whole lot less complex with a SVN-like model, where you basically work with the linearly growing reflog only. Björn -- 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