浏览代码

Add support for mergetags.

Bug: https://bugs.launchpad.net/dulwich/+bug/963525
milki 12 年之前
父节点
当前提交
c54f4c7150
共有 3 个文件被更改,包括 147 次插入3 次删除
  1. 4 0
      NEWS
  2. 32 2
      dulwich/objects.py
  3. 111 1
      dulwich/tests/test_objects.py

+ 4 - 0
NEWS

@@ -7,6 +7,10 @@
   * Use indentation consistent with C Git in config files.
     (#1031356, Curt Moore, Jelmer Vernooij)
 
+ FEATURES
+
+  * Add support for mergetags. (milki, #963525)
+
 0.8.7	2012-11-27
 
  BUG FIXES

+ 32 - 2
dulwich/objects.py

@@ -51,7 +51,8 @@ _PARENT_HEADER = "parent"
 _AUTHOR_HEADER = "author"
 _COMMITTER_HEADER = "committer"
 _ENCODING_HEADER = "encoding"
-
+_MERGETAG_HEADER = "mergetag"
+_INTERNAL_EXTRA_HEADER = "_extra_"
 
 # Header fields for objects
 _OBJECT_HEADER = "object"
@@ -583,7 +584,15 @@ def _parse_tag_or_commit(text):
         field named None for the freeform tag/commit text.
     """
     f = StringIO(text)
+    extra = ""
     for l in f:
+        if l.startswith(" "):
+            # Beginning space indicates embedded extra header
+            extra += l.lstrip(" ")
+            continue
+        if extra:
+            yield _INTERNAL_EXTRA_HEADER, extra
+            extra = ""
         l = l.rstrip("\n")
         if l == "":
             # Empty line indicates end of headers
@@ -1038,12 +1047,13 @@ class Commit(ShaFile):
                  '_commit_timezone_neg_utc', '_commit_time',
                  '_author_time', '_author_timezone', '_commit_timezone',
                  '_author', '_committer', '_parents', '_extra',
-                 '_encoding', '_tree', '_message')
+                 '_encoding', '_tree', '_message', '_mergetag')
 
     def __init__(self):
         super(Commit, self).__init__()
         self._parents = []
         self._encoding = None
+        self._mergetag = []
         self._extra = []
         self._author_timezone_neg_utc = False
         self._commit_timezone_neg_utc = False
@@ -1059,6 +1069,7 @@ class Commit(ShaFile):
         self._parents = []
         self._extra = []
         self._author = None
+        mergetag = ""
         for field, value in parse_commit(''.join(chunks)):
             if field == _TREE_HEADER:
                 self._tree = value
@@ -1078,6 +1089,12 @@ class Commit(ShaFile):
                 self._encoding = value
             elif field is None:
                 self._message = value
+            elif field == _MERGETAG_HEADER:
+                mergetag = "%s\n" % value
+            elif field == _INTERNAL_EXTRA_HEADER:
+                if mergetag:
+                    self._mergetag.append(Tag.from_string(mergetag + value))
+                    mergetag = ""
             else:
                 self._extra.append((field, value))
 
@@ -1132,6 +1149,16 @@ class Commit(ShaFile):
                           self._commit_timezone_neg_utc)))
         if self.encoding:
             chunks.append("%s %s\n" % (_ENCODING_HEADER, self.encoding))
+        for mergetag in self.mergetag:
+            mergetag_chunks = mergetag.as_raw_string().split("\n")
+
+            chunks.append("%s %s\n" % (_MERGETAG_HEADER, mergetag_chunks[0]))
+            # Embedded extra header needs leading space
+            for chunk in mergetag_chunks[1:]:
+                chunks.append(" %s\n" % chunk)
+
+            # No trailing empty line
+            chunks[-1] = chunks[-1].rstrip(" \n")
         for k, v in self.extra:
             if "\n" in k or "\n" in v:
                 raise AssertionError("newline in extra data: %r -> %r" % (k, v))
@@ -1186,6 +1213,9 @@ class Commit(ShaFile):
     encoding = serializable_property("encoding",
         "Encoding of the commit message.")
 
+    mergetag = serializable_property("mergetag",
+        "Associated signed tag.")
+
 
 OBJECT_CLASSES = (
     Commit,

+ 111 - 1
dulwich/tests/test_objects.py

@@ -157,7 +157,8 @@ class BlobReadTests(TestCase):
 
     def test_read_tag_from_file(self):
         t = self.get_tag(tag_sha)
-        self.assertEqual(t.object, (Commit, '51b668fd5bf7061b7d6fa525f88803e6cfadaa51'))
+        self.assertEqual(t.object,
+            (Commit, '51b668fd5bf7061b7d6fa525f88803e6cfadaa51'))
         self.assertEqual(t.name,'signed')
         self.assertEqual(t.tagger,'Ali Sabil <ali.sabil@gmail.com>')
         self.assertEqual(t.tag_time, 1231203091)
@@ -313,6 +314,115 @@ class CommitSerializationTests(TestCase):
         d._deserialize(c.as_raw_chunks())
         self.assertEqual(c, d)
 
+    def test_serialize_mergetag(self):
+        tag = make_object(
+            Tag, object=(Commit, "a38d6181ff27824c79fc7df825164a212eff6a3f"),
+            object_type_name="commit",
+            name="v2.6.22-rc7",
+            tag_time=1183319674,
+            tag_timezone=0,
+            tagger="Linus Torvalds <torvalds@woody.linux-foundation.org>",
+            message=default_message)
+        commit = self.make_commit(mergetag=[tag])
+
+        self.assertEqual("""tree d80c186a03f423a81b39df39dc87fd269736ca86
+parent ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd
+parent 4cffe90e0a41ad3f5190079d7c8f036bde29cbe6
+author James Westby <jw+debian@jameswestby.net> 1174773719 +0000
+committer James Westby <jw+debian@jameswestby.net> 1174773719 +0000
+mergetag object a38d6181ff27824c79fc7df825164a212eff6a3f
+ type commit
+ tag v2.6.22-rc7
+ tagger Linus Torvalds <torvalds@woody.linux-foundation.org> 1183319674 +0000
+ 
+ Linux 2.6.22-rc7
+ -----BEGIN PGP SIGNATURE-----
+ Version: GnuPG v1.4.7 (GNU/Linux)
+ 
+ iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql
+ OK2XeQOiEeXtT76rV4t2WR4=
+ =ivrA
+ -----END PGP SIGNATURE-----
+
+Merge ../b
+""", commit.as_raw_string())
+
+    def test_serialize_mergetags(self):
+        tag = make_object(
+            Tag, object=(Commit, "a38d6181ff27824c79fc7df825164a212eff6a3f"),
+            object_type_name="commit",
+            name="v2.6.22-rc7",
+            tag_time=1183319674,
+            tag_timezone=0,
+            tagger="Linus Torvalds <torvalds@woody.linux-foundation.org>",
+            message=default_message)
+        commit = self.make_commit(mergetag=[tag, tag])
+
+        self.assertEqual("""tree d80c186a03f423a81b39df39dc87fd269736ca86
+parent ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd
+parent 4cffe90e0a41ad3f5190079d7c8f036bde29cbe6
+author James Westby <jw+debian@jameswestby.net> 1174773719 +0000
+committer James Westby <jw+debian@jameswestby.net> 1174773719 +0000
+mergetag object a38d6181ff27824c79fc7df825164a212eff6a3f
+ type commit
+ tag v2.6.22-rc7
+ tagger Linus Torvalds <torvalds@woody.linux-foundation.org> 1183319674 +0000
+ 
+ Linux 2.6.22-rc7
+ -----BEGIN PGP SIGNATURE-----
+ Version: GnuPG v1.4.7 (GNU/Linux)
+ 
+ iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql
+ OK2XeQOiEeXtT76rV4t2WR4=
+ =ivrA
+ -----END PGP SIGNATURE-----
+mergetag object a38d6181ff27824c79fc7df825164a212eff6a3f
+ type commit
+ tag v2.6.22-rc7
+ tagger Linus Torvalds <torvalds@woody.linux-foundation.org> 1183319674 +0000
+ 
+ Linux 2.6.22-rc7
+ -----BEGIN PGP SIGNATURE-----
+ Version: GnuPG v1.4.7 (GNU/Linux)
+ 
+ iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql
+ OK2XeQOiEeXtT76rV4t2WR4=
+ =ivrA
+ -----END PGP SIGNATURE-----
+
+Merge ../b
+""", commit.as_raw_string())
+
+    def test_deserialize_mergetag(self):
+        tag = make_object(
+            Tag, object=(Commit, "a38d6181ff27824c79fc7df825164a212eff6a3f"),
+            object_type_name="commit",
+            name="v2.6.22-rc7",
+            tag_time=1183319674,
+            tag_timezone=0,
+            tagger="Linus Torvalds <torvalds@woody.linux-foundation.org>",
+            message=default_message)
+        commit = self.make_commit(mergetag=[tag])
+
+        d = Commit()
+        d._deserialize(commit.as_raw_chunks())
+        self.assertEquals(commit, d)
+
+    def test_deserialize_mergetags(self):
+        tag = make_object(
+            Tag, object=(Commit, "a38d6181ff27824c79fc7df825164a212eff6a3f"),
+            object_type_name="commit",
+            name="v2.6.22-rc7",
+            tag_time=1183319674,
+            tag_timezone=0,
+            tagger="Linus Torvalds <torvalds@woody.linux-foundation.org>",
+            message=default_message)
+        commit = self.make_commit(mergetag=[tag, tag])
+
+        d = Commit()
+        d._deserialize(commit.as_raw_chunks())
+        self.assertEquals(commit, d)
+
 
 default_committer = 'James Westby <jw+debian@jameswestby.net> 1174773719 +0000'