Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm used to version control, in particular I currently use Mercurial. I have some doubts about how to make it work in large teams, where there is a good probability of having more people working on the same file.

Let me make an example with Mercurial (but any decentralized system will be more or less the same). Say we have a central server and three developers Alice, Bob and Carl. The three decide to start working at the same moment and they all pull from the server. By chance it happens that they are working on the same file.

Alice finishes first, and push her changes to the server. Then both Bob and Carl finish, more or less at the same time. Before pushing, they check whether there is something new, and find Alice's commit. So they pull it, and each one merges the changes locally. Then Bob pushes it and Carl pushes its changes.

What happens here is that on the server there are two heads: one by Bob and one by Carl, and both include merges with Alice's work. Whoever now pulls from the server will find a little mess. Of course one can just merge Bob and Carl heads, but that may not be as simple. Bob and Carl may have had different ideas on how to merge with Alice's work.

As soon as more people start working on the project, things can go even worse. So, while in theory I understand how merges are supposed to work, it is not clear to me how to make things manageable in a large project.

How do people manage to resolve conflicts when there are many people working on the same file, possibly having done different merges in different orders?

share|improve this question
7  
If Alice, Carl and Bob all have non trivial work to perform on the same file, then there may well be something wrong with the way you have your source setup, and/or your dev-to-dev communication channels need to be improved. –  Binary Worrier Apr 29 '11 at 10:38
    
Take a look at hginit.com it's a pretty good Mercurial tutorial –  JF Dion Apr 29 '11 at 14:29
2  
You could look at how the Linux kernel is developed. There's lots more than three people involved, and they use Git (which is the same sort of version control as Mercurial, and probably works identically on the level you're talking about). It works for them. –  David Thornley Apr 29 '11 at 14:54

7 Answers 7

up vote 5 down vote accepted

The way this is done is that every developer must merge changes before they commit a file. I have never used Mercurial so I don't know the commands or the exact process, but in any serious config management tool you will be warned if you try to check in "over the top" of someone else. When you get this warning you should merge the other changes in to your checked out copy, check the build and tests etc and then check in.

This is a very common issue, and merging in this way can be a real PITA, but that's life. The alternative approach of locking all checked out files prevents this issue, but has the serious drawback of blocking everyone else while you work on a file, which in turn leads to people editing uncontrolled versions and then all hell breaks loose...

share|improve this answer
    
I agree, but Carl and Bob have just pulled from the server. Let us say that Bob finishes his merge first, and pushes it to the server. Let us also assume that Carl is a good guy, so instead of pushing is merge, he pulls again to see whether there are any new changes. The situation will be identical, the only difference being that the mess is now on Carl's computer rather than on the server. The problem is that people can make not only different changes - that should be merged - but also different merges, and merges of merges and so on... –  Andrea Apr 29 '11 at 8:50
3  
Yes the "mess" wil be on the developers PC and not the server. That's about all you can hope for, the developer then has to untangle the mess locally before checking in. And yes, changes can get lost in this way sometimes. –  Steve Haigh Apr 29 '11 at 8:52
1  
In my experience, this happens far less often that you might expect, although the frequency at which clashes occur really depends upon how the work is organized, how much code changes on each checkin and how the code is structured. (Individual ownership of components = good; small, frequent checkins = good; well-organized repository = good) –  William Payne Jan 4 '12 at 21:41

I'm not sure if Mercurial is different, but git simply won't allow* you to push to a destination that has diverged from your branch (eg. in your case if Bob pushes first, then the server has diverged from Carl's branch). Carl must pull down Bob's changes, commit them, then push.

*well it will, if you use the --force option. But if you have to use that, you should know why.

share|improve this answer
    
Mercurial also requires you to force a push in that situation, the difference is that with Hg you end up with two unnamed heads, whereas with git the original head would be lost and so the revision(s) might eventually be garbage collected. –  Mark Booth Apr 29 '11 at 10:45

With mercurial, you can only get multiple heads on the upstream repository if Carl forces his push. What should happen is that after Bob and Carl independently do their merge of Alice's changes, Bob, who pushes first should be Ok, but Carl will get a message telling him that his push would create new remote heads and his push would be cancelled.

The solution of course, is for Carl to pull down Bobs changes, merge them in and then push back that merge too, so that you end up with all three sets of changes.

How often you see this sort of problem will depend on how big your repository is and how often developers work on the same things simultaneously. Also it depends on whether developers have got into the habit of forcing pushes (or set up their tools to do it automatically). If the latter is the case then I would highly recommend against it.

If you see people working on the same code too often, then perhaps you should look at whether your application has an excess of coupling (say a super-singleton that has to be edited whenever anyone changes anything anywhere else in the code) or whether you need to split up your repository into a group of sub-repositories.

share|improve this answer

Something's wrong with your Mercurial setup (or I don't know how this system is supposed to work). It shouldn't allow the emergence of "two heads". It should be either Alice->Bob->Carl or Alice->Carl->Bob. That's the way it worked in Subversion in both teams I worked for, and we always managed to sort out the conflicts. Continuous merging helps a lot. Trying to merge 2 months' work of multiple developers into a different branch often hurts.

