DVCS strategies for mixed-role small team? - version-control

I've done a lot of reading, and have been trialing GIT, GIT Tortoise, Tortoise SVN and PlasticSCM, to find the right source control for our small team (5-10 users).
Some background on our team: 6 copy writers/editors (2 remote), 2 developers, 2 graphic designers. We are not always working on projects together, sometimes up to 5 of us might be working on a given project. I'm unconcerned about the developers with DVCS, my concern is mainly around the other roles who are (in the nicest way) limited in their technical capability. Some of our copy writers update multiple source files (HTML, PDFs and adding concept graphics) to live, unversioned build directories (backed up as build.23.06.11.new.new.final.zip!). The copy and GD team will not have time, or to be brutally honest, the inclination to merge/resolve conflicts, or probably even remember to switch branches.
A few SO questions have shed light on what what seems to be a fairly consistent approach - main trunk (no junk in the trunk!) with teams having their own branches, and having release branches etc.
Every time I've re-read the links...
https://stackoverflow.com/questions/3854583/version-control-system-for-small-in-house-team
Getting started with Version Control
http://svn-ref.assembla.com/subversion-how-tos.html
...and google in general, I still end up asking myself the same questions:
Is it a Bad Idea to create role-specific branches for "trouble points" (copy team), where they can push to the repo, then our developers will merge their work into the actual project branch?
Should I still try to enforce a task-per-branch for everyone else?
Should I do task-per-branch for everyone but let the copy team create very broad tasks?
Is there usually a team/group/person who is considered an "admin" role for a repo who does crucial merges?
(is there an alternative suggested workflow where copy writers don't touch source?)
Unfortunately, the copy teams play a vital role in updating files which in turn affect layouts and all sorts of things, on a continual basis during dev. Its not like I can keep them in a bubble until the end of a project and chuck their work in.
... the good news is that hopefully, after a number of years, I'm ready to force everyone to move to version control! We've also settled on PlasticSCM for its intuitive GUI and Windows integration.
The best answer to this question would try to answer the 4 points above - tackle point 5 if you like - explain weak points if possible, and provide advice, gotchyas, etc.
cheers!

So basically you want to know how to get team-member of different skill-levels to use SCM and play nice with each other.
Buy-in from your team is priority #1. If you can't make them learn it, then you're left with providing a path of least resistance. So you really need to be flexible. There might be a wrong-way and a right-way to use the tool, but if the users won't accept the right-way, then the wrong-way is better than them not using it at all. How you achieve this balance is going to be different for every team.
Is it a Bad Idea to create role-specific branches for "trouble points" (copy team), where they can push to the repo, then our developers will merge their work into the actual project branch?
No, maybe its not optimal, but if this makes it easy for the Copy Team, then thats what you're left with. You could probably go even further and setup each user with their own branch. Then they never have to worry about merging other peoples changes.
Should I still try to enforce a task-per-branch for everyone else?
Each dev should have a unique "local" branch, that is not tracking an upstream branch. For example, use something generic like mydev. This makes it easy for them to switch between their local code and the current upstream branch.
You don't necessarily need to force everyone to create a local branch for every task, cause in the end, you're going to want them just to rebase their working branch onto the upstream one, and commit so it just becomes a fast-forward (i.e. linear commit).
Now for tasks that multiple devs are working on, or it is a feature that involves groups of smaller commits, then yes it does make sense to force them to create a new specific task branch. When they merge they can make sure to force a merge-commit, then it is clear that a set of commits are grouped together and all were part of a specific task. The merge commit will display like merged branch feature-X.
Should I do task-per-branch for everyone but let the copy team create very broad tasks?
It's really up to how much buy-in you can get from the Copy Team. I think if they really get confused with the DVCS tools, then you have to scale back until you can find something that does not cause too much of an impact.
One solution, is to have one of your devs help integrate the Copy Teams changes into another branch that everyone else will look at. That will help offload the learning-curve of the tool onto someone outside of the Copy Team.
Is there usually a team/group/person who is considered an "admin" role for a repo who does crucial merges?
Yes, this makes sense. However the great thing about SCM, is that everyone will be able to go back and do a code review on a merge. So if a merge breaks the code, you can either append the corrections after the merge, or remove the merge, and do it over.
(is there an alternative suggested workflow where copy writers don't touch source?)
Well, one possible technique is the Integration Manager model. The developers commit changes to their own share repos, but its up to the integration manger, to merge in the changes to the blessed repository.
I'm sure there are other methods that might work for your users, but this question is slightly ambiguous.

Related

Can I keep "pushing to Origin" everyday with GitDesktop?

I'm not sure if it's an appropriate question here, and I haven't found another related question.
I'm new to programming, and I save my work every day, updating my repository with GItHub Desktop.
Is OK to do that? Is this good practice?
Is there a better way to keep saving my work on a daily basis?
it’s perfectly fine to push your project to origin and that is one of the reasons for git as it keeps your work safe. Further, having frequent commits during stages allows you revert back to those commits when you make a mistake or something goes wrong.
Although when it comes to best practice you should create different branches in your GitHub project and merge those branches into the main branch once it is in a complete state so your main branch is always a functioning product. Here’s some further reading on this:
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches
You may also want to explore more of the GitHub docs.
Git can become quiet complex especially when working with other people so it’s useful to get in the habit with following branching structures and writing useful commit messages. Also you’ll often find different organisations have specific rules to this and you’ll have to understand git enough to work with in the way your team does.

How to protect trunk from devs

We are using TFS for our code: trunk + branches for coding activities. There are 6 devs in my team.
Problem: sometimes developers don't want to create a new branch (or use an old one) to fix/develop something. They just do it in trunk. OK, in some cases it's acceptable. But most of the time it creates a lot of troubles.
How can I enforce protection of trunk and force devs to create new or reuse old branches?
UPD: I don't want to give read-only access to the devs on trunk (they have to be able to create branches and merge them back by themselves). I want some compromise - can create branches/do merging but can't develop in the trunk.
Working on the trunk directly is almost always incorrect. Yes it can be the most efficient way sometimes, but breaking process is breaking process and that will bite you eventually.
I think this problem is best solved with education, but limiting trunk write access to senior devs might help too - if they aren't "infected" too :)
Wortyh bearing in mind though that any good source-repository (read: not VSS) will save you from terminal problems in this area, it's just a matter of effort and watchfulness. You never want to rely on rollbacks, just saying "don't panic".
You can set permissions at the folder level.
Creating a branch is a powerfull permission. You will probably have to have one person who creates the branches and then sets the permissions.
For information on setting permissions see: http://msdn.microsoft.com/en-us/library/ms252587.aspx
I'll second what #annakata said. Additionally, I highly recommend that whomever is responsible for managing SCM in your organization to set up a check-in alert that lets you know when someone checks code into the trunk. That way, you can follow up (with the previously-mentioned cricket bat, if necessary) with the developer responsible.
Some other techniques to consider:
Only allow senior developers to check in. Developers shelve their changes, and the senior devs review then check-in. They can help be your gatekeeper.
Use the gated-check-in feature of TFS2010 to help you. Turn on gated check-ins for the trunk.
Education in a form that developers can understand. Make them know exactly why building off the trunk is a bad thing. SCM process education can go a long way to getting people to comply. If they think it's just an arbitrary rule, they don't feel bad about violating it.
Add consequences (to whatever degree your organization allows). Things like a beer/pizza fund that they need to contribute to when they screw up, or a funny hat that needs to be worn, or even a loud announcement to the entire development organization when someone checks in to trunk. It gets the point across quickly.
Does TFS has support for running hook scripts like subversion has?
If it has you can run pre-commit and post-commit checks to see if commits follows process guidelines, reject patches with an email explaining why etc.
If thats too much work my best advice is talking to people and use good old reward for adhering to rules and punishment for breaking them.
What kind of "fixes" are they making to the TRUNK? Typically you should never check-in to TRUNK but only merge...
If they have enhancements or bug fixes that can wait and that are not emergencies they should do their development in the DEV branch.
If it is an emergency then branch off of TRUNK and make a HOTFIX branch. This will be a copy of what is in production.
Example of when you would want to use HOTFIX:
Let's say you have a change you want to make to production or QA but you don't want the future work done in DEV to go out just yet as it has breaking changes for the QA environment or maybe you just want to be as safe as possible and make sure only the code you know you wanted to change went out with your deployment. If you do not have a HOTFIX branch then click on TRUNK and select "Branch" and name it HOTFIX or something meaningful to you. Then make your changes in HOTFIX, check them in, and deploy from the HOTFIX branch. The HOTFIX will only contain two things then A. What is in TRUNK and B. Your one-off changes. It will not include all of the extra work that you haven't validated or tested from the DEV branch, which is a good thing.
You can create user group within TFS to give readonly or no acess at all. If you right mouse click over the team project and click group membership, then add those groups to the folder structure in the source control Explorer.

Good github structure when dealing with many small projects that have a common code base?

I'm working for a web development company and we're thinking about using GitHub for version control. We work with several different .NET-based CMS-platforms and of course with a lot of different customers.
We have a standard code base for each CMS which we start from when building a new site. We of course would like to maintain that and make it possible to merge some changes from a developed site (when the standard code base has been improved in some way).
We often need to make small changes to a published site at a later date and would like to be able to do this with minimal effort (i.e. the customer gladly pays for us to fix his problem in 2 hours, but doesn't want to pay for a 2 hour set up first).
How should we set this up to be able to work in an efficient fashion? I'm not very used to distributed version control (I've worked with CVS, Subversion and Clear Case before), but from my imagination we could:
Set up one repository for each customer, start with a copy of the standard code base and go from there. Lots of repositories of course.
Set up one repository for each CMS and then branch off one branch for each customer. This is probably (?) the best way, but what happens when we have 100 customers (=branches) in the same repository? It also doesn't feel entirely nice that we create a lot of branches that we don't really have any intention of ever merging back to the main branch.
I don't know, perhaps lots of branches is only a problem in my imagination or perhaps there are better ways to do this that I haven't thought about. I would be interested in any experince in similar problems.
Thank you for your time and help.
With Git, several repos make sense for submodules purpose (sharing common component, see nature of Git submodules, in the third part of the answer)
But in your case, one repo with a branch per customer can work, provided you are using the branches to:
isolate some client-specific changes (and long-lived branch with no merging back to master are ok),
while rebasing those same branches on top of master (which contains the common code, with common evolutions needed by all the branches).

Version control best practices

I just made the move to version control the other day, and after a bad experience with Subversion, I switched to Mercurial, and so far am happy with it.
Although I understand and appreciate the idea of version control, I don't really have any practical experience with it.
Right now, I am using it for a couple websites I am working on, and a couple questions have come to mind:
When/how often should I commit? After any major change, whether it works or not? When I'm done for the night? Only when it reaches it's next stable iteration? After any bugfixes?
Would I branch off when I wanted to, say, change the layout of a menu, then merge back in?
Should I branch? What is the difference (for just me, a lone developer) between branching, then merging back in, and cloning the repository and pulling it back in?
Any other advice for a version control newbie?
So far, everyone has given me good advice, but very team-oriented. I would like to clarify:
At the moment, I am just using VC on some websites I do on the side. Not quite full-out freelance work, but for the purposes of VC, I am the only one that really touches the website code.
Also, since I am using PHP on the sites, there is no compiling to be done.
Does this change your answers significantly?
Most of the questions you're asking about depends mostly on who you are working with. If you're a lone developer it shouldn't matter a lot, since you can do whatever you'd like. But if you're in a team where you have to share your code then you should discuss with your team members what the code of conduct should be since sharing changes between one another can become tricky at times.
The discussion regarding code of conduct doesn't need to be lengthy, it can be very brief; as long everyone is on the same page on how to use the repository that is shared between the programmers in the team. If you want to use the more advanced features in Mercurial, such as cherry picking or patch queues, then try using them so that it won't impact your team members in a negative way, such as rebasing on a public repository.
Remember version control has to be easy to use for everyone in the team, or else it won't be used.
When/how often should I commit? After any major change, whether it works or not? When I'm done for the night? Only when it reaches it's next stable iteration? After any bugfixes?
While working with a team there are several approaches, but the common rule is to commit early and often. The main reason on why you should commit often is to make merge conflicts easier to handle.
A merge conflict is simply put whenever merging a file that has been changed by at least two people doesn't work because they've been editing on the same lines. If you're holding on to a commit that involves a very large change with several lines of changes across several files, it will become very difficult to manage for the receiver to manage the conflicts that may occur. The merge conflict becomes even more difficult to handle if the said set of changes are held on for too long.
There are some exceptions to the rule of committing often and one is whenever you have a breaking change. although if you have the ability to commit locally (which you are doing in Mercurial and git inherently) you could commit breaking changes. As long as you fix whatever broke, you should push it upstream to the shared repository when you've fixed your own breaking change.
Would I branch off when I wanted to, say, change the layout of a menu, then merge back in?
Should I branch?
There are many branching strategies to choose from (there is the Streamed Lines paper from 1998 that has an exhaustive pattern list of branching strategies) and when you're making them for yourself it should be open game for yourself. However when working in teams, you'd better discuss openly with the team if you need to branch or not. Whenever you have the urge to branch though you should ask yourself the following questions:
Will my future changes be breaking the work of others?
Will my team have a direct negative impact from the changes I'll be doing until I'm done?
Is my code throwaway code?
If the answer is yes in any of the questions above you should probably branch publically, or keep it for yourself (since you can do that in Mercurial in several ways). You should first discuss with your team on how to execute the whole endavour to see if there is any other way of doing it and if you're going to merge your changes back in, sometimes there are factors at play where there is no need to branch (this is mostly related to how modular the code is).
When you decide to branch be prepared to handle a merge conflict. It is sane to assume the one who created the branch and made the commits to be able to merge it back into the "main branch". At these times it would be great if everyone in the team made relevant commit comments.
As a side note: You do write good commit comments, right? RIGHT!? A good commit comment usually tells why that particular change was made or what feature the committer was working on instead of a nondescript "I made a commit" kind of comment. This makes it easier for the one who is handling the big merge conflict to figure out what line changes can be overwritten and which ones to keep while going through the revision history.
Compile times, or build times rather, sometimes play into the branch discussion you may have. If your project has a slow build time then it might be a good idea to use a staging strategy in your branches. This strategy takes into account that all developers should integrate to a "main line" and changes that are approved are elevated (or "promoted") to the next stage, such as testing or release lines. It is classically illustrated with tag names for open source software like this:
main -o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-> ...
\ \ \
test o-----------o--------------o---------> ...
1.0 RC1 \ 1.0 RC2 2.0 RC1
release o----------------------> ...
1.0
The point with this is that testers can work without being interrupted by the programmers and that there is a known baseline for those who are in release management. In distributed version control, the different lines could be cloned repositories and it may look a bit different since repositories share the versioning graph. The principle however is the same.
Regarding web development, there are virtually no build times. But branching in stages (or by tagging your release revisions) it becomes easier to roll-back if you want to check a difficult-to-track-down bug.
However, a whole other thing comes into play and that is the time it takes to deploy the site. Version control tools in my experience are really bad at asset management. Handling art assets that are in total up to several GB usually is a huge pain in the butt to handle in Subversion (more so in Mercurial). Assets may require you to handle them in another way that is less time consuming, such as putting them in a shared space that are synched and backed up in a traditional manner (art assets are usually not worked on concurrently as with source code files).
What is the difference (for just me, a lone developer) between branching, then merging back in, and cloning the repository and pulling it back in?
The concepts of branching and keeping remote repositories are closer now than with centralized version control tools. You could almost consider them being the same thing. In Mercurial (and in git) you can "branch" either by:
Cloning a repository
Creating a named branch
Creating a named branch means that you're making a new path in the versioning graph for the repository you're creating it on. Creating a cloned repository means you're copying the source repository into a new location, and making a new path in the cloned repository's versioning graph. They are both two different implementations of branching as a general concept in version control.
In practice, the only difference between both methods that you should care about is in usage. You clone a repository to have a copy of the source code and have a place to store your own changes in and you create named branches whenever you want to do small experiments for yourself.
Since browsing through branches is a bit quirky for those who accustomed to a straight line of commits, advanced users know how to manipulate their versions so the version history is "clean" with e.g. cherry picking or rebase. At the moment git docs actually explain rebase rather well.
These are the practices that I follow
Each commit should make sense: one bug fix (or a set of bugs related to each other), one (small) new feature, etc. The idea is that if you need to rollback, your rollbacks fall on well defined "boundaries"
Every commit should have a good message explaining what you are committing. Really get into this habit, you will thank yourself later. Doesn't have to be verbose, a few sentences can do. If you are using a bug tracking system, associating a bug number with your commit is also extremely helpful
Now that I use git and branching is so incredibly fast and cheap, I tend to make a new branch for each new feature I'm about to implement. I'd never even consider doing this for many other VCSes. So branching depends on the system you are using, your codebase, your team, etc, there are no hard rules there.
I prefer to always use the command line and get to know my VCS's commands directly. The disconnect that a GUI based frontend can cause can be a pain, and even damaging. Controlling your source code is very important, it's worth getting in there and doing it directly. But that's just my preference.
Back up your VCS. I back up my local repository with Time Machine, and then I push out to a remote repository on my server, and that server is backed up as well. VCS alone is not really a "backup", it can go down too just like anything else.
When/how often should I commit?
You'll probably get lots of contradictory answers on this one. My view is that you should commit changes when they are working, and each commit (or checkin) should contain exactly one "edit". An "edit" is an atomic set of changes that go together to fix a bug or implement a new feature.
There is a theory that you should check in code every few hours even if it's not working, but in that case you will need to be working on your own branch - you don't want to be checking in broken code to your main line, or onto a shared branch.
The advantage of checking in every night is that you have backups (assuming that your repository is on a different machine).
As for branching:
you should have main line that contains always working code.
you should have a current development branch that contains the latest code. When you are happy with this (and it's passed all it's tests) you should merge it back into the main line.
you might want a branch that contains the last released version. This can be used for testing/debugging bugs and releasing patches (in extremis).
update before each commit
provide commit comments
commit as soon as you have something finished
don't commit anything that makes the code in the repository not compiling or buggy
update every morning
sometimes verbally communicate with colleages if there is something important to update
commit code relevant to exactly one thing (i.e. fixing a bug, implementing a feature)
don't worry to make very small commits, as long as they conform to the previous rule
Btw, what's the bad experience with Subversion?
I commit when I am finished a piece of work and only if it is working. It's bad practise to commit to somewhere where other people use the code.
Branching is something that people will argue about. Some people say never branch and just have switches to get something working or not. Do what you feel more comfortable but don't branch just because you can. I use branching and Branch when i am working on a major bit of work where if I commit broken code by accident its not going to affect everyone else.
Q: When/how often should I commit? After any major change, whether it works or not? When I'm done for the night? Only when it reaches it's next stable iteration? After any bugfixes?
A: Whenever you are feeling comfortable, I am commiting as soon as a unit of work is finished and working (which does not mean that the complete task has to be finished). But you should not commit something that does not compile (might inhibit other people in the team,if any). Also, you should not commit incomplete stuff to the trunk if there is any possibility that you have to implement a quick fix or small change before completing it.
Q: Would I branch off when I wanted to, say, change the layout of a menu, then merge back in?
A: Only if there is a possibility that you have to implement a quick fix or small change before completing your task.
The nice thing about branching is that all commits you are doing in the branch will still be available for future reference (if necessary). Also it is much simpler and faster than cloning the repo, I think ;-)
I agree with others on commit times.
Regarding branching, I generally branch only when working on something that breaks what others are doing or when a patch needs to be rolled to production in a file that already has changes that should not go to production. If you're only one developer, then the first scenario doesn't really apply.
I use tags to manage releases - the "production" tag is always associated with the current prod code, and each release is tagged with "release-YYYYMMDD". This allows you to roll back if necessary.

How suitable is a DVCS for the corporate environment?

I've been using SVN for some time now, and am pretty happy with how it works (but I can't say I'm an expert, and I haven't really done much with branches and merging). However an opportunity has arisen to put in some new practises on a new team and so I thought I'd take a look at DVCSs to see if it's worth making the jump.
The company I work for is a pretty standard company where we all work in the same location (or sometimes at home) and we want to keep a central store of all code.
My question is: if all you are doing with a DVCS is creating a central hub that everyone pushes their changes to, is there really any benefit to moving to a DVCS and its extra overheads in this sort of environment?
With DVCS's people can maintain their own local branches without making any changes in the central repository, and push their changes to the master repository when they think it's cooked up. Our project is stored in an SVN repository but personally I use git-svn to manage my local changes and find it quite useful, because we are not allowed to submit all the changes immediately(they have to be approved by the integrator first).
It all depends on how you want to work on projects. Distributed environments are great if everybody wants to build on its own branch. I prefer a central repository for my work (in a small team) as it makes the developers think about releasing one version of our product.
In my experience I see a lot of DVCS users who think of their own changes as the ones they don't have to review and these users review the changes of all other developers before merging them in their own tree. I like to see my changes as the change to the core product, so I review these changes before I commit them. As a result we try to keep the product pretty stable during the entire development cycle. Refactoring works OK, as we all update often.
Several DVCS users I know prefer to work on their feature on an independent tree and leave the integration with the central product to the final phase of their development. This works fine if the feature is independent, but I wouldn't like to be the one who has to integrate all the features developed this way with a deadline in sight.
If you integrate often, DVCS's don't differ much from central VCS's, and most DVCS's support a central repository, while more and more central VCS's support several features that where unique to DVCS's before, like offline commit and shelving.
(FYI: Offline commits are planned for Subversion 1.8)
Personally, I find it's a huge benefit. Even with a central repo, a DVCS changes the flow from "edit code, update from central, commit" to "edit code, commit, push to central". Among other things, that means that conflict resolution is far less stressful. It can also encourage development in smaller chunks, since you don't have to push after every commit. If your team is OK with it, that means your individual commits might leave the app in a strange state, as long as it's working when you finally push to the central repo. If they're not OK with that, as long as you're using git (or patch queues for hg, IIRC), you can still do dev in the same style, but then condense all your smaller commits into one larger commit that is complete before you push it to the central repo.
The big benefit of using a DVCS for me is that I can commit to my local repository without having to share these changes with everyone else. So when working on a big change I do small incremental commits, meaning I can revert just the last 30 minutes work, or do a diff against a version that was working yesterday, but then only push to the central repository once all my work is complete.
I think this benefit alone is worth moving to a DVCS for.
However, using a DVCS does require a little more thought and understanding and using a "standard" version control system like SVN or CVS so you will need to consider the training overhead if moving to a DVCS or your central repository will end up full of a lot different branches people didn't realise they were creating.
You'll get the inevitable war of Git vs. Mercurial starting here soon... :-) I personally use Mercurial, but what I've got to say should be suitable for all DVCS.
In my opinion, yes, they are suitable for corporate use. I use them at my own company, albeit with a small number of developers using it, but if you're worried about scalability, look at the large Open source projects using git and mercurial, e.g. Mozilla, Python.
The central hub approach works well - it's a familiar working model to users of subversion and you've always got a "definitive" version. Lock down access to this and apply any hooks to enforce commit policies and after that, developers have a large amount of freedom to work how they like with their local copies.
Another big plus is that I've found merging much less painful with mercurial than with subversion.
What's trickier with a DVCS is managing binary files - you can't require a lock on a binary file like you can with subversion (amongst others). Manage this with communication ideally.
Finally, cloning a repo is great for keeping checkouts in sync if you're working from several PCs.
Hope this helps.
K
I think the main benefit of a DVCS comes when you want to push your changes directly to other people (or machines, e.g. taking the repository home with you), without going through a central hub. If you have the need to do this, a DVCS is definitely the way to go. If, as you say,
all you are doing with a DVCS is creating a central hub that everyone pushes their changes to
then you’re not really taking advantage of the main purpose of a DVCS and I would say SVN is sufficient.
P.S. One might also make the argument that a DVCS encourages users to commit more often since they can do so in their personal repository and only publish their changes when they’re ready — but this can be easily accomplished in SVN using branches, with the only “downside” being that “personal” commits increment the version number of the whole repository.
Even with a hub workflow, a DVCS gets you the ability to make small commits locally, merge them only when you want to, and push them when they are ready.
With a non-DVCS, you are forced to either:
do your work without committing, until it's polished and you push a huge commit.
make small commits as you go, which everyone has to merge often, though merging intermediate commits brings them nothing of value.
And if you explore a dead end, without DVCS: with the first method, you can't rewind, you don't have a commit to go back to; with the second, both your commits and their reverts had to be merged pointlessly by everyone else.
Personally i think the biggest advantage of DVCS is that you commit (locally) before merging, so if halfway through the merge it turns out to be more complex than you originally thought, it is trivial to get back to a clean state without losing your work. compare to CVCS where you usually have to merge succesfully before you can commit.
additional advantages include:
working from home/at clients site becomes easier as you don't require network connection just to check something in, and if you wait till back at base to push changes the history is preserved rather than lumping everything into one change.
Most DVCS operations are actually a lot faster as they don't need to pull data over the network
Some things (e.g. user settings scripts) are better shared directly between developers who want to share them rather than via a central location
In my experience there are several ways to use a DVCS inside a corporate environment:
Multi-site support: you've separated teams and you use your DVCS to set up different "servers" at each location so they're not limited by the underlying network problems (and believe me, there will be). It used to be done with "big things" like Clearcase Multi-site or Wandisco (for SVN/CVS) but now it's pretty doable with DVCS systems.
Support "roaming users": you're a corp. developer but you want to work at home for a certain time (or ever): instead of relying on the VPN you can have a DVCS at your laptop and then you're free to commit, review, diff, branch and merge without being slow down by the central server. You synch back when you're online or back at the office.
True "distributed development": which is the extreme case: each developer having his own DVCS (like you'd do on the OSS world). It will really depend on team's skills and motivation: if the team really wants to move into it, they'll benefit, otherwise it will be SYSADM's nightmare having to manage not a single repo but hundreds... with their corresponding issues.
the overhead is not so big, in fact, in our environment, the added hg push is less of an overhead than commiting to the central svn repo was. but the biggest plus is all the bells and whistles that come with mercurial, that are great for an individual developer regardless of the team size or workflow. first and foremost, the fact that every wc is a repo is great, since you can experiment much more freely without polluting the master repo. then, there is functionality that builds on the wc == repo equality: bisect to quickly find the revision where a bug sneaked in, grep to, well, grep the history, as well as functionality simply missing from subversion, like colored diffs in the terminal.
Bazaar VCS can work as distributed VCS and as centralized VCS so you have the freedom to select the workflow you need. In the same time local private branches (where people can experiment while working on new features and in the same time commit their progress regularly) is huge benefit.
Also DVCS makes natural development workflow when mandatory code review required before new changes will be landed to trunk. This workflow (regarding SVN) described brilliantly in the UQDS article. And despite the fact that article described SVN-based workflow you'll find it more natural when you're using any DVCS instead of SVN, because in DVCS branching and merging is basic first-class operation.