diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 6d6d291..937696b 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
 -   repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.5.0
+    rev: v4.6.0
     hooks:
     -   id: trailing-whitespace
     -   id: end-of-file-fixer
@@ -23,7 +23,7 @@ repos:
     hooks:
     -   id: add-trailing-comma
 -   repo: https://github.com/asottile/pyupgrade
-    rev: v3.15.1
+    rev: v3.15.2
     hooks:
     -   id: pyupgrade
         args: [--py38-plus]
diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml
index c0d811c..4b4d0cf 100644
--- a/.pre-commit-hooks.yaml
+++ b/.pre-commit-hooks.yaml
@@ -145,7 +145,7 @@
     language: python
     types: [text]
 -   id: fix-encoding-pragma
-    name: fix python encoding pragma
+    name: fix python encoding pragma (deprecated)
     description: 'adds # -*- coding: utf-8 -*- to the top of python files.'
     language: python
     entry: fix-encoding-pragma
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c1daaba..bf99d9f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+4.6.0 - 2024-04-06
+==================
+
+### Features
+- `requirements-txt-fixer`: remove duplicate packages.
+    - #1014 PR by @vhoulbreque-withings.
+    - #960 issue @csibe17.
+
+### Migrating
+- `fix-encoding-pragma`: deprecated -- will be removed in 5.0.0.  use
+  [pyupgrade](https://github.com/asottile/pyupgrade) or some other tool.
+    - #1033 PR by @mxr.
+    - #1032 issue by @mxr.
+
 4.5.0 - 2023-10-07
 ==================
 
diff --git a/README.md b/README.md
index 9ae7ec5..4992baf 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ Add this to your `.pre-commit-config.yaml`
 
 ```yaml
 -   repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.5.0  # Use the ref you want to point at
+    rev: v4.6.0  # Use the ref you want to point at
     hooks:
     -   id: trailing-whitespace
     # -   id: ...
@@ -127,6 +127,9 @@ The following arguments are available:
 removes UTF-8 byte order marker
 
 #### `fix-encoding-pragma`
+
+_Deprecated since py2 is EOL - use [pyupgrade](https://github.com/asottile/pyupgrade) instead._
+
 Add `# -*- coding: utf-8 -*-` to the top of python files.
   - To remove the coding pragma pass `--remove` (useful in a python3-only codebase)
 
diff --git a/pre_commit_hooks/fix_encoding_pragma.py b/pre_commit_hooks/fix_encoding_pragma.py
index 60c71ee..eee6705 100644
--- a/pre_commit_hooks/fix_encoding_pragma.py
+++ b/pre_commit_hooks/fix_encoding_pragma.py
@@ -1,6 +1,7 @@
 from __future__ import annotations
 
 import argparse
+import sys
 from typing import IO
 from typing import NamedTuple
 from typing import Sequence
@@ -107,6 +108,13 @@ def _normalize_pragma(pragma: str) -> bytes:
 
 
 def main(argv: Sequence[str] | None = None) -> int:
+    print(
+        'warning: this hook is deprecated and will be removed in a future '
+        'release because py2 is EOL. instead, use '
+        'https://github.com/asottile/pyupgrade',
+        file=sys.stderr,
+    )
+
     parser = argparse.ArgumentParser(
         'Fixes the encoding pragma of python files',
     )
diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py
index 261acc9..07b57e1 100644
--- a/pre_commit_hooks/requirements_txt_fixer.py
+++ b/pre_commit_hooks/requirements_txt_fixer.py
@@ -115,7 +115,10 @@ def fix_requirements(f: IO[bytes]) -> int:
     # which is automatically added by broken pip package under Debian
     requirements = [
         req for req in requirements
-        if req.value != b'pkg-resources==0.0.0\n'
+        if req.value not in [
+            b'pkg-resources==0.0.0\n',
+            b'pkg_resources==0.0.0\n',
+        ]
     ]
 
     # sort the requirements and remove duplicates
diff --git a/setup.cfg b/setup.cfg
index 6a4c459..82a5457 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = pre_commit_hooks
-version = 4.5.0
+version = 4.6.0
 description = Some out-of-the-box hooks for pre-commit.
 long_description = file: README.md
 long_description_content_type = text/markdown

diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py
index c400be1..c0d2c65 100644
--- a/tests/requirements_txt_fixer_test.py
+++ b/tests/requirements_txt_fixer_test.py
@@ -82,6 +82,8 @@ from pre_commit_hooks.requirements_txt_fixer import Requirement
         ),
         (b'bar\npkg-resources==0.0.0\nfoo\n', FAIL, b'bar\nfoo\n'),
         (b'foo\npkg-resources==0.0.0\nbar\n', FAIL, b'bar\nfoo\n'),
