From 517f83aae949511fcc0696d4b67392d024acded1 Mon Sep 17 00:00:00 2001
From: Jirka <jirka.borovec@seznam.cz>
Date: Mon, 11 Mar 2024 21:33:19 +0100
Subject: [PATCH 1/3] lint: switch Black with `ruff-format`

---
 .github/workflows/lint.yml |  2 --
 .pre-commit-config.yaml    | 18 ++----------------
 Makefile                   |  2 +-
 pyproject.toml             |  5 -----
 test-requirements.txt      |  1 -
 tox.ini                    |  2 --
 6 files changed, 3 insertions(+), 27 deletions(-)

diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index d805124fc..a32fb6c4e 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -16,5 +16,3 @@ jobs:
     - uses: pre-commit/action@v3.0.1
       with:
         extra_args: --all-files --hook-stage manual
-      env:
-        SKIP: black-format
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index cd5f58441..60bbe3518 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,24 +1,10 @@
 repos:
-- repo: https://github.com/psf/black-pre-commit-mirror
-  rev: 23.9.1
-  hooks:
-  - id: black
-    alias: black-check
-    name: black (check)
-    args: [--check, --diff]
-    exclude: ^git/ext/
-    stages: [manual]
-
-  - id: black
-    alias: black-format
-    name: black (format)
-    exclude: ^git/ext/
 
 - repo: https://github.com/astral-sh/ruff-pre-commit
   rev: v0.3.0
   hooks:
-  #- id: ruff-format  # todo: eventually replace Black with Ruff for consistency
-  #  args: ["--preview"]
+  - id: ruff-format
+    exclude: ^git/ext/
   - id: ruff
     args: ["--fix"]
     exclude: ^doc|^git/ext/
diff --git a/Makefile b/Makefile
index 839dc9f78..71a370ef2 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ all:
 	@awk -F: '/^[[:alpha:]].*:/ && !/^all:/ {print $$1}' Makefile
 
 lint:
-	SKIP=black-format pre-commit run --all-files --hook-stage manual
+	SKIP=pre-commit run --all-files --hook-stage manual
 
 clean:
 	rm -rf build/ dist/ .eggs/ .tox/
diff --git a/pyproject.toml b/pyproject.toml
index af0e52ca4..eb57cc7b7 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -42,11 +42,6 @@ source = ["git"]
 include = ["*/git/*"]
 omit = ["*/git/ext/*"]
 
-[tool.black]
-line-length = 120
-target-version = ["py37"]
-extend-exclude = "git/ext/gitdb"
-
 [tool.ruff]
 target-version = "py37"
 line-length = 120
diff --git a/test-requirements.txt b/test-requirements.txt
index 7cfb977a1..e1f5e2ed4 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,4 +1,3 @@
-black
 coverage[toml]
 ddt >= 1.1.1, != 1.4.3
 mock ; python_version < "3.8"
diff --git a/tox.ini b/tox.ini
index f9ac25b78..28b7b147f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -12,8 +12,6 @@ commands = pytest --color=yes {posargs}
 [testenv:lint]
 description = Lint via pre-commit
 base_python = py{39,310,311,312,38,37}
-set_env =
-    SKIP = black-format
 commands = pre-commit run --all-files --hook-stage manual
 
 [testenv:mypy]

From 2d0158c2c147dae90f9bbceeead1c4f322e90436 Mon Sep 17 00:00:00 2001
From: Jirka <jirka.borovec@seznam.cz>
Date: Mon, 11 Mar 2024 21:36:25 +0100
Subject: [PATCH 2/3] apply `ruff-format`

---
 git/cmd.py          | 72 ++++++++++++++++++---------------------------
 git/compat.py       | 18 ++++--------
 git/index/fun.py    |  6 ++--
 git/objects/fun.py  |  6 ++--
 git/objects/tree.py |  2 +-
 git/objects/util.py | 12 +++-----
 git/remote.py       | 11 +++----
 git/util.py         |  9 ++----
 8 files changed, 52 insertions(+), 84 deletions(-)

diff --git a/git/cmd.py b/git/cmd.py
index 731d0fab8..915f46a05 100644
--- a/git/cmd.py
+++ b/git/cmd.py
@@ -495,9 +495,8 @@ def refresh(cls, path: Union[None, PathLike] = None) -> bool:
                 if mode in quiet:
                     pass
                 elif mode in warn or mode in error:
