Junio C Hamano <gitster@xxxxxxxxx> writes: > Jonathan Watt <jwatt@xxxxxxxxx> writes: > > My understanding is if you push into a non-bare tree in merc, they make > the branch head into "unmerged" state, and as far as the work tree is > concerned you are still on the previous commit, and you merge "the other > commit" that was pushed into from sideways to update the branch tip with > pushed-into commit. > > In git, if you detach HEAD when you push into a checked-out 'master', your > work tree won't be associated with 'master' anymore, and to merge the > pushed-into state into the history of 'master', you would need: > ... > The second point bothers me quite a lot, as you are assuming that the > user at the repository that was pushed into does _not_ know what is going > on, and may keep working on a detached HEAD _without knowing_ what is > going on. Let's back up a bit and try again. I was trying to say what Mercurial presents at the UI level may be much nicer with respect to pushing into a checked out repository. Their notion of 'head' (and 'branch' in general) is quite different from ours in that their branch can have more than one 'head's that the user can choose to merge into its 'tip', and 'push' does not update the 'tip'. It instead adds a new (unmerged) 'head' or fast-forwards an existing 'head', and the user can choose to merge them into 'tip' when convenient (please correct me here, since I am talking from my reading their documentation and I may have misread it). In git, a branch is just a ref and points at a single commit, and push and fetch updates a single ref. There is no direct notion of "these other refs are related to this branch ref and you may want to merge them" at the low level plumbing layer, so if you push to update a ref, git does what it is told to do. The branch ref is directly updated, and won't get split to be merged back later like Mercurial does. My objection to the "always detach HEAD automatically" is because that solution, while it may solve the issue of work tree and HEAD getting inconsistent silently behind user's back, would introduce more confusion. - The repository loses where we were (so we would add a hack to record which branch you were on), and operations after that silent detaching will _not_ advance your local branch anymore, because the push took over the branch 'tip'. If you switch to some other branch, you lose. - The final merge happens in the wrong direction. The other commit is already called the official 'tip' of the branch because push took over the branch 'tip', and after merging it into your stale HEAD, you have to update 'master' with the merge made on the detached HEAD. - It's your repository and the commit you were on when this push from sideways happened should _stay_ as the official 'tip' of the branch, until you tell git so. In that sense, pushing into a non-bare repository's refs/heads/ hierarchy directly is conceptually wrong, whether the branch in question is currently checked out or not. Although we do not have their split branch heads, we do have a similar concept by the name of "branch tracking". Your 'master' is marked as being related to 'remotes/origin/master' by "git clone" and by "git checkout -b foo remotes/origin/foo", and recent "git checkout" to switch to such a branch will report how diverged you are from the other party. The mothership-satellite configuration described in FAQ is about using this facility, because "git push" into a non-bare repository is exactly a "git fetch" run in the reverse direction (i.e. fetching to pushed-into repository from pushed-from repository). -- 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