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.

Though I use and like DVCS for my personal projects, and can totally see how it makes managing contributions to your project from others easier (e.g. your typical Github scenario), it seems like for a "traditional" team there could be some problems over the centralized approach employed by solutions like TFS, Perforce, etc. (By "traditional" I mean a team of developers in an office working on one project that no one person "owns", with potentially everyone touching the same code.)

A couple of these problems I've foreseen on my own, but please chime in with other considerations.

In a traditional system, when you try to check your change in to the server, if someone else has previously checked in a conflicting change then you are forced to merge before you can check yours in. In the DVCS model, each developer checks in their changes locally and at some point pushes to some other repo. That repo then has a branch of that file that 2 people changed. It seems that now someone must be put in charge of dealing with that situation. A designated person on the team might not have sufficient knowledge of the entire codebase to be able to handle merging all conflicts. So now an extra step has been added where someone has to approach one of those developers, tell him to pull and do the merge and then push again (or you have to build an infrastructure that automates that task).

Furthermore, since DVCS tends to make working locally so convenient, it is probable that developers could accumulate a few changes in their local repos before pushing, making such conflicts more common and more complicated.

Obviously if everyone on the team only works on different areas of the code, this isn't an issue. But I'm curious about the case where everyone is working on the same code. It seems like the centralized model forces conflicts to be dealt with quickly and frequently, minimizing the need to do large, painful merges or have anyone "police" the main repo.

So for those of you who do use a DVCS with your team in your office, how do you handle such cases? Do you find your daily (or more likely, weekly) workflow affected negatively? Are there any other considerations I should be aware of before recommending a DVCS at my workplace?

share|improve this question
    
