How do I undo the last commit in Git without losing my changes?
Which command you want depends on whether the commit has been pushed, because that decides whether rewriting history is safe.
If the commit is still local, a soft reset to the previous commit is what you want. It moves the branch pointer back one commit and leaves every change staged, exactly as it was just before you committed. This is the right choice for fixing a commit message, splitting a commit that did too much, or adding a file you forgot.
A mixed reset does the same but leaves the changes unstaged rather than staged, which is useful when you want to reselect what goes in. Both preserve your work in the working tree.
A hard reset also discards the changes themselves. It is the only one of the three that loses work, and it is worth typing deliberately. If you run it by accident, the reflog still holds the commit for a while and recovery is usually possible.
If the goal is only to adjust the most recent commit rather than remove it, amending is more direct. Staging the fix and amending replaces the previous commit in place, though this still rewrites history and produces a new hash.
If the commit has already been pushed to a shared branch, none of the above is appropriate, because rewriting history others have pulled forces everyone to reconcile a divergence. Reverting is the correct tool instead: it creates a new commit undoing the changes, leaving the original in place. History grows rather than changing, which is exactly what you want on a branch other people build on.
The rule of thumb is simple. Reset and amend for work only you have. Revert for anything already shared.