So yes, you should have a second STAGE server. What I do is put my code into CVS on my dev box, and do regular commits as i go along. When I am ready to push a version to the "STAGE" server, I go through the files I want to STAGE and tag them STAGE:
cvs tag -F STAGE
Then I go to the STAGE server and do an update with the STAGE flag to get the STAGE version of files:
cvs up -r STAGE
This also sets the sticky tag to be "STAGE" on those files, so in the future, I can just leave the STAGE tag off when I do updates on my stage server:
cvs up
finally, when I've tested my code on the STAGE server, I roll it to the production server using rsync...
We have several developers working together so keeping a stable STAGE version up can get tricky. In that case, if I just have small changes to one or two files, I will just scp them individually over to the production server..
Finally, to ensure I know what is out on my production servers, after I send a file or files off to the production server, I tag all the files on my stage server as RELEASE, and also as RELEASE20090713 or whatever the current date is.. That way I have moving snapshots though time that I can get if needed. Note though, this doesn't update the sticky tag, so my regular old
cvs up
on the stage server still gets me the latest STAGE files.
Now in your case, as far as the hardcoded URL's goes... You already know.. bad bad bad... so fix them as you go... But you may be able to use apache URL rewriting to rewrite URL's on STAGE to talk to a custom TCP port.
If you have a smart network device like a cisco router, you can set it up to do PAT (port address translation) for your IP's. Port 80 can forward to your regular production webserver, and port 8080 can forward to your STAGE server (its port 80).. Then all you do is have apache do URL rewriting on your STAGE server and append 8080 to all the hostnames it sees. Now all your posts and links will go to the correct STAGE servers, and your apache configs can be exactly the same also.