Background:
I have used Mercurial myself as a single user to keep track of the changes I make to my own code, and I think I am already familiar with the fundamentals. However, I am now about to start working on a software project with somebody else in my lab and want to make sure I understand how to properly share code with somebody else using Mercurial.
Our situation is the following: We both have our own repository in a shared volume (i.e. different paths) in a Linux cluster, and we both have read and write access to our own and each other's repositories.
We can call开发者_如何转开发 these two repositories: Bob's and Alice's repositories for the purpose of the discussion.
My understanding is that there are multiple ways of having Bob and Alice share their code, two of them being the following:
Option 1: Sharing via pulling
- Bob pulls from Alice whenever he wants to see her changes
- Similarly, Alice pulls from Bob whenever she wants to see his changes.
Option 2: Sharing via pushing
- Bob pro-actively pushes his changes into Alice's repository whenever he wants to share his changes with her.
- Similarly, Alice pro-actively pushes her changes into Bob's repository whenever he wants to share his changes with her.
Questions:
My interpretation from reading the Mercurial documentation and tutorials online is that the first option above is usually preferred over the second one. One question I have is why?
Can the second option above lead to any problems? What would happen if Bob commits into his own repository while Alice also pushes her changes simultaneously into Bob's repository?
Thanks
Either works and in the end it really doesn't matter because pushing/pulling doesn't do the update
or the merge
for the recipient -- it just moves changeset into the underlying repo, not into the working directory.
The first option, pulling, is more commonly done because:
- usually you don't have write access to one another's repos (and probably shouldn't) and with pulling you only need read access to one another's repos
- when you push changesets to someone there's no notification to them that they received new changesets. They won't discover it until they run
hg summary
(orhg heads
orhg log
) and then they'll have tohg merge
. So as long as the recipient has to take an explicit action (check and merge) to get your changes they may as well just pull and merge instead. It's no more work for them and less for you.
As others have pointed out a repository write-look will prevent commiting during incoming push or pull operations.
From what I've read about Hg's file model, it handles concurrent writes elegantly so file corruption is not an issue.
The issue is more about workflow. There is no "simultaneous" because the later write operation will be blocked until the earlier write operation finishes. If Bob's commit is earlier, then Alice's push will (by default) fail because it would create a new head. She would have to force push to create a new head in Bob's repo and then he would have to merge them. Or she can pull Bob's change and merge then push. If Alice's push is earlier, then Bob's commit will go through, creating a branch that he will have to merge. Either way, a merge is gonna have to happen. What I don't like about this approach is that Bob is now going to be surprised by these new changesets in his repo and he'll have to do hg update to bring them into his working copy anyways.
The model we use on our team of 4 is to have a central repo that everyone pulls/pushes from. This is also where our CI server pulls to run automated builds. This has worked pretty smoothly for 11 months now.
Mercurial easily handles both scenarios. To me option one is preferred because it's easier to maintain. What if Alice doesn't want Bob's changes pushed into her repo? Then she has to go through the trouble of backing out his push. Where as if Alice wants to pull Bob's changes, she has clearly given consent to the pull and resulting merge, and is expecting it. Chances are she will pull into a separate repo before merging with her primary repo to ensure she actually wants to integrate his changes.
Maybe it's just me, but pushing changes onto someone else feels dirty. I would much rather let them know an update is available, and if they are interested they can pull the changes from you.
That being said, the way we handle it here in the office is to push most code to a central repo that everyone has access to. After it gets approved via code review, those changes get pushed into our real repo and become available for everyone else to pull. It's only in fairly rare circumstances that developers would push code to one another directly, and usually occurs when they are working closely on the same feature.
精彩评论