+        (b'bar\npkg_resources==0.0.0\nfoo\n', FAIL, b'bar\nfoo\n'),
+        (b'foo\npkg_resources==0.0.0\nbar\n', FAIL, b'bar\nfoo\n'),
         (
             b'git+ssh://git_url@tag#egg=ocflib\nDjango\nijk\n',
             FAIL,

requirements-txt-fixer doesn't handle new pkg_resources==0.0.0
Perhaps something changed on PyPI but instead of Ubuntu 20.04 generating `pkg-resources==0.0.0` it now generates `npkg_resources==0.0.0` which should also be ignored.
tests/requirements_txt_fixer_test.py::test_integration[bar\npkg_resources==0.0.0\nfoo\n-1-bar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[foo\npkg_resources==0.0.0\nbar\n-1-bar\nfoo\n]
tests/requirements_txt_fixer_test.py::test_integration[-0-] tests/requirements_txt_fixer_test.py::test_integration[\n-0-\n] tests/requirements_txt_fixer_test.py::test_integration[# tests/requirements_txt_fixer_test.py::test_integration[foo\n# tests/requirements_txt_fixer_test.py::test_integration[foo\nbar\n-1-bar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[bar\nfoo\n-0-bar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[a\nc\nb\n-1-a\nb\nc\n] tests/requirements_txt_fixer_test.py::test_integration[a\nc\nb-1-a\nb\nc\n] tests/requirements_txt_fixer_test.py::test_integration[a\nb\nc-1-a\nb\nc\n] tests/requirements_txt_fixer_test.py::test_integration[#comment1\nfoo\n#comment2\nbar\n-1-#comment2\nbar\n#comment1\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[#comment1\nbar\n#comment2\nfoo\n-0-#comment1\nbar\n#comment2\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[#comment\n\nfoo\nbar\n-1-#comment\n\nbar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[#comment\n\nbar\nfoo\n-0-#comment\n\nbar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[foo\n\t#comment tests/requirements_txt_fixer_test.py::test_integration[bar\n\t#comment tests/requirements_txt_fixer_test.py::test_integration[\nfoo\nbar\n-1-bar\n\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[\nbar\nfoo\n-0-\nbar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[pyramid-foo==1\npyramid>=2\n-1-pyramid>=2\npyramid-foo==1\n] tests/requirements_txt_fixer_test.py::test_integration[a==1\nc>=1\nbbbb!=1\nc-a>=1;python_version>="3.6"\ne>=2\nd>2\ng<2\nf<=2\n-1-a==1\nbbbb!=1\nc>=1\nc-a>=1;python_version>="3.6"\nd>2\ne>=2\nf<=2\ng<2\n] tests/requirements_txt_fixer_test.py::test_integration[a==1\nb==1\na==1\n-1-a==1\nb==1\n] tests/requirements_txt_fixer_test.py::test_integration[a==1\nb==1\n#comment tests/requirements_txt_fixer_test.py::test_integration[ocflib\nDjango\nPyMySQL\n-1-Django\nocflib\nPyMySQL\n] tests/requirements_txt_fixer_test.py::test_integration[-e tests/requirements_txt_fixer_test.py::test_integration[bar\npkg-resources==0.0.0\nfoo\n-1-bar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[foo\npkg-resources==0.0.0\nbar\n-1-bar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[git+ssh://git_url@tag#egg=ocflib\nDjango\nijk\n-1-Django\nijk\ngit+ssh://git_url@tag#egg=ocflib\n] tests/requirements_txt_fixer_test.py::test_integration[b==1.0.0\nc=2.0.0 tests/requirements_txt_fixer_test.py::test_integration[a=2.0.0 tests/requirements_txt_fixer_test.py::test_requirement_object