def setUp(self): super(ProtocolGraphWalkerEmptyTestCase, self).setUp() self._repo = MemoryRepo.init_bare([], {}) backend = DictBackend({b'/': self._repo}) self._walker = ProtocolGraphWalker( TestUploadPackHandler(backend, [b'/', b'host=lolcats'], TestProto()), self._repo.object_store, self._repo.get_peeled)
def setUp(self): super(GitImportProcessorTests, self).setUp() self.repo = MemoryRepo() try: from dulwich.fastexport import GitImportProcessor except ImportError: raise SkipTest("python-fastimport not available") self.processor = GitImportProcessor(self.repo)
def _test_backend(objects, refs=None, named_files=None): if not refs: refs = {} if not named_files: named_files = {} repo = MemoryRepo.init_bare(objects, refs) for path, contents in named_files.iteritems(): repo._put_named_file(path, contents) return DictBackend({'/': repo})
def test_receive_pack(self): commit = make_commit(id=ONE, parents=[], commit_time=111) self.backend.repos["/"] = MemoryRepo.init_bare([commit], {"refs/heads/master": commit.id}) outf = BytesIO() exitcode = self.serve_command(ReceivePackHandler, ["/"], BytesIO("0000"), outf) outlines = outf.getvalue().splitlines() self.assertEqual(2, len(outlines)) self.assertEqual("1111111111111111111111111111111111111111 refs/heads/master", outlines[0][4:].split("\x00")[0]) self.assertEqual("0000", outlines[-1]) self.assertEqual(0, exitcode)
def test_commit_config_identity_in_memoryrepo(self): # commit falls back to the users' identity if it wasn't specified r = MemoryRepo.init_bare([], {}) c = r.get_config() c.set(("user",), "name", "Jelmer") c.set(("user",), "email", "*****@*****.**") commit_sha = r.do_commit("message", tree=objects.Tree().id) self.assertEqual("Jelmer <*****@*****.**>", r[commit_sha].author) self.assertEqual("Jelmer <*****@*****.**>", r[commit_sha].committer)
def setUp(self): super(ProtocolGraphWalkerTestCase, self).setUp() # Create the following commit tree: # 3---5 # / # 1---2---4 commits = [ make_commit(id=ONE, parents=[], commit_time=111), make_commit(id=TWO, parents=[ONE], commit_time=222), make_commit(id=THREE, parents=[ONE], commit_time=333), make_commit(id=FOUR, parents=[TWO], commit_time=444), make_commit(id=FIVE, parents=[THREE], commit_time=555), ] self._repo = MemoryRepo.init_bare(commits, {}) backend = DictBackend({b'/': self._repo}) self._walker = ProtocolGraphWalker( TestUploadPackHandler(backend, [b'/', b'host=lolcats'], TestProto()), self._repo.object_store, self._repo.get_peeled)
def fetch_commit(url, sha): repo = MemoryRepo() repo.object_store = TreelessObjectStore() client, path = get_transport_and_path(url) client.fetch(path, repo) return repo[sha.encode('ascii')]
def setUp(self): super(UploadPackHandlerTestCase, self).setUp() self._repo = MemoryRepo.init_bare([], {}) backend = DictBackend({'/': self._repo}) self._handler = UploadPackHandler( backend, ['/', 'host=lolcathost'], TestProto())
def test_from_ref(self): r = MemoryRepo() c1, c2, c3 = build_commit_graph(r.object_store, [[1], [2, 1], [3, 1, 2]]) r.refs[b'refs/heads/foo'] = c1.id self.assertEqual(r[c1.tree], parse_tree(r, b'foo'))
def test_commit_by_short_sha(self): r = MemoryRepo() [c1] = build_commit_graph(r.object_store, [[1]]) self.assertEqual(c1, parse_commit(r, c1.id[:10]))
def test_bad_repo_path(self): repo = MemoryRepo.init_bare([], {}) backend = DictBackend({b'/': repo}) self.assertRaises(NotGitRepository, lambda: backend.open_repository('/ups'))
def test_fetch_into_empty(self): c = LocalGitClient() t = MemoryRepo() s = open_repo('a.git') self.assertEquals(s.get_refs(), c.fetch(s.path, t))
def setUp(self): super(ReceivePackHandlerTestCase, self).setUp() self._repo = MemoryRepo.init_bare([], {}) backend = DictBackend({b'/': self._repo}) self._handler = ReceivePackHandler( backend, [b'/', b'host=lolcathost'], TestProto())
def test_fetch_into_empty(self): c = LocalGitClient() t = MemoryRepo() s = open_repo('a.git') self.addCleanup(tear_down_repo, s) self.assertEqual(s.get_refs(), c.fetch(s.path, t).refs)
def test_nonexistant(self): repo = MemoryRepo.init_bare([], {}) backend = DictBackend({b'/': repo}) self.assertRaises(NotGitRepository, backend.open_repository, "/does/not/exist/unless/foo")
class GitImportProcessorTests(TestCase): """Tests for the GitImportProcessor tests.""" def setUp(self): super(GitImportProcessorTests, self).setUp() self.repo = MemoryRepo() try: from dulwich.fastexport import GitImportProcessor except ImportError: raise SkipTest("python-fastimport not available") self.processor = GitImportProcessor(self.repo) def test_reset_handler(self): from fastimport import commands [c1] = build_commit_graph(self.repo.object_store, [[1]]) cmd = commands.ResetCommand(b"refs/heads/foo", c1.id) self.processor.reset_handler(cmd) self.assertEqual(c1.id, self.repo.get_refs()[b"refs/heads/foo"]) def test_commit_handler(self): from fastimport import commands cmd = commands.CommitCommand(b"refs/heads/foo", b"mrkr", (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), b"FOO", None, [], []) self.processor.commit_handler(cmd) commit = self.repo[self.processor.last_commit] self.assertEqual(b"Jelmer <*****@*****.**>", commit.author) self.assertEqual(b"Jelmer <*****@*****.**>", commit.committer) self.assertEqual(b"FOO", commit.message) self.assertEqual([], commit.parents) self.assertEqual(432432432.0, commit.commit_time) self.assertEqual(432432432.0, commit.author_time) self.assertEqual(3600, commit.commit_timezone) self.assertEqual(3600, commit.author_timezone) self.assertEqual(commit, self.repo[b"refs/heads/foo"]) def test_import_stream(self): markers = self.processor.import_stream(BytesIO(b"""blob mark :1 data 11 text for a commit refs/heads/master mark :2 committer Joe Foo <*****@*****.**> 1288287382 +0000 data 20 <The commit message> M 100644 :1 a """)) self.assertEqual(2, len(markers)) self.assertTrue(isinstance(self.repo[markers[b"1"]], Blob)) self.assertTrue(isinstance(self.repo[markers[b"2"]], Commit)) def test_file_add(self): from fastimport import commands cmd = commands.BlobCommand(b"23", b"data") self.processor.blob_handler(cmd) cmd = commands.CommitCommand(b"refs/heads/foo", b"mrkr", (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), b"FOO", None, [], [commands.FileModifyCommand(b"path", 0o100644, b":23", None)]) self.processor.commit_handler(cmd) commit = self.repo[self.processor.last_commit] self.assertEqual([ (b'path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172')], self.repo[commit.tree].items()) def simple_commit(self): from fastimport import commands cmd = commands.BlobCommand(b"23", b"data") self.processor.blob_handler(cmd) cmd = commands.CommitCommand(b"refs/heads/foo", b"mrkr", (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), b"FOO", None, [], [commands.FileModifyCommand(b"path", 0o100644, b":23", None)]) self.processor.commit_handler(cmd) commit = self.repo[self.processor.last_commit] return commit def make_file_commit(self, file_cmds): """Create a trivial commit with the specified file commands. :param file_cmds: File commands to run. :return: The created commit object """ from fastimport import commands cmd = commands.CommitCommand(b"refs/heads/foo", b"mrkr", (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), b"FOO", None, [], file_cmds) self.processor.commit_handler(cmd) return self.repo[self.processor.last_commit] def test_file_copy(self): from fastimport import commands self.simple_commit() commit = self.make_file_commit([commands.FileCopyCommand(b"path", b"new_path")]) self.assertEqual([ (b'new_path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172'), (b'path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172'), ], self.repo[commit.tree].items()) def test_file_move(self): from fastimport import commands self.simple_commit() commit = self.make_file_commit([commands.FileRenameCommand(b"path", b"new_path")]) self.assertEqual([ (b'new_path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172'), ], self.repo[commit.tree].items()) def test_file_delete(self): from fastimport import commands self.simple_commit() commit = self.make_file_commit([commands.FileDeleteCommand(b"path")]) self.assertEqual([], self.repo[commit.tree].items()) def test_file_deleteall(self): from fastimport import commands self.simple_commit() commit = self.make_file_commit([commands.FileDeleteAllCommand()]) self.assertEqual([], self.repo[commit.tree].items())
def test_git_loader(scheduler_host, git_origin): url = git_origin print(f"Retrieve references available at {url}") repo = MemoryRepo() gitrefs = porcelain.fetch(repo, url).refs print(f"Look for origin {url}") # use quote_plus to prevent urljoin from messing with the 'http://' part of # the url origin = apiget(f"origin/{quote_plus(url)}/get") assert origin["url"] == url visit = apiget(f"origin/{quote_plus(url)}/visit/latest") assert visit["status"] == "full" print("Check every identified git ref has been loaded") snapshot = apiget(f'snapshot/{visit["snapshot"]}') print(f'snapshot has {len(snapshot["branches"])} branches') branches = snapshot["branches"] # check every fetched branch is present in the snapshot for branch_name, rev in gitrefs.items(): # for tags, only check for final revision id if branch_name.startswith( b"refs/tags/") and not branch_name.endswith(b"^{}"): continue rev_desc = apiget(f"revision/{rev.decode()}") assert rev_desc["type"] == "git" tag_revision = {} tag_release = {} for tag, rev in gitrefs.items(): if tag.startswith(b"refs/tags/"): tag_str = tag.decode() rev_str = rev.decode() if tag.endswith(b"^{}"): tag_revision[tag_str[:-3]] = rev_str else: tag_release[tag_str] = rev_str for tag, revision in tag_revision.items(): # check that every release tag listed in the snapshot is known by the # archive and consistent release_id = tag_release[tag] release = apiget(f"release/{release_id}") assert release["id"] == release_id assert release["target_type"] == "revision" assert release["target"] == revision # and compare this with what git ls-remote reported tag_desc = branches[tag] assert tag_desc["target_type"] == "release" assert tag_desc["target"] == release_id print("Check every git object stored in the repository has been loaded") for sha1 in repo.object_store: obj = repo.get_object(sha1) sha1_str = sha1.decode() if obj.type_name == b"blob": apiget(f"content/sha1_git:{sha1_str}") elif obj.type_name == b"commit": apiget(f"revision/{sha1_str}") elif obj.type_name == b"tree": apiget(f"directory/{sha1_str}") elif obj.type_name == b"tag": apiget(f"release/{sha1_str}")
def test_current_commit_is_none_if_repo_is_empty(): assert GitRepo(MemoryRepo()).current_commit is None
def test_set_description(self): r = MemoryRepo.init_bare([], {}) description = b"Some description" r.set_description(description) self.assertEqual(description, r.get_description())
# This script creates a clone of a remote repository in local memory, # then adds a single file and pushes the result back. # # Example usage: # python examples/memoryrepo.py git+ssh://github.com/jelmer/testrepo import stat # import sys remote_url='https://gitee.com/qgbcs/gt.git' from dulwich import porcelain from dulwich.objects import Blob from dulwich.repo import MemoryRepo local_repo = MemoryRepo() local_repo.refs.set_symbolic_ref(b'HEAD', b'refs/heads/master') print(local_repo.refs.as_dict()) porcelain.fetch(local_repo, remote_url) local_repo[b'refs/heads/master'] = local_repo[b'refs/remotes/origin/master'] last_tree = local_repo[local_repo['HEAD'].tree] new_blob = Blob.from_string(b'Some contents') local_repo.object_store.add_object(new_blob) last_tree.add(b'test', stat.S_IFREG, new_blob.id) local_repo.object_store.add_object(last_tree) local_repo.do_commit( message=b'Add a file called \'test\'',
def test_create_memory(self): repo = MemoryRepo.init_bare([], {}) self._check_repo_contents(repo, True)
def test_current_tree_should_be_new_if_repo_is_empty(): tree = GitRepo(MemoryRepo()).current_tree assert tree is not None assert list(tree) == []
class GitImportProcessorTests(TestCase): """Tests for the GitImportProcessor tests.""" def setUp(self): super(GitImportProcessorTests, self).setUp() self.repo = MemoryRepo() try: from dulwich.fastexport import GitImportProcessor except ImportError: raise SkipTest("python-fastimport not available") self.processor = GitImportProcessor(self.repo) def test_reset_handler(self): from fastimport import commands [c1] = build_commit_graph(self.repo.object_store, [[1]]) cmd = commands.ResetCommand(b"refs/heads/foo", c1.id) self.processor.reset_handler(cmd) self.assertEqual(c1.id, self.repo.get_refs()[b"refs/heads/foo"]) self.assertEqual(c1.id, self.processor.last_commit) def test_reset_handler_marker(self): from fastimport import commands [c1, c2] = build_commit_graph(self.repo.object_store, [[1], [2]]) self.processor.markers[b'10'] = c1.id cmd = commands.ResetCommand(b"refs/heads/foo", b':10') self.processor.reset_handler(cmd) self.assertEqual(c1.id, self.repo.get_refs()[b"refs/heads/foo"]) def test_reset_handler_default(self): from fastimport import commands [c1, c2] = build_commit_graph(self.repo.object_store, [[1], [2]]) cmd = commands.ResetCommand(b"refs/heads/foo", None) self.processor.reset_handler(cmd) self.assertEqual(ZERO_SHA, self.repo.get_refs()[b"refs/heads/foo"]) def test_commit_handler(self): from fastimport import commands cmd = commands.CommitCommand( b"refs/heads/foo", b"mrkr", (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), b"FOO", None, [], []) self.processor.commit_handler(cmd) commit = self.repo[self.processor.last_commit] self.assertEqual(b"Jelmer <*****@*****.**>", commit.author) self.assertEqual(b"Jelmer <*****@*****.**>", commit.committer) self.assertEqual(b"FOO", commit.message) self.assertEqual([], commit.parents) self.assertEqual(432432432.0, commit.commit_time) self.assertEqual(432432432.0, commit.author_time) self.assertEqual(3600, commit.commit_timezone) self.assertEqual(3600, commit.author_timezone) self.assertEqual(commit, self.repo[b"refs/heads/foo"]) def test_commit_handler_markers(self): from fastimport import commands [c1, c2, c3] = build_commit_graph(self.repo.object_store, [[1], [2], [3]]) self.processor.markers[b'10'] = c1.id self.processor.markers[b'42'] = c2.id self.processor.markers[b'98'] = c3.id cmd = commands.CommitCommand( b"refs/heads/foo", b"mrkr", (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), b"FOO", b':10', [b':42', b':98'], []) self.processor.commit_handler(cmd) commit = self.repo[self.processor.last_commit] self.assertEqual(c1.id, commit.parents[0]) self.assertEqual(c2.id, commit.parents[1]) self.assertEqual(c3.id, commit.parents[2]) def test_import_stream(self): markers = self.processor.import_stream( BytesIO(b"""blob mark :1 data 11 text for a commit refs/heads/master mark :2 committer Joe Foo <*****@*****.**> 1288287382 +0000 data 20 <The commit message> M 100644 :1 a """)) self.assertEqual(2, len(markers)) self.assertTrue(isinstance(self.repo[markers[b"1"]], Blob)) self.assertTrue(isinstance(self.repo[markers[b"2"]], Commit)) def test_file_add(self): from fastimport import commands cmd = commands.BlobCommand(b"23", b"data") self.processor.blob_handler(cmd) cmd = commands.CommitCommand( b"refs/heads/foo", b"mrkr", (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), b"FOO", None, [], [commands.FileModifyCommand(b"path", 0o100644, b":23", None)]) self.processor.commit_handler(cmd) commit = self.repo[self.processor.last_commit] self.assertEqual( [(b'path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172')], self.repo[commit.tree].items()) def simple_commit(self): from fastimport import commands cmd = commands.BlobCommand(b"23", b"data") self.processor.blob_handler(cmd) cmd = commands.CommitCommand( b"refs/heads/foo", b"mrkr", (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), b"FOO", None, [], [commands.FileModifyCommand(b"path", 0o100644, b":23", None)]) self.processor.commit_handler(cmd) commit = self.repo[self.processor.last_commit] return commit def make_file_commit(self, file_cmds): """Create a trivial commit with the specified file commands. :param file_cmds: File commands to run. :return: The created commit object """ from fastimport import commands cmd = commands.CommitCommand( b"refs/heads/foo", b"mrkr", (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), (b"Jelmer", b"*****@*****.**", 432432432.0, 3600), b"FOO", None, [], file_cmds) self.processor.commit_handler(cmd) return self.repo[self.processor.last_commit] def test_file_copy(self): from fastimport import commands self.simple_commit() commit = self.make_file_commit( [commands.FileCopyCommand(b"path", b"new_path")]) self.assertEqual([ (b'new_path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172'), (b'path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172'), ], self.repo[commit.tree].items()) def test_file_move(self): from fastimport import commands self.simple_commit() commit = self.make_file_commit( [commands.FileRenameCommand(b"path", b"new_path")]) self.assertEqual([ (b'new_path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172'), ], self.repo[commit.tree].items()) def test_file_delete(self): from fastimport import commands self.simple_commit() commit = self.make_file_commit([commands.FileDeleteCommand(b"path")]) self.assertEqual([], self.repo[commit.tree].items()) def test_file_deleteall(self): from fastimport import commands self.simple_commit() commit = self.make_file_commit([commands.FileDeleteAllCommand()]) self.assertEqual([], self.repo[commit.tree].items())
def setup(self): self.teardown() index = RamStorage().create_index(DateRevisionHybrid()) repo = MemoryRepo() store = repo.object_store sample_page_rst_blob, sample_page_with_attachments_rst_blob = ( Blob.from_string(_SAMPLE_PAGE_RST), Blob.from_string(_SAMPLE_PAGE_WITH_ATTACHMENTS_RST), ) store.add_object(sample_page_rst_blob) store.add_object(sample_page_with_attachments_rst_blob) sample_page_tree = Tree() sample_page_tree.add('page.rst', 0100644, sample_page_rst_blob.id) store.add_object(sample_page_tree) sample_page_with_attachments_tree = Tree() sample_page_with_attachments_tree.add( 'page.rst', 0100644, sample_page_with_attachments_rst_blob.id ) store.add_object(sample_page_with_attachments_tree) pages_tree = Tree() pages_tree.add('sample-page', 0100755, sample_page_tree.id) pages_tree.add( 'sample-page-with-attachments', 0100755, sample_page_with_attachments_tree.id, ) store.add_object(pages_tree) root_tree = Tree() root_tree.add('page', 0100755, pages_tree.id) store.add_object(root_tree) c = Commit() c.tree = root_tree.id c.message = 'initial commit' c.committer = 'test committer <test@committer>' c.author = 'test author <test@author>' c.commit_time = 1174773719 c.author_time = 1174773719 c.commit_timezone = 0 c.author_timezone = 0 store.add_object(c) repo.refs['refs/heads/master'] = c.id repo.refs['HEAD'] = c.id build_hybrid_index( index=index, repo=repo, ref='HEAD', ) searcher = index.searcher() self.index = index self.searcher = searcher self.api = GitPages(repo, searcher) self.repo = repo self.root_tree = root_tree self.pages_tree = pages_tree self.sample_page_tree = sample_page_tree self.sample_page_rst_blob = sample_page_rst_blob
def test_from_commit(self): r = MemoryRepo() c1, c2, c3 = build_commit_graph(r.object_store, [[1], [2, 1], [3, 1, 2]]) self.assertEqual(r[c1.tree], parse_tree(r, c1.id)) self.assertEqual(r[c1.tree], parse_tree(r, c1.tree))
def test_blob_by_sha(self): r = MemoryRepo() b = Blob.from_string(b"Blah") r.object_store.add_object(b) self.assertEqual(b, parse_object(r, b.id))
def test_commit_by_sha(self): r = MemoryRepo() c1, c2, c3 = build_commit_graph(r.object_store, [[1], [2, 1], [3, 1, 2]]) self.assertEqual([c1], list(parse_commit_range(r, c1.id)))
def test_nonexistent(self): r = MemoryRepo() self.assertRaises(KeyError, parse_commit, r, "thisdoesnotexist")
#!/usr/bin/python # This script creates a clone of a remote repository in local memory, # then adds a single file and pushes the result back. # # Example usage: # python examples/memoryrepo.py git+ssh://github.com/jelmer/testrepo import stat import sys from dulwich import porcelain from dulwich.objects import Blob from dulwich.repo import MemoryRepo local_repo = MemoryRepo() local_repo.refs.set_symbolic_ref(b'HEAD', b'refs/heads/master') print(local_repo.refs.as_dict()) porcelain.fetch(local_repo, sys.argv[1]) local_repo['refs/heads/master'] = local_repo['refs/remotes/origin/master'] last_tree = local_repo[local_repo['HEAD'].tree] new_blob = Blob.from_string(b'Some contents') local_repo.object_store.add_object(new_blob) last_tree.add(b'test', stat.S_IFREG, new_blob.id) local_repo.object_store.add_object(last_tree) local_repo.do_commit( message=b'Add a file called \'test\'', ref=b'refs/heads/master', tree=last_tree.id)