test_patch.py 21 KB

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