Browse Source

Allow passing in plain strings to tag_create

Fixes #1499
Jelmer Vernooij 3 weeks ago
parent
commit
16896cb51b
3 changed files with 64 additions and 8 deletions
  1. 3 0
      NEWS
  2. 16 8
      dulwich/porcelain.py
  3. 45 0
      tests/test_porcelain.py

+ 3 - 0
NEWS

@@ -1,5 +1,8 @@
 0.22.8	UNRELEASED
 
+ * Allow passing in plain strings to ``dulwich.porcelain.tag_create``
+   (Jelmer Vernooij, #1499)
+
 0.22.7	2024-12-19
 
  * Fix serializing of commits with empty commit messages.

+ 16 - 8
dulwich/porcelain.py

@@ -125,6 +125,7 @@ from .refs import (
     LOCAL_BRANCH_PREFIX,
     LOCAL_REMOTE_PREFIX,
     LOCAL_TAG_PREFIX,
+    Ref,
     _import_remote_refs,
 )
 from .repo import BaseRepo, Repo, get_user_identity
@@ -1039,15 +1040,15 @@ def submodule_list(repo):
 
 def tag_create(
     repo,
-    tag,
-    author=None,
-    message=None,
+    tag: Union[str, bytes],
+    author: Optional[str] = None,
+    message: Optional[Union[str, bytes]] = None,
     annotated=False,
-    objectish="HEAD",
+    objectish: Union[str, bytes] = "HEAD",
     tag_time=None,
     tag_timezone=None,
-    sign=False,
-    encoding=DEFAULT_ENCODING,
+    sign: bool = False,
+    encoding: str = DEFAULT_ENCODING,
 ) -> None:
     """Creates a tag in git via dulwich calls.
 
@@ -1067,12 +1068,19 @@ def tag_create(
     with open_repo_closing(repo) as r:
         object = parse_object(r, objectish)
 
+        if isinstance(tag, str):
+            tag = tag.encode(encoding)
+
         if annotated:
             # Create the tag object
             tag_obj = Tag()
             if author is None:
                 author = get_user_identity(r.get_config_stack())
+            if isinstance(author, str):
+                author = author.encode(encoding)
             tag_obj.tagger = author
+            if isinstance(message, str):
+                message = message.encode(encoding)
             tag_obj.message = message + "\n".encode(encoding)
             tag_obj.name = tag
             tag_obj.object = (type(object), object.id)
@@ -1590,13 +1598,13 @@ def receive_pack(path=".", inf=None, outf=None) -> int:
     return 0
 
 
-def _make_branch_ref(name):
+def _make_branch_ref(name: Union[str, bytes]) -> Ref:
     if getattr(name, "encode", None):
         name = name.encode(DEFAULT_ENCODING)
     return LOCAL_BRANCH_PREFIX + name
 
 
-def _make_tag_ref(name):
+def _make_tag_ref(name: Union[str, bytes]) -> Ref:
     if getattr(name, "encode", None):
         name = name.encode(DEFAULT_ENCODING)
     return LOCAL_TAG_PREFIX + name

+ 45 - 0
tests/test_porcelain.py

@@ -1186,6 +1186,51 @@ Date:   Fri Jan 01 2010 00:00:00 +0000
 
 Test message.
 
+diff --git a/somename b/somename
+new file mode 100644
+index 0000000..ea5c7bf
+--- /dev/null
++++ b/somename
+@@ -0,0 +1 @@
++The Foo
+""",
+        )
+
+    def test_tag_unicode(self) -> None:
+        a = Blob.from_string(b"The Foo\n")
+        ta = Tree()
+        ta.add(b"somename", 0o100644, a.id)
+        ca = make_commit(tree=ta.id)
+        self.repo.object_store.add_objects([(a, None), (ta, None), (ca, None)])
+        porcelain.tag_create(
+            self.repo.path,
+            "tryme",
+            "foo <foo@bar.com>",
+            "bar",
+            annotated=True,
+            objectish=ca.id,
+            tag_time=1552854211,
+            tag_timezone=0,
+        )
+        outstream = StringIO()
+        porcelain.show(self.repo, objects=[b"refs/tags/tryme"], outstream=outstream)
+        self.maxDiff = None
+        self.assertMultiLineEqual(
+            outstream.getvalue(),
+            """\
+Tagger: foo <foo@bar.com>
+Date:   Sun Mar 17 2019 20:23:31 +0000
+
+bar
+
+--------------------------------------------------
+commit: 344da06c1bb85901270b3e8875c988a027ec087d
+Author: Test Author <test@nodomain.com>
+Committer: Test Committer <test@nodomain.com>
+Date:   Fri Jan 01 2010 00:00:00 +0000
+
+Test message.
+
 diff --git a/somename b/somename
 new file mode 100644
 index 0000000..ea5c7bf