test_patch.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. # test_patch.py -- tests for patch.py
  2. # Copyright (C) 2010 Jelmer Vernooij <jelmer@jelmer.uk>
  3. #
  4. # Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
  5. # General Public License as public by the Free Software Foundation; version 2.0
  6. # or (at your option) any later version. You can redistribute it and/or
  7. # modify it under the terms of either of these two licenses.
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. #
  15. # You should have received a copy of the licenses; if not, see
  16. # <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
  17. # and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
  18. # License, Version 2.0.
  19. #
  20. """Tests for patch.py."""
  21. from io import BytesIO, StringIO
  22. from dulwich.object_store import MemoryObjectStore
  23. from dulwich.objects import S_IFGITLINK, Blob, Commit, Tree
  24. from dulwich.patch import (
  25. get_summary,
  26. git_am_patch_split,
  27. write_blob_diff,
  28. write_commit_patch,
  29. write_object_diff,
  30. write_tree_diff,
  31. )
  32. from . import SkipTest, TestCase
  33. class WriteCommitPatchTests(TestCase):
  34. def test_simple_bytesio(self):
  35. f = BytesIO()
  36. c = Commit()
  37. c.committer = c.author = b"Jelmer <jelmer@samba.org>"
  38. c.commit_time = c.author_time = 1271350201
  39. c.commit_timezone = c.author_timezone = 0
  40. c.message = b"This is the first line\nAnd this is the second line.\n"
  41. c.tree = Tree().id
  42. write_commit_patch(f, c, b"CONTENTS", (1, 1), version="custom")
  43. f.seek(0)
  44. lines = f.readlines()
  45. self.assertTrue(
  46. lines[0].startswith(b"From 0b0d34d1b5b596c928adc9a727a4b9e03d025298")
  47. )
  48. self.assertEqual(lines[1], b"From: Jelmer <jelmer@samba.org>\n")
  49. self.assertTrue(lines[2].startswith(b"Date: "))
  50. self.assertEqual(
  51. [
  52. b"Subject: [PATCH 1/1] This is the first line\n",
  53. b"And this is the second line.\n",
  54. b"\n",
  55. b"\n",
  56. b"---\n",
  57. ],
  58. lines[3:8],
  59. )
  60. self.assertEqual([b"CONTENTS-- \n", b"custom\n"], lines[-2:])
  61. if len(lines) >= 12:
  62. # diffstat may not be present
  63. self.assertEqual(lines[8], b" 0 files changed\n")
  64. class ReadGitAmPatch(TestCase):
  65. def test_extract_string(self):
  66. text = b"""\
  67. From ff643aae102d8870cac88e8f007e70f58f3a7363 Mon Sep 17 00:00:00 2001
  68. From: Jelmer Vernooij <jelmer@samba.org>
  69. Date: Thu, 15 Apr 2010 15:40:28 +0200
  70. Subject: [PATCH 1/2] Remove executable bit from prey.ico (triggers a warning).
  71. ---
  72. pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  73. 1 files changed, 0 insertions(+), 0 deletions(-)
  74. mode change 100755 => 100644 pixmaps/prey.ico
  75. --
  76. 1.7.0.4
  77. """
  78. c, diff, version = git_am_patch_split(StringIO(text.decode("utf-8")), "utf-8")
  79. self.assertEqual(b"Jelmer Vernooij <jelmer@samba.org>", c.committer)
  80. self.assertEqual(b"Jelmer Vernooij <jelmer@samba.org>", c.author)
  81. self.assertEqual(
  82. b"Remove executable bit from prey.ico " b"(triggers a warning).\n",
  83. c.message,
  84. )
  85. self.assertEqual(
  86. b""" pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  87. 1 files changed, 0 insertions(+), 0 deletions(-)
  88. mode change 100755 => 100644 pixmaps/prey.ico
  89. """,
  90. diff,
  91. )
  92. self.assertEqual(b"1.7.0.4", version)
  93. def test_extract_bytes(self):
  94. text = b"""\
  95. From ff643aae102d8870cac88e8f007e70f58f3a7363 Mon Sep 17 00:00:00 2001
  96. From: Jelmer Vernooij <jelmer@samba.org>
  97. Date: Thu, 15 Apr 2010 15:40:28 +0200
  98. Subject: [PATCH 1/2] Remove executable bit from prey.ico (triggers a warning).
  99. ---
  100. pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  101. 1 files changed, 0 insertions(+), 0 deletions(-)
  102. mode change 100755 => 100644 pixmaps/prey.ico
  103. --
  104. 1.7.0.4
  105. """
  106. c, diff, version = git_am_patch_split(BytesIO(text))
  107. self.assertEqual(b"Jelmer Vernooij <jelmer@samba.org>", c.committer)
  108. self.assertEqual(b"Jelmer Vernooij <jelmer@samba.org>", c.author)
  109. self.assertEqual(
  110. b"Remove executable bit from prey.ico " b"(triggers a warning).\n",
  111. c.message,
  112. )
  113. self.assertEqual(
  114. b""" pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  115. 1 files changed, 0 insertions(+), 0 deletions(-)
  116. mode change 100755 => 100644 pixmaps/prey.ico
  117. """,
  118. diff,
  119. )
  120. self.assertEqual(b"1.7.0.4", version)
  121. def test_extract_spaces(self):
  122. text = b"""From ff643aae102d8870cac88e8f007e70f58f3a7363 Mon Sep 17 00:00:00 2001
  123. From: Jelmer Vernooij <jelmer@samba.org>
  124. Date: Thu, 15 Apr 2010 15:40:28 +0200
  125. Subject: [Dulwich-users] [PATCH] Added unit tests for
  126. dulwich.object_store.tree_lookup_path.
  127. * dulwich/tests/test_object_store.py
  128. (TreeLookupPathTests): This test case contains a few tests that ensure the
  129. tree_lookup_path function works as expected.
  130. ---
  131. pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  132. 1 files changed, 0 insertions(+), 0 deletions(-)
  133. mode change 100755 => 100644 pixmaps/prey.ico
  134. --
  135. 1.7.0.4
  136. """
  137. c, diff, version = git_am_patch_split(BytesIO(text), "utf-8")
  138. self.assertEqual(
  139. b"""\
  140. Added unit tests for dulwich.object_store.tree_lookup_path.
  141. * dulwich/tests/test_object_store.py
  142. (TreeLookupPathTests): This test case contains a few tests that ensure the
  143. tree_lookup_path function works as expected.
  144. """,
  145. c.message,
  146. )
  147. def test_extract_pseudo_from_header(self):
  148. text = b"""From ff643aae102d8870cac88e8f007e70f58f3a7363 Mon Sep 17 00:00:00 2001
  149. From: Jelmer Vernooij <jelmer@samba.org>
  150. Date: Thu, 15 Apr 2010 15:40:28 +0200
  151. Subject: [Dulwich-users] [PATCH] Added unit tests for
  152. dulwich.object_store.tree_lookup_path.
  153. From: Jelmer Vernooij <jelmer@debian.org>
  154. * dulwich/tests/test_object_store.py
  155. (TreeLookupPathTests): This test case contains a few tests that ensure the
  156. tree_lookup_path function works as expected.
  157. ---
  158. pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  159. 1 files changed, 0 insertions(+), 0 deletions(-)
  160. mode change 100755 => 100644 pixmaps/prey.ico
  161. --
  162. 1.7.0.4
  163. """
  164. c, diff, version = git_am_patch_split(BytesIO(text), "utf-8")
  165. self.assertEqual(b"Jelmer Vernooij <jelmer@debian.org>", c.author)
  166. self.assertEqual(
  167. b"""\
  168. Added unit tests for dulwich.object_store.tree_lookup_path.
  169. * dulwich/tests/test_object_store.py
  170. (TreeLookupPathTests): This test case contains a few tests that ensure the
  171. tree_lookup_path function works as expected.
  172. """,
  173. c.message,
  174. )
  175. def test_extract_no_version_tail(self):
  176. text = b"""\
  177. From ff643aae102d8870cac88e8f007e70f58f3a7363 Mon Sep 17 00:00:00 2001
  178. From: Jelmer Vernooij <jelmer@samba.org>
  179. Date: Thu, 15 Apr 2010 15:40:28 +0200
  180. Subject: [Dulwich-users] [PATCH] Added unit tests for
  181. dulwich.object_store.tree_lookup_path.
  182. From: Jelmer Vernooij <jelmer@debian.org>
  183. ---
  184. pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  185. 1 files changed, 0 insertions(+), 0 deletions(-)
  186. mode change 100755 => 100644 pixmaps/prey.ico
  187. """
  188. c, diff, version = git_am_patch_split(BytesIO(text), "utf-8")
  189. self.assertEqual(None, version)
  190. def test_extract_mercurial(self):
  191. raise SkipTest(
  192. "git_am_patch_split doesn't handle Mercurial patches " "properly yet"
  193. )
  194. expected_diff = """\
  195. diff --git a/dulwich/tests/test_patch.py b/dulwich/tests/test_patch.py
  196. --- a/dulwich/tests/test_patch.py
  197. +++ b/dulwich/tests/test_patch.py
  198. @@ -158,7 +158,7 @@
  199. '''
  200. c, diff, version = git_am_patch_split(BytesIO(text))
  201. - self.assertIs(None, version)
  202. + self.assertEqual(None, version)
  203. class DiffTests(TestCase):
  204. """
  205. text = (
  206. """\
  207. From dulwich-users-bounces+jelmer=samba.org@lists.launchpad.net \
  208. Mon Nov 29 00:58:18 2010
  209. Date: Sun, 28 Nov 2010 17:57:27 -0600
  210. From: Augie Fackler <durin42@gmail.com>
  211. To: dulwich-users <dulwich-users@lists.launchpad.net>
  212. Subject: [Dulwich-users] [PATCH] test_patch: fix tests on Python 2.6
  213. Content-Transfer-Encoding: 8bit
  214. Change-Id: I5e51313d4ae3a65c3f00c665002a7489121bb0d6
  215. %s
  216. _______________________________________________
  217. Mailing list: https://launchpad.net/~dulwich-users
  218. Post to : dulwich-users@lists.launchpad.net
  219. Unsubscribe : https://launchpad.net/~dulwich-users
  220. More help : https://help.launchpad.net/ListHelp
  221. """
  222. % expected_diff
  223. )
  224. c, diff, version = git_am_patch_split(BytesIO(text))
  225. self.assertEqual(expected_diff, diff)
  226. self.assertEqual(None, version)
  227. class DiffTests(TestCase):
  228. """Tests for write_blob_diff and write_tree_diff."""
  229. def test_blob_diff(self):
  230. f = BytesIO()
  231. write_blob_diff(
  232. f,
  233. (b"foo.txt", 0o644, Blob.from_string(b"old\nsame\n")),
  234. (b"bar.txt", 0o644, Blob.from_string(b"new\nsame\n")),
  235. )
  236. self.assertEqual(
  237. [
  238. b"diff --git a/foo.txt b/bar.txt",
  239. b"index 3b0f961..a116b51 644",
  240. b"--- a/foo.txt",
  241. b"+++ b/bar.txt",
  242. b"@@ -1,2 +1,2 @@",
  243. b"-old",
  244. b"+new",
  245. b" same",
  246. ],
  247. f.getvalue().splitlines(),
  248. )
  249. def test_blob_add(self):
  250. f = BytesIO()
  251. write_blob_diff(
  252. f,
  253. (None, None, None),
  254. (b"bar.txt", 0o644, Blob.from_string(b"new\nsame\n")),
  255. )
  256. self.assertEqual(
  257. [
  258. b"diff --git a/bar.txt b/bar.txt",
  259. b"new file mode 644",
  260. b"index 0000000..a116b51",
  261. b"--- /dev/null",
  262. b"+++ b/bar.txt",
  263. b"@@ -0,0 +1,2 @@",
  264. b"+new",
  265. b"+same",
  266. ],
  267. f.getvalue().splitlines(),
  268. )
  269. def test_blob_remove(self):
  270. f = BytesIO()
  271. write_blob_diff(
  272. f,
  273. (b"bar.txt", 0o644, Blob.from_string(b"new\nsame\n")),
  274. (None, None, None),
  275. )
  276. self.assertEqual(
  277. [
  278. b"diff --git a/bar.txt b/bar.txt",
  279. b"deleted file mode 644",
  280. b"index a116b51..0000000",
  281. b"--- a/bar.txt",
  282. b"+++ /dev/null",
  283. b"@@ -1,2 +0,0 @@",
  284. b"-new",
  285. b"-same",
  286. ],
  287. f.getvalue().splitlines(),
  288. )
  289. def test_tree_diff(self):
  290. f = BytesIO()
  291. store = MemoryObjectStore()
  292. added = Blob.from_string(b"add\n")
  293. removed = Blob.from_string(b"removed\n")
  294. changed1 = Blob.from_string(b"unchanged\nremoved\n")
  295. changed2 = Blob.from_string(b"unchanged\nadded\n")
  296. unchanged = Blob.from_string(b"unchanged\n")
  297. tree1 = Tree()
  298. tree1.add(b"removed.txt", 0o644, removed.id)
  299. tree1.add(b"changed.txt", 0o644, changed1.id)
  300. tree1.add(b"unchanged.txt", 0o644, changed1.id)
  301. tree2 = Tree()
  302. tree2.add(b"added.txt", 0o644, added.id)
  303. tree2.add(b"changed.txt", 0o644, changed2.id)
  304. tree2.add(b"unchanged.txt", 0o644, changed1.id)
  305. store.add_objects(
  306. [
  307. (o, None)
  308. for o in [
  309. tree1,
  310. tree2,
  311. added,
  312. removed,
  313. changed1,
  314. changed2,
  315. unchanged,
  316. ]
  317. ]
  318. )
  319. write_tree_diff(f, store, tree1.id, tree2.id)
  320. self.assertEqual(
  321. [
  322. b"diff --git a/added.txt b/added.txt",
  323. b"new file mode 644",
  324. b"index 0000000..76d4bb8",
  325. b"--- /dev/null",
  326. b"+++ b/added.txt",
  327. b"@@ -0,0 +1 @@",
  328. b"+add",
  329. b"diff --git a/changed.txt b/changed.txt",
  330. b"index bf84e48..1be2436 644",
  331. b"--- a/changed.txt",
  332. b"+++ b/changed.txt",
  333. b"@@ -1,2 +1,2 @@",
  334. b" unchanged",
  335. b"-removed",
  336. b"+added",
  337. b"diff --git a/removed.txt b/removed.txt",
  338. b"deleted file mode 644",
  339. b"index 2c3f0b3..0000000",
  340. b"--- a/removed.txt",
  341. b"+++ /dev/null",
  342. b"@@ -1 +0,0 @@",
  343. b"-removed",
  344. ],
  345. f.getvalue().splitlines(),
  346. )
  347. def test_tree_diff_submodule(self):
  348. f = BytesIO()
  349. store = MemoryObjectStore()
  350. tree1 = Tree()
  351. tree1.add(
  352. b"asubmodule",
  353. S_IFGITLINK,
  354. b"06d0bdd9e2e20377b3180e4986b14c8549b393e4",
  355. )
  356. tree2 = Tree()
  357. tree2.add(
  358. b"asubmodule",
  359. S_IFGITLINK,
  360. b"cc975646af69f279396d4d5e1379ac6af80ee637",
  361. )
  362. store.add_objects([(o, None) for o in [tree1, tree2]])
  363. write_tree_diff(f, store, tree1.id, tree2.id)
  364. self.assertEqual(
  365. [
  366. b"diff --git a/asubmodule b/asubmodule",
  367. b"index 06d0bdd..cc97564 160000",
  368. b"--- a/asubmodule",
  369. b"+++ b/asubmodule",
  370. b"@@ -1 +1 @@",
  371. b"-Subproject commit 06d0bdd9e2e20377b3180e4986b14c8549b393e4",
  372. b"+Subproject commit cc975646af69f279396d4d5e1379ac6af80ee637",
  373. ],
  374. f.getvalue().splitlines(),
  375. )
  376. def test_object_diff_blob(self):
  377. f = BytesIO()
  378. b1 = Blob.from_string(b"old\nsame\n")
  379. b2 = Blob.from_string(b"new\nsame\n")
  380. store = MemoryObjectStore()
  381. store.add_objects([(b1, None), (b2, None)])
  382. write_object_diff(
  383. f, store, (b"foo.txt", 0o644, b1.id), (b"bar.txt", 0o644, b2.id)
  384. )
  385. self.assertEqual(
  386. [
  387. b"diff --git a/foo.txt b/bar.txt",
  388. b"index 3b0f961..a116b51 644",
  389. b"--- a/foo.txt",
  390. b"+++ b/bar.txt",
  391. b"@@ -1,2 +1,2 @@",
  392. b"-old",
  393. b"+new",
  394. b" same",
  395. ],
  396. f.getvalue().splitlines(),
  397. )
  398. def test_object_diff_add_blob(self):
  399. f = BytesIO()
  400. store = MemoryObjectStore()
  401. b2 = Blob.from_string(b"new\nsame\n")
  402. store.add_object(b2)
  403. write_object_diff(f, store, (None, None, None), (b"bar.txt", 0o644, b2.id))
  404. self.assertEqual(
  405. [
  406. b"diff --git a/bar.txt b/bar.txt",
  407. b"new file mode 644",
  408. b"index 0000000..a116b51",
  409. b"--- /dev/null",
  410. b"+++ b/bar.txt",
  411. b"@@ -0,0 +1,2 @@",
  412. b"+new",
  413. b"+same",
  414. ],
  415. f.getvalue().splitlines(),
  416. )
  417. def test_object_diff_remove_blob(self):
  418. f = BytesIO()
  419. b1 = Blob.from_string(b"new\nsame\n")
  420. store = MemoryObjectStore()
  421. store.add_object(b1)
  422. write_object_diff(f, store, (b"bar.txt", 0o644, b1.id), (None, None, None))
  423. self.assertEqual(
  424. [
  425. b"diff --git a/bar.txt b/bar.txt",
  426. b"deleted file mode 644",
  427. b"index a116b51..0000000",
  428. b"--- a/bar.txt",
  429. b"+++ /dev/null",
  430. b"@@ -1,2 +0,0 @@",
  431. b"-new",
  432. b"-same",
  433. ],
  434. f.getvalue().splitlines(),
  435. )
  436. def test_object_diff_bin_blob_force(self):
  437. f = BytesIO()
  438. # Prepare two slightly different PNG headers
  439. b1 = Blob.from_string(
  440. b"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"
  441. b"\x00\x00\x00\x0d\x49\x48\x44\x52"
  442. b"\x00\x00\x01\xd5\x00\x00\x00\x9f"
  443. b"\x08\x04\x00\x00\x00\x05\x04\x8b"
  444. )
  445. b2 = Blob.from_string(
  446. b"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"
  447. b"\x00\x00\x00\x0d\x49\x48\x44\x52"
  448. b"\x00\x00\x01\xd5\x00\x00\x00\x9f"
  449. b"\x08\x03\x00\x00\x00\x98\xd3\xb3"
  450. )
  451. store = MemoryObjectStore()
  452. store.add_objects([(b1, None), (b2, None)])
  453. write_object_diff(
  454. f,
  455. store,
  456. (b"foo.png", 0o644, b1.id),
  457. (b"bar.png", 0o644, b2.id),
  458. diff_binary=True,
  459. )
  460. self.assertEqual(
  461. [
  462. b"diff --git a/foo.png b/bar.png",
  463. b"index f73e47d..06364b7 644",
  464. b"--- a/foo.png",
  465. b"+++ b/bar.png",
  466. b"@@ -1,4 +1,4 @@",
  467. b" \x89PNG",
  468. b" \x1a",
  469. b" \x00\x00\x00",
  470. b"-IHDR\x00\x00\x01\xd5\x00\x00\x00"
  471. b"\x9f\x08\x04\x00\x00\x00\x05\x04\x8b",
  472. b"\\ No newline at end of file",
  473. b"+IHDR\x00\x00\x01\xd5\x00\x00\x00\x9f"
  474. b"\x08\x03\x00\x00\x00\x98\xd3\xb3",
  475. b"\\ No newline at end of file",
  476. ],
  477. f.getvalue().splitlines(),
  478. )
  479. def test_object_diff_bin_blob(self):
  480. f = BytesIO()
  481. # Prepare two slightly different PNG headers
  482. b1 = Blob.from_string(
  483. b"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"
  484. b"\x00\x00\x00\x0d\x49\x48\x44\x52"
  485. b"\x00\x00\x01\xd5\x00\x00\x00\x9f"
  486. b"\x08\x04\x00\x00\x00\x05\x04\x8b"
  487. )
  488. b2 = Blob.from_string(
  489. b"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"
  490. b"\x00\x00\x00\x0d\x49\x48\x44\x52"
  491. b"\x00\x00\x01\xd5\x00\x00\x00\x9f"
  492. b"\x08\x03\x00\x00\x00\x98\xd3\xb3"
  493. )
  494. store = MemoryObjectStore()
  495. store.add_objects([(b1, None), (b2, None)])
  496. write_object_diff(
  497. f, store, (b"foo.png", 0o644, b1.id), (b"bar.png", 0o644, b2.id)
  498. )
  499. self.assertEqual(
  500. [
  501. b"diff --git a/foo.png b/bar.png",
  502. b"index f73e47d..06364b7 644",
  503. b"Binary files a/foo.png and b/bar.png differ",
  504. ],
  505. f.getvalue().splitlines(),
  506. )
  507. def test_object_diff_add_bin_blob(self):
  508. f = BytesIO()
  509. b2 = Blob.from_string(
  510. b"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"
  511. b"\x00\x00\x00\x0d\x49\x48\x44\x52"
  512. b"\x00\x00\x01\xd5\x00\x00\x00\x9f"
  513. b"\x08\x03\x00\x00\x00\x98\xd3\xb3"
  514. )
  515. store = MemoryObjectStore()
  516. store.add_object(b2)
  517. write_object_diff(f, store, (None, None, None), (b"bar.png", 0o644, b2.id))
  518. self.assertEqual(
  519. [
  520. b"diff --git a/bar.png b/bar.png",
  521. b"new file mode 644",
  522. b"index 0000000..06364b7",
  523. b"Binary files /dev/null and b/bar.png differ",
  524. ],
  525. f.getvalue().splitlines(),
  526. )
  527. def test_object_diff_remove_bin_blob(self):
  528. f = BytesIO()
  529. b1 = Blob.from_string(
  530. b"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"
  531. b"\x00\x00\x00\x0d\x49\x48\x44\x52"
  532. b"\x00\x00\x01\xd5\x00\x00\x00\x9f"
  533. b"\x08\x04\x00\x00\x00\x05\x04\x8b"
  534. )
  535. store = MemoryObjectStore()
  536. store.add_object(b1)
  537. write_object_diff(f, store, (b"foo.png", 0o644, b1.id), (None, None, None))
  538. self.assertEqual(
  539. [
  540. b"diff --git a/foo.png b/foo.png",
  541. b"deleted file mode 644",
  542. b"index f73e47d..0000000",
  543. b"Binary files a/foo.png and /dev/null differ",
  544. ],
  545. f.getvalue().splitlines(),
  546. )
  547. def test_object_diff_kind_change(self):
  548. f = BytesIO()
  549. b1 = Blob.from_string(b"new\nsame\n")
  550. store = MemoryObjectStore()
  551. store.add_object(b1)
  552. write_object_diff(
  553. f,
  554. store,
  555. (b"bar.txt", 0o644, b1.id),
  556. (
  557. b"bar.txt",
  558. 0o160000,
  559. b"06d0bdd9e2e20377b3180e4986b14c8549b393e4",
  560. ),
  561. )
  562. self.assertEqual(
  563. [
  564. b"diff --git a/bar.txt b/bar.txt",
  565. b"old file mode 644",
  566. b"new file mode 160000",
  567. b"index a116b51..06d0bdd 160000",
  568. b"--- a/bar.txt",
  569. b"+++ b/bar.txt",
  570. b"@@ -1,2 +1 @@",
  571. b"-new",
  572. b"-same",
  573. b"+Subproject commit 06d0bdd9e2e20377b3180e4986b14c8549b393e4",
  574. ],
  575. f.getvalue().splitlines(),
  576. )
  577. class GetSummaryTests(TestCase):
  578. def test_simple(self):
  579. c = Commit()
  580. c.committer = c.author = b"Jelmer <jelmer@samba.org>"
  581. c.commit_time = c.author_time = 1271350201
  582. c.commit_timezone = c.author_timezone = 0
  583. c.message = b"This is the first line\nAnd this is the second line.\n"
  584. c.tree = Tree().id
  585. self.assertEqual("This-is-the-first-line", get_summary(c))