From e4360aea32aad11bf3c54b0dc0a6cabb21b5e687 Mon Sep 17 00:00:00 2001 From: Hiroki Tokunaga Date: Wed, 6 Apr 2022 23:08:36 +0900 Subject: [PATCH 1/5] feat(cmd): add the `strip_newline` flag This commit adds the `strip_newline` flag to the `Git.execute` method. When this flag is set to `True`, it will trim the trailing `\n`. The default value is `True` for backward compatibility. Setting it to `False` is helpful for, e.g., the `git show` output, especially with the binary file, as the missing `\n` may invalidate the file. --- git/cmd.py | 7 +++++-- test/test_repo.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 4f0569879..9c5da89dc 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -55,7 +55,7 @@ execute_kwargs = {'istream', 'with_extended_output', 'with_exceptions', 'as_process', 'stdout_as_string', 'output_stream', 'with_stdout', 'kill_after_timeout', - 'universal_newlines', 'shell', 'env', 'max_chunk_size'} + 'universal_newlines', 'shell', 'env', 'max_chunk_size', 'strip_newline'} log = logging.getLogger(__name__) log.addHandler(logging.NullHandler()) @@ -738,6 +738,7 @@ def execute(self, shell: Union[None, bool] = None, env: Union[None, Mapping[str, str]] = None, max_chunk_size: int = io.DEFAULT_BUFFER_SIZE, + strip_newline: bool = True, **subprocess_kwargs: Any ) -> Union[str, bytes, Tuple[int, Union[str, bytes], str], AutoInterrupt]: """Handles executing the command on the shell and consumes and returns @@ -810,6 +811,8 @@ def execute(self, effects on a repository. For example, stale locks in case of git gc could render the repository incapable of accepting changes until the lock is manually removed. + :param strip_newline: + Whether to strip the trailing '\n' of the command output. :return: * str(output) if extended_output = False (Default) @@ -944,7 +947,7 @@ def _kill_process(pid: int) -> None: if not universal_newlines: stderr_value = stderr_value.encode(defenc) # strip trailing "\n" - if stdout_value.endswith(newline): # type: ignore + if stdout_value.endswith(newline) and strip_newline: # type: ignore stdout_value = stdout_value[:-1] if stderr_value.endswith(newline): # type: ignore stderr_value = stderr_value[:-1] diff --git a/test/test_repo.py b/test/test_repo.py index 6d6176090..14339f57f 100644 --- a/test/test_repo.py +++ b/test/test_repo.py @@ -1098,3 +1098,13 @@ def test_rebasing(self, rw_dir): except GitCommandError: pass self.assertEqual(r.currently_rebasing_on(), commitSpanish) + + @with_rw_directory + def test_do_not_strip_newline(self, rw_dir): + r = Repo.init(rw_dir) + fp = osp.join(rw_dir, 'hello.txt') + with open(fp, 'w') as fs: + fs.write("hello\n") + r.git.add(Git.polish_url(https://github.com/fp)) + r.git.commit(message="init") + self.assertEqual(r.git.show("HEAD:hello.txt", strip_newline=False), 'hello\n') From 946b64b62bdc9fb3447b6daf0053b11a2e4c5277 Mon Sep 17 00:00:00 2001 From: Hiroki Tokunaga Date: Wed, 6 Apr 2022 23:23:42 +0900 Subject: [PATCH 2/5] chore: add me to AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 55d681813..546818f5f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -45,4 +45,5 @@ Contributors are: -Alba Mendez -Robert Westman -Hugo van Kemenade +-Hiroki Tokunaga Portions derived from other open source works and are clearly marked. From 49150e79c6f7a19a0d61a5ea6864b9ac140264ff Mon Sep 17 00:00:00 2001 From: Hiroki Tokunaga Date: Thu, 7 Apr 2022 10:04:19 +0900 Subject: [PATCH 3/5] chore: `s/strip_newline/&_in_stdout` --- git/cmd.py | 10 +++++----- test/test_repo.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 9c5da89dc..228b9d382 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -55,7 +55,7 @@ execute_kwargs = {'istream', 'with_extended_output', 'with_exceptions', 'as_process', 'stdout_as_string', 'output_stream', 'with_stdout', 'kill_after_timeout', - 'universal_newlines', 'shell', 'env', 'max_chunk_size', 'strip_newline'} + 'universal_newlines', 'shell', 'env', 'max_chunk_size', 'strip_newline_in_stdout'} log = logging.getLogger(__name__) log.addHandler(logging.NullHandler()) @@ -738,7 +738,7 @@ def execute(self, shell: Union[None, bool] = None, env: Union[None, Mapping[str, str]] = None, max_chunk_size: int = io.DEFAULT_BUFFER_SIZE, - strip_newline: bool = True, + strip_newline_in_stdout: bool = True, **subprocess_kwargs: Any ) -> Union[str, bytes, Tuple[int, Union[str, bytes], str], AutoInterrupt]: """Handles executing the command on the shell and consumes and returns @@ -811,8 +811,8 @@ def execute(self, effects on a repository. For example, stale locks in case of git gc could render the repository incapable of accepting changes until the lock is manually removed. - :param strip_newline: - Whether to strip the trailing '\n' of the command output. + :param strip_newline_in_stdout: + Whether to strip the trailing '\n' of the command stdout. :return: * str(output) if extended_output = False (Default) @@ -947,7 +947,7 @@ def _kill_process(pid: int) -> None: if not universal_newlines: stderr_value = stderr_value.encode(defenc) # strip trailing "\n" - if stdout_value.endswith(newline) and strip_newline: # type: ignore + if stdout_value.endswith(newline) and strip_newline_in_stdout: # type: ignore stdout_value = stdout_value[:-1] if stderr_value.endswith(newline): # type: ignore stderr_value = stderr_value[:-1] diff --git a/test/test_repo.py b/test/test_repo.py index 14339f57f..c5b2680d0 100644 --- a/test/test_repo.py +++ b/test/test_repo.py @@ -1100,11 +1100,11 @@ def test_rebasing(self, rw_dir): self.assertEqual(r.currently_rebasing_on(), commitSpanish) @with_rw_directory - def test_do_not_strip_newline(self, rw_dir): + def test_do_not_strip_newline_in_stdout(self, rw_dir): r = Repo.init(rw_dir) fp = osp.join(rw_dir, 'hello.txt') with open(fp, 'w') as fs: fs.write("hello\n") r.git.add(Git.polish_url(https://github.com/fp)) r.git.commit(message="init") - self.assertEqual(r.git.show("HEAD:hello.txt", strip_newline=False), 'hello\n') + self.assertEqual(r.git.show("HEAD:hello.txt", strip_newline_in_stdout=False), 'hello\n') From 2a50f28fa3571e3d2c4d5ea86f4243f715717269 Mon Sep 17 00:00:00 2001 From: Hiroki Tokunaga Date: Thu, 7 Apr 2022 10:11:28 +0900 Subject: [PATCH 4/5] docs: escape with backticks --- git/cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/cmd.py b/git/cmd.py index 228b9d382..fe161309b 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -812,7 +812,7 @@ def execute(self, render the repository incapable of accepting changes until the lock is manually removed. :param strip_newline_in_stdout: - Whether to strip the trailing '\n' of the command stdout. + Whether to strip the trailing `\n` of the command stdout. :return: * str(output) if extended_output = False (Default) From 17b2b128fb6d6f987b47d60ccb1ab09b8fc238ea Mon Sep 17 00:00:00 2001 From: Hiroki Tokunaga Date: Thu, 7 Apr 2022 10:20:59 +0900 Subject: [PATCH 5/5] fix(docs): remove an unexpected blank line --- git/cmd.py | 1 - 1 file changed, 1 deletion(-) diff --git a/git/cmd.py b/git/cmd.py index fe161309b..1ddf9e03f 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -813,7 +813,6 @@ def execute(self, removed. :param strip_newline_in_stdout: Whether to strip the trailing `\n` of the command stdout. - :return: * str(output) if extended_output = False (Default) * tuple(int(status), str(stdout), str(stderr)) if extended_output = True