diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 43f8b4a9c..f858029c1 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -2,6 +2,8 @@ ## New in git-machete 3.26.2 +- fixed: parsing of multiline git config keys (reported by @saveman71) + ## New in git-machete 3.26.1 - fixed: readability of autogenerated PR/MR descriptions diff --git a/docs/man/git-machete.1 b/docs/man/git-machete.1 index 7bdb2f57c..e680113e7 100644 --- a/docs/man/git-machete.1 +++ b/docs/man/git-machete.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "GIT-MACHETE" "1" "Jul 01, 2024" "" "git-machete" +.TH "GIT-MACHETE" "1" "Jul 03, 2024" "" "git-machete" .SH NAME git-machete \- git-machete 3.26.2 .sp diff --git a/git_machete/git_operations.py b/git_machete/git_operations.py index ec6f81b02..ac1c81145 100644 --- a/git_machete/git_operations.py +++ b/git_machete/git_operations.py @@ -303,13 +303,15 @@ def get_git_timespec_parsed_to_unix_timestamp(self, date: str) -> int: def __ensure_config_loaded(self) -> None: if self.__config_cached is None: self.__config_cached = {} - for config_line in utils.get_non_empty_lines(self._popen_git("config", "--list").stdout): - k_v = config_line.split("=", 1) - if len(k_v) == 2: - k, v = k_v - self.__config_cached[k.lower()] = v + git_config_stdout = self._popen_git("config", "--list", "--null").stdout + for config_entry in filter(None, git_config_stdout.split("\0")): + # Apparently, even on Windows, this command uses just \n (and not \r\n) to separate config key from value. + key_and_value_lines = config_entry.split('\n', 1) + if len(key_and_value_lines) == 2: + key, value_lines = key_and_value_lines + self.__config_cached[key.lower()] = value_lines else: - raise UnexpectedMacheteException(f"Cannot parse config line: {config_line}.") + raise UnexpectedMacheteException(f"Cannot parse config entry: {config_entry}.") def get_config_attr_or_none(self, key: str) -> Optional[str]: self.__ensure_config_loaded() diff --git a/tests/test_git_operations.py b/tests/test_git_operations.py index cbe266c66..6dbed2139 100644 --- a/tests/test_git_operations.py +++ b/tests/test_git_operations.py @@ -164,3 +164,8 @@ def test_is_equivalent_tree_or_patch_reachable_when_no_common_ancestor(self) -> assert git.is_equivalent_tree_reachable(equivalent_to=feature, reachable_from=master) is False assert git.is_equivalent_patch_reachable(equivalent_to=feature, reachable_from=master) is False + + def test_git_config_with_newlines(self) -> None: + self.repo_sandbox.write_to_file(".git/config", '[foo]\n bar = "hello\\nworld"') + git = GitContext() + assert git.get_config_attr_or_none("foo.bar") == "hello\nworld"