"Re-introduce duplication by inlining the abstracted code back into every caller."
Or maybe if there are, say, 10 places dependent on the shared code, we can make them 5 places dependent on one version and 5 places dependent on another?
Forking and merging is part of business as usual in programming and we should be used to it. We should not be shocked that sometimes you have to fork a function because adding more parameters is not feasible, but nor should we declare sharing is therefore wrong or harmful.
Also, how you design parameters is extremely important. One callback parameter may be worth a hundred "normal" ones.