Bläddra i källkod

Fix deprecation warnings (#1733)

Jelmer Vernooij 1 månad sedan
förälder
incheckning
6f46fc3318

+ 1 - 1
docs/tutorial/remote.txt

@@ -6,7 +6,7 @@ Most of the tests in this file require a Dulwich server, so let's start one:
     >>> from dulwich.server import DictBackend, TCPGitServer
     >>> from dulwich.server import DictBackend, TCPGitServer
     >>> import threading
     >>> import threading
     >>> repo = Repo.init("remote", mkdir=True)
     >>> repo = Repo.init("remote", mkdir=True)
-    >>> cid = repo.do_commit(b"message", committer=b"Jelmer <jelmer@samba.org>")
+    >>> cid = repo.get_worktree().commit(b"message", committer=b"Jelmer <jelmer@samba.org>")
     >>> backend = DictBackend({b'/': repo})
     >>> backend = DictBackend({b'/': repo})
     >>> dul_server = TCPGitServer(backend, b'localhost', 0)
     >>> dul_server = TCPGitServer(backend, b'localhost', 0)
     >>> server_thread = threading.Thread(target=dul_server.serve)
     >>> server_thread = threading.Thread(target=dul_server.serve)

+ 4 - 4
docs/tutorial/repo.txt

@@ -71,7 +71,7 @@ aren't tracked explicitly by git. Let's create a simple text file and stage it::
     >>> _ = f.write(b"monty")
     >>> _ = f.write(b"monty")
     >>> f.close()
     >>> f.close()
 
 
-    >>> repo.stage([b"foo"])
+    >>> repo.get_worktree().stage([b"foo"])
 
 
 It will now show up in the index::
 It will now show up in the index::
 
 
@@ -83,7 +83,7 @@ Creating new commits
 --------------------
 --------------------
 
 
 Now that we have staged a change, we can commit it. The easiest way to
 Now that we have staged a change, we can commit it. The easiest way to
-do this is by using ``Repo.do_commit``. It is also possible to manipulate
+do this is by using ``WorkTree.commit``. It is also possible to manipulate
 the lower-level objects involved in this, but we'll leave that for a
 the lower-level objects involved in this, but we'll leave that for a
 separate chapter of the tutorial.
 separate chapter of the tutorial.
 
 
@@ -91,10 +91,10 @@ To create a simple commit on the current branch, it is only necessary
 to specify the message. The committer and author will be retrieved from the
 to specify the message. The committer and author will be retrieved from the
 repository configuration or global configuration if they are not specified::
 repository configuration or global configuration if they are not specified::
 
 
-    >>> commit_id = repo.do_commit(
+    >>> commit_id = repo.get_worktree().commit(
     ...     b"The first commit", committer=b"Jelmer Vernooij <jelmer@samba.org>")
     ...     b"The first commit", committer=b"Jelmer Vernooij <jelmer@samba.org>")
 
 
-``do_commit`` returns the SHA1 of the commit. Since the commit was to the 
+``commit`` returns the SHA1 of the commit. Since the commit was to the 
 default branch, the repository's head will now be set to that commit::
 default branch, the repository's head will now be set to that commit::
 
 
     >>> repo.head() == commit_id
     >>> repo.head() == commit_id

+ 2 - 2
dulwich/client.py

@@ -901,7 +901,7 @@ class GitClient:
                     head = None
                     head = None
 
 
             if checkout and head is not None:
             if checkout and head is not None:
-                target.reset_index()
+                target.get_worktree().reset_index()
         except BaseException:
         except BaseException:
             if target is not None:
             if target is not None:
                 target.close()
                 target.close()
@@ -1699,7 +1699,7 @@ class SubprocessGitClient(TraditionalGitClient):
     def from_parsedurl(cls, parsedurl, **kwargs):
     def from_parsedurl(cls, parsedurl, **kwargs):
         return cls(**kwargs)
         return cls(**kwargs)
 
 
-    git_command = None
+    git_command: Optional[str] = None
 
 
     def _connect(
     def _connect(
         self,
         self,

+ 1 - 1
dulwich/diff_tree.py

@@ -46,7 +46,7 @@ _NULL_ENTRY = TreeEntry(None, None, None)
 _MAX_SCORE = 100
 _MAX_SCORE = 100
 RENAME_THRESHOLD = 60
 RENAME_THRESHOLD = 60
 MAX_FILES = 200
 MAX_FILES = 200
-REWRITE_THRESHOLD = None
+REWRITE_THRESHOLD: Optional[int] = None
 
 
 
 
 class TreeChange(namedtuple("TreeChange", ["type", "old", "new"])):
 class TreeChange(namedtuple("TreeChange", ["type", "old", "new"])):

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 208 - 120
dulwich/porcelain.py


+ 13 - 12
dulwich/repo.py

@@ -677,6 +677,7 @@ class BaseRepo:
 
 
     def head(self) -> bytes:
     def head(self) -> bytes:
         """Return the SHA1 pointed at by HEAD."""
         """Return the SHA1 pointed at by HEAD."""
+        # TODO: move this method to WorkTree
         return self.refs[b"HEAD"]
         return self.refs[b"HEAD"]
 
 
     def _get_object(self, sha, cls):
     def _get_object(self, sha, cls):
@@ -1000,7 +1001,7 @@ class BaseRepo:
             "Working tree operations not supported by this repository type"
             "Working tree operations not supported by this repository type"
         )
         )
 
 
-    @replace_me()
+    @replace_me(remove_in="0.26.0")
     def do_commit(
     def do_commit(
         self,
         self,
         message: Optional[bytes] = None,
         message: Optional[bytes] = None,
@@ -1441,7 +1442,7 @@ class Repo(BaseRepo):
         # missing index file, which is treated as empty.
         # missing index file, which is treated as empty.
         return not self.bare
         return not self.bare
 
 
-    @replace_me()
+    @replace_me(remove_in="0.26.0")
     def stage(
     def stage(
         self,
         self,
         fs_paths: Union[
         fs_paths: Union[
@@ -1455,7 +1456,7 @@ class Repo(BaseRepo):
         """
         """
         return self.get_worktree().stage(fs_paths)
         return self.get_worktree().stage(fs_paths)
 
 
-    @replace_me()
+    @replace_me(remove_in="0.26.0")
     def unstage(self, fs_paths: list[str]) -> None:
     def unstage(self, fs_paths: list[str]) -> None:
         """Unstage specific file in the index
         """Unstage specific file in the index
         Args:
         Args:
@@ -1547,7 +1548,7 @@ class Repo(BaseRepo):
                         head = None
                         head = None
 
 
                 if checkout and head is not None:
                 if checkout and head is not None:
-                    target.reset_index()
+                    target.get_worktree().reset_index()
             except BaseException:
             except BaseException:
                 target.close()
                 target.close()
                 raise
                 raise
@@ -1559,7 +1560,7 @@ class Repo(BaseRepo):
             raise
             raise
         return target
         return target
 
 
-    @replace_me()
+    @replace_me(remove_in="0.26.0")
     def reset_index(self, tree: Optional[bytes] = None):
     def reset_index(self, tree: Optional[bytes] = None):
         """Reset the index back to a specific tree.
         """Reset the index back to a specific tree.
 
 
@@ -1821,7 +1822,7 @@ class Repo(BaseRepo):
         with open(os.path.join(worktree_controldir, "HEAD"), "wb") as f:
         with open(os.path.join(worktree_controldir, "HEAD"), "wb") as f:
             f.write(main_repo.head() + b"\n")
             f.write(main_repo.head() + b"\n")
         r = cls(os.path.normpath(path))
         r = cls(os.path.normpath(path))
-        r.reset_index()
+        r.get_worktree().reset_index()
         return r
         return r
 
 
     @classmethod
     @classmethod
@@ -1989,22 +1990,22 @@ class Repo(BaseRepo):
 
 
         return GitAttributes(patterns)
         return GitAttributes(patterns)
 
 
-    @replace_me()
+    @replace_me(remove_in="0.26.0")
     def _sparse_checkout_file_path(self) -> str:
     def _sparse_checkout_file_path(self) -> str:
         """Return the path of the sparse-checkout file in this repo's control dir."""
         """Return the path of the sparse-checkout file in this repo's control dir."""
         return self.get_worktree()._sparse_checkout_file_path()
         return self.get_worktree()._sparse_checkout_file_path()
 
 
-    @replace_me()
+    @replace_me(remove_in="0.26.0")
     def configure_for_cone_mode(self) -> None:
     def configure_for_cone_mode(self) -> None:
         """Ensure the repository is configured for cone-mode sparse-checkout."""
         """Ensure the repository is configured for cone-mode sparse-checkout."""
         return self.get_worktree().configure_for_cone_mode()
         return self.get_worktree().configure_for_cone_mode()
 
 
-    @replace_me()
+    @replace_me(remove_in="0.26.0")
     def infer_cone_mode(self) -> bool:
     def infer_cone_mode(self) -> bool:
         """Return True if 'core.sparseCheckoutCone' is set to 'true' in config, else False."""
         """Return True if 'core.sparseCheckoutCone' is set to 'true' in config, else False."""
         return self.get_worktree().infer_cone_mode()
         return self.get_worktree().infer_cone_mode()
 
 
-    @replace_me()
+    @replace_me(remove_in="0.26.0")
     def get_sparse_checkout_patterns(self) -> list[str]:
     def get_sparse_checkout_patterns(self) -> list[str]:
         """Return a list of sparse-checkout patterns from info/sparse-checkout.
         """Return a list of sparse-checkout patterns from info/sparse-checkout.
 
 
@@ -2013,7 +2014,7 @@ class Repo(BaseRepo):
         """
         """
         return self.get_worktree().get_sparse_checkout_patterns()
         return self.get_worktree().get_sparse_checkout_patterns()
 
 
-    @replace_me()
+    @replace_me(remove_in="0.26.0")
     def set_sparse_checkout_patterns(self, patterns: list[str]) -> None:
     def set_sparse_checkout_patterns(self, patterns: list[str]) -> None:
         """Write the given sparse-checkout patterns into info/sparse-checkout.
         """Write the given sparse-checkout patterns into info/sparse-checkout.
 
 
@@ -2024,7 +2025,7 @@ class Repo(BaseRepo):
         """
         """
         return self.get_worktree().set_sparse_checkout_patterns(patterns)
         return self.get_worktree().set_sparse_checkout_patterns(patterns)
 
 
-    @replace_me()
+    @replace_me(remove_in="0.26.0")
     def set_cone_mode_patterns(self, dirs: Union[list[str], None] = None) -> None:
     def set_cone_mode_patterns(self, dirs: Union[list[str], None] = None) -> None:
         """Write the given cone-mode directory patterns into info/sparse-checkout.
         """Write the given cone-mode directory patterns into info/sparse-checkout.
 
 

+ 2 - 2
dulwich/stash.py

@@ -268,7 +268,7 @@ class Stash:
         # Create a dangling commit for the index state
         # Create a dangling commit for the index state
         # Note: We pass ref=None which is handled specially in do_commit
         # Note: We pass ref=None which is handled specially in do_commit
         # to create a commit without updating any reference
         # to create a commit without updating any reference
-        index_commit_id = self._repo.do_commit(
+        index_commit_id = self._repo.get_worktree().commit(
             tree=index_tree_id,
             tree=index_tree_id,
             message=b"Index stash",
             message=b"Index stash",
             merge_heads=[self._repo.head()],
             merge_heads=[self._repo.head()],
@@ -299,7 +299,7 @@ class Stash:
         # TODO(jelmer): Just pass parents into do_commit()?
         # TODO(jelmer): Just pass parents into do_commit()?
         self._repo.refs[self._ref] = self._repo.head()
         self._repo.refs[self._ref] = self._repo.head()
 
 
-        cid = self._repo.do_commit(
+        cid = self._repo.get_worktree().commit(
             ref=self._ref,
             ref=self._ref,
             tree=stash_tree_id,
             tree=stash_tree_id,
             message=message,
             message=message,

+ 1 - 1
dulwich/worktree.py

@@ -887,7 +887,7 @@ def add_worktree(
         wt_repo.refs.set_symbolic_ref(b"HEAD", branch)
         wt_repo.refs.set_symbolic_ref(b"HEAD", branch)
 
 
     # Reset index to match HEAD
     # Reset index to match HEAD
-    wt_repo.reset_index()
+    wt_repo.get_worktree().reset_index()
 
 
     return wt_repo
     return wt_repo
 
 

+ 1 - 1
examples/memoryrepo.py

@@ -27,7 +27,7 @@ local_repo.object_store.add_object(new_blob)
 last_tree.add(b"test", stat.S_IFREG, new_blob.id)
 last_tree.add(b"test", stat.S_IFREG, new_blob.id)
 local_repo.object_store.add_object(last_tree)
 local_repo.object_store.add_object(last_tree)
 
 
-local_repo.do_commit(
+local_repo.get_worktree().commit(
     message=b"Add a file called 'test'", ref=b"refs/heads/master", tree=last_tree.id
     message=b"Add a file called 'test'", ref=b"refs/heads/master", tree=last_tree.id
 )
 )
 
 

+ 8 - 6
examples/merge_driver.py

@@ -69,8 +69,10 @@ with open(config_path, "w") as f:
     json.dump(initial_config, f, indent=2)
     json.dump(initial_config, f, indent=2)
 
 
 # Add and commit initial files
 # Add and commit initial files
-repo.stage([".gitattributes", "config.json"])
-initial_commit = repo.do_commit(b"Initial commit", committer=b"Test <test@example.com>")
+repo.get_worktree().stage([".gitattributes", "config.json"])
+initial_commit = repo.get_worktree().commit(
+    b"Initial commit", committer=b"Test <test@example.com>"
+)
 
 
 # Register our custom merge driver globally
 # Register our custom merge driver globally
 registry = get_merge_driver_registry()
 registry = get_merge_driver_registry()
@@ -90,8 +92,8 @@ feature_config = {
 with open(config_path, "w") as f:
 with open(config_path, "w") as f:
     json.dump(feature_config, f, indent=2)
     json.dump(feature_config, f, indent=2)
 
 
-repo.stage(["config.json"])
-feature_commit = repo.do_commit(
+repo.get_worktree().stage(["config.json"])
+feature_commit = repo.get_worktree().commit(
     b"Add author and features", committer=b"Alice <alice@example.com>"
     b"Add author and features", committer=b"Alice <alice@example.com>"
 )
 )
 
 
@@ -108,8 +110,8 @@ master_config = {
 with open(config_path, "w") as f:
 with open(config_path, "w") as f:
     json.dump(master_config, f, indent=2)
     json.dump(master_config, f, indent=2)
 
 
-repo.stage(["config.json"])
-master_commit = repo.do_commit(
+repo.get_worktree().stage(["config.json"])
+master_commit = repo.get_worktree().commit(
     b"Add description and license", committer=b"Bob <bob@example.com>"
     b"Add description and license", committer=b"Bob <bob@example.com>"
 )
 )
 
 

+ 2 - 2
fuzzing/fuzz-targets/fuzz_repo.py

@@ -38,8 +38,8 @@ def TestOneInput(data) -> Optional[int]:
             return -1
             return -1
 
 
         try:
         try:
-            repo.stage(file_names)
-            repo.do_commit(
+            repo.get_worktree().stage(file_names)
+            repo.get_worktree().commit(
                 message=fdp.ConsumeRandomBytes(),
                 message=fdp.ConsumeRandomBytes(),
                 committer=fdp.ConsumeRandomBytes(),
                 committer=fdp.ConsumeRandomBytes(),
                 author=fdp.ConsumeRandomBytes(),
                 author=fdp.ConsumeRandomBytes(),

+ 1 - 1
tests/compat/test_client.py

@@ -130,7 +130,7 @@ class DulwichClientTestBase:
                 ("zop", "zop contents"),
                 ("zop", "zop contents"),
             ]:
             ]:
                 tree_id = self._add_file(local, tree_id, filename, contents)
                 tree_id = self._add_file(local, tree_id, filename, contents)
-                commit_id = local.do_commit(
+                commit_id = local.get_worktree().commit(
                     message=b"add " + filename.encode("utf-8"),
                     message=b"add " + filename.encode("utf-8"),
                     committer=b"Joe Example <joe@example.com>",
                     committer=b"Joe Example <joe@example.com>",
                     tree=tree_id,
                     tree=tree_id,

+ 2 - 2
tests/compat/test_dumb.py

@@ -191,7 +191,7 @@ class DumbHTTPClientNoPackTests(CompatTestCase):
                     dest_repo.refs[ref] = sha
                     dest_repo.refs[ref] = sha
 
 
             # Checkout files
             # Checkout files
-            dest_repo.reset_index()
+            dest_repo.get_worktree().reset_index()
 
 
             # Verify the clone
             # Verify the clone
             test_file = os.path.join(dest_path, "test0.txt")
             test_file = os.path.join(dest_path, "test0.txt")
@@ -245,7 +245,7 @@ class DumbHTTPClientNoPackTests(CompatTestCase):
                     dest_repo.refs[ref] = sha
                     dest_repo.refs[ref] = sha
 
 
             # Reset to new commit
             # Reset to new commit
-            dest_repo.reset_index()
+            dest_repo.get_worktree().reset_index()
 
 
             # Verify the new file exists
             # Verify the new file exists
             test_file2_dest = os.path.join(dest_path, "test2.txt")
             test_file2_dest = os.path.join(dest_path, "test2.txt")

+ 8 - 4
tests/compat/test_patch.py

@@ -53,9 +53,11 @@ class CompatPatchTestCase(CompatTestCase):
             with open(file_path, "w"):
             with open(file_path, "w"):
                 pass
                 pass
 
 
-        self.repo.stage(file_list)
+        self.repo.get_worktree().stage(file_list)
 
 
-        first_commit = self.repo.do_commit(b"The first commit")
+        first_commit = self.repo.get_worktree().commit(
+            message=b"The first commit",
+        )
 
 
         # Make a copy of the repository so we can apply the diff later
         # Make a copy of the repository so we can apply the diff later
         copy_path = os.path.join(self.test_dir, "copy")
         copy_path = os.path.join(self.test_dir, "copy")
@@ -70,9 +72,11 @@ class CompatPatchTestCase(CompatTestCase):
         with open(os.path.join(self.repo_path, "to_add"), "w"):
         with open(os.path.join(self.repo_path, "to_add"), "w"):
             pass
             pass
 
 
-        self.repo.stage(["to_modify", "to_delete", "to_add"])
+        self.repo.get_worktree().stage(["to_modify", "to_delete", "to_add"])
 
 
-        second_commit = self.repo.do_commit(b"The second commit")
+        second_commit = self.repo.get_worktree().commit(
+            message=b"The second commit",
+        )
 
 
         # Get the patch
         # Get the patch
         first_tree = self.repo[first_commit].tree
         first_tree = self.repo[first_commit].tree

+ 14 - 8
tests/contrib/test_swift_smoke.py

@@ -127,7 +127,7 @@ class SwiftRepoSmokeTest(unittest.TestCase):
 
 
         local_repo = repo.Repo.init(self.temp_d, mkdir=True)
         local_repo = repo.Repo.init(self.temp_d, mkdir=True)
         # Nothing in the staging area
         # Nothing in the staging area
-        local_repo.do_commit("Test commit", "fbo@localhost")
+        local_repo.get_worktree().commit("Test commit", "fbo@localhost")
         sha = local_repo.refs.read_loose_ref("refs/heads/master")
         sha = local_repo.refs.read_loose_ref("refs/heads/master")
         swift.SwiftRepo.init_bare(self.scon, self.conf)
         swift.SwiftRepo.init_bare(self.scon, self.conf)
         tcp_client = client.TCPGitClient(self.server_address, port=self.port)
         tcp_client = client.TCPGitClient(self.server_address, port=self.port)
@@ -144,7 +144,9 @@ class SwiftRepoSmokeTest(unittest.TestCase):
 
 
         local_repo = repo.Repo.init(self.temp_d, mkdir=True)
         local_repo = repo.Repo.init(self.temp_d, mkdir=True)
         # Nothing in the staging area
         # Nothing in the staging area
-        local_repo.do_commit("Test commit", "fbo@localhost", ref="refs/heads/mybranch")
+        local_repo.get_worktree().commit(
+            "Test commit", "fbo@localhost", ref="refs/heads/mybranch"
+        )
         sha = local_repo.refs.read_loose_ref("refs/heads/mybranch")
         sha = local_repo.refs.read_loose_ref("refs/heads/mybranch")
         swift.SwiftRepo.init_bare(self.scon, self.conf)
         swift.SwiftRepo.init_bare(self.scon, self.conf)
         tcp_client = client.TCPGitClient(self.server_address, port=self.port)
         tcp_client = client.TCPGitClient(self.server_address, port=self.port)
@@ -168,7 +170,7 @@ class SwiftRepoSmokeTest(unittest.TestCase):
         local_shas = {}
         local_shas = {}
         remote_shas = {}
         remote_shas = {}
         for branch in ("master", "mybranch", "pullr-108"):
         for branch in ("master", "mybranch", "pullr-108"):
-            local_shas[branch] = local_repo.do_commit(
+            local_shas[branch] = local_repo.get_worktree().commit(
                 f"Test commit {branch}",
                 f"Test commit {branch}",
                 "fbo@localhost",
                 "fbo@localhost",
                 ref=f"refs/heads/{branch}",
                 ref=f"refs/heads/{branch}",
@@ -194,8 +196,10 @@ class SwiftRepoSmokeTest(unittest.TestCase):
         for f in files:
         for f in files:
             open(os.path.join(self.temp_d, f), "w").write(f"DATA {i}")
             open(os.path.join(self.temp_d, f), "w").write(f"DATA {i}")
             i += 1
             i += 1
-        local_repo.stage(files)
-        local_repo.do_commit("Test commit", "fbo@localhost", ref="refs/heads/master")
+        local_repo.get_worktree().stage(files)
+        local_repo.get_worktree().commit(
+            "Test commit", "fbo@localhost", ref="refs/heads/master"
+        )
         swift.SwiftRepo.init_bare(self.scon, self.conf)
         swift.SwiftRepo.init_bare(self.scon, self.conf)
         tcp_client = client.TCPGitClient(self.server_address, port=self.port)
         tcp_client = client.TCPGitClient(self.server_address, port=self.port)
         tcp_client.send_pack(
         tcp_client.send_pack(
@@ -245,8 +249,10 @@ class SwiftRepoSmokeTest(unittest.TestCase):
         for f in files:
         for f in files:
             open(os.path.join(self.temp_d, f), "w").write(f"DATA {i}")
             open(os.path.join(self.temp_d, f), "w").write(f"DATA {i}")
             i += 1
             i += 1
-        local_repo.stage(files)
-        local_repo.do_commit("Test commit", "fbo@localhost", ref="refs/heads/master")
+        local_repo.get_worktree().stage(files)
+        local_repo.get_worktree().commit(
+            "Test commit", "fbo@localhost", ref="refs/heads/master"
+        )
         tcp_client.send_pack(
         tcp_client.send_pack(
             "/fakerepo", determine_wants, local_repo.generate_pack_data
             "/fakerepo", determine_wants, local_repo.generate_pack_data
         )
         )
@@ -277,7 +283,7 @@ class SwiftRepoSmokeTest(unittest.TestCase):
 
 
         local_repo = repo.Repo.init(self.temp_d, mkdir=True)
         local_repo = repo.Repo.init(self.temp_d, mkdir=True)
         # Nothing in the staging area
         # Nothing in the staging area
-        sha = local_repo.do_commit("Test commit", "fbo@localhost")
+        sha = local_repo.get_worktree().commit("Test commit", "fbo@localhost")
         otype, data = local_repo.object_store.get_raw(sha)
         otype, data = local_repo.object_store.get_raw(sha)
         commit = objects.ShaFile.from_raw_string(otype, data)
         commit = objects.ShaFile.from_raw_string(otype, data)
         tag = objects.Tag()
         tag = objects.Tag()

+ 3 - 3
tests/test_annotate.py

@@ -322,11 +322,11 @@ class IntegrationTestCase(TestCase):
             f.write(content)
             f.write(content)
 
 
         # Stage file
         # Stage file
-        self.repo.stage([filename.encode()])
+        self.repo.get_worktree().stage([filename.encode()])
 
 
         # Create commit
         # Create commit
-        commit_id = self.repo.do_commit(
-            message.encode(),
+        commit_id = self.repo.get_worktree().commit(
+            message=message.encode(),
             committer=b"Test Committer <test@example.com>",
             committer=b"Test Committer <test@example.com>",
             author=b"Test Author <test@example.com>",
             author=b"Test Author <test@example.com>",
             commit_timestamp=1000000000,
             commit_timestamp=1000000000,

+ 10 - 10
tests/test_cli.py

@@ -945,7 +945,7 @@ class FormatPatchCommandTest(DulwichCliTestCase):
         # Initial commit
         # Initial commit
         tree1 = Tree()
         tree1 = Tree()
         self.repo.object_store.add_object(tree1)
         self.repo.object_store.add_object(tree1)
-        self.repo.do_commit(
+        self.repo.get_worktree().commit(
             message=b"Initial commit",
             message=b"Initial commit",
             tree=tree1.id,
             tree=tree1.id,
         )
         )
@@ -956,7 +956,7 @@ class FormatPatchCommandTest(DulwichCliTestCase):
         tree2 = Tree()
         tree2 = Tree()
         tree2.add(b"hello.txt", 0o100644, blob.id)
         tree2.add(b"hello.txt", 0o100644, blob.id)
         self.repo.object_store.add_object(tree2)
         self.repo.object_store.add_object(tree2)
-        self.repo.do_commit(
+        self.repo.get_worktree().commit(
             message=b"Add hello.txt",
             message=b"Add hello.txt",
             tree=tree2.id,
             tree=tree2.id,
         )
         )
@@ -990,7 +990,7 @@ class FormatPatchCommandTest(DulwichCliTestCase):
         # Initial commit
         # Initial commit
         tree1 = Tree()
         tree1 = Tree()
         self.repo.object_store.add_object(tree1)
         self.repo.object_store.add_object(tree1)
-        self.repo.do_commit(
+        self.repo.get_worktree().commit(
             message=b"Initial commit",
             message=b"Initial commit",
             tree=tree1.id,
             tree=tree1.id,
         )
         )
@@ -1001,7 +1001,7 @@ class FormatPatchCommandTest(DulwichCliTestCase):
         tree2 = Tree()
         tree2 = Tree()
         tree2.add(b"file1.txt", 0o100644, blob1.id)
         tree2.add(b"file1.txt", 0o100644, blob1.id)
         self.repo.object_store.add_object(tree2)
         self.repo.object_store.add_object(tree2)
-        self.repo.do_commit(
+        self.repo.get_worktree().commit(
             message=b"Add file1.txt",
             message=b"Add file1.txt",
             tree=tree2.id,
             tree=tree2.id,
         )
         )
@@ -1013,7 +1013,7 @@ class FormatPatchCommandTest(DulwichCliTestCase):
         tree3.add(b"file1.txt", 0o100644, blob1.id)
         tree3.add(b"file1.txt", 0o100644, blob1.id)
         tree3.add(b"file2.txt", 0o100644, blob2.id)
         tree3.add(b"file2.txt", 0o100644, blob2.id)
         self.repo.object_store.add_object(tree3)
         self.repo.object_store.add_object(tree3)
-        self.repo.do_commit(
+        self.repo.get_worktree().commit(
             message=b"Add file2.txt",
             message=b"Add file2.txt",
             tree=tree3.id,
             tree=tree3.id,
         )
         )
@@ -1049,7 +1049,7 @@ class FormatPatchCommandTest(DulwichCliTestCase):
         tree = Tree()
         tree = Tree()
         tree.add(b"test.txt", 0o100644, blob.id)
         tree.add(b"test.txt", 0o100644, blob.id)
         self.repo.object_store.add_object(tree)
         self.repo.object_store.add_object(tree)
-        self.repo.do_commit(
+        self.repo.get_worktree().commit(
             message=b"Test commit",
             message=b"Test commit",
             tree=tree.id,
             tree=tree.id,
         )
         )
@@ -1083,7 +1083,7 @@ class FormatPatchCommandTest(DulwichCliTestCase):
         tree0 = Tree()
         tree0 = Tree()
         self.repo.object_store.add_object(tree0)
         self.repo.object_store.add_object(tree0)
         trees.append(tree0)
         trees.append(tree0)
-        c0 = self.repo.do_commit(
+        c0 = self.repo.get_worktree().commit(
             message=b"Initial commit",
             message=b"Initial commit",
             tree=tree0.id,
             tree=tree0.id,
         )
         )
@@ -1103,7 +1103,7 @@ class FormatPatchCommandTest(DulwichCliTestCase):
             self.repo.object_store.add_object(tree)
             self.repo.object_store.add_object(tree)
             trees.append(tree)
             trees.append(tree)
 
 
-            c = self.repo.do_commit(
+            c = self.repo.get_worktree().commit(
                 message=f"Add file{i}.txt".encode(),
                 message=f"Add file{i}.txt".encode(),
                 tree=tree.id,
                 tree=tree.id,
             )
             )
@@ -1145,7 +1145,7 @@ class FormatPatchCommandTest(DulwichCliTestCase):
         self.repo.object_store.add_object(blob1)
         self.repo.object_store.add_object(blob1)
         tree1.add(b"file.txt", 0o100644, blob1.id)
         tree1.add(b"file.txt", 0o100644, blob1.id)
         self.repo.object_store.add_object(tree1)
         self.repo.object_store.add_object(tree1)
-        self.repo.do_commit(
+        self.repo.get_worktree().commit(
             message=b"Initial commit",
             message=b"Initial commit",
             tree=tree1.id,
             tree=tree1.id,
         )
         )
@@ -1155,7 +1155,7 @@ class FormatPatchCommandTest(DulwichCliTestCase):
         self.repo.object_store.add_object(blob2)
         self.repo.object_store.add_object(blob2)
         tree2.add(b"file.txt", 0o100644, blob2.id)
         tree2.add(b"file.txt", 0o100644, blob2.id)
         self.repo.object_store.add_object(tree2)
         self.repo.object_store.add_object(tree2)
-        self.repo.do_commit(
+        self.repo.get_worktree().commit(
             message=b"Modify file.txt",
             message=b"Modify file.txt",
             tree=tree2.id,
             tree=tree2.id,
         )
         )

+ 4 - 4
tests/test_cli_cherry_pick.py

@@ -52,7 +52,7 @@ class CherryPickCommandTests(TestCase):
 
 
                 # Create a branch and switch to it
                 # Create a branch and switch to it
                 porcelain.branch_create(".", "feature")
                 porcelain.branch_create(".", "feature")
-                porcelain.checkout_branch(".", "feature")
+                porcelain.checkout(".", "feature")
 
 
                 # Add a file on feature branch
                 # Add a file on feature branch
                 with open("file2.txt", "w") as f:
                 with open("file2.txt", "w") as f:
@@ -61,7 +61,7 @@ class CherryPickCommandTests(TestCase):
                 feature_commit = porcelain.commit(".", message=b"Add feature file")
                 feature_commit = porcelain.commit(".", message=b"Add feature file")
 
 
                 # Go back to master
                 # Go back to master
-                porcelain.checkout_branch(".", "master")
+                porcelain.checkout(".", "master")
 
 
                 # Cherry-pick via CLI
                 # Cherry-pick via CLI
                 cmd = cmd_cherry_pick()
                 cmd = cmd_cherry_pick()
@@ -91,7 +91,7 @@ class CherryPickCommandTests(TestCase):
 
 
                 # Create a branch and switch to it
                 # Create a branch and switch to it
                 porcelain.branch_create(".", "feature")
                 porcelain.branch_create(".", "feature")
-                porcelain.checkout_branch(".", "feature")
+                porcelain.checkout(".", "feature")
 
 
                 # Add a file on feature branch
                 # Add a file on feature branch
                 with open("file2.txt", "w") as f:
                 with open("file2.txt", "w") as f:
@@ -100,7 +100,7 @@ class CherryPickCommandTests(TestCase):
                 feature_commit = porcelain.commit(".", message=b"Add feature file")
                 feature_commit = porcelain.commit(".", message=b"Add feature file")
 
 
                 # Go back to master
                 # Go back to master
-                porcelain.checkout_branch(".", "master")
+                porcelain.checkout(".", "master")
 
 
                 # Cherry-pick with --no-commit
                 # Cherry-pick with --no-commit
                 cmd = cmd_cherry_pick()
                 cmd = cmd_cherry_pick()

+ 10 - 10
tests/test_cli_merge.py

@@ -50,7 +50,7 @@ class CLIMergeTests(TestCase):
 
 
             # Create a branch
             # Create a branch
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             # Add a file on feature branch
             # Add a file on feature branch
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
@@ -59,7 +59,7 @@ class CLIMergeTests(TestCase):
             porcelain.commit(tmpdir, message=b"Add feature")
             porcelain.commit(tmpdir, message=b"Add feature")
 
 
             # Go back to master
             # Go back to master
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
 
 
             # Test merge via CLI
             # Test merge via CLI
             old_cwd = os.getcwd()
             old_cwd = os.getcwd()
@@ -91,14 +91,14 @@ class CLIMergeTests(TestCase):
 
 
             # Create a branch and modify file1
             # Create a branch and modify file1
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Feature content\n")
                 f.write("Feature content\n")
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.commit(tmpdir, message=b"Modify file1 in feature")
             porcelain.commit(tmpdir, message=b"Modify file1 in feature")
 
 
             # Go back to master and modify file1 differently
             # Go back to master and modify file1 differently
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Master content\n")
                 f.write("Master content\n")
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.add(tmpdir, paths=["file1.txt"])
@@ -157,7 +157,7 @@ class CLIMergeTests(TestCase):
 
 
             # Create a branch
             # Create a branch
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             # Add a file on feature branch
             # Add a file on feature branch
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
@@ -166,7 +166,7 @@ class CLIMergeTests(TestCase):
             porcelain.commit(tmpdir, message=b"Add feature")
             porcelain.commit(tmpdir, message=b"Add feature")
 
 
             # Go back to master and add another file
             # Go back to master and add another file
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
             with open(os.path.join(tmpdir, "file3.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file3.txt"), "w") as f:
                 f.write("Master content\n")
                 f.write("Master content\n")
             porcelain.add(tmpdir, paths=["file3.txt"])
             porcelain.add(tmpdir, paths=["file3.txt"])
@@ -203,7 +203,7 @@ class CLIMergeTests(TestCase):
 
 
             # Create a branch
             # Create a branch
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             # Add a file on feature branch
             # Add a file on feature branch
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
@@ -212,7 +212,7 @@ class CLIMergeTests(TestCase):
             porcelain.commit(tmpdir, message=b"Add feature")
             porcelain.commit(tmpdir, message=b"Add feature")
 
 
             # Go back to master
             # Go back to master
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
 
 
             # Test merge via CLI with --no-ff
             # Test merge via CLI with --no-ff
             old_cwd = os.getcwd()
             old_cwd = os.getcwd()
@@ -242,7 +242,7 @@ class CLIMergeTests(TestCase):
 
 
             # Create a branch
             # Create a branch
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             # Add a file on feature branch
             # Add a file on feature branch
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
@@ -251,7 +251,7 @@ class CLIMergeTests(TestCase):
             porcelain.commit(tmpdir, message=b"Add feature")
             porcelain.commit(tmpdir, message=b"Add feature")
 
 
             # Go back to master and add another file
             # Go back to master and add another file
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
             with open(os.path.join(tmpdir, "file3.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file3.txt"), "w") as f:
                 f.write("Master content\n")
                 f.write("Master content\n")
             porcelain.add(tmpdir, paths=["file3.txt"])
             porcelain.add(tmpdir, paths=["file3.txt"])

+ 30 - 6
tests/test_grafts.py

@@ -159,9 +159,15 @@ class GraftsInRepoTests(GraftsInRepositoryBase, TestCase):
             "author_timezone": 0,
             "author_timezone": 0,
         }
         }
 
 
-        self._shas.append(r.do_commit(b"empty commit", **commit_kwargs))
-        self._shas.append(r.do_commit(b"empty commit", **commit_kwargs))
-        self._shas.append(r.do_commit(b"empty commit", **commit_kwargs))
+        self._shas.append(
+            r.get_worktree().commit(message=b"empty commit", **commit_kwargs)
+        )
+        self._shas.append(
+            r.get_worktree().commit(message=b"empty commit", **commit_kwargs)
+        )
+        self._shas.append(
+            r.get_worktree().commit(message=b"empty commit", **commit_kwargs)
+        )
 
 
     def test_init_with_empty_info_grafts(self) -> None:
     def test_init_with_empty_info_grafts(self) -> None:
         r = self._repo
         r = self._repo
@@ -191,6 +197,7 @@ class GraftsInMemoryRepoTests(GraftsInRepositoryBase, TestCase):
         self._shas = []
         self._shas = []
 
 
         tree = Tree()
         tree = Tree()
+        r.object_store.add_object(tree)
 
 
         commit_kwargs = {
         commit_kwargs = {
             "committer": b"Test Committer <test@nodomain.com>",
             "committer": b"Test Committer <test@nodomain.com>",
@@ -202,6 +209,23 @@ class GraftsInMemoryRepoTests(GraftsInRepositoryBase, TestCase):
             "tree": tree.id,
             "tree": tree.id,
         }
         }
 
 
-        self._shas.append(r.do_commit(b"empty commit", **commit_kwargs))
-        self._shas.append(r.do_commit(b"empty commit", **commit_kwargs))
-        self._shas.append(r.do_commit(b"empty commit", **commit_kwargs))
+        # Create commits directly for MemoryRepo since it doesn't support worktree
+        from dulwich.objects import Commit
+
+        for i in range(3):
+            c = Commit()
+            c.message = b"empty commit"
+            c.committer = commit_kwargs["committer"]
+            c.author = commit_kwargs["author"]
+            c.commit_time = commit_kwargs["commit_timestamp"]
+            c.commit_timezone = commit_kwargs["commit_timezone"]
+            c.author_time = commit_kwargs["author_timestamp"]
+            c.author_timezone = commit_kwargs["author_timezone"]
+            c.tree = commit_kwargs["tree"]
+            if self._shas:
+                c.parents = [self._shas[-1]]
+            r.object_store.add_object(c)
+            self._shas.append(c.id)
+
+        # Set HEAD to point to the last commit
+        r.refs[b"HEAD"] = self._shas[-1]

+ 24 - 20
tests/test_index.py

@@ -837,11 +837,11 @@ class GetUnstagedChangesTests(TestCase):
             with open(foo2_fullpath, "wb") as f:
             with open(foo2_fullpath, "wb") as f:
                 f.write(b"origstuff")
                 f.write(b"origstuff")
 
 
-            repo.stage(["foo1", "foo2"])
-            repo.do_commit(
-                b"test status",
-                author=b"author <email>",
+            repo.get_worktree().stage(["foo1", "foo2"])
+            repo.get_worktree().commit(
+                message=b"test status",
                 committer=b"committer <email>",
                 committer=b"committer <email>",
+                author=b"author <email>",
             )
             )
 
 
             with open(foo1_fullpath, "wb") as f:
             with open(foo1_fullpath, "wb") as f:
@@ -864,11 +864,11 @@ class GetUnstagedChangesTests(TestCase):
             with open(foo1_fullpath, "wb") as f:
             with open(foo1_fullpath, "wb") as f:
                 f.write(b"origstuff")
                 f.write(b"origstuff")
 
 
-            repo.stage(["foo1"])
-            repo.do_commit(
-                b"test status",
-                author=b"author <email>",
+            repo.get_worktree().stage(["foo1"])
+            repo.get_worktree().commit(
+                message=b"test status",
                 committer=b"committer <email>",
                 committer=b"committer <email>",
+                author=b"author <email>",
             )
             )
 
 
             os.unlink(foo1_fullpath)
             os.unlink(foo1_fullpath)
@@ -887,11 +887,11 @@ class GetUnstagedChangesTests(TestCase):
             with open(foo1_fullpath, "wb") as f:
             with open(foo1_fullpath, "wb") as f:
                 f.write(b"origstuff")
                 f.write(b"origstuff")
 
 
-            repo.stage(["foo1"])
-            repo.do_commit(
-                b"test status",
-                author=b"author <email>",
+            repo.get_worktree().stage(["foo1"])
+            repo.get_worktree().commit(
+                message=b"test status",
                 committer=b"committer <email>",
                 committer=b"committer <email>",
+                author=b"author <email>",
             )
             )
 
 
             os.remove(foo1_fullpath)
             os.remove(foo1_fullpath)
@@ -912,11 +912,11 @@ class GetUnstagedChangesTests(TestCase):
             with open(foo1_fullpath, "wb") as f:
             with open(foo1_fullpath, "wb") as f:
                 f.write(b"origstuff")
                 f.write(b"origstuff")
 
 
-            repo.stage(["foo1"])
-            repo.do_commit(
-                b"test status",
-                author=b"author <email>",
+            repo.get_worktree().stage(["foo1"])
+            repo.get_worktree().commit(
+                message=b"test status",
                 committer=b"committer <email>",
                 committer=b"committer <email>",
+                author=b"author <email>",
             )
             )
 
 
             os.remove(foo1_fullpath)
             os.remove(foo1_fullpath)
@@ -1184,8 +1184,10 @@ class TestIndexEntryFromPath(TestCase):
         with open(test_file, "wb") as f:
         with open(test_file, "wb") as f:
             f.write(b"test content")
             f.write(b"test content")
 
 
-        submodule_repo.stage(["testfile"])
-        commit_id = submodule_repo.do_commit(b"Test commit for submodule")
+        submodule_repo.get_worktree().stage(["testfile"])
+        commit_id = submodule_repo.get_worktree().commit(
+            message=b"Test commit for submodule",
+        )
 
 
         # Test reading the HEAD
         # Test reading the HEAD
         head_sha = read_submodule_head(sub_repo_dir)
         head_sha = read_submodule_head(sub_repo_dir)
@@ -1241,8 +1243,10 @@ class TestIndexEntryFromPath(TestCase):
         with open(test_file, "wb") as f:
         with open(test_file, "wb") as f:
             f.write(b"test content")
             f.write(b"test content")
 
 
-        submodule_repo.stage(["testfile"])
-        commit_id = submodule_repo.do_commit(b"Test commit for submodule")
+        submodule_repo.get_worktree().stage(["testfile"])
+        commit_id = submodule_repo.get_worktree().commit(
+            message=b"Test commit for submodule",
+        )
 
 
         # Create an entry with the correct commit SHA
         # Create an entry with the correct commit SHA
         correct_entry = IndexEntry(
         correct_entry = IndexEntry(

+ 2 - 2
tests/test_lfs.py

@@ -238,7 +238,7 @@ class LFSIntegrationTests(TestCase):
             f.write(large_content)
             f.write(large_content)
 
 
         # Add files to repo
         # Add files to repo
-        self.repo.stage([".gitattributes", "large.bin"])
+        self.repo.get_worktree().stage([".gitattributes", "large.bin"])
 
 
         # Get the blob for large.bin from the index
         # Get the blob for large.bin from the index
         index = self.repo.open_index()
         index = self.repo.open_index()
@@ -390,7 +390,7 @@ class LFSIntegrationTests(TestCase):
         porcelain.commit(self.repo, message=b"Add LFS file")
         porcelain.commit(self.repo, message=b"Add LFS file")
 
 
         # Reset index to trigger checkout with filter
         # Reset index to trigger checkout with filter
-        self.repo.reset_index()
+        self.repo.get_worktree().reset_index()
 
 
         # Check file content
         # Check file content
         with open(pointer_file, "rb") as f:
         with open(pointer_file, "rb") as f:

+ 6 - 6
tests/test_porcelain.py

@@ -6260,14 +6260,14 @@ class ReceivePackTests(PorcelainTestCase):
         with open(fullpath, "w") as f:
         with open(fullpath, "w") as f:
             f.write("stuff")
             f.write("stuff")
         porcelain.add(repo=self.repo.path, paths=fullpath)
         porcelain.add(repo=self.repo.path, paths=fullpath)
-        self.repo.do_commit(
+        self.repo.get_worktree().commit(
             message=b"test status",
             message=b"test status",
-            author=b"author <email>",
             committer=b"committer <email>",
             committer=b"committer <email>",
-            author_timestamp=1402354300,
+            author=b"author <email>",
             commit_timestamp=1402354300,
             commit_timestamp=1402354300,
-            author_timezone=0,
             commit_timezone=0,
             commit_timezone=0,
+            author_timestamp=1402354300,
+            author_timezone=0,
         )
         )
         outf = BytesIO()
         outf = BytesIO()
         exitcode = porcelain.receive_pack(self.repo.path, BytesIO(b"0000"), outf)
         exitcode = porcelain.receive_pack(self.repo.path, BytesIO(b"0000"), outf)
@@ -6837,7 +6837,7 @@ class CheckIgnoreTests(PorcelainTestCase):
         path = os.path.join(self.repo.path, "foo")
         path = os.path.join(self.repo.path, "foo")
         with open(path, "w") as f:
         with open(path, "w") as f:
             f.write("BAR")
             f.write("BAR")
-        self.repo.stage(["foo"])
+        self.repo.get_worktree().stage(["foo"])
         with open(os.path.join(self.repo.path, ".gitignore"), "w") as f:
         with open(os.path.join(self.repo.path, ".gitignore"), "w") as f:
             f.write("foo\n")
             f.write("foo\n")
         self.assertEqual([], list(porcelain.check_ignore(self.repo, [path])))
         self.assertEqual([], list(porcelain.check_ignore(self.repo, [path])))
@@ -6849,7 +6849,7 @@ class CheckIgnoreTests(PorcelainTestCase):
     def test_check_added_rel(self) -> None:
     def test_check_added_rel(self) -> None:
         with open(os.path.join(self.repo.path, "foo"), "w") as f:
         with open(os.path.join(self.repo.path, "foo"), "w") as f:
             f.write("BAR")
             f.write("BAR")
-        self.repo.stage(["foo"])
+        self.repo.get_worktree().stage(["foo"])
         with open(os.path.join(self.repo.path, ".gitignore"), "w") as f:
         with open(os.path.join(self.repo.path, ".gitignore"), "w") as f:
             f.write("foo\n")
             f.write("foo\n")
         cwd = os.getcwd()
         cwd = os.getcwd()

+ 9 - 9
tests/test_porcelain_cherry_pick.py

@@ -46,7 +46,7 @@ class PorcelainCherryPickTests(TestCase):
 
 
             # Create a branch and switch to it
             # Create a branch and switch to it
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             # Add a file on feature branch
             # Add a file on feature branch
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
@@ -55,7 +55,7 @@ class PorcelainCherryPickTests(TestCase):
             feature_commit = porcelain.commit(tmpdir, message=b"Add feature file")
             feature_commit = porcelain.commit(tmpdir, message=b"Add feature file")
 
 
             # Go back to master
             # Go back to master
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
 
 
             # Cherry-pick the feature commit
             # Cherry-pick the feature commit
             new_commit = porcelain.cherry_pick(tmpdir, feature_commit)
             new_commit = porcelain.cherry_pick(tmpdir, feature_commit)
@@ -81,7 +81,7 @@ class PorcelainCherryPickTests(TestCase):
 
 
             # Create a branch and switch to it
             # Create a branch and switch to it
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             # Add a file on feature branch
             # Add a file on feature branch
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
@@ -90,7 +90,7 @@ class PorcelainCherryPickTests(TestCase):
             feature_commit = porcelain.commit(tmpdir, message=b"Add feature file")
             feature_commit = porcelain.commit(tmpdir, message=b"Add feature file")
 
 
             # Go back to master
             # Go back to master
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
 
 
             # Cherry-pick with no-commit
             # Cherry-pick with no-commit
             result = porcelain.cherry_pick(tmpdir, feature_commit, no_commit=True)
             result = porcelain.cherry_pick(tmpdir, feature_commit, no_commit=True)
@@ -119,7 +119,7 @@ class PorcelainCherryPickTests(TestCase):
 
 
             # Create a branch and modify the file
             # Create a branch and modify the file
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Feature modification\n")
                 f.write("Feature modification\n")
@@ -127,7 +127,7 @@ class PorcelainCherryPickTests(TestCase):
             feature_commit = porcelain.commit(tmpdir, message=b"Modify file on feature")
             feature_commit = porcelain.commit(tmpdir, message=b"Modify file on feature")
 
 
             # Go back to master and make a different modification
             # Go back to master and make a different modification
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Master modification\n")
                 f.write("Master modification\n")
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.add(tmpdir, paths=["file1.txt"])
@@ -154,7 +154,7 @@ class PorcelainCherryPickTests(TestCase):
 
 
             # Create another branch with a different initial commit
             # Create another branch with a different initial commit
             porcelain.branch_create(tmpdir, "other")
             porcelain.branch_create(tmpdir, "other")
-            porcelain.checkout_branch(tmpdir, "other")
+            porcelain.checkout(tmpdir, "other")
 
 
             # Try to cherry-pick root commit - should fail
             # Try to cherry-pick root commit - should fail
             with self.assertRaises(porcelain.Error) as cm:
             with self.assertRaises(porcelain.Error) as cm:
@@ -176,7 +176,7 @@ class PorcelainCherryPickTests(TestCase):
 
 
             # Create branch and make conflicting changes
             # Create branch and make conflicting changes
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Feature content\n")
                 f.write("Feature content\n")
@@ -184,7 +184,7 @@ class PorcelainCherryPickTests(TestCase):
             feature_commit = porcelain.commit(tmpdir, message=b"Feature change")
             feature_commit = porcelain.commit(tmpdir, message=b"Feature change")
 
 
             # Go back to master and make different change
             # Go back to master and make different change
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Master content\n")
                 f.write("Master content\n")
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.add(tmpdir, paths=["file1.txt"])

+ 1 - 1
tests/test_porcelain_filters.py

@@ -207,7 +207,7 @@ class PorcelainFilterTests(TestCase):
         target_config.write_to_path()
         target_config.write_to_path()
 
 
         # Now checkout the files with autocrlf enabled
         # Now checkout the files with autocrlf enabled
-        target_repo.reset_index()
+        target_repo.get_worktree().reset_index()
 
 
         # Check that the working tree file has CRLF endings
         # Check that the working tree file has CRLF endings
         target_file = os.path.join(target_dir, "test.txt")
         target_file = os.path.join(target_dir, "test.txt")

+ 16 - 16
tests/test_porcelain_merge.py

@@ -48,7 +48,7 @@ class PorcelainMergeTests(TestCase):
 
 
             # Create a branch
             # Create a branch
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             # Add a file on feature branch
             # Add a file on feature branch
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
@@ -57,7 +57,7 @@ class PorcelainMergeTests(TestCase):
             feature_commit = porcelain.commit(tmpdir, message=b"Add feature")
             feature_commit = porcelain.commit(tmpdir, message=b"Add feature")
 
 
             # Go back to master
             # Go back to master
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
 
 
             # Merge feature branch (should fast-forward)
             # Merge feature branch (should fast-forward)
             merge_commit, conflicts = porcelain.merge(tmpdir, "feature")
             merge_commit, conflicts = porcelain.merge(tmpdir, "feature")
@@ -100,7 +100,7 @@ class PorcelainMergeTests(TestCase):
 
 
             # Create a branch
             # Create a branch
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             # Add a file on feature branch
             # Add a file on feature branch
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
@@ -109,7 +109,7 @@ class PorcelainMergeTests(TestCase):
             feature_commit = porcelain.commit(tmpdir, message=b"Add feature")
             feature_commit = porcelain.commit(tmpdir, message=b"Add feature")
 
 
             # Go back to master
             # Go back to master
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
 
 
             # Merge feature branch with no-ff
             # Merge feature branch with no-ff
             merge_commit, conflicts = porcelain.merge(tmpdir, "feature", no_ff=True)
             merge_commit, conflicts = porcelain.merge(tmpdir, "feature", no_ff=True)
@@ -140,14 +140,14 @@ class PorcelainMergeTests(TestCase):
 
 
             # Create a branch and modify file1
             # Create a branch and modify file1
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Feature content\n")
                 f.write("Feature content\n")
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.commit(tmpdir, message=b"Modify file1 in feature")
             porcelain.commit(tmpdir, message=b"Modify file1 in feature")
 
 
             # Go back to master and modify file2
             # Go back to master and modify file2
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
                 f.write("Master file2\n")
                 f.write("Master file2\n")
             porcelain.add(tmpdir, paths=["file2.txt"])
             porcelain.add(tmpdir, paths=["file2.txt"])
@@ -179,14 +179,14 @@ class PorcelainMergeTests(TestCase):
 
 
             # Create a branch and modify file1
             # Create a branch and modify file1
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Feature content\n")
                 f.write("Feature content\n")
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.commit(tmpdir, message=b"Modify file1 in feature")
             porcelain.commit(tmpdir, message=b"Modify file1 in feature")
 
 
             # Go back to master and modify file1 differently
             # Go back to master and modify file1 differently
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Master content\n")
                 f.write("Master content\n")
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.add(tmpdir, paths=["file1.txt"])
@@ -220,7 +220,7 @@ class PorcelainMergeTests(TestCase):
 
 
             # Create a branch
             # Create a branch
             porcelain.branch_create(tmpdir, "feature")
             porcelain.branch_create(tmpdir, "feature")
-            porcelain.checkout_branch(tmpdir, "feature")
+            porcelain.checkout(tmpdir, "feature")
 
 
             # Add a file on feature branch
             # Add a file on feature branch
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
@@ -229,7 +229,7 @@ class PorcelainMergeTests(TestCase):
             porcelain.commit(tmpdir, message=b"Add feature")
             porcelain.commit(tmpdir, message=b"Add feature")
 
 
             # Go back to master and add another file
             # Go back to master and add another file
-            porcelain.checkout_branch(tmpdir, "master")
+            porcelain.checkout(tmpdir, "master")
             with open(os.path.join(tmpdir, "file3.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file3.txt"), "w") as f:
                 f.write("Master content\n")
                 f.write("Master content\n")
             porcelain.add(tmpdir, paths=["file3.txt"])
             porcelain.add(tmpdir, paths=["file3.txt"])
@@ -293,7 +293,7 @@ class PorcelainMergeTreeTests(TestCase):
 
 
             # Create our branch
             # Create our branch
             porcelain.branch_create(tmpdir, "ours")
             porcelain.branch_create(tmpdir, "ours")
-            porcelain.checkout_branch(tmpdir, "ours")
+            porcelain.checkout(tmpdir, "ours")
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Our content\n")
                 f.write("Our content\n")
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file2.txt"), "w") as f:
@@ -302,9 +302,9 @@ class PorcelainMergeTreeTests(TestCase):
             our_commit = porcelain.commit(tmpdir, message=b"Our commit")
             our_commit = porcelain.commit(tmpdir, message=b"Our commit")
 
 
             # Create their branch
             # Create their branch
-            porcelain.checkout_branch(tmpdir, b"master")
+            porcelain.checkout(tmpdir, b"master")
             porcelain.branch_create(tmpdir, "theirs")
             porcelain.branch_create(tmpdir, "theirs")
-            porcelain.checkout_branch(tmpdir, "theirs")
+            porcelain.checkout(tmpdir, "theirs")
             with open(os.path.join(tmpdir, "file3.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file3.txt"), "w") as f:
                 f.write("Their new file\n")
                 f.write("Their new file\n")
             porcelain.add(tmpdir, paths=["file3.txt"])
             porcelain.add(tmpdir, paths=["file3.txt"])
@@ -340,16 +340,16 @@ class PorcelainMergeTreeTests(TestCase):
 
 
             # Create our branch with changes
             # Create our branch with changes
             porcelain.branch_create(tmpdir, "ours")
             porcelain.branch_create(tmpdir, "ours")
-            porcelain.checkout_branch(tmpdir, "ours")
+            porcelain.checkout(tmpdir, "ours")
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Our content\n")
                 f.write("Our content\n")
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.add(tmpdir, paths=["file1.txt"])
             our_commit = porcelain.commit(tmpdir, message=b"Our commit")
             our_commit = porcelain.commit(tmpdir, message=b"Our commit")
 
 
             # Create their branch with conflicting changes
             # Create their branch with conflicting changes
-            porcelain.checkout_branch(tmpdir, b"master")
+            porcelain.checkout(tmpdir, b"master")
             porcelain.branch_create(tmpdir, "theirs")
             porcelain.branch_create(tmpdir, "theirs")
-            porcelain.checkout_branch(tmpdir, "theirs")
+            porcelain.checkout(tmpdir, "theirs")
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
             with open(os.path.join(tmpdir, "file1.txt"), "w") as f:
                 f.write("Their content\n")
                 f.write("Their content\n")
             porcelain.add(tmpdir, paths=["file1.txt"])
             porcelain.add(tmpdir, paths=["file1.txt"])

+ 6 - 6
tests/test_rebase.py

@@ -385,9 +385,9 @@ class RebasePorcelainTestCase(TestCase):
         with open(os.path.join(self.test_dir, "README.md"), "wb") as f:
         with open(os.path.join(self.test_dir, "README.md"), "wb") as f:
             f.write(b"# Test Repository\n")
             f.write(b"# Test Repository\n")
 
 
-        self.repo.stage(["README.md"])
-        self.initial_commit = self.repo.do_commit(
-            b"Initial commit",
+        self.repo.get_worktree().stage(["README.md"])
+        self.initial_commit = self.repo.get_worktree().commit(
+            message=b"Initial commit",
             committer=b"Test User <test@example.com>",
             committer=b"Test User <test@example.com>",
             author=b"Test User <test@example.com>",
             author=b"Test User <test@example.com>",
         )
         )
@@ -404,7 +404,7 @@ class RebasePorcelainTestCase(TestCase):
 
 
         # Create and checkout feature branch
         # Create and checkout feature branch
         self.repo.refs[b"refs/heads/feature"] = self.initial_commit
         self.repo.refs[b"refs/heads/feature"] = self.initial_commit
-        porcelain.checkout_branch(self.repo, "feature")
+        porcelain.checkout(self.repo, "feature")
 
 
         # Add commit to feature branch
         # Add commit to feature branch
         with open(os.path.join(self.test_dir, "feature.txt"), "wb") as f:
         with open(os.path.join(self.test_dir, "feature.txt"), "wb") as f:
@@ -419,7 +419,7 @@ class RebasePorcelainTestCase(TestCase):
         )
         )
 
 
         # Switch to main and add different commit
         # Switch to main and add different commit
-        porcelain.checkout_branch(self.repo, "master")
+        porcelain.checkout(self.repo, "master")
 
 
         with open(os.path.join(self.test_dir, "main.txt"), "wb") as f:
         with open(os.path.join(self.test_dir, "main.txt"), "wb") as f:
             f.write(b"Main file\n")
             f.write(b"Main file\n")
@@ -433,7 +433,7 @@ class RebasePorcelainTestCase(TestCase):
         )
         )
 
 
         # Switch back to feature and rebase
         # Switch back to feature and rebase
-        porcelain.checkout_branch(self.repo, "feature")
+        porcelain.checkout(self.repo, "feature")
 
 
         # Perform rebase
         # Perform rebase
         new_shas = porcelain.rebase(self.repo, "master")
         new_shas = porcelain.rebase(self.repo, "master")

+ 108 - 88
tests/test_repository.py

@@ -203,9 +203,9 @@ class MemoryRepoTests(TestCase):
                 f.write("test content\n")
                 f.write("test content\n")
 
 
             # Stage and commit using dulwich
             # Stage and commit using dulwich
-            initial_repo.stage(["test.txt"])
-            initial_repo.do_commit(
-                b"Initial commit\n",
+            initial_repo.get_worktree().stage(["test.txt"])
+            initial_repo.get_worktree().commit(
+                message=b"Initial commit\n",
                 committer=b"Test Committer <test@example.com>",
                 committer=b"Test Committer <test@example.com>",
                 author=b"Test Author <test@example.com>",
                 author=b"Test Author <test@example.com>",
             )
             )
@@ -606,8 +606,10 @@ class RepositoryRootTests(TestCase):
 
 
         o = Repo.init(os.path.join(tmp_dir, "s"), mkdir=True)
         o = Repo.init(os.path.join(tmp_dir, "s"), mkdir=True)
         os.symlink("foo", os.path.join(tmp_dir, "s", "bar"))
         os.symlink("foo", os.path.join(tmp_dir, "s", "bar"))
-        o.stage("bar")
-        o.do_commit(b"add symlink")
+        o.get_worktree().stage("bar")
+        o.get_worktree().commit(
+            message=b"add symlink",
+        )
 
 
         t = o.clone(os.path.join(tmp_dir, "t"), symlinks=True)
         t = o.clone(os.path.join(tmp_dir, "t"), symlinks=True)
         o.close()
         o.close()
@@ -626,8 +628,10 @@ class RepositoryRootTests(TestCase):
         o = Repo.init(os.path.join(tmp_dir, "s"), mkdir=True)
         o = Repo.init(os.path.join(tmp_dir, "s"), mkdir=True)
         o.close()
         o.close()
         os.symlink("foo", os.path.join(tmp_dir, "s", "bar"))
         os.symlink("foo", os.path.join(tmp_dir, "s", "bar"))
-        o.stage("bar")
-        o.do_commit(b"add symlink")
+        o.get_worktree().stage("bar")
+        o.get_worktree().commit(
+            message=b"add symlink",
+        )
 
 
         t = o.clone(os.path.join(tmp_dir, "t"), symlinks=False)
         t = o.clone(os.path.join(tmp_dir, "t"), symlinks=False)
         with open(os.path.join(tmp_dir, "t", "bar")) as f:
         with open(os.path.join(tmp_dir, "t", "bar")) as f:
@@ -655,7 +659,7 @@ class RepositoryRootTests(TestCase):
 
 
         # Try to stage the malicious path - should be rejected
         # Try to stage the malicious path - should be rejected
         with self.assertRaises(ValueError):
         with self.assertRaises(ValueError):
-            repo.stage([attack_name])
+            repo.get_worktree().stage([attack_name])
 
 
         # Test with protectHFS disabled
         # Test with protectHFS disabled
         config.set(b"core", b"core.protectHFS", b"false")
         config.set(b"core", b"core.protectHFS", b"false")
@@ -849,8 +853,8 @@ exit 0
             f.write(pre_commit_success)
             f.write(pre_commit_success)
         os.chmod(pre_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
         os.chmod(pre_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
 
 
-        commit_sha = r.do_commit(
-            b"empty commit",
+        commit_sha = r.get_worktree().commit(
+            message=b"empty commit",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -899,8 +903,8 @@ exit 0
             f.write(commit_msg_success)
             f.write(commit_msg_success)
         os.chmod(commit_msg, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
         os.chmod(commit_msg, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
 
 
-        commit_sha = r.do_commit(
-            b"empty commit",
+        commit_sha = r.get_worktree().commit(
+            message=b"empty commit",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -937,7 +941,7 @@ r.stage(['foo'])
         with open(os.path.join(repo_dir, "blah"), "w") as f:
         with open(os.path.join(repo_dir, "blah"), "w") as f:
             f.write("blah")
             f.write("blah")
 
 
-        r.stage(["blah"])
+        r.get_worktree().stage(["blah"])
 
 
         pre_commit = os.path.join(r.controldir(), "hooks", "pre-commit")
         pre_commit = os.path.join(r.controldir(), "hooks", "pre-commit")
 
 
@@ -945,8 +949,8 @@ r.stage(['foo'])
             f.write(pre_commit_contents)
             f.write(pre_commit_contents)
         os.chmod(pre_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
         os.chmod(pre_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
 
 
-        commit_sha = r.do_commit(
-            b"new commit",
+        commit_sha = r.get_worktree().commit(
+            message=b"new commit",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -979,8 +983,8 @@ rm """
 """
 """
         )
         )
 
 
-        root_sha = r.do_commit(
-            b"empty commit",
+        root_sha = r.get_worktree().commit(
+            message=b"empty commit",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12345,
             commit_timestamp=12345,
@@ -996,8 +1000,8 @@ rm """
             f.write(post_commit_msg.encode(locale.getpreferredencoding()))
             f.write(post_commit_msg.encode(locale.getpreferredencoding()))
         os.chmod(post_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
         os.chmod(post_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
 
 
-        commit_sha = r.do_commit(
-            b"empty commit",
+        commit_sha = r.get_worktree().commit(
+            message=b"empty commit",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12345,
             commit_timestamp=12345,
@@ -1021,8 +1025,8 @@ exit 1
         warnings_list, restore_warnings = setup_warning_catcher()
         warnings_list, restore_warnings = setup_warning_catcher()
         self.addCleanup(restore_warnings)
         self.addCleanup(restore_warnings)
 
 
-        commit_sha2 = r.do_commit(
-            b"empty commit",
+        commit_sha2 = r.get_worktree().commit(
+            message=b"empty commit",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12345,
             commit_timestamp=12345,
@@ -1071,8 +1075,8 @@ exit 1
         self.addCleanup(shutil.rmtree, worktree_temp_dir)
         self.addCleanup(shutil.rmtree, worktree_temp_dir)
         r = Repo.init(temp_dir)
         r = Repo.init(temp_dir)
         self.addCleanup(r.close)
         self.addCleanup(r.close)
-        root_sha = r.do_commit(
-            b"empty commit",
+        root_sha = r.get_worktree().commit(
+            message=b"empty commit",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12345,
             commit_timestamp=12345,
@@ -1083,8 +1087,8 @@ exit 1
         r.refs[b"refs/heads/master"] = root_sha
         r.refs[b"refs/heads/master"] = root_sha
         w = Repo._init_new_working_directory(worktree_temp_dir, r)
         w = Repo._init_new_working_directory(worktree_temp_dir, r)
         self.addCleanup(w.close)
         self.addCleanup(w.close)
-        new_sha = w.do_commit(
-            b"new commit",
+        new_sha = w.get_worktree().commit(
+            message=b"new commit",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12345,
             commit_timestamp=12345,
@@ -1122,9 +1126,9 @@ class BuildRepoRootTests(TestCase):
 
 
         with open(os.path.join(r.path, "a"), "wb") as f:
         with open(os.path.join(r.path, "a"), "wb") as f:
             f.write(b"file contents")
             f.write(b"file contents")
-        r.stage(["a"])
-        commit_sha = r.do_commit(
-            b"msg",
+        r.get_worktree().stage(["a"])
+        commit_sha = r.get_worktree().commit(
+            message=b"msg",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12345,
             commit_timestamp=12345,
@@ -1180,9 +1184,9 @@ class BuildRepoRootTests(TestCase):
         r = self._repo
         r = self._repo
         with open(os.path.join(r.path, "a"), "wb") as f:
         with open(os.path.join(r.path, "a"), "wb") as f:
             f.write(b"new contents")
             f.write(b"new contents")
-        r.stage(["a"])
-        commit_sha = r.do_commit(
-            b"modified a",
+        r.get_worktree().stage(["a"])
+        commit_sha = r.get_worktree().commit(
+            message=b"modified a",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1199,9 +1203,9 @@ class BuildRepoRootTests(TestCase):
     def test_commit_symlink(self) -> None:
     def test_commit_symlink(self) -> None:
         r = self._repo
         r = self._repo
         os.symlink("a", os.path.join(r.path, "b"))
         os.symlink("a", os.path.join(r.path, "b"))
-        r.stage(["a", "b"])
-        commit_sha = r.do_commit(
-            b"Symlink b",
+        r.get_worktree().stage(["a", "b"])
+        commit_sha = r.get_worktree().commit(
+            message=b"Symlink b",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1220,8 +1224,8 @@ class BuildRepoRootTests(TestCase):
         r = Repo.init(tmp_dir)
         r = Repo.init(tmp_dir)
         with open(os.path.join(r.path, "a"), "w") as f:
         with open(os.path.join(r.path, "a"), "w") as f:
             f.write("initial text")
             f.write("initial text")
-        c1 = r.do_commit(
-            b"initial commit",
+        c1 = r.get_worktree().commit(
+            message=b"initial commit",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1233,9 +1237,9 @@ class BuildRepoRootTests(TestCase):
             f.write("merged text")
             f.write("merged text")
         with open(os.path.join(r.path, ".git", "MERGE_HEAD"), "w") as f:
         with open(os.path.join(r.path, ".git", "MERGE_HEAD"), "w") as f:
             f.write("c27a2d21dd136312d7fa9e8baabb82561a1727d0\n")
             f.write("c27a2d21dd136312d7fa9e8baabb82561a1727d0\n")
-        r.stage(["a"])
-        commit_sha = r.do_commit(
-            b"deleted a",
+        r.get_worktree().stage(["a"])
+        commit_sha = r.get_worktree().commit(
+            message=b"deleted a",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1251,9 +1255,9 @@ class BuildRepoRootTests(TestCase):
     def test_commit_deleted(self) -> None:
     def test_commit_deleted(self) -> None:
         r = self._repo
         r = self._repo
         os.remove(os.path.join(r.path, "a"))
         os.remove(os.path.join(r.path, "a"))
-        r.stage(["a"])
-        commit_sha = r.do_commit(
-            b"deleted a",
+        r.get_worktree().stage(["a"])
+        commit_sha = r.get_worktree().commit(
+            message=b"deleted a",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1269,8 +1273,8 @@ class BuildRepoRootTests(TestCase):
     def test_commit_follows(self) -> None:
     def test_commit_follows(self) -> None:
         r = self._repo
         r = self._repo
         r.refs.set_symbolic_ref(b"HEAD", b"refs/heads/bla")
         r.refs.set_symbolic_ref(b"HEAD", b"refs/heads/bla")
-        commit_sha = r.do_commit(
-            b"commit with strange character",
+        commit_sha = r.get_worktree().commit(
+            message=b"commit with strange character",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1283,8 +1287,8 @@ class BuildRepoRootTests(TestCase):
 
 
     def test_commit_encoding(self) -> None:
     def test_commit_encoding(self) -> None:
         r = self._repo
         r = self._repo
-        commit_sha = r.do_commit(
-            b"commit with strange character \xee",
+        commit_sha = r.get_worktree().commit(
+            message=b"commit with strange character \xee",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1361,8 +1365,8 @@ class BuildRepoRootTests(TestCase):
         c = r.get_config()
         c = r.get_config()
         c.set(("i18n",), "commitEncoding", "iso8859-1")
         c.set(("i18n",), "commitEncoding", "iso8859-1")
         c.write_to_path()
         c.write_to_path()
-        commit_sha = r.do_commit(
-            b"commit with strange character \xee",
+        commit_sha = r.get_worktree().commit(
+            message=b"commit with strange character \xee",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1379,7 +1383,9 @@ class BuildRepoRootTests(TestCase):
         c.set((b"user",), b"name", b"Jelmer")
         c.set((b"user",), b"name", b"Jelmer")
         c.set((b"user",), b"email", b"jelmer@apache.org")
         c.set((b"user",), b"email", b"jelmer@apache.org")
         c.write_to_path()
         c.write_to_path()
-        commit_sha = r.do_commit(b"message")
+        commit_sha = r.get_worktree().commit(
+            message=b"message",
+        )
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].author)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].author)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].committer)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].committer)
 
 
@@ -1391,7 +1397,9 @@ class BuildRepoRootTests(TestCase):
         c.set((b"user",), b"name", b"Jelmer")
         c.set((b"user",), b"name", b"Jelmer")
         c.set((b"user",), b"email", b"<jelmer@apache.org>")
         c.set((b"user",), b"email", b"<jelmer@apache.org>")
         c.write_to_path()
         c.write_to_path()
-        commit_sha = r.do_commit(b"message")
+        commit_sha = r.get_worktree().commit(
+            message=b"message",
+        )
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].author)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].author)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].committer)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].committer)
 
 
@@ -1402,7 +1410,15 @@ class BuildRepoRootTests(TestCase):
         c.set((b"user",), b"name", b"Jelmer")
         c.set((b"user",), b"name", b"Jelmer")
         c.set((b"user",), b"email", b"jelmer@apache.org")
         c.set((b"user",), b"email", b"jelmer@apache.org")
 
 
-        commit_sha = r.do_commit(b"message", tree=objects.Tree().id)
+        # Create a tree object
+        tree = objects.Tree()
+        r.object_store.add_object(tree)
+
+        # Use do_commit for MemoryRepo since it doesn't support worktree
+        commit_sha = r.do_commit(
+            message=b"message",
+            tree=tree.id,
+        )
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].author)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].author)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].committer)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].committer)
 
 
@@ -1415,7 +1431,9 @@ class BuildRepoRootTests(TestCase):
         c.set((b"user",), b"name", b"Jelmer")
         c.set((b"user",), b"name", b"Jelmer")
         c.set((b"user",), b"email", b"jelmer@apache.org")
         c.set((b"user",), b"email", b"jelmer@apache.org")
         c.write_to_path()
         c.write_to_path()
-        commit_sha = r.do_commit(b"message")
+        commit_sha = r.get_worktree().commit(
+            message=b"message",
+        )
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].author)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].author)
         self.assertEqual(b"joe <joe@example.com>", r[commit_sha].committer)
         self.assertEqual(b"joe <joe@example.com>", r[commit_sha].committer)
 
 
@@ -1463,8 +1481,8 @@ class BuildRepoRootTests(TestCase):
             # Generate a message
             # Generate a message
             return b"Generated commit for tree " + commit.tree[:8]
             return b"Generated commit for tree " + commit.tree[:8]
 
 
-        commit_sha = r.do_commit(
-            message_callback,  # Pass the callback as message
+        commit_sha = r.get_worktree().commit(
+            message=message_callback,
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12345,
             commit_timestamp=12345,
@@ -1501,17 +1519,17 @@ class BuildRepoRootTests(TestCase):
         r = self._repo
         r = self._repo
 
 
         # Create two parent commits first
         # Create two parent commits first
-        parent1 = r.do_commit(
-            b"Parent 1",
+        parent1 = r.get_worktree().commit(
+            message=b"Parent 1",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
         )
         )
 
 
-        parent2 = r.do_commit(
-            b"Parent 2",
+        parent2 = r.get_worktree().commit(
+            message=b"Parent 2",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
-            ref=None,  # Dangling commit
+            ref=None,
         )
         )
 
 
         def message_callback(repo, commit):
         def message_callback(repo, commit):
@@ -1519,8 +1537,8 @@ class BuildRepoRootTests(TestCase):
             self.assertEqual(2, len(commit.parents))
             self.assertEqual(2, len(commit.parents))
             return b"Merge commit with %d parents" % len(commit.parents)
             return b"Merge commit with %d parents" % len(commit.parents)
 
 
-        merge_sha = r.do_commit(
-            message_callback,
+        merge_sha = r.get_worktree().commit(
+            message=message_callback,
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             merge_heads=[parent2],
             merge_heads=[parent2],
@@ -1533,8 +1551,8 @@ class BuildRepoRootTests(TestCase):
     def test_commit_branch(self) -> None:
     def test_commit_branch(self) -> None:
         r = self._repo
         r = self._repo
 
 
-        commit_sha = r.do_commit(
-            b"commit to branch",
+        commit_sha = r.get_worktree().commit(
+            message=b"commit to branch",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1550,8 +1568,8 @@ class BuildRepoRootTests(TestCase):
 
 
         new_branch_head = commit_sha
         new_branch_head = commit_sha
 
 
-        commit_sha = r.do_commit(
-            b"commit to branch 2",
+        commit_sha = r.get_worktree().commit(
+            message=b"commit to branch 2",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1566,8 +1584,8 @@ class BuildRepoRootTests(TestCase):
 
 
     def test_commit_merge_heads(self) -> None:
     def test_commit_merge_heads(self) -> None:
         r = self._repo
         r = self._repo
-        merge_1 = r.do_commit(
-            b"commit to branch 2",
+        merge_1 = r.get_worktree().commit(
+            message=b"commit to branch 2",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1576,8 +1594,8 @@ class BuildRepoRootTests(TestCase):
             author_timezone=0,
             author_timezone=0,
             ref=b"refs/heads/new_branch",
             ref=b"refs/heads/new_branch",
         )
         )
-        commit_sha = r.do_commit(
-            b"commit with merge",
+        commit_sha = r.get_worktree().commit(
+            message=b"commit with merge",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1593,8 +1611,8 @@ class BuildRepoRootTests(TestCase):
 
 
         old_shas = set(r.object_store)
         old_shas = set(r.object_store)
         old_refs = r.get_refs()
         old_refs = r.get_refs()
-        commit_sha = r.do_commit(
-            b"commit with no ref",
+        commit_sha = r.get_worktree().commit(
+            message=b"commit with no ref",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1617,8 +1635,8 @@ class BuildRepoRootTests(TestCase):
 
 
         old_shas = set(r.object_store)
         old_shas = set(r.object_store)
         old_refs = r.get_refs()
         old_refs = r.get_refs()
-        commit_sha = r.do_commit(
-            b"commit with no ref",
+        commit_sha = r.get_worktree().commit(
+            message=b"commit with no ref",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,
@@ -1645,21 +1663,23 @@ class BuildRepoRootTests(TestCase):
     def test_stage_deleted(self) -> None:
     def test_stage_deleted(self) -> None:
         r = self._repo
         r = self._repo
         os.remove(os.path.join(r.path, "a"))
         os.remove(os.path.join(r.path, "a"))
-        r.stage(["a"])
-        r.stage(["a"])  # double-stage a deleted path
+        r.get_worktree().stage(["a"])
+        r.get_worktree().stage(["a"])  # double-stage a deleted path
         self.assertEqual([], list(r.open_index()))
         self.assertEqual([], list(r.open_index()))
 
 
     def test_stage_directory(self) -> None:
     def test_stage_directory(self) -> None:
         r = self._repo
         r = self._repo
         os.mkdir(os.path.join(r.path, "c"))
         os.mkdir(os.path.join(r.path, "c"))
-        r.stage(["c"])
+        r.get_worktree().stage(["c"])
         self.assertEqual([b"a"], list(r.open_index()))
         self.assertEqual([b"a"], list(r.open_index()))
 
 
     def test_stage_submodule(self) -> None:
     def test_stage_submodule(self) -> None:
         r = self._repo
         r = self._repo
         s = Repo.init(os.path.join(r.path, "sub"), mkdir=True)
         s = Repo.init(os.path.join(r.path, "sub"), mkdir=True)
-        s.do_commit(b"message")
-        r.stage(["sub"])
+        s.get_worktree().commit(
+            message=b"message",
+        )
+        r.get_worktree().stage(["sub"])
         self.assertEqual([b"a", b"sub"], list(r.open_index()))
         self.assertEqual([b"a", b"sub"], list(r.open_index()))
 
 
     def test_unstage_midify_file_with_dir(self) -> None:
     def test_unstage_midify_file_with_dir(self) -> None:
@@ -1677,7 +1697,7 @@ class BuildRepoRootTests(TestCase):
         )
         )
         with open(full_path, "a") as f:
         with open(full_path, "a") as f:
             f.write("something new")
             f.write("something new")
-        self._repo.unstage(["new_dir/foo"])
+        self._repo.get_worktree().unstage(["new_dir/foo"])
         status = list(porcelain.status(self._repo))
         status = list(porcelain.status(self._repo))
         self.assertEqual(
         self.assertEqual(
             [{"add": [], "delete": [], "modify": []}, [b"new_dir/foo"], []], status
             [{"add": [], "delete": [], "modify": []}, [b"new_dir/foo"], []], status
@@ -1689,7 +1709,7 @@ class BuildRepoRootTests(TestCase):
         with open(full_path, "w") as f:
         with open(full_path, "w") as f:
             f.write("hello")
             f.write("hello")
         porcelain.add(self._repo, paths=[full_path])
         porcelain.add(self._repo, paths=[full_path])
-        self._repo.unstage([file])
+        self._repo.get_worktree().unstage([file])
         status = list(porcelain.status(self._repo))
         status = list(porcelain.status(self._repo))
         self.assertEqual([{"add": [], "delete": [], "modify": []}, [], ["foo"]], status)
         self.assertEqual([{"add": [], "delete": [], "modify": []}, [], ["foo"]], status)
 
 
@@ -1705,7 +1725,7 @@ class BuildRepoRootTests(TestCase):
         with open(full_path, "w") as f:
         with open(full_path, "w") as f:
             f.write("hello")
             f.write("hello")
         porcelain.add(self._repo, paths=[full_path])
         porcelain.add(self._repo, paths=[full_path])
-        self._repo.unstage([file])
+        self._repo.get_worktree().unstage([file])
         status = list(porcelain.status(self._repo))
         status = list(porcelain.status(self._repo))
         self.assertEqual([{"add": [], "delete": [], "modify": []}, [], ["foo"]], status)
         self.assertEqual([{"add": [], "delete": [], "modify": []}, [], ["foo"]], status)
 
 
@@ -1724,7 +1744,7 @@ class BuildRepoRootTests(TestCase):
         with open(full_path, "a") as f:
         with open(full_path, "a") as f:
             f.write("broken")
             f.write("broken")
         porcelain.add(self._repo, paths=[full_path])
         porcelain.add(self._repo, paths=[full_path])
-        self._repo.unstage([file])
+        self._repo.get_worktree().unstage([file])
         status = list(porcelain.status(self._repo))
         status = list(porcelain.status(self._repo))
 
 
         self.assertEqual(
         self.assertEqual(
@@ -1744,7 +1764,7 @@ class BuildRepoRootTests(TestCase):
             author=b"John <john@example.com>",
             author=b"John <john@example.com>",
         )
         )
         os.remove(full_path)
         os.remove(full_path)
-        self._repo.unstage([file])
+        self._repo.get_worktree().unstage([file])
         status = list(porcelain.status(self._repo))
         status = list(porcelain.status(self._repo))
         self.assertEqual(
         self.assertEqual(
             [{"add": [], "delete": [], "modify": []}, [b"foo"], []], status
             [{"add": [], "delete": [], "modify": []}, [b"foo"], []], status
@@ -1756,12 +1776,12 @@ class BuildRepoRootTests(TestCase):
             f.write(b"changed")
             f.write(b"changed")
         with open(os.path.join(r.path, "b"), "wb") as f:
         with open(os.path.join(r.path, "b"), "wb") as f:
             f.write(b"added")
             f.write(b"added")
-        r.stage(["a", "b"])
+        r.get_worktree().stage(["a", "b"])
         status = list(porcelain.status(self._repo))
         status = list(porcelain.status(self._repo))
         self.assertEqual(
         self.assertEqual(
             [{"add": [b"b"], "delete": [], "modify": [b"a"]}, [], []], status
             [{"add": [b"b"], "delete": [], "modify": [b"a"]}, [], []], status
         )
         )
-        r.reset_index()
+        r.get_worktree().reset_index()
         status = list(porcelain.status(self._repo))
         status = list(porcelain.status(self._repo))
         self.assertEqual([{"add": [], "delete": [], "modify": []}, [], ["b"]], status)
         self.assertEqual([{"add": [], "delete": [], "modify": []}, [], ["b"]], status)
 
 
@@ -1782,9 +1802,9 @@ class BuildRepoRootTests(TestCase):
             # ourselves.
             # ourselves.
             self.addCleanup(os.remove, full_path)
             self.addCleanup(os.remove, full_path)
 
 
-        r.stage(names)
-        commit_sha = r.do_commit(
-            b"Files with different encodings",
+        r.get_worktree().stage(names)
+        commit_sha = r.get_worktree().commit(
+            message=b"Files with different encodings",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12395,
             commit_timestamp=12395,

+ 1 - 1
tests/test_server.py

@@ -1174,7 +1174,7 @@ class UpdateServerInfoTests(TestCase):
             self.assertEqual(b"", f.read())
             self.assertEqual(b"", f.read())
 
 
     def test_simple(self) -> None:
     def test_simple(self) -> None:
-        commit_id = self.repo.do_commit(
+        commit_id = self.repo.get_worktree().commit(
             message=b"foo",
             message=b"foo",
             committer=b"Joe Example <joe@example.com>",
             committer=b"Joe Example <joe@example.com>",
             ref=b"refs/heads/foo",
             ref=b"refs/heads/foo",

+ 7 - 5
tests/test_sparse_patterns.py

@@ -196,7 +196,7 @@ class ComputeIncludedPathsFullTests(TestCase):
         with open(full, "wb") as f:
         with open(full, "wb") as f:
             f.write(content)
             f.write(content)
         # Stage in the index
         # Stage in the index
-        self.repo.stage([relpath])
+        self.repo.get_worktree().stage([relpath])
 
 
     def test_basic_inclusion_exclusion(self):
     def test_basic_inclusion_exclusion(self):
         """Given patterns, check correct set of included paths."""
         """Given patterns, check correct set of included paths."""
@@ -237,7 +237,7 @@ class ComputeIncludedPathsConeTests(TestCase):
         os.makedirs(os.path.dirname(full), exist_ok=True)
         os.makedirs(os.path.dirname(full), exist_ok=True)
         with open(full, "wb") as f:
         with open(full, "wb") as f:
             f.write(content)
             f.write(content)
-        self.repo.stage([relpath])
+        self.repo.get_worktree().stage([relpath])
 
 
     def test_cone_mode_patterns(self):
     def test_cone_mode_patterns(self):
         """Simpler pattern handling in cone mode.
         """Simpler pattern handling in cone mode.
@@ -332,7 +332,7 @@ class DetermineIncludedPathsTests(TestCase):
         os.makedirs(os.path.dirname(path), exist_ok=True)
         os.makedirs(os.path.dirname(path), exist_ok=True)
         with open(path, "wb") as f:
         with open(path, "wb") as f:
             f.write(b"data")
             f.write(b"data")
-        self.repo.stage([relpath])
+        self.repo.get_worktree().stage([relpath])
 
 
     def test_full_mode(self):
     def test_full_mode(self):
         self._add_file_to_index("foo.py")
         self._add_file_to_index("foo.py")
@@ -370,9 +370,11 @@ class ApplyIncludedPathsTests(TestCase):
         os.makedirs(os.path.dirname(full), exist_ok=True)
         os.makedirs(os.path.dirname(full), exist_ok=True)
         with open(full, "wb") as f:
         with open(full, "wb") as f:
             f.write(content)
             f.write(content)
-        self.repo.stage([relpath])
+        self.repo.get_worktree().stage([relpath])
         # Actually commit so the object is in the store
         # Actually commit so the object is in the store
-        self.repo.do_commit(message=b"Commit " + relpath.encode())
+        self.repo.get_worktree().commit(
+            message=b"Commit " + relpath.encode(),
+        )
 
 
     def test_set_skip_worktree_bits(self):
     def test_set_skip_worktree_bits(self):
         """If a path is not in included_paths, skip_worktree bit is set."""
         """If a path is not in included_paths, skip_worktree bit is set."""

+ 14 - 9
tests/test_stash.py

@@ -50,7 +50,10 @@ class StashTests(TestCase):
         tree.add(b"initial.txt", 0o100644, blob.id)
         tree.add(b"initial.txt", 0o100644, blob.id)
         tree_id = self.repo.object_store.add_object(tree)
         tree_id = self.repo.object_store.add_object(tree)
 
 
-        self.commit_id = self.repo.do_commit(b"Initial commit", tree=tree_id)
+        self.commit_id = self.repo.get_worktree().commit(
+            message=b"Initial commit",
+            tree=tree_id,
+        )
 
 
     def tearDown(self):
     def tearDown(self):
         shutil.rmtree(self.test_dir)
         shutil.rmtree(self.test_dir)
@@ -77,7 +80,7 @@ class StashTests(TestCase):
         file_path = os.path.join(self.repo_dir, "testfile.txt")
         file_path = os.path.join(self.repo_dir, "testfile.txt")
         with open(file_path, "wb") as f:
         with open(file_path, "wb") as f:
             f.write(b"test data")
             f.write(b"test data")
-        self.repo.stage(["testfile.txt"])
+        self.repo.get_worktree().stage(["testfile.txt"])
 
 
         # Push to stash
         # Push to stash
         commit_id = stash.push(message=b"Test stash message")
         commit_id = stash.push(message=b"Test stash message")
@@ -102,13 +105,13 @@ class StashTests(TestCase):
         file1_path = os.path.join(self.repo_dir, "testfile1.txt")
         file1_path = os.path.join(self.repo_dir, "testfile1.txt")
         with open(file1_path, "wb") as f:
         with open(file1_path, "wb") as f:
             f.write(b"test data 1")
             f.write(b"test data 1")
-        self.repo.stage(["testfile1.txt"])
+        self.repo.get_worktree().stage(["testfile1.txt"])
         commit_id1 = stash.push(message=b"Test stash 1")
         commit_id1 = stash.push(message=b"Test stash 1")
 
 
         file2_path = os.path.join(self.repo_dir, "testfile2.txt")
         file2_path = os.path.join(self.repo_dir, "testfile2.txt")
         with open(file2_path, "wb") as f:
         with open(file2_path, "wb") as f:
             f.write(b"test data 2")
             f.write(b"test data 2")
-        self.repo.stage(["testfile2.txt"])
+        self.repo.get_worktree().stage(["testfile2.txt"])
         stash.push(message=b"Test stash 2")
         stash.push(message=b"Test stash 2")
 
 
         self.assertEqual(2, len(stash))
         self.assertEqual(2, len(stash))
@@ -138,7 +141,7 @@ class StashTests(TestCase):
         file_path = os.path.join(self.repo_dir, "testfile.txt")
         file_path = os.path.join(self.repo_dir, "testfile.txt")
         with open(file_path, "wb") as f:
         with open(file_path, "wb") as f:
             f.write(b"test data")
             f.write(b"test data")
-        self.repo.stage(["testfile.txt"])
+        self.repo.get_worktree().stage(["testfile.txt"])
 
 
         # Push to stash
         # Push to stash
         stash.push(message=b"Test stash message")
         stash.push(message=b"Test stash message")
@@ -173,13 +176,15 @@ class StashTests(TestCase):
         tracked_path = os.path.join(self.repo_dir, "tracked.txt")
         tracked_path = os.path.join(self.repo_dir, "tracked.txt")
         with open(tracked_path, "wb") as f:
         with open(tracked_path, "wb") as f:
             f.write(b"original content")
             f.write(b"original content")
-        self.repo.stage(["tracked.txt"])
-        self.repo.do_commit(b"Add tracked file")
+        self.repo.get_worktree().stage(["tracked.txt"])
+        self.repo.get_worktree().commit(
+            message=b"Add tracked file",
+        )
 
 
         # Modify the tracked file and stage it
         # Modify the tracked file and stage it
         with open(tracked_path, "wb") as f:
         with open(tracked_path, "wb") as f:
             f.write(b"staged changes")
             f.write(b"staged changes")
-        self.repo.stage(["tracked.txt"])
+        self.repo.get_worktree().stage(["tracked.txt"])
 
 
         # Modify it again but don't stage
         # Modify it again but don't stage
         with open(tracked_path, "wb") as f:
         with open(tracked_path, "wb") as f:
@@ -189,7 +194,7 @@ class StashTests(TestCase):
         new_file_path = os.path.join(self.repo_dir, "new.txt")
         new_file_path = os.path.join(self.repo_dir, "new.txt")
         with open(new_file_path, "wb") as f:
         with open(new_file_path, "wb") as f:
             f.write(b"new file content")
             f.write(b"new file content")
-        self.repo.stage(["new.txt"])
+        self.repo.get_worktree().stage(["new.txt"])
 
 
         # Push to stash
         # Push to stash
         stash.push(message=b"Test stash with index")
         stash.push(message=b"Test stash with index")

+ 4 - 2
tests/test_submodule.py

@@ -68,8 +68,10 @@ class SubmoduleTests(TestCase):
             f.write(b"test file content")
             f.write(b"test file content")
 
 
         # Stage and commit the file to create some basic content
         # Stage and commit the file to create some basic content
-        repo.stage(["file.txt"])
-        repo.do_commit(b"Initial commit")
+        repo.get_worktree().stage(["file.txt"])
+        repo.get_worktree().commit(
+            message=b"Initial commit",
+        )
 
 
         # Manually create the raw string for a tree with our file and a submodule
         # Manually create the raw string for a tree with our file and a submodule
         # Format for tree entries: [mode] [name]\0[sha]
         # Format for tree entries: [mode] [name]\0[sha]

+ 16 - 8
tests/test_worktree.py

@@ -57,9 +57,9 @@ class WorkTreeTestCase(TestCase):
         # Create initial commit with a file
         # Create initial commit with a file
         with open(os.path.join(self.test_dir, "a"), "wb") as f:
         with open(os.path.join(self.test_dir, "a"), "wb") as f:
             f.write(b"contents of file a")
             f.write(b"contents of file a")
-        self.repo.stage(["a"])
-        self.root_commit = self.repo.do_commit(
-            b"Initial commit",
+        self.repo.get_worktree().stage(["a"])
+        self.root_commit = self.repo.get_worktree().commit(
+            message=b"Initial commit",
             committer=b"Test Committer <test@nodomain.com>",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
             commit_timestamp=12345,
             commit_timestamp=12345,
@@ -147,7 +147,9 @@ class WorkTreeStagingTests(WorkTreeTestCase):
         """Test staging a submodule."""
         """Test staging a submodule."""
         r = self.repo
         r = self.repo
         s = Repo.init(os.path.join(r.path, "sub"), mkdir=True)
         s = Repo.init(os.path.join(r.path, "sub"), mkdir=True)
-        s.do_commit(b"message")
+        s.get_worktree().commit(
+            message=b"message",
+        )
         self.worktree.stage(["sub"])
         self.worktree.stage(["sub"])
         self.assertEqual([b"a", b"sub"], list(r.open_index()))
         self.assertEqual([b"a", b"sub"], list(r.open_index()))
 
 
@@ -392,7 +394,9 @@ class WorkTreeBackwardCompatibilityTests(WorkTreeTestCase):
 
 
         with warnings.catch_warnings(record=True) as w:
         with warnings.catch_warnings(record=True) as w:
             warnings.simplefilter("always")
             warnings.simplefilter("always")
-            self.repo.stage(["new_file"])
+            self.repo.stage(
+                ["new_file"]
+            )  # Call deprecated method on Repo, not WorkTree
             self.assertTrue(len(w) > 0)
             self.assertTrue(len(w) > 0)
             self.assertTrue(issubclass(w[0].category, DeprecationWarning))
             self.assertTrue(issubclass(w[0].category, DeprecationWarning))
 
 
@@ -403,7 +407,7 @@ class WorkTreeBackwardCompatibilityTests(WorkTreeTestCase):
 
 
         with warnings.catch_warnings(record=True) as w:
         with warnings.catch_warnings(record=True) as w:
             warnings.simplefilter("always")
             warnings.simplefilter("always")
-            self.repo.unstage(["a"])
+            self.repo.unstage(["a"])  # Call deprecated method on Repo, not WorkTree
             self.assertTrue(len(w) > 0)
             self.assertTrue(len(w) > 0)
             self.assertTrue(issubclass(w[0].category, DeprecationWarning))
             self.assertTrue(issubclass(w[0].category, DeprecationWarning))
 
 
@@ -414,7 +418,9 @@ class WorkTreeBackwardCompatibilityTests(WorkTreeTestCase):
         # Test get_sparse_checkout_patterns
         # Test get_sparse_checkout_patterns
         with warnings.catch_warnings(record=True) as w:
         with warnings.catch_warnings(record=True) as w:
             warnings.simplefilter("always")
             warnings.simplefilter("always")
-            patterns = self.repo.get_sparse_checkout_patterns()
+            patterns = (
+                self.repo.get_sparse_checkout_patterns()
+            )  # Call deprecated method on Repo
             self.assertEqual([], patterns)
             self.assertEqual([], patterns)
             self.assertTrue(len(w) > 0)
             self.assertTrue(len(w) > 0)
             self.assertTrue(issubclass(w[0].category, DeprecationWarning))
             self.assertTrue(issubclass(w[0].category, DeprecationWarning))
@@ -422,7 +428,9 @@ class WorkTreeBackwardCompatibilityTests(WorkTreeTestCase):
         # Test set_sparse_checkout_patterns
         # Test set_sparse_checkout_patterns
         with warnings.catch_warnings(record=True) as w:
         with warnings.catch_warnings(record=True) as w:
             warnings.simplefilter("always")
             warnings.simplefilter("always")
-            self.repo.set_sparse_checkout_patterns(["*.py"])
+            self.repo.set_sparse_checkout_patterns(
+                ["*.py"]
+            )  # Call deprecated method on Repo
             self.assertTrue(len(w) > 0)
             self.assertTrue(len(w) > 0)
             self.assertTrue(issubclass(w[0].category, DeprecationWarning))
             self.assertTrue(issubclass(w[0].category, DeprecationWarning))
 
 

Vissa filer visades inte eftersom för många filer har ändrats