Because you source code is in source control like git, you have quite fine control over the various versions of your software. So you have both options available to you.
What you do in practice depends on the bug. Lets say you have an e-commerce site and the bug is, when i buy two items it doesn't add the price of the second one.
You look at the code and you see a mistake in the basket object, it doesn't multiply by the quantity, so you add that in and it seems to fix the problem.
But then the next day you get another bug report, when you add socks it charges you for two pairs. you realise that the quantity of socks is 2 when you buy a single pair and your bug fix doesn't work for socks.
So, now you have a choice, change the code so that pairs have quantity 1 and leave your original fix in place. Or, replace the calculation code with something more complicated which checks for pairs.
Changing the quantity thing might have all sorts or repercussions. You don't want to mess with that even though it seems crazy to count pairs as 2 things.
Also, if you weren't the dev who put the 'multiply by quantity' bit in, well you dont really know if that it wrong or right either. Probably you just tack an ugly fix into the code, 'if item is a pair, divide quantity by 2 before multiplying'. It seems bad, but in many cases its the best thing to do.
With live apps you have to weigh the risk of breaking things vs the elegance of the solution. Often the quickest, smallest change is economically the correct thing to do.
This is why automated tests are so important. If you have confidence that you haven't broken anything then you are able to write better code. Because you can refactor more for the same level of risk.