| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -549,11 +549,21 @@ def _included_paths(self) -> List[Tuple[str, str]]: | |||
| 549 | 549 | :return: | |
| 550 | 550 | The list of paths, where each path is a tuple of (option, value). | |
| 551 | 551 | """ | |
| 552 | + | ||
| 553 | + def _all_items(section: str) -> List[Tuple[str, str]]: | ||
| 554 | + """Return all (key, value) pairs for a section, including duplicate keys.""" | ||
| 555 | + return [ | ||
| 556 | + (key, value) | ||
| 557 | + for key, values in self._sections[section].items_all() | ||
| 558 | + if key != "__name__" | ||
| 559 | + for value in values | ||
| 560 | + ] | ||
| 561 | + | ||
| 552 | 562 | paths = [] | |
| 553 | 563 | ||
| 554 | 564 | for section in self.sections(): | |
| 555 | 565 | if section == "include": | |
| 556 | - paths += self.items(section) | ||
| 566 | + paths += _all_items(section) | ||
| 557 | 567 | ||
| 558 | 568 | match = CONDITIONAL_INCLUDE_REGEXP.search(section) | |
| 559 | 569 | if match is None or self._repo is None: | |
@@ -579,7 +589,7 @@ def _included_paths(self) -> List[Tuple[str, str]]: | |||
| 579 | 589 | ) | |
| 580 | 590 | if self._repo.git_dir: | |
| 581 | 591 | if fnmatch.fnmatchcase(os.fspath(self._repo.git_dir), value): | |
| 582 | - paths += self.items(section) | ||
| 592 | + paths += _all_items(section) | ||
| 583 | 593 | ||
| 584 | 594 | elif keyword == "onbranch": | |
| 585 | 595 | try: | |
@@ -589,11 +599,11 @@ def _included_paths(self) -> List[Tuple[str, str]]: | |||
| 589 | 599 | continue | |
| 590 | 600 | ||
| 591 | 601 | if fnmatch.fnmatchcase(branch_name, value): | |
| 592 | - paths += self.items(section) | ||
| 602 | + paths += _all_items(section) | ||
| 593 | 603 | elif keyword == "hasconfig:remote.*.url": | |
| 594 | 604 | for remote in self._repo.remotes: | |
| 595 | 605 | if fnmatch.fnmatchcase(remote.url, value): | |
| 596 | - paths += self.items(section) | ||
| 606 | + paths += _all_items(section) | ||
| 597 | 607 | break | |
| 598 | 608 | return paths | |
| 599 | 609 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -246,6 +246,43 @@ def check_test_value(cr, value): | |||
| 246 | 246 | with GitConfigParser(fpa, read_only=True) as cr: | |
| 247 | 247 | check_test_value(cr, tv) | |
| 248 | 248 | ||
| 249 | + @with_rw_directory | ||
| 250 | + def test_multiple_include_paths_with_same_key(self, rw_dir): | ||
| 251 | + """Test that multiple 'path' entries under [include] are all respected. | ||
| 252 | + | ||
| 253 | + Regression test for https://github.com/gitpython-developers/GitPython/issues/2099. | ||
| 254 | + Git config allows multiple ``path`` values under ``[include]``, e.g.:: | ||
| 255 | + | ||
| 256 | + [include] | ||
| 257 | + path = file1 | ||
| 258 | + path = file2 | ||
| 259 | + | ||
| 260 | + Previously only one of these was included because _OMD.items() returns | ||
| 261 | + only the last value for each key. | ||
| 262 | + """ | ||
| 263 | + # Create two config files to be included. | ||
| 264 | + fp_inc1 = osp.join(rw_dir, "inc1.cfg") | ||
| 265 | + fp_inc2 = osp.join(rw_dir, "inc2.cfg") | ||
| 266 | + fp_main = osp.join(rw_dir, "main.cfg") | ||
| 267 | + | ||
| 268 | + with GitConfigParser(fp_inc1, read_only=False) as cw: | ||
| 269 | + cw.set_value("user", "name", "from-inc1") | ||
| 270 | + | ||
| 271 | + with GitConfigParser(fp_inc2, read_only=False) as cw: | ||
| 272 | + cw.set_value("core", "bar", "from-inc2") | ||
| 273 | + | ||
| 274 | + # Write a config with two path entries under a single [include] section. | ||
| 275 | + # We write it manually because set_value would overwrite the key. | ||
| 276 | + with open(fp_main, "w") as f: | ||
| 277 | + f.write("[include]\n") | ||
| 278 | + f.write(f"\tpath = {fp_inc1}\n") | ||
| 279 | + f.write(f"\tpath = {fp_inc2}\n") | ||
| 280 | + | ||
| 281 | + with GitConfigParser(fp_main, read_only=True) as cr: | ||
| 282 | + # Both included files should be loaded. | ||
| 283 | + assert cr.get_value("user", "name") == "from-inc1" | ||
| 284 | + assert cr.get_value("core", "bar") == "from-inc2" | ||
| 285 | + | ||
| 249 | 286 | @pytest.mark.xfail( | |
| 250 | 287 | sys.platform == "win32", | |
| 251 | 288 | reason='Second config._has_includes() assertion fails (for "config is included if path is matching git_dir")', | |
| Back | FazBrowse Home | New Git URL |
0 commit comments