test_repository.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. # test_repository.py -- tests for repository.py
  2. # Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; version 2
  7. # of the License or (at your option) any later version of
  8. # the License.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  18. # MA 02110-1301, USA.
  19. """Tests for the repository."""
  20. from cStringIO import StringIO
  21. import os
  22. import shutil
  23. import tempfile
  24. import unittest
  25. import warnings
  26. from dulwich import errors
  27. from dulwich import objects
  28. from dulwich.repo import (
  29. check_ref_format,
  30. Repo,
  31. read_packed_refs,
  32. read_packed_refs_with_peeled,
  33. write_packed_refs,
  34. _split_ref_line,
  35. )
  36. from dulwich.tests.utils import (
  37. open_repo,
  38. tear_down_repo,
  39. )
  40. missing_sha = 'b91fa4d900e17e99b433218e988c4eb4a3e9a097'
  41. class CreateRepositoryTests(unittest.TestCase):
  42. def test_create(self):
  43. tmp_dir = tempfile.mkdtemp()
  44. try:
  45. repo = Repo.init_bare(tmp_dir)
  46. self.assertEquals(tmp_dir, repo._controldir)
  47. finally:
  48. shutil.rmtree(tmp_dir)
  49. class RepositoryTests(unittest.TestCase):
  50. def setUp(self):
  51. self._repo = None
  52. def tearDown(self):
  53. if self._repo is not None:
  54. tear_down_repo(self._repo)
  55. def test_simple_props(self):
  56. r = self._repo = open_repo('a.git')
  57. self.assertEqual(r.controldir(), r.path)
  58. def test_ref(self):
  59. r = self._repo = open_repo('a.git')
  60. self.assertEqual(r.ref('refs/heads/master'),
  61. 'a90fa2d900a17e99b433217e988c4eb4a2e9a097')
  62. def test_setitem(self):
  63. r = self._repo = open_repo('a.git')
  64. r["refs/tags/foo"] = 'a90fa2d900a17e99b433217e988c4eb4a2e9a097'
  65. self.assertEquals('a90fa2d900a17e99b433217e988c4eb4a2e9a097',
  66. r["refs/tags/foo"].id)
  67. def test_get_refs(self):
  68. r = self._repo = open_repo('a.git')
  69. self.assertEqual({
  70. 'HEAD': 'a90fa2d900a17e99b433217e988c4eb4a2e9a097',
  71. 'refs/heads/master': 'a90fa2d900a17e99b433217e988c4eb4a2e9a097',
  72. 'refs/tags/mytag': '28237f4dc30d0d462658d6b937b08a0f0b6ef55a',
  73. 'refs/tags/mytag-packed': 'b0931cadc54336e78a1d980420e3268903b57a50',
  74. }, r.get_refs())
  75. def test_head(self):
  76. r = self._repo = open_repo('a.git')
  77. self.assertEqual(r.head(), 'a90fa2d900a17e99b433217e988c4eb4a2e9a097')
  78. def test_get_object(self):
  79. r = self._repo = open_repo('a.git')
  80. obj = r.get_object(r.head())
  81. self.assertEqual(obj.type_name, 'commit')
  82. def test_get_object_non_existant(self):
  83. r = self._repo = open_repo('a.git')
  84. self.assertRaises(KeyError, r.get_object, missing_sha)
  85. def test_commit(self):
  86. r = self._repo = open_repo('a.git')
  87. warnings.simplefilter("ignore", DeprecationWarning)
  88. try:
  89. obj = r.commit(r.head())
  90. finally:
  91. warnings.resetwarnings()
  92. self.assertEqual(obj.type_name, 'commit')
  93. def test_commit_not_commit(self):
  94. r = self._repo = open_repo('a.git')
  95. warnings.simplefilter("ignore", DeprecationWarning)
  96. try:
  97. self.assertRaises(errors.NotCommitError,
  98. r.commit, '4f2e6529203aa6d44b5af6e3292c837ceda003f9')
  99. finally:
  100. warnings.resetwarnings()
  101. def test_tree(self):
  102. r = self._repo = open_repo('a.git')
  103. commit = r[r.head()]
  104. warnings.simplefilter("ignore", DeprecationWarning)
  105. try:
  106. tree = r.tree(commit.tree)
  107. finally:
  108. warnings.resetwarnings()
  109. self.assertEqual(tree.type_name, 'tree')
  110. self.assertEqual(tree.sha().hexdigest(), commit.tree)
  111. def test_tree_not_tree(self):
  112. r = self._repo = open_repo('a.git')
  113. warnings.simplefilter("ignore", DeprecationWarning)
  114. try:
  115. self.assertRaises(errors.NotTreeError, r.tree, r.head())
  116. finally:
  117. warnings.resetwarnings()
  118. def test_tag(self):
  119. r = self._repo = open_repo('a.git')
  120. tag_sha = '28237f4dc30d0d462658d6b937b08a0f0b6ef55a'
  121. warnings.simplefilter("ignore", DeprecationWarning)
  122. try:
  123. tag = r.tag(tag_sha)
  124. finally:
  125. warnings.resetwarnings()
  126. self.assertEqual(tag.type_name, 'tag')
  127. self.assertEqual(tag.sha().hexdigest(), tag_sha)
  128. obj_class, obj_sha = tag.object
  129. self.assertEqual(obj_class, objects.Commit)
  130. self.assertEqual(obj_sha, r.head())
  131. def test_tag_not_tag(self):
  132. r = self._repo = open_repo('a.git')
  133. warnings.simplefilter("ignore", DeprecationWarning)
  134. try:
  135. self.assertRaises(errors.NotTagError, r.tag, r.head())
  136. finally:
  137. warnings.resetwarnings()
  138. def test_get_peeled(self):
  139. # unpacked ref
  140. r = self._repo = open_repo('a.git')
  141. tag_sha = '28237f4dc30d0d462658d6b937b08a0f0b6ef55a'
  142. self.assertNotEqual(r[tag_sha].sha().hexdigest(), r.head())
  143. self.assertEqual(r.get_peeled('refs/tags/mytag'), r.head())
  144. # packed ref with cached peeled value
  145. packed_tag_sha = 'b0931cadc54336e78a1d980420e3268903b57a50'
  146. parent_sha = r[r.head()].parents[0]
  147. self.assertNotEqual(r[packed_tag_sha].sha().hexdigest(), parent_sha)
  148. self.assertEqual(r.get_peeled('refs/tags/mytag-packed'), parent_sha)
  149. # TODO: add more corner cases to test repo
  150. def test_get_peeled_not_tag(self):
  151. r = self._repo = open_repo('a.git')
  152. self.assertEqual(r.get_peeled('HEAD'), r.head())
  153. def test_get_blob(self):
  154. r = self._repo = open_repo('a.git')
  155. commit = r[r.head()]
  156. tree = r[commit.tree]
  157. blob_sha = tree.entries()[0][2]
  158. warnings.simplefilter("ignore", DeprecationWarning)
  159. try:
  160. blob = r.get_blob(blob_sha)
  161. finally:
  162. warnings.resetwarnings()
  163. self.assertEqual(blob.type_name, 'blob')
  164. self.assertEqual(blob.sha().hexdigest(), blob_sha)
  165. def test_get_blob_notblob(self):
  166. r = self._repo = open_repo('a.git')
  167. warnings.simplefilter("ignore", DeprecationWarning)
  168. try:
  169. self.assertRaises(errors.NotBlobError, r.get_blob, r.head())
  170. finally:
  171. warnings.resetwarnings()
  172. def test_linear_history(self):
  173. r = self._repo = open_repo('a.git')
  174. history = r.revision_history(r.head())
  175. shas = [c.sha().hexdigest() for c in history]
  176. self.assertEqual(shas, [r.head(),
  177. '2a72d929692c41d8554c07f6301757ba18a65d91'])
  178. def test_merge_history(self):
  179. r = self._repo = open_repo('simple_merge.git')
  180. history = r.revision_history(r.head())
  181. shas = [c.sha().hexdigest() for c in history]
  182. self.assertEqual(shas, ['5dac377bdded4c9aeb8dff595f0faeebcc8498cc',
  183. 'ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd',
  184. '4cffe90e0a41ad3f5190079d7c8f036bde29cbe6',
  185. '60dacdc733de308bb77bb76ce0fb0f9b44c9769e',
  186. '0d89f20333fbb1d2f3a94da77f4981373d8f4310'])
  187. def test_revision_history_missing_commit(self):
  188. r = self._repo = open_repo('simple_merge.git')
  189. self.assertRaises(errors.MissingCommitError, r.revision_history,
  190. missing_sha)
  191. def test_out_of_order_merge(self):
  192. """Test that revision history is ordered by date, not parent order."""
  193. r = self._repo = open_repo('ooo_merge.git')
  194. history = r.revision_history(r.head())
  195. shas = [c.sha().hexdigest() for c in history]
  196. self.assertEqual(shas, ['7601d7f6231db6a57f7bbb79ee52e4d462fd44d1',
  197. 'f507291b64138b875c28e03469025b1ea20bc614',
  198. 'fb5b0425c7ce46959bec94d54b9a157645e114f5',
  199. 'f9e39b120c68182a4ba35349f832d0e4e61f485c'])
  200. def test_get_tags_empty(self):
  201. r = self._repo = open_repo('ooo_merge.git')
  202. self.assertEqual({}, r.refs.as_dict('refs/tags'))
  203. def test_get_config(self):
  204. r = self._repo = open_repo('ooo_merge.git')
  205. self.assertEquals({}, r.get_config())
  206. def test_common_revisions(self):
  207. """
  208. This test demonstrates that ``find_common_revisions()`` actually returns
  209. common heads, not revisions; dulwich already uses
  210. ``find_common_revisions()`` in such a manner (see
  211. ``Repo.fetch_objects()``).
  212. """
  213. expected_shas = set(['60dacdc733de308bb77bb76ce0fb0f9b44c9769e'])
  214. # Source for objects.
  215. r_base = open_repo('simple_merge.git')
  216. # Re-create each-side of the merge in simple_merge.git.
  217. #
  218. # Since the trees and blobs are missing, the repository created is
  219. # corrupted, but we're only checking for commits for the purpose of this
  220. # test, so it's immaterial.
  221. r1_dir = tempfile.mkdtemp()
  222. r1_commits = ['ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd', # HEAD
  223. '60dacdc733de308bb77bb76ce0fb0f9b44c9769e',
  224. '0d89f20333fbb1d2f3a94da77f4981373d8f4310']
  225. r2_dir = tempfile.mkdtemp()
  226. r2_commits = ['4cffe90e0a41ad3f5190079d7c8f036bde29cbe6', # HEAD
  227. '60dacdc733de308bb77bb76ce0fb0f9b44c9769e',
  228. '0d89f20333fbb1d2f3a94da77f4981373d8f4310']
  229. try:
  230. r1 = Repo.init_bare(r1_dir)
  231. map(lambda c: r1.object_store.add_object(r_base.get_object(c)), \
  232. r1_commits)
  233. r1.refs['HEAD'] = r1_commits[0]
  234. r2 = Repo.init_bare(r2_dir)
  235. map(lambda c: r2.object_store.add_object(r_base.get_object(c)), \
  236. r2_commits)
  237. r2.refs['HEAD'] = r2_commits[0]
  238. # Finally, the 'real' testing!
  239. shas = r2.object_store.find_common_revisions(r1.get_graph_walker())
  240. self.assertEqual(set(shas), expected_shas)
  241. shas = r1.object_store.find_common_revisions(r2.get_graph_walker())
  242. self.assertEqual(set(shas), expected_shas)
  243. finally:
  244. shutil.rmtree(r1_dir)
  245. shutil.rmtree(r2_dir)
  246. class CheckRefFormatTests(unittest.TestCase):
  247. """Tests for the check_ref_format function.
  248. These are the same tests as in the git test suite.
  249. """
  250. def test_valid(self):
  251. self.assertTrue(check_ref_format('heads/foo'))
  252. self.assertTrue(check_ref_format('foo/bar/baz'))
  253. self.assertTrue(check_ref_format('refs///heads/foo'))
  254. self.assertTrue(check_ref_format('foo./bar'))
  255. self.assertTrue(check_ref_format('heads/foo@bar'))
  256. self.assertTrue(check_ref_format('heads/fix.lock.error'))
  257. def test_invalid(self):
  258. self.assertFalse(check_ref_format('foo'))
  259. self.assertFalse(check_ref_format('heads/foo/'))
  260. self.assertFalse(check_ref_format('./foo'))
  261. self.assertFalse(check_ref_format('.refs/foo'))
  262. self.assertFalse(check_ref_format('heads/foo..bar'))
  263. self.assertFalse(check_ref_format('heads/foo?bar'))
  264. self.assertFalse(check_ref_format('heads/foo.lock'))
  265. self.assertFalse(check_ref_format('heads/v@{ation'))
  266. self.assertFalse(check_ref_format('heads/foo\bar'))
  267. ONES = "1" * 40
  268. TWOS = "2" * 40
  269. THREES = "3" * 40
  270. FOURS = "4" * 40
  271. class PackedRefsFileTests(unittest.TestCase):
  272. def test_split_ref_line_errors(self):
  273. self.assertRaises(errors.PackedRefsException, _split_ref_line,
  274. 'singlefield')
  275. self.assertRaises(errors.PackedRefsException, _split_ref_line,
  276. 'badsha name')
  277. self.assertRaises(errors.PackedRefsException, _split_ref_line,
  278. '%s bad/../refname' % ONES)
  279. def test_read_without_peeled(self):
  280. f = StringIO('# comment\n%s ref/1\n%s ref/2' % (ONES, TWOS))
  281. self.assertEqual([(ONES, 'ref/1'), (TWOS, 'ref/2')],
  282. list(read_packed_refs(f)))
  283. def test_read_without_peeled_errors(self):
  284. f = StringIO('%s ref/1\n^%s' % (ONES, TWOS))
  285. self.assertRaises(errors.PackedRefsException, list, read_packed_refs(f))
  286. def test_read_with_peeled(self):
  287. f = StringIO('%s ref/1\n%s ref/2\n^%s\n%s ref/4' % (
  288. ONES, TWOS, THREES, FOURS))
  289. self.assertEqual([
  290. (ONES, 'ref/1', None),
  291. (TWOS, 'ref/2', THREES),
  292. (FOURS, 'ref/4', None),
  293. ], list(read_packed_refs_with_peeled(f)))
  294. def test_read_with_peeled_errors(self):
  295. f = StringIO('^%s\n%s ref/1' % (TWOS, ONES))
  296. self.assertRaises(errors.PackedRefsException, list, read_packed_refs(f))
  297. f = StringIO('%s ref/1\n^%s\n^%s' % (ONES, TWOS, THREES))
  298. self.assertRaises(errors.PackedRefsException, list, read_packed_refs(f))
  299. def test_write_with_peeled(self):
  300. f = StringIO()
  301. write_packed_refs(f, {'ref/1': ONES, 'ref/2': TWOS},
  302. {'ref/1': THREES})
  303. self.assertEqual(
  304. "# pack-refs with: peeled\n%s ref/1\n^%s\n%s ref/2\n" % (
  305. ONES, THREES, TWOS), f.getvalue())
  306. def test_write_without_peeled(self):
  307. f = StringIO()
  308. write_packed_refs(f, {'ref/1': ONES, 'ref/2': TWOS})
  309. self.assertEqual("%s ref/1\n%s ref/2\n" % (ONES, TWOS), f.getvalue())
  310. class RefsContainerTests(unittest.TestCase):
  311. def setUp(self):
  312. self._repo = open_repo('refs.git')
  313. self._refs = self._repo.refs
  314. def tearDown(self):
  315. tear_down_repo(self._repo)
  316. def test_get_packed_refs(self):
  317. self.assertEqual({
  318. 'refs/heads/packed': '42d06bd4b77fed026b154d16493e5deab78f02ec',
  319. 'refs/tags/refs-0.1': 'df6800012397fb85c56e7418dd4eb9405dee075c',
  320. }, self._refs.get_packed_refs())
  321. def test_get_peeled_not_packed(self):
  322. # not packed
  323. self.assertEqual(None, self._refs.get_peeled('refs/tags/refs-0.2'))
  324. self.assertEqual('3ec9c43c84ff242e3ef4a9fc5bc111fd780a76a8',
  325. self._refs['refs/tags/refs-0.2'])
  326. # packed, known not peelable
  327. self.assertEqual(self._refs['refs/heads/packed'],
  328. self._refs.get_peeled('refs/heads/packed'))
  329. # packed, peeled
  330. self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
  331. self._refs.get_peeled('refs/tags/refs-0.1'))
  332. def test_keys(self):
  333. self.assertEqual([
  334. 'HEAD',
  335. 'refs/heads/loop',
  336. 'refs/heads/master',
  337. 'refs/heads/packed',
  338. 'refs/tags/refs-0.1',
  339. 'refs/tags/refs-0.2',
  340. ], sorted(list(self._refs.keys())))
  341. self.assertEqual(['loop', 'master', 'packed'],
  342. sorted(self._refs.keys('refs/heads')))
  343. self.assertEqual(['refs-0.1', 'refs-0.2'],
  344. sorted(self._refs.keys('refs/tags')))
  345. def test_as_dict(self):
  346. # refs/heads/loop does not show up
  347. self.assertEqual({
  348. 'HEAD': '42d06bd4b77fed026b154d16493e5deab78f02ec',
  349. 'refs/heads/master': '42d06bd4b77fed026b154d16493e5deab78f02ec',
  350. 'refs/heads/packed': '42d06bd4b77fed026b154d16493e5deab78f02ec',
  351. 'refs/tags/refs-0.1': 'df6800012397fb85c56e7418dd4eb9405dee075c',
  352. 'refs/tags/refs-0.2': '3ec9c43c84ff242e3ef4a9fc5bc111fd780a76a8',
  353. }, self._refs.as_dict())
  354. def test_setitem(self):
  355. self._refs['refs/some/ref'] = '42d06bd4b77fed026b154d16493e5deab78f02ec'
  356. self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
  357. self._refs['refs/some/ref'])
  358. f = open(os.path.join(self._refs.path, 'refs', 'some', 'ref'), 'rb')
  359. self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
  360. f.read()[:40])
  361. f.close()
  362. def test_setitem_symbolic(self):
  363. ones = '1' * 40
  364. self._refs['HEAD'] = ones
  365. self.assertEqual(ones, self._refs['HEAD'])
  366. # ensure HEAD was not modified
  367. f = open(os.path.join(self._refs.path, 'HEAD'), 'rb')
  368. self.assertEqual('ref: refs/heads/master', iter(f).next().rstrip('\n'))
  369. f.close()
  370. # ensure the symbolic link was written through
  371. f = open(os.path.join(self._refs.path, 'refs', 'heads', 'master'), 'rb')
  372. self.assertEqual(ones, f.read()[:40])
  373. f.close()
  374. def test_set_if_equals(self):
  375. nines = '9' * 40
  376. self.assertFalse(self._refs.set_if_equals('HEAD', 'c0ffee', nines))
  377. self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
  378. self._refs['HEAD'])
  379. self.assertTrue(self._refs.set_if_equals(
  380. 'HEAD', '42d06bd4b77fed026b154d16493e5deab78f02ec', nines))
  381. self.assertEqual(nines, self._refs['HEAD'])
  382. # ensure symref was followed
  383. self.assertEqual(nines, self._refs['refs/heads/master'])
  384. self.assertFalse(os.path.exists(
  385. os.path.join(self._refs.path, 'refs', 'heads', 'master.lock')))
  386. self.assertFalse(os.path.exists(
  387. os.path.join(self._refs.path, 'HEAD.lock')))
  388. def test_add_if_new(self):
  389. nines = '9' * 40
  390. self.assertFalse(self._refs.add_if_new('refs/heads/master', nines))
  391. self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
  392. self._refs['refs/heads/master'])
  393. self.assertTrue(self._refs.add_if_new('refs/some/ref', nines))
  394. self.assertEqual(nines, self._refs['refs/some/ref'])
  395. # don't overwrite packed ref
  396. self.assertFalse(self._refs.add_if_new('refs/tags/refs-0.1', nines))
  397. self.assertEqual('df6800012397fb85c56e7418dd4eb9405dee075c',
  398. self._refs['refs/tags/refs-0.1'])
  399. def test_check_refname(self):
  400. try:
  401. self._refs._check_refname('HEAD')
  402. except KeyError:
  403. self.fail()
  404. try:
  405. self._refs._check_refname('refs/heads/foo')
  406. except KeyError:
  407. self.fail()
  408. self.assertRaises(KeyError, self._refs._check_refname, 'refs')
  409. self.assertRaises(KeyError, self._refs._check_refname, 'notrefs/foo')
  410. def test_follow(self):
  411. self.assertEquals(
  412. ('refs/heads/master', '42d06bd4b77fed026b154d16493e5deab78f02ec'),
  413. self._refs._follow('HEAD'))
  414. self.assertEquals(
  415. ('refs/heads/master', '42d06bd4b77fed026b154d16493e5deab78f02ec'),
  416. self._refs._follow('refs/heads/master'))
  417. self.assertRaises(KeyError, self._refs._follow, 'notrefs/foo')
  418. self.assertRaises(KeyError, self._refs._follow, 'refs/heads/loop')
  419. def test_contains(self):
  420. self.assertTrue('refs/heads/master' in self._refs)
  421. self.assertFalse('refs/heads/bar' in self._refs)
  422. def test_delitem(self):
  423. self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
  424. self._refs['refs/heads/master'])
  425. del self._refs['refs/heads/master']
  426. self.assertRaises(KeyError, lambda: self._refs['refs/heads/master'])
  427. ref_file = os.path.join(self._refs.path, 'refs', 'heads', 'master')
  428. self.assertFalse(os.path.exists(ref_file))
  429. self.assertFalse('refs/heads/master' in self._refs.get_packed_refs())
  430. def test_delitem_symbolic(self):
  431. self.assertEqual('ref: refs/heads/master',
  432. self._refs.read_loose_ref('HEAD'))
  433. del self._refs['HEAD']
  434. self.assertRaises(KeyError, lambda: self._refs['HEAD'])
  435. self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
  436. self._refs['refs/heads/master'])
  437. self.assertFalse(os.path.exists(os.path.join(self._refs.path, 'HEAD')))
  438. def test_remove_if_equals(self):
  439. nines = '9' * 40
  440. self.assertFalse(self._refs.remove_if_equals('HEAD', 'c0ffee'))
  441. self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
  442. self._refs['HEAD'])
  443. # HEAD is a symref, so shouldn't equal its dereferenced value
  444. self.assertFalse(self._refs.remove_if_equals(
  445. 'HEAD', '42d06bd4b77fed026b154d16493e5deab78f02ec'))
  446. self.assertTrue(self._refs.remove_if_equals(
  447. 'refs/heads/master', '42d06bd4b77fed026b154d16493e5deab78f02ec'))
  448. self.assertRaises(KeyError, lambda: self._refs['refs/heads/master'])
  449. # HEAD is now a broken symref
  450. self.assertRaises(KeyError, lambda: self._refs['HEAD'])
  451. self.assertEqual('ref: refs/heads/master',
  452. self._refs.read_loose_ref('HEAD'))
  453. self.assertFalse(os.path.exists(
  454. os.path.join(self._refs.path, 'refs', 'heads', 'master.lock')))
  455. self.assertFalse(os.path.exists(
  456. os.path.join(self._refs.path, 'HEAD.lock')))
  457. # test removing ref that is only packed
  458. self.assertEqual('df6800012397fb85c56e7418dd4eb9405dee075c',
  459. self._refs['refs/tags/refs-0.1'])
  460. self.assertTrue(
  461. self._refs.remove_if_equals('refs/tags/refs-0.1',
  462. 'df6800012397fb85c56e7418dd4eb9405dee075c'))
  463. self.assertRaises(KeyError, lambda: self._refs['refs/tags/refs-0.1'])
  464. def test_read_ref(self):
  465. self.assertEqual('ref: refs/heads/master', self._refs.read_ref("HEAD"))
  466. self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
  467. self._refs.read_ref("refs/heads/packed"))
  468. self.assertEqual(None,
  469. self._refs.read_ref("nonexistant"))