share|improve this answer
    
Mercurial, unlike SVN, is not centralized. So there is not really any hierarchy like the one you describe. Appearance of heads is the rule in Mercurial, and merging of two branches is rather painless. I was wondering what happens in a more complex situation, though. –  Andrea Apr 29 '11 at 8:46
    
You can impose a hierarchy by policy. That's how it works for the Linux kernel, apparently. –  reinierpost Apr 29 '11 at 8:55
    
@Andrea, quant_dev is right, even though Mercurial is a DVCS you still shouldn't end up with two heads. To get two heads the pusher has to explicitly force it to accept the new head. –  Mark Booth Apr 29 '11 at 10:36

It's really not as bad as you're thinking it would be in practice.

In theory, if two people were working on the same file on the same lines then it's a problem that needs manual intervention.

However, in practice, that situation is very rare. More likely that they may be working on the same file, but in different locations. If the two (or three, or four) developers are working on different sections of the file, the automatic merge is generally smart enough to figure it out.

There are occasions where I've modified a line of code and a coworker has modified the same line so that when I pull the latest from source control, I need to manually merge. But that's rare and usually only happens if I've made a large change that touches a large number of lines anyway (e.g. if I've modified some API that is used by a lot of clients).

share|improve this answer

Your scenario -- three people -- one file -- is a symptom of poor architecture and poor management.

This is not a tool problem.

share|improve this answer
    
Not necessarily, there are some files which will always end up being edited by many people. For example, the main configuration file for the application. –  quant_dev Apr 29 '11 at 13:59
    
I agree. But I have never worked in a large team, and I'm not sure it would be unlikely in a project with 50000 files and 500 people. –  Andrea Apr 29 '11 at 14:16
    
@Andrea: At 100 files per person, it's really, really unlikely to have this kind of overlap. With a team of 500 the responsibilities must have some partitioning and structure to them. Chaos is really, really unlikely. –  S.Lott Apr 29 '11 at 14:28
    
@quant_dev: If the main configuration file requires changes in the same places for all sorts of different changes, so that merging is not normally automatic or at the very least easy, rethink your architecture, because it isn't going to scale under any circumstances. –  David Thornley Apr 29 '11 at 14:58
    
@David Thornley: "rethink your architecture, because it isn't going to scale". Actually, if you're having update conflicts, it didn't scale and the update conflict is all the evidence a manager or architect needs to fix it. –  S.Lott Apr 29 '11 at 15:45

I don't know if mercurial supports this, but in a small cohesive team, the centralized workflow may be the best. In this workflow developers have to update/pull from the central server first before they can push a new commit.

In larger or distributed projects, I recommend the gatekeeper workflow:

  • The developers do not merge from each other. The gatekeeper merges developer branches into a branch designated as the official branch.
  • Developers work on feature branches, and when a feature is done they propose to the gatekeeper for merging.
  • The gatekeeper has good overall understanding of the project. If merging a branch results in conflicts, he may need help from the developer to sort them out, but maybe not, as the conflicts should be caused by a merge proposal he recently approved himself.
  • The gatekeeper is also in charge of the quality of code and project-wide best practices. He rejects merge proposals that have any problems, the original developer should perform any necessary fixes and resubmit his branch.
  • Being a gatekeeper is a full-time activity.
  • As the project grows larger, there can be more gatekeepers, forming a hierarchy.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.