First, as you already did, reset the master to the last sain commit git reset <last_sain_commit> --hard.
Please ensure the repository is clean (using something like git clean -fxd).
This makes sure that you don't accidentally commit the bug again.
Afterward, you will have two strains, "feature_2" with only blue commits and "feature_1" with only red commits.
Now simply reset the master branch to the feature_2 branch using git reset feature_2 --hard.
You can also replace feature_2 with a specific commit or another branch.
To get rid of the buggy commit, switch to "feature_1".
Now we have two options, revert and remove.
I'd recommend you revert, as it removes the bug without potentially destructive changes to the history, but you might actually want to use remove.
Revert
Revert the specific commit using git revert <invalid_commit_id>.
This will produce the following structure (from newest to oldest):
- Revert "Red 1"
- Red 7
- Red 6
- ...
- Red 1
- Blue (shared)
Remove
Open a rebase prompt by running: git rebase --no-autosquash --interactive --keep-empty <hash_of_last_blue_commit_in_branch>.
This will open a text editor containing a bunch of lines similar to this.
pick <commit_hash> Red 1
pick <commit_hash> Red 2
pick <commit_hash> Red 3
pick <commit_hash> Red 4
pick <commit_hash> Red 5
pick <commit_hash> Red 6
pick <commit_hash> Red 7
Replace "pick" with "drop" for all commits that introduced part of your problem.
So, in your example:
drop <commit_hash> Red 1
pick <commit_hash> Red 2
pick <commit_hash> Red 3
pick <commit_hash> Red 4
pick <commit_hash> Red 5
pick <commit_hash> Red 6
pick <commit_hash> Red 7
Confirm and exit.
This will replay all commits except the ones marked with drop.
Don't forget to push the modified history (using git push -f).