To roll back a bad dependency upgrade, create a new commit that reverses it with git revert, confirm the lockfile returned to the old versions, run your tests, and deploy the revert. Do not rewrite shared history. For a merge commit, tell Git which parent is the mainline with the -m option.
Decide: revert or fix forward
Reverting is the right first move when the upgrade is clearly the cause and the old version is acceptable. Fixing forward fits when the old version is itself vulnerable and exposed. Often you do both: revert now to stop the damage, then plan a better fix.
If the old version carries a serious known vulnerability, say so in the revert PR and set an owner and a date for the real fix. A revert that quietly reintroduces a known issue is how the same finding comes back a month later.
Step 1: find the commit
Identify how the change landed. A squash merge produces one ordinary commit. A merge commit has two parents. A rebase merge produces several commits. The method decides your command.
Step 2: revert it
Git revert records new commits that undo the changes of earlier ones. It adds history instead of rewriting it, which is what you want on a shared branch.
For a squash merge or a single commit:
git revert <commit>
For a merge commit, name the mainline parent, numbered from 1:
git revert -m 1 <merge-commit>
Git cannot otherwise know which side of the merge to treat as the baseline.
Step 3: understand the side effect of reverting a merge
Git's own documentation warns that reverting a merge declares you never want the tree changes that merge brought in. If you later merge the same branch again, only commits that were not ancestors of the reverted merge will come through. That can silently drop the original changes. If you plan to reapply the upgrade after fixing it, read the revert a faulty merge guidance linked from the git revert page, or simply open a fresh PR with the corrected change.
Step 4: verify the lockfile
After the revert, check that the lockfile lists the previous versions of the package and its transitive dependencies. On npm, npm ci installs exactly what the lockfile says and fails if the lockfile and package.json disagree, so it is a good way to prove they match. It also deletes existing node_modules before installing, so run it on a clean build, not in the middle of an experiment.
Step 5: test and deploy
Run the tests that failed in production, and add one that would have caught the problem. Deploy the revert through the normal pipeline, with expedited approval if needed.
Step 6: write the message
Git strongly recommends explaining why a commit is reverted. State the symptom, the package and versions, and the plan. Avoid chains of "Revert the revert" titles. Reword them so they stay readable.
Step 7: stop the bot from retrying
If an automated tool opened the upgrade, it may open it again. Pause that category or ignore that version until the issue is understood. Then feed the failure back into your rollback plan.
Quick check
Should I use git reset to undo a merged PR?
Not on a shared branch. Reset rewrites history and breaks everyone else's clone. Use revert, which adds a new commit.
Why does reverting a merge need the -m option?
A merge commit has two parents and Git needs to know which one is the mainline to compute the reversal. Use -m 1 when the first parent is your main branch.
Safeguard's remediation opens fix PRs for review and ships off by default, so every change has a human decision point you can reverse.
Sources
Last reviewed: 19 October 2026.