So this is to fix duplicate coinbase transactions potentially causing two coinbase transactions becoming invalid?
It makes the duplication ~impossible (save getting a hash collision). There was not previously a behavior where two coinbase transactions became invalid, rather one could replace another— though that is prevented by BIP30.
Why doesn't the client just identify transactions by a mixture of the transaction hash and the parent block
Because transaction exist externally to and independently of blocks. Even if you were willing to create software which only worked with confirmed transactions (e.g. not a full node) you'd still have crazy issues with transaction IDs changing when the chain reorginizes which could itself create some awesome exploits against merchant software.
(Hence removing the bug with no need for a hack)
Including the height as part of the hash for the coinbase transaction is something Bitcoin should have always done. Although it should have been listed as the 'input' rather than putting it in the coinbase, but sadly the former can't be done compatibly.
and why not get the majority of miners to reject blocks with duplicate coinbases to prevent a blockchain fork?
(As of BIP30) We reject duplication which would overwrite an existing unspent transaction, because that in and of itself creates some really nasty and critical attacks, but we can't explicitly prevent duplication of already spent transaction in the general case without making pruning impossible. (If you have to remember every txn ID that ever was in order to refuse to mine duplicates you can't forget spent transactions).
Including the height in the coinbase implicitly prevents duplication by making it infesable but doesn't require unbounded storage like explicit prevention. It also allows nodes software to be more DOS attack resistant because it would allow additional filtering prior to connecting. This is described in some of the links gavin provided.
BIP30 was an emergency fix for a severe vulnerability, deployed because the real fix couldn't be deployed quickly. This change fixes the underlying protocol design flaw and fixes up some of the less critiial corner cases the other fix couldn't really address (e.g. the prospect of having to deal with duplicate transaction IDs for distinct transactions).