Commit Diff


commit - fe61d0eba8abbe99778fc60f76538f880098b3a2
commit + a9bbc1604976b991408baba4e451459397467ee2
blob - 729170e3c5b2eed3b4629b86da9895e8e855c4f7
blob + f6772af586b57446e50879c6a63e15e48c0161d5
--- NEWS
+++ NEWS
@@ -1,5 +1,8 @@
 0.21.3	UNRELEASED
 
+ * Add support for ``worktreeconfig`` extension.
+   (Jelmer Vernooij)
+
 0.21.2	2023-01-18
 
  * Fix early file close bug in ``dulwich.pack.extend_pack``.
blob - e3faf8d12db1cc30b0f449743335830d599a1bc3
blob + d331e04e8141219df0f6cf6c4311443114a1429a
--- dulwich/repo.py
+++ dulwich/repo.py
@@ -685,6 +685,11 @@ class BaseRepo:
         Returns: `ConfigFile` object for the ``.git/config`` file.
         """
         raise NotImplementedError(self.get_config)
+
+    def get_worktree_config(self) -> "ConfigFile":
+        """Retrieve the worktree config object.
+        """
+        raise NotImplementedError(self.get_worktree_config)
 
     def get_description(self):
         """Retrieve the description for this repository.
@@ -711,11 +716,16 @@ class BaseRepo:
 
         Returns: `Config` instance for this repository
         """
-        from dulwich.config import StackedConfig
+        from dulwich.config import StackedConfig, ConfigFile
 
-        backends = [self.get_config()] + StackedConfig.default_backends()
-        return StackedConfig(backends, writable=backends[0])
+        local_config = self.get_config()
+        backends: List[ConfigFile] = [local_config]
+        if local_config.get_boolean((b"extensions", ), b"worktreeconfig", False):
+            backends.append(self.get_worktree_config())
 
+        backends += StackedConfig.default_backends()
+        return StackedConfig(backends, writable=local_config)
+
     def get_shallow(self) -> Set[ObjectID]:
         """Get the set of shallow commits.
 
@@ -1168,8 +1178,9 @@ class Repo(BaseRepo):
         if format_version not in (0, 1):
             raise UnsupportedVersion(format_version)
 
-        for extension in config.items((b"extensions", )):
-            raise UnsupportedExtension(extension)
+        for extension, _value in config.items((b"extensions", )):
+            if extension not in (b'worktreeconfig', ):
+                raise UnsupportedExtension(extension)
 
         if object_store is None:
             object_store = DiskObjectStore.from_config(
@@ -1594,6 +1605,16 @@ class Repo(BaseRepo):
             symlink_fn=self.symlink_fn,
         )
 
+    def get_worktree_config(self) -> "ConfigFile":
+        from dulwich.config import ConfigFile
+        path = os.path.join(self.commondir(), "config.worktree")
+        try:
+            return ConfigFile.from_path(path)
+        except FileNotFoundError:
+            cf = ConfigFile()
+            cf.path = path
+            return cf
+
     def get_config(self) -> "ConfigFile":
         """Retrieve the config object.
 
blob - 73c1aae4a775df87e32c4b20300c6ab921210363
blob + b3329800b233a7145bace72842dfe10f11995ffb
--- dulwich/tests/test_repository.py
+++ dulwich/tests/test_repository.py
@@ -1097,12 +1097,25 @@ class BuildRepoRootTests(TestCase):
         c.write_to_path()
         Repo(self._repo_dir)
 
-    def test_repositoryformatversion_1_extension(self):
+    def test_worktreeconfig_extension(self):
         r = self._repo
         c = r.get_config()
         c.set(("core",), "repositoryformatversion", "1")
         c.set(("extensions", ), "worktreeconfig", True)
         c.write_to_path()
+        c = r.get_worktree_config()
+        c.set(("user",), "repositoryformatversion", "1")
+        c.set((b"user",), b"name", b"Jelmer")
+        c.write_to_path()
+        cs = r.get_config_stack()
+        self.assertEqual(cs.get(("user", ), "name"), b"Jelmer")
+
+    def test_repositoryformatversion_1_extension(self):
+        r = self._repo
+        c = r.get_config()
+        c.set(("core",), "repositoryformatversion", "1")
+        c.set(("extensions", ), "unknownextension", True)
+        c.write_to_path()
         self.assertRaises(UnsupportedExtension, Repo, self._repo_dir)
 
     def test_commit_encoding_from_config(self):