-                    err = (
-                        dedent(
-                            """\
+                    err = dedent(
+                        """\
                         %s
                         All git commands will error until this is rectified.
 
@@ -510,16 +509,14 @@ def refresh(cls, path: Union[None, PathLike] = None) -> bool:
                         Example:
                             export %s=%s
                         """
-                        )
-                        % (
-                            err,
-                            cls._refresh_env_var,
-                            "|".join(quiet),
-                            "|".join(warn),
-                            "|".join(error),
-                            cls._refresh_env_var,
-                            quiet[0],
-                        )
+                    ) % (
+                        err,
+                        cls._refresh_env_var,
+                        "|".join(quiet),
+                        "|".join(warn),
+                        "|".join(error),
+                        cls._refresh_env_var,
+                        quiet[0],
                     )
 
                     if mode in warn:
@@ -527,9 +524,8 @@ def refresh(cls, path: Union[None, PathLike] = None) -> bool:
                     else:
                         raise ImportError(err)
                 else:
-                    err = (
-                        dedent(
-                            """\
+                    err = dedent(
+                        """\
                         %s environment variable has been set but it has been set with an invalid value.
 
                         Use only the following values:
@@ -537,13 +533,11 @@ def refresh(cls, path: Union[None, PathLike] = None) -> bool:
                             - %s: for a warning message (logging level CRITICAL, displayed by default)
                             - %s: for a raised exception
                         """
-                        )
-                        % (
-                            cls._refresh_env_var,
-                            "|".join(quiet),
-                            "|".join(warn),
-                            "|".join(error),
-                        )
+                    ) % (
+                        cls._refresh_env_var,
+                        "|".join(quiet),
+                        "|".join(warn),
+                        "|".join(error),
                     )
                     raise ImportError(err)
 
@@ -565,13 +559,11 @@ def is_cygwin(cls) -> bool:
 
     @overload
     @classmethod
-    def polish_url(cls, url: str, is_cygwin: Literal[False] = ...) -> str:
-        ...
+    def polish_url(cls, url: str, is_cygwin: Literal[False] = ...) -> str: ...
 
     @overload
     @classmethod
-    def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None) -> str:
-        ...
+    def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None) -> str: ...
 
     @classmethod
     def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None) -> PathLike:
