Right, so you’ve just done a dnf upgrade and 200 packages flew by. Your terminal looks like the opening crawl of Star Wars. Now, what if, five minutes from now, you realize that this shiny new version of glibc has decided it no longer wants to be friends with your mission-critical, proprietary application that was built when Bill Clinton was in office? You panic. You consider calling in sick. Don’t. This is why dnf history exists. It’s your giant, glowing undo button for the entire universe of RPM packages. It’s not just a log; it’s a time machine, and I’m going to show you how to drive it.

Think of every dnf transaction—an install, update, or remove—as a “save point” in a video game. dnf history lists all of them. Let’s see what we’ve been up to:

sudo dnf history

You’ll get a neat table showing the transaction ID (the most important number you’ll see today), the command that was run, the date and time, and whether it succeeded. The transaction ID is your key to everything. Let’s say the last transaction, ID 42, was the one that broke everything. First, get the details.

Inspecting a Transaction

Before you go yanking packages out of the system, be a good detective. See exactly what happened in that transaction.

sudo dnf history info 42

This dumps a verbose list of every package that was installed, updated, or removed. This is crucial. You’re not just blindly reverting; you’re confirming your suspicions. “Ah-ha!” you’ll say, “There it is! glibc-2.35-999.1.x86_64, you villain!” Now you know what you’re dealing with.

The Magic Undo: history undo

This is the command that saves your bacon. It’s brilliantly simple in concept: it tells DNF, “Make my system look exactly like it did before transaction 42 happened.”

sudo dnf history undo 42

Here’s the brilliant part of how it works: It doesn’t just try to reinstall the old packages. It calculates the exact inverse of the transaction. If transaction 42 installed foo-2.0 and removed foo-1.0, then undo will do the opposite: remove foo-2.0 and install foo-1.0. It does this for every single package in the transaction. This is why it’s so much more reliable than you trying to manually dnf downgrade a dozen packages and hoping you got the dependencies right.

The Almost-Magic Redo: history redo

So you undid transaction 42. You’ve been running stable for a week. The vendor of your crusty old app finally releases a compatibility patch. Now you want to re-apply that update. You could just do dnf upgrade again, but what if other packages have been updated in the meantime? You want to replay exactly what happened in 42. That’s what redo is for.

sudo dnf history redo 42

This will replay the exact same transaction, using the same package versions that were available at the time. It’s a fantastic way to be precise.

The Pitfalls and The Power User Stuff

Now, the honest truth. undo isn’t flawless. Its biggest weakness is when a transaction installed a package that then pulled in new dependencies that weren’t previously on the system. When you undo, it will remove that package and those dependencies. This is usually correct, but sometimes a dependency might have been kept around for another reason. DNF’s dependency solver is pretty smart, so it often gets this right, but it’s not clairvoyant. Always check what undo plans to do before you tell it to do it. Use the --assumeno flag to do a dry run:

sudo dnf history undo 42 --assumeno

This will let you review the massive list of changes before you commit. It’s the equivalent of looking before you leap.

For more surgical control, you can use history rollback. This is a bit different. rollback N tells DNF to “take me back to how the system looked after transaction N.” So if you want to go back to the state you were in at transaction 20, you’d use:

sudo dnf history rollback 20

Use undo to revert one bad transaction. Use rollback to rewind the entire system to a specific point in history.

Finally, if your history is a mess of a thousand tiny transactions and you want to clean it up (or just to practice), you can start a new history “era.” This doesn’t change your packages; it just makes the history log easier to read by grouping future transactions under a new ID.

sudo dnf history new

So next time you’re about to perform a big, scary update, just remember: you’re not committing to it. You’re just trying it on. If it doesn’t fit, dnf history undo is your dressing room.