That's an excellent question. The way you described the problem is pretty much the main reason (among others) why I don't consider using DVCS with my team (fortunately - or not - I'm in a position to make such call). –  Alex Nov 21 '11 at 3:20
    
My experiences and feelings are very similar to yours. –  William Payne May 31 '12 at 0:54

6 Answers 6

We've been using Mercurial for about a year. While the headache you mention exists, by far, the biggest challenge to full adoption for us was getting into the DVCS mindset of local repositories (= commit often.) The old mindset of "Commit once you have polished code" can be hard to let go.

You said:

In the DVCS model, each developer checks in their changes locally and at some point pushes to some other repo. That repo then has a branch of that file that 2 people changed. It seems that now someone must be put in charge of dealing with that situation.

A default install of Mercurial blocks this behavior. It won't allow a push if more than one head will be created in the remote repo, without extra confirmation. For daily activities, we avoid that. (Git has named heads and each can only be updated if it fully merges the previous version, without extra confirmation, so again the situation cannot arise. The other DVCS have similar protection too.)

So at the end of each working day, some time needs to be set aside for the commit, which is really these activities:

  1. Commit local changes.
  2. Pull from central repo.
  3. Merge (& commit merge.)
  4. Push to central repo.

This keeps the merge activity on a person who was recently working on this code, and should be able to integrate their changes as quickly as anyone else.

As pointed out in the question, this really only adds effort when two people are working on the same area of code. If that's the case, then there are more benefits to using DVCS anyway, so the payoff is already evident to those developers. (Additional benefits include each developer being able to separately commit code and play with their own repo without another developer getting in the way. )

Another issue you mention:

Furthermore, since DVCS tends to make working locally so convenient, it is probable that developers could accumulate a few changes in their local repos before pushing, making such conflicts more common and more complicated.

This doesn't create a merge issue for us, but could create a different issue:

The flexibility of DVCS means that many different workflows are possible, but some of those are irresponsible. With DVCS, the need for clear process or procedures increases. The activity of keeping local changes may or may not be appropriate, depending on many things.

For example: can a developer work on a pet feature in spare time over a few weeks? In some environments this is encouraged, in some this would be inappropriate and all changes should be centralized soon. But if a dev is keeping changes locally, then they will certainly want to pull any related changes to make sure their work will continue to play nicely with the latest common rev.

When the rubber meets the road, the software releases or deployments usually come from a central repo, so developers need to get their changes there for testing and deployment.

That's my story, and I'm sticking to it, for at least a couple minutes...

share|improve this answer
    
Thank you, this was very helpful! –  J Cooper Nov 11 '11 at 23:44
    
This is pretty good. Branching can add some complexity in the situation as well. –  Paul Nathan Nov 12 '11 at 22:31
4  
With DVCS, the need for clear process or procedures increases. with great power comes great responsibilities. –  Newtopian Nov 21 '11 at 3:23

The premise of your question seems to be around "Merges are hard and must be avoided". DVCS systems remove this barrier, in fact they do more, the embrace the idea of merging - you should not be scared of merges and merge conflicts as a result, as unlike centralized tools, the DVCS tools support it by design.

As the excellent answer by Jamie F states - Work flow of Commit-Pull-Merge-Push done regularly (daily) means that if you are walking on some elses work, you see it early - as long as it's visible, it can be managed.

The problems you describe are as more about how you choose to use the tools.

We switched from SVN to GIT 6 months ago, after using SVN and GIT locally for a couple of years. No one will go back, and painful merge conflicts are a thing of the past. The "Commit small and often" mantra is the key.

share|improve this answer
    
+1 for commit-small-and-often. –  William Payne May 31 '12 at 0:55

When I worked on a team that used git, the rule of thumb was this: work on a private branch, then, when you are ready to make your work available to the rest of the team, rebase your branch onto master before you push. (Then validate your branch.)

This strategy meant that master was a linear series of commits, and that all of the integration issues were repaired on branches before they were public.

share|improve this answer
    
Rebasing "changes history" and can be a little more dangerous. If the rebase goes poorly, you no longer have a record of what the changes looked like before the rebase. For this reason, many developers would argue that you should merge instead. You lose the pretty, straight lines, but you gain the ability to retry a merge gone awry. Also, if you don't push any changes until everything's done, you aren't protecting yourself from hard drive crashes or other local disasters. But I'm sure this approach still works for many people: probably much better than a centralized VCS. –  StriplingWarrior May 31 '12 at 3:17

A tool like SVN strongly encourages a tightly integrated way of working.

I.e. committing frequently to a shared branch (either trunk or a dev branch).

This is A-OK for most corporate development environments that I have experienced, and is facilitated and encouraged even further through the use of Continuous Integration supported by extensive integration tests, regression tests and unit tests (Helping individual developers gain confidence that they have not broken anything by their changes).

DVCS gives you the freedom to work more independently, which you do need in some situations, and the (much-vaunted) improved support for merges cannot do any harm whatsoever.

The worry that always lingers at the back of my mind is this: With great freedom comes the temptation to use that freedom.

Certainly, in my (limited) experience, I spend a lot more time working independently in my current team (using Mercurial) than I did in previous roles (Where we used SVN, CVS & P4).

This is only partially attributable to the tool, but I think that it is a reasonable observation to make that, absent a compelling reason to expend the effort on communication and coordination, people will tend to work apart and in isolation.

This is not necessarily a bad thing, but I believe that it is something that needs to be taken into consideration.

share|improve this answer

The principle of working with centralized repository is the same when working with non-locking centralized or distributed system:

  • In centralized system you:
    1. Get the latest version from mainline ("trunk" in subversion, "master" in git, ...)
    2. Modify the files
    3. Merge the modifications with latest version from mainline using "update" command
    4. Commit to mainline
  • In distributed system you:
    1. Get the latest version from mainline
    2. Modify the files
    3. Commit locally
    4. Merge the modifications with latest version from mainline and commit the result locally
    5. Push to mainline.

No distributed version will allow you to push revision that does not fully merge the previous head revision (without special override; sometimes it's useful), so it won't go through without doing the merge step (so there won't be two versions somebody would have to consolidate as you concerned).

Now note that four of the steps are the same except for terminology, but distributed systems add an extra step "3. Commit locally". The big advantage of this step is that when the update/pull creates conflicts and you are not sure how to resolve them or make a mistake resolving them, you can go back, review what you did and redo the merge. Subversion won't remember any of those, so if you make a mistake resolving update, you are screwed.

As for accumulating changes, people tend to do that with centralized system too. Especially if you have to switch between features often (like interrupt some longer work to fix a bug or do some tweak that customer urgently needs), people will often need to keep changes locally simply because they are not finished. So it's better if the system at least supports making sense of it.

In either case these issues need to be addressed by proper guidelines and communication in the team and not the tools. With more flexible tools the guidelines are more important, but the more flexible tools allows better addressing various corner cases.

share|improve this answer

The thing with git/mercurial type version control, is to commit often, and push to centralized server when the code is good. One big plus with this is that it creates small patches, which are easy to apply in cases of conflicts. Also, you workflow should be something in the lines of:

  1. Many local commit
  2. Pull from server
  3. Push to server

This pull from server might create conflicts, but to solve this, all that is needed a lot of times is a simple rebase, instead of a merge. This will, I feel, keep the mainline history quite clean, and remove quite a lot of conflicts.

This is also the case when you pull from the local repo of a co-worker, as two things might happen. Either he pushes to the server first, which is fine since you already have his patches, and no conflicts should occur, or you push first, which means he will only get your patches when he pull.

Of course, sometimes a merge is a better solution, as an example if your working on a feature branch which should be merge into master.

In your workflow you are talking about people having to explicitly go to another developer and telling him to fix the conflict, but that should not be necessary. The central server is the "boss", and what you should be mainly working against. If your changes applies to the central repo, then your ok. If not, it's YOUR job to fix the conflict, which might require the developer you conflict with to help out understanding his/her changes. This is something you see when you try to pull/rebase from the server. So be happy committing, and deal with conflicts when you should pull from the server.

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.