| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 983e182 commit 22f137d
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -632,13 +632,15 @@ def escapes_are_known(value: str) -> bool: | |||
| 632 | 632 | # next line is appended before the complete value is | |
| 633 | 633 | # parsed. An even number means the last backslash is | |
| 634 | 634 | # escaped and the value ends there. | |
| 635 | + eof_continuation = False | ||
| 635 | 636 | while True: | |
| 636 | 637 | if not is_line_continuation(optval): | |
| 637 | 638 | break | |
| 638 | 639 | continuation = fp.readline() | |
| 639 | 640 | if not continuation: | |
| 640 | - # Backslash at end of file: git drops it. | ||
| 641 | - optval = optval[:-1] | ||
| 641 | + # Keep the backslash until parsing so preceding | ||
| 642 | + # whitespace is significant even though git drops it. | ||
| 643 | + eof_continuation = True | ||
| 642 | 644 | break | |
| 643 | 645 | lineno = lineno + 1 | |
| 644 | 646 | joined = continuation.decode(defenc) | |
@@ -649,8 +651,11 @@ def escapes_are_known(value: str) -> bool: | |||
| 649 | 651 | # values, but only a value in which every backslash is part | |
| 650 | 652 | # of a known escape is decoded, so that a Windows path keeps | |
| 651 | 653 | # its backslashes instead of losing them one escape at a time. | |
| 654 | + optval, _ = strip_inline_comment(optval) | ||
| 652 | 655 | if escapes_are_known(optval): | |
| 653 | 656 | optval = parse_value(optval) | |
| 657 | + elif eof_continuation: | ||
| 658 | + optval = optval[:-1] | ||
| 654 | 659 | elif quote_open: | |
| 655 | 660 | # Opens quoting and does not close: appears to start multi-line quoting. | |
| 656 | 661 | is_multi_line = True | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -378,6 +378,33 @@ def test_backslash_line_continuation(self): | |||
| 378 | 378 | key = "co" if section == "alias" else "k" | |
| 379 | 379 | self.assertEqual(config.get_value(section, key), expected) | |
| 380 | 380 | ||
| 381 | + @with_rw_directory | ||
| 382 | + def test_continued_values_preserve_comments_and_eof_whitespace(self, rw_dir): | ||
| 383 | + cases = [ | ||
| 384 | + (b"one\\\n two # C:\\Users\n", "one two"), | ||
| 385 | + (b"one\\\n two ; C:\\Users\n", "one two"), | ||
| 386 | + (b"one\\\n two\\tthree # C:\\Users\n", "one two\tthree"), | ||
| 387 | + (b'one\\\n "two # three" # C:\\Users\n', "one two # three"), | ||
| 388 | + (b"value \\", "value "), | ||
| 389 | + (b"value \\\n", "value "), | ||
| 390 | + (b"value \t\\\n", "value \t"), | ||
| 391 | + (b"one\\\n two \\\n", "one two "), | ||
| 392 | + (b"C:\\Users \\\n", "C:\\Users "), | ||
| 393 | + ] | ||
| 394 | + config_path = osp.join(rw_dir, "config") | ||
| 395 | + for value, expected in cases: | ||
| 396 | + with self.subTest(value=value): | ||
| 397 | + with open(config_path, "wb") as config_file: | ||
| 398 | + config_file.write(b"[a]\n\tk = " + value) | ||
| 399 | + | ||
| 400 | + with GitConfigParser(config_path, read_only=False) as config: | ||
| 401 | + self.assertEqual(config.get_value("a", "k"), expected) | ||
| 402 | + config.set_value("other", "value", "updated") | ||
| 403 | + | ||
| 404 | + with GitConfigParser(config_path) as config: | ||
| 405 | + self.assertEqual(config.get_value("a", "k"), expected) | ||
| 406 | + self.assertEqual(config.get_value("other", "value"), "updated") | ||
| 407 | + | ||
| 381 | 408 | def test_get_value_reads_git_boolean_spellings(self): | |
| 382 | 409 | # git accepts yes/no and on/off as well as true/false, and getboolean on | |
| 383 | 410 | # this class already did. get_value returned them as strings, so "no" and | |
| Back | FazBrowse Home | New Git URL |
0 commit comments