Part of this depends on what you want the history to look like.
--- A --- bad change --- B --- C --- D --- E -- MAIN
your history looks (very roughly) like this right now.
Here are some possible "fixes".
1:
--- A --- bad change --- B --- C --- D --- E --- undo bad change -- MAIN
this is what git revert bad_change_guid would do.
2:
--- A --- bad change --- B --- C --- D --- E --\
\-------------------B --- C --- D --- E -- merge -- MAIN
This would be creating a new branch without the bad change, applying every change on it, then merging MAIN into it.
3:
--- A ------------------ B --- C --- D --- E -- MAIN
This is "deleting bad change from ever happening".
If you are working totally locally, it is possible that you want to do #3. It has the disadvantage that it rewrites history. If you aren't working totally locally doing #3 is very hostile.
#2 is like #3, except it keeps history intact. You create an "alternative universe" in which the changes after the bad change occurred without the bad change. Then you merge the bad history over to the new, corrected history.
#1 is by far the simplest. Here, you create a CL that represents undoing the bad change, and you apply it today.
By default you should probably do #1. To use it, you need to find the identifier of the bad change (its guid or other identifier). Then you need to do "git revert IDENTIFIER" to create a commit that attempts to undo it.
You'll then have to manually inspect this change and the result of it to determine if it did everything correctly.
The way I'd do #2 would be to first create a new branch on top of main. Then I'd do an interactive rebase to strip bad_change out of the history (using git rebase -i bad_change_id~). Test the result, then do a merge of main into this branch, but for all conflicts take the branch version. Then push the resulting merge history up to your remote repo.
To do #3, you'd do the interactive rebase to strip out the bad commit, then you'd push the new MAIN branch up to the remote repo.
#3 is highly hostile to anyone else, because their work is now going to be on top of changes that no longer exist. In addition, rewriting history is dangerous: if you screw up again, you won't be able to undo the screw up nearly as easily.
Both #2 and #3 are significantly trickier to do right than #1.