So some background. I had recently discovered HipHop, so I was trying to get that set up on my server. During this process I made a number of large mistakes.

Of course, the biggest mistake was attempting to compile and install an unfamiliar application on my production server, but it gets better. I couldn't compile HipHop without a newer version of Boost, so I did what I've done before when I need a newer package than stable provides: add testing to my repository list and setting stable as the default, so only the packages that absolutely have to be updated to testing get updated. Unfortunately, however, Boost requires a newer version of libc6, which APT happily installed, but in the process it also uninstalled my web server and a slew of other packages, which were incompatible with that version. So I was kind of stuck. I canceled the operation halfway through when I realized what I had done.

At this point I obviously panicked a little bit, then I tried

apt-get install libc6/stable
And then it complained about various dependencies being newer. Try to add those to the list, and it complains about the packages that /those/ packages depend on.

So now here I am. The dreaded dependency hell situation. Can't stay upgraded because I need my older packages, but I also can't downgrade because apt-get is being stupid. I also can't use apt-get download because this version doesn't have it, and I can't use aptitude download because it was uninstalled. Neither of those would help me in this situation anyway, as they try to download the latest version, which would just end up downloading the testing packages.

What I did to get out of this situation:

Change /etc/apt/sources.list to not include testing. Then run these commands.

apt-get update
mv /var/lib/dpkg/status{,.backup}
touch /var/lib/dpkg/status
mkdir packages
cd packages
dpkg --get-selections | grep -P '\sinstall' | awk '{print $1}' > packagelist
apt-get clean
xargs --arg-file=packagelist apt-get -qq --print-uris | awk '{print $1}' > urilist
xargs --arg-file=urilist wget

mv /var/lib/dpkg/status{.backup,}
for each in *.deb ; do
dpkg --force-depends -i $each

apt-get install -f
What this does is trick dpkg into thinking you don't have any packages installed, so when you go to run the other commands apt-get will pull all the packages from the repositories available in /etc/apt/sources.list. That allows you to get the URI list, download the packages, and then manually reinstall them one by one (be sure to put dpkg's status file back before reinstalling, otherwise you'll lose the record of all your manually installed packages, such as ones made through checkinstall). Then running apt-get install -f cleans up any new packages that are missing dependencies.

That should get you to a somewhat workable state, but YMMV. I just wanted to post this here in case someone else got stuck at some point. Make sure you reboot the system when you're done, as installing the packages out of order may cause things to behave strangely.