Consider for example, having two branches: "stable", "master" which have already diverged. Fixes go into "stable" and are regularly merged into "master".
Now imagine someone writes a fix F, which must be applied immediately to both "stable" and "master" and can't wait for the regular merge effort.
So with git, you just cherry-pick F into "stable" and "master".
Now, someone who uses "stable" discovers a big flaw in F, and reverts it. They assume their work will be merged into "master" as usual.
Then, a merge from "stable" to "master" happens, and the merge sees that the "stable" branch has 0 changes w.r.t F (commit+revert), whereas it has the F change in "master". Git's merge algorithm will consider this a trivial case, and do the wrong thing. The merge result will have the broken F application in "master", and there will be no conflict or any indication of a problem! This has been a huge problem for us.
So the result of this is that git forces you to either "merge" upstream, or "cherry-pick", but you really should not mix these two modes.
If you only use "merge", then the guy who merges must intimately understand everyone's changes in all cases of conflict. If he doesn't, others must help him resolve the conflicts on his working directory. Then, the merge result is one monolithic commit that makes understanding changes very difficult.
If you only use "cherry-pick", then you lose tracking of which changes have already been merged upstream, and which haven't. You start relying on the grep of "git log", which is unreliable, and you have no reliable tools to automate this. "git cherry" is unreliable and has plenty of false negatives/positives. Then there are of course problems with patch dependency, where you have to figure it all out on your own.
In short, the snapshot model is very problematic here. None of these problems would occur in the darcs model. Unfortunately, darcs does not scale. Whether that's inherent or not, I don't know. But if it did, I know I'd definitely prefer to use darcs in a large collaborative effort than git.
Surely this is something that the Linux project runs into constantly? I wonder if they have a solution?
In our case, we had the "bleeding edge" branch (master) and a maintenance branch. Fixes generally go into the maintenance branch and then are merged upwards. But we allowed "emergency patches" to be cherry-picked upwards (or downwards) too. The combination is the problem.
If we had stuck to just cherry-picks or just merges, we would not have this problem. But as I also explained, sticking to one of the approaches has severe drawbacks too.