The key difference is that DVCS offline commits are much more flexible. They allow you to prepare a whole series of changesets which you can then publish as a group in one go. You can also do some clever things with them, such as reordering them, combining them, splitting them apart, or even deleting some of them altogether. With TFS shelvesets, on the other hand, you are limited to working locally with only one changeset at a time.
Let's say you have made ten separate changes, numbered 1 to 10. In DVCS, you just check in after each change, then push to origin in a single operation once you're finished. With TFS, you end up with ten shelvesets, each of which contains the difference between your work and the latest version in the repository. They will look like this:
- Change 1
- Change 1 + change 2
- Change 1 + change 2 + change 3
And so on.
This means that you can't just publish a series of changesets with a single command (as in git push origin master
), you have to unshelve them one at a time then check them all in individually. That alone is cumbersome enough, but on top of that, the second and subsequent changesets will all give you merge conflicts because you are re-applying earlier changes which have already been applied.
Furthermore, your options for controlling which changes get published are severely limited. If you wanted to check in only changes 1, 2, 4, 6-8 and 10, omitting changes 3, 5 and 9, you couldn't do it. You couldn't reorder them either, nor could you squash a non-contiguous range of changes.
The upshot of this is that in TFS, even with shelving, it isn't practical to adhere to the best practice of checking in locally several times an hour, ensuring that every check-in makes only one change, and then tidying up before you publish your changes. The result will be a history consisting of larger, more bloated check-ins that are harder to understand and less useful if, for instance, you need to track down the revision that introduced a bug.