@@ -932,8 +924,7 @@ def execute(
         command: Union[str, Sequence[Any]],
         *,
         as_process: Literal[True],
-    ) -> "AutoInterrupt":
-        ...
+    ) -> "AutoInterrupt": ...
 
     @overload
     def execute(
@@ -942,8 +933,7 @@ def execute(
         *,
         as_process: Literal[False] = False,
         stdout_as_string: Literal[True],
-    ) -> Union[str, Tuple[int, str, str]]:
-        ...
+    ) -> Union[str, Tuple[int, str, str]]: ...
 
     @overload
     def execute(
@@ -952,8 +942,7 @@ def execute(
         *,
         as_process: Literal[False] = False,
         stdout_as_string: Literal[False] = False,
-    ) -> Union[bytes, Tuple[int, bytes, str]]:
-        ...
+    ) -> Union[bytes, Tuple[int, bytes, str]]: ...
 
     @overload
     def execute(
@@ -963,8 +952,7 @@ def execute(
         with_extended_output: Literal[False],
         as_process: Literal[False],
         stdout_as_string: Literal[True],
-    ) -> str:
-        ...
+    ) -> str: ...
 
     @overload
     def execute(
@@ -974,8 +962,7 @@ def execute(
         with_extended_output: Literal[False],
         as_process: Literal[False],
         stdout_as_string: Literal[False],
-    ) -> bytes:
-        ...
+    ) -> bytes: ...
 
     def execute(
         self,
@@ -1387,8 +1374,9 @@ def __call__(self, **kwargs: Any) -> "Git":
         return self
 
     @overload
-    def _call_process(self, method: str, *args: None, **kwargs: None) -> str:
-        ...  # If no args were given, execute the call with all defaults.
+    def _call_process(
+        self, method: str, *args: None, **kwargs: None
+    ) -> str: ...  # If no args were given, execute the call with all defaults.
 
     @overload
     def _call_process(
@@ -1398,14 +1386,12 @@ def _call_process(
         as_process: Literal[True],
         *args: Any,
         **kwargs: Any,
-    ) -> "Git.AutoInterrupt":
-        ...
+    ) -> "Git.AutoInterrupt": ...
 
     @overload
     def _call_process(
         self, method: str, *args: Any, **kwargs: Any
-    ) -> Union[str, bytes, Tuple[int, Union[str, bytes], str], "Git.AutoInterrupt"]:
-        ...
+    ) -> Union[str, bytes, Tuple[int, Union[str, bytes], str], "Git.AutoInterrupt"]: ...
 
     def _call_process(
         self, method: str, *args: Any, **kwargs: Any
diff --git a/git/compat.py b/git/compat.py
index 7753fe8b2..e64c645c7 100644
--- a/git/compat.py
+++ b/git/compat.py
@@ -69,13 +69,11 @@
 
 
 @overload
-def safe_decode(s: None) -> None:
-    ...
+def safe_decode(s: None) -> None: ...
 
 
 @overload
-def safe_decode(s: AnyStr) -> str:
-    ...
+def safe_decode(s: AnyStr) -> str: ...
 
 
 def safe_decode(s: Union[AnyStr, None]) -> Optional[str]:
@@ -91,13 +89,11 @@ def safe_decode(s: Union[AnyStr, None]) -> Optional[str]:
 
 
 @overload
-def safe_encode(s: None) -> None:
-    ...
+def safe_encode(s: None) -> None: ...
 
 
 @overload
-def safe_encode(s: AnyStr) -> bytes:
-    ...
+def safe_encode(s: AnyStr) -> bytes: ...
 
 
 def safe_encode(s: Optional[AnyStr]) -> Optional[bytes]:
@@ -113,13 +109,11 @@ def safe_encode(s: Optional[AnyStr]) -> Optional[bytes]:
 
 
 @overload
-def win_encode(s: None) -> None:
-    ...
+def win_encode(s: None) -> None: ...
 
 
 @overload
-def win_encode(s: AnyStr) -> bytes:
-    ...
+def win_encode(s: AnyStr) -> bytes: ...
 
 
 def win_encode(s: Optional[AnyStr]) -> Optional[bytes]:
diff --git a/git/index/fun.py b/git/index/fun.py
index 58335739e..beca67d3f 100644
--- a/git/index/fun.py
+++ b/git/index/fun.py
@@ -286,9 +286,9 @@ def read_cache(
     #   4 bytes length of chunk
     #   Repeated 0 - N times
     extension_data = stream.read(~0)
-    assert (
-        len(extension_data) > 19
-    ), "Index Footer was not at least a sha on content as it was only %i bytes in size" % len(extension_data)
+    assert len(extension_data) > 19, (
+        "Index Footer was not at least a sha on content as it was only %i bytes in size" % len(extension_data)
+    )
 
     content_sha = extension_data[-20:]
 
diff --git a/git/objects/fun.py b/git/objects/fun.py
index 22b99cb6b..5bd8a3d62 100644
--- a/git/objects/fun.py
+++ b/git/objects/fun.py
@@ -152,13 +152,11 @@ def _find_by_name(tree_data: MutableSequence[EntryTupOrNone], name: str, is_dir:
 
 
 @overload
-def _to_full_path(item: None, path_prefix: str) -> None:
-    ...
+def _to_full_path(item: None, path_prefix: str) -> None: ...
 
 
 @overload
-def _to_full_path(item: EntryTup, path_prefix: str) -> EntryTup:
-    ...
+def _to_full_path(item: EntryTup, path_prefix: str) -> EntryTup: ...
 
 
 def _to_full_path(item: EntryTupOrNone, path_prefix: str) -> EntryTupOrNone:
diff --git a/git/objects/tree.py b/git/objects/tree.py
index 731ab5fa1..3964b016c 100644
--- a/git/objects/tree.py
+++ b/git/objects/tree.py
@@ -188,7 +188,7 @@ class Tree(IndexObject, git_diff.Diffable, util.Traversable, util.Serializable):
     _map_id_to_type: Dict[int, Type[IndexObjUnion]] = {
         commit_id: Submodule,
         blob_id: Blob,
-        symlink_id: Blob
+        symlink_id: Blob,
         # Tree ID added once Tree is defined.
     }
 
diff --git a/git/objects/util.py b/git/objects/util.py
index 71eb9c230..26a34f94c 100644
--- a/git/objects/util.py
+++ b/git/objects/util.py
@@ -620,8 +620,7 @@ def list_traverse(self: T_TIobj, *args: Any, **kwargs: Any) -> IterableList[T_TI
         return super()._list_traverse(*args, **kwargs)
 
     @overload  # type: ignore
-    def traverse(self: T_TIobj) -> Iterator[T_TIobj]:
-        ...
+    def traverse(self: T_TIobj) -> Iterator[T_TIobj]: ...
 
     @overload
     def traverse(
@@ -633,8 +632,7 @@ def traverse(
         visit_once: bool,
         ignore_self: Literal[True],
         as_edge: Literal[False],
-    ) -> Iterator[T_TIobj]:
-        ...
+    ) -> Iterator[T_TIobj]: ...
 
     @overload
     def traverse(
@@ -646,8 +644,7 @@ def traverse(
         visit_once: bool,
         ignore_self: Literal[False],
         as_edge: Literal[True],
-    ) -> Iterator[Tuple[Union[T_TIobj, None], T_TIobj]]:
-        ...
+    ) -> Iterator[Tuple[Union[T_TIobj, None], T_TIobj]]: ...
 
     @overload
     def traverse(
@@ -659,8 +656,7 @@ def traverse(
         visit_once: bool,
         ignore_self: Literal[True],
         as_edge: Literal[True],
-    ) -> Iterator[Tuple[T_TIobj, T_TIobj]]:
-        ...
+    ) -> Iterator[Tuple[T_TIobj, T_TIobj]]: ...
 
     def traverse(
         self: T_TIobj,
diff --git a/git/remote.py b/git/remote.py
index fd4de7100..b63cfc208 100644
--- a/git/remote.py
+++ b/git/remote.py
@@ -93,22 +93,19 @@ def add_progress(
 
 
 @overload
-def to_progress_instance(progress: None) -> RemoteProgress:
-    ...
+def to_progress_instance(progress: None) -> RemoteProgress: ...
 
 
 @overload
-def to_progress_instance(progress: Callable[..., Any]) -> CallableRemoteProgress:
-    ...
+def to_progress_instance(progress: Callable[..., Any]) -> CallableRemoteProgress: ...
 
 
 @overload
-def to_progress_instance(progress: RemoteProgress) -> RemoteProgress:
-    ...
+def to_progress_instance(progress: RemoteProgress) -> RemoteProgress: ...
 
 
 def to_progress_instance(
-    progress: Union[Callable[..., Any], RemoteProgress, None]
+    progress: Union[Callable[..., Any], RemoteProgress, None],
 ) -> Union[RemoteProgress, CallableRemoteProgress]:
     """Given the `progress` return a suitable object derived from
     :class:`~git.util.RemoteProgress`."""
diff --git a/git/util.py b/git/util.py
index 9d451eee2..27751f687 100644
--- a/git/util.py
+++ b/git/util.py
@@ -441,13 +441,11 @@ def decygpath(path: PathLike) -> str:
 
 
 @overload
-def is_cygwin_git(git_executable: None) -> Literal[False]:
-    ...
+def is_cygwin_git(git_executable: None) -> Literal[False]: ...
 
 
 @overload
-def is_cygwin_git(git_executable: PathLike) -> bool:
-    ...
+def is_cygwin_git(git_executable: PathLike) -> bool: ...
 
 
 def is_cygwin_git(git_executable: Union[None, PathLike]) -> bool:
@@ -494,8 +492,7 @@ def finalize_process(proc: Union[subprocess.Popen, "Git.AutoInterrupt"], **kwarg
 
 
 @overload
-def expand_path(p: None, expand_vars: bool = ...) -> None:
-    ...
+def expand_path(p: None, expand_vars: bool = ...) -> None: ...
 
 
 @overload

From 1b8812a968a76f47acdf80bc1d15e6b0dd5d84bf Mon Sep 17 00:00:00 2001
From: Jirka <jirka.borovec@seznam.cz>
Date: Tue, 12 Mar 2024 21:08:54 +0100
Subject: [PATCH 3/3] drop `make lint`

---
 Makefile  | 5 +----
 README.md | 3 ---
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/Makefile b/Makefile
index 71a370ef2..d4f9acf87 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,8 @@
-.PHONY: all lint clean release force_release
+.PHONY: all clean release force_release
 
 all:
 	@awk -F: '/^[[:alpha:]].*:/ && !/^all:/ {print $$1}' Makefile
 
-lint:
-	SKIP=pre-commit run --all-files --hook-stage manual
-
 clean:
 	rm -rf build/ dist/ .eggs/ .tox/
 
diff --git a/README.md b/README.md
index 1e4a59d7f..33e093945 100644
--- a/README.md
+++ b/README.md
@@ -165,9 +165,6 @@ To lint, and apply automatic code formatting, run:
 pre-commit run --all-files
 ```
 
-- Linting without modifying code can be done with: `make lint`
-- Auto-formatting without other lint checks can be done with: `black .`
-
 To typecheck, run:
 
 ```bash