There's a great article somewhere about how the normal version control flow doesn't really work for this style of computing.
You want to keep both "versions" of code live and active in the same place at the same time (often in the same notebook).
People end up with methods named methodName, methodName2 etc, which isn't very good. But once you see the workflow you understand why normal version control doesn't work either.
There should be a solution to this, but AFAIK there isn't yet.
No, branches break down badly when you have many experiments. You end up with a bunch of incompatible versions of the system that you need to merge together later which can be a huge mess (depending on the size of the changes).
By all means, branches are great for super-prototypey early code, but once you know that you want to keep the ability to run the experiment around, guard it with a flag and merge it into mainline to avoid nightmare merges later!
It's a little more work sometimes, especially when your experiment changes things structurally, but it pays off over and over.