In the best case scenario they all slighty change over time without forcing complexity on each other. But it becomes a problem as changes that should be breaking only break part of the code, and the rest can go unfixed as nobody remembers all the linked bits.
It would be critical for instance if the duplicated bits were involved in invoicing procedures, and one in five remained unchanged while the other got updated.
Additional logic is only needed when code is almost duplicated, and that is where the question arises of whether what is happening is best viewed as a different “version” of some common process, or a different basic process that has similarities.
Actual duplication doesn't require additional logic to remove duplication; and even near dupes often don’t require distinct (i.e., branching) logic if the language offers the right abstraction facilities.
// @note this code is duped in ../../some/other/file.code
This difference is something important to stress.