On Sun, Feb 8, 2009 at 6:41 PM, Johannes Schindelin <Johannes.Schindelin@xxxxxx> wrote: > Hi, > > On Sun, 8 Feb 2009, Jay Soffian wrote: > >> If you had paid attention, you would have noticed that Mercurial did not >> attempt to merge. Rather, it created a new branch head in the remote >> repository. > > So this is the "detached HEAD" idea. Which contradicts the law of the > least surprise. I agree that a detached HEAD is a bad idea. The closest parallel that I can come up with for git would be for receive-pack to store incoming changes into separate branch hierarchy, NOT for it to detach HEAD. A toy-patch I played around with earlier allowed this on the non-bare upstream repo: [receive] prefix = refs/remotes/incoming Then a push to refs/heads/master was automatically stored as refs/remotes/incoming/master instead. And yes, I'm aware the user can use a push refspec on the sending side. > It should be clear that the equivalent of a central repository is a bare > repository. And hopefully Junio's strategy will make that clearer, so I > think this is the superior approach. I foresee new user doing this: laptop:~$ git clone ssh://workstation/~/repo laptop:~$ cd repo laptop:~/repo (master)$ echo change >> file && git commit -am change laptop:~/repo (master)$ git push ... error: refusing to update checked out branch: refs/heads/master To ssh://workstation/~/repo ! [remote rejected] master -> master (branch is currently checked out) error: failed to push some refs to 'ssh://workstation/~/repo' And now new user is stumped. Perhaps adding something like this to the git-push man page: ---8<--- Non-bare Repositories --------------------- When pushing to a non-bare upstream repository (i.e. an upstream repository with a working copy), changes to the checked out branch are NOT reflected in the upstream index, nor in the working copy. This creates a situation where it is easy to accidentally revert the changes on the next commit in the upstream repository. e.g. Assume the following history exists in the upstream repository: A---B master master is the currently checked out branch, nothing is staged in the index and the working copy is clean. A single change is made to master downstream and pushed. The upstream repository is now in this state: A---B---C master However, the index and working copy reflect the state at commit B. Performing a new commit in the upstream repository would do this: A---B---C---B' master B' is a new commit, but reflects the same state as B. In order to prevent this situation, it is recommended that if you need to push into a non-bare upstream repository, set receive.denyCurrentBranch = true in the upstream repository (this will become the default in git-X.Y). This will prevent the push from occurring. Instead, you can push into an alternate branch, and then merge that branch in the upstream repository. e.g.: server$ cd ~/repo && git config receive.denyCurrentBranch true laptop$ git push ... error: refusing to update checked out branch: refs/heads/master To ssh://server/~/repo ! [remote rejected] master -> master (branch is currently checked out) error: failed to push some refs to 'ssh://server/~/repo' laptop$ git push origin master:refs/remotes/laptop/master laptop$ ssh server server$ cd ~/repo server$ git merge laptop/master Alternatively, you can set receive.denyCurrentBranch = warn in the upstream repo, but then you must remember to perform "git reset --hard" in the upstream repo after pushing to its currently checked out branch. (But be careful, as "git reset --hard" throws away uncommitted changes.) ---8<--- j. -- 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