Then you add in stuff like experimental features (refactors, porting to new framework versions, etc.) that need to be developed alongside regular work without clobbering it, or features that get shelved while they are half-done, and things get just downright messy fast in something like SVN.
So my guess is that you aren't stupid at all, but that you just haven't had to deal with that sort of garbage.
(It's also possible your teammates simple deal with all this other crap for you, and don't bother you with the details.)
For instance, when refactoring something quite complex with good test coverage, you want each commit to be the smallest atomic commit that can pass all tests. But you also want to very quickly and "carelessly" add debug logs, assertions, changes in many files. For this kind of task I have found the following workflow to be very helpful and fast:
1. edit files relentlessly running a few tests cases
2. when you feel you "got" something run full test suite
3. if 2. pass, use `git add -p` to add the smallest changeset doing the thing.
4. Use `git stash --keep-index` to remove all other changes
5. Run full test suite
6. If 5. fails `git add -p` to continue editing your commit, or `git reset` if too far off
7. If 5. pass, `git commit` and `git reset --hard`.
Edit: When using `git add -p` you can even use 'e' command to manually edit your patch.
1. (same)
2. (same)
3. put all changes that you are not interested in on shelve: `bzr shelve` (or qshelve if you want QT gui)
4. Run full test suite
5. If 4. fails keep editing
6. If 4. pass `bzr commit` (or `bzr ci`), and to revert shelving use `bzr unshelve`
You need to remember 6+ git command to accomplish this tasks, and only 3 with bzr. Moreover there is symmetry in bzr (fe: shelve - unshelve, commit - uncommit) that is no present in git.
edit: formatting
Usually what I want is the opposite: cherry pick a few changes, increasingly adding them to the staging area (or index in gitspeak), because oftentimes I have a change that I am not sure is required for this patch.
I was very unconvinced by the staging area thing when starting using git and tried to avoid it, but in fact it is very powerful and not that complex. I do not know bzr and only used hg for a few months so maybe they have similar tools, but my main point is not git against the other, it is learn power uses of the tools to help improve workflow, against the claim that dcvs should be not our concern.
This is not something specific to git. Also, this example as a whole is nowhere near an improvement over an hg + mq workflow:
1. `hg qinit; hg qnew refactoring' to add a patchset
2. Make changes, add to patch with `hg qrefresh'
3. Run tests, if tests fail, pop a patch from the queue with `hg qpop'
4. Repeat until everything is fine, then `hg qfinish' to commit the patch to the history.
And yet, even those simple operations are different between different DVCS. 'hg pull' and 'git pull' are not equivalent, same with push. I try to stay away from git but when I can't avoid it, I have to remember that the sane/safe way to pull in git is apparently 'git pull --ff-only'.. #fail
I have in the past worked on larger teams (~15 developers), that project used svn and we never seemed to really run into any issues even though we had branches for mainline dev work, and support branches for each "released" version. I'd get the occasional conflict to resolve but it generally wasn't too bad, and I get those with Git also.
I've never worked on a project where dozens or hundreds of remote developers were contributing, but I'd say that outside of a small number of high-profile open-source projects, most people don't. I understand that's what git was built for; maybe that's why all those features just seem like overkill for anything I've never worked on.
The issues are really in dealing with multiple concurrent streams of development (multiple developers, or different branches of your own development if you have to switch between tasks). It's also useful having good tools to look at diffs and history to try to diagnose any problems.