Here is one way (I seem to remember that something similar was discussed before, but could not find it):
ClearAll[withBlockedVars];
SetAttributes[withBlockedVars,HoldRest];
withBlockedVars[Hold[expr_],code_]:=
With[
{
heldVars=
Thread[
Cases[
Unevaluated[expr],
s_Symbol/;Context[s]==="Global`"&&DownValues[s]==={}:>
HoldComplete[s],
\[Infinity],
Heads->True
],
HoldComplete
]
},
heldVars/.
HoldComplete[vars_List]:>Block[vars,code]
]
which tries to dynamically determine which symbols to block (it has some arbitrariness in the criteria). Here is how you can use this:
x = 1; y = 2; z = 3;
withBlockedVars[
Hold[x*y/z],
Hold[x*y/z] /. {x -> y + z, y -> x + z, z -> x + y}
]
(* Hold[((y + z) (x + z))/(x + y)] *)