Esempio n. 1
0
 def disable_ff_and_make_dummy_commit(self):
     # disable non-fast-forward pushes to the server
     dest = repo.Repo(os.path.join(self.gitroot, 'dest'))
     run_git_or_fail(['config', 'receive.denyNonFastForwards', 'true'],
                     cwd=dest.path)
     commit_id = self.make_dummy_commit(dest)
     return dest, commit_id
    def test_push_to_dulwich(self):
        self.import_repos()
        self.assertReposNotEqual(self._old_repo, self._new_repo)
        port = self._start_server(self._old_repo)

        run_git_or_fail(['push', self.url(port)] + self.branch_args(),
                        cwd=self._new_repo.path)
        self.assertReposEqual(self._old_repo, self._new_repo)
Esempio n. 3
0
 def setUp(self):
     CompatTestCase.setUp(self)
     DulwichClientTestBase.setUp(self)
     self._httpd = HTTPGitServer(("localhost", 0), self.gitroot)
     self.addCleanup(self._httpd.shutdown)
     threading.Thread(target=self._httpd.serve_forever).start()
     run_git_or_fail(['config', 'http.uploadpack', 'true'],
                     cwd=self.dest)
     run_git_or_fail(['config', 'http.receivepack', 'true'],
                     cwd=self.dest)
    def test_fetch_from_dulwich(self):
        self.import_repos()
        self.assertReposNotEqual(self._old_repo, self._new_repo)
        port = self._start_server(self._new_repo)

        run_git_or_fail(['fetch', self.url(port)] + self.branch_args(),
                        cwd=self._old_repo.path)
        # flush the pack cache so any new packs are picked up
        self._old_repo.object_store._pack_cache_time = 0
        self.assertReposEqual(self._old_repo, self._new_repo)
    def test_push_to_dulwich_remove_branch(self):
        self._old_repo = self.import_repo('server_old.export')
        self._new_repo = self.import_repo('server_old.export')
        self.assertReposEqual(self._old_repo, self._new_repo)
        port = self._start_server(self._old_repo)

        run_git_or_fail(['push', self.url(port), ":master"],
                        cwd=self._new_repo.path)

        self.assertEqual(list(self._old_repo.get_refs().keys()),
                         [b"refs/heads/branch"])
    def test_push_to_dulwich_issue_88_standard(self):
        # Same thing, but we reverse the role of the server/client
        # and do a push instead.
        self._source_repo = self.import_repo(
            'issue88_expect_ack_nak_client.export')
        self._client_repo = self.import_repo(
            'issue88_expect_ack_nak_server.export')
        port = self._start_server(self._source_repo)

        run_git_or_fail(['push', self.url(port), 'master'],
                        cwd=self._client_repo.path)
        self.assertReposEqual(self._source_repo, self._client_repo)
Esempio n. 7
0
    def create_new_worktree(self, repo_dir, branch):
        """Create a new worktree using git-worktree.

        :param repo_dir: The directory of the main working tree.
        :param branch: The branch or commit to checkout in the new worktree.

        :returns: The path to the new working tree.
        """
        temp_dir = tempfile.mkdtemp()
        run_git_or_fail(['worktree', 'add', temp_dir, branch], cwd=repo_dir)
        self.addCleanup(rmtree_ro, temp_dir)
        return temp_dir
    def test_clone_from_dulwich_empty(self):
        old_repo_dir = tempfile.mkdtemp()
        self.addCleanup(shutil.rmtree, old_repo_dir)
        self._old_repo = Repo.init_bare(old_repo_dir)
        port = self._start_server(self._old_repo)

        new_repo_base_dir = tempfile.mkdtemp()
        self.addCleanup(shutil.rmtree, new_repo_base_dir)
        new_repo_dir = os.path.join(new_repo_base_dir, 'empty_new')
        run_git_or_fail(['clone', self.url(port), new_repo_dir],
                        cwd=new_repo_base_dir)
        new_repo = Repo(new_repo_dir)
        self.assertReposEqual(self._old_repo, new_repo)
    def test_fetch_from_dulwich_issue_88_standard(self):
        # Basically an integration test to see that the ACK/NAK
        # generation works on repos with common head.
        self._source_repo = self.import_repo(
            'issue88_expect_ack_nak_server.export')
        self._client_repo = self.import_repo(
            'issue88_expect_ack_nak_client.export')
        port = self._start_server(self._source_repo)

        run_git_or_fail(['fetch', self.url(port), 'master'],
                        cwd=self._client_repo.path)
        self.assertObjectStoreEqual(self._source_repo.object_store,
                                    self._client_repo.object_store)
 def test_delta_medium_object(self):
     # This tests an object set that will have a copy operation
     # 2**20 in size.
     with self.get_pack(pack1_sha) as orig_pack:
         orig_blob = orig_pack[a_sha]
         new_blob = Blob()
         new_blob.data = orig_blob.data + (b'x' * 2**20)
         new_blob_2 = Blob()
         new_blob_2.data = new_blob.data + b'y'
         all_to_pack = list(orig_pack.pack_tuples()) + [(new_blob, None),
                                                        (new_blob_2, None)]
     pack_path = os.path.join(self._tempdir, 'pack_with_deltas')
     write_pack(pack_path, all_to_pack, deltify=True)
     output = run_git_or_fail(['verify-pack', '-v', pack_path])
     self.assertEqual(set(x[0].id for x in all_to_pack),
                      _git_verify_pack_object_list(output))
     # We specifically made a new blob that should be a delta
     # against the blob a_sha, so make sure we really got only 3
     # non-delta objects:
     got_non_delta = int(_NON_DELTA_RE.search(output).group('non_delta'))
     self.assertEqual(
         3, got_non_delta,
         'Expected 3 non-delta objects, got %d' % got_non_delta)
     # We expect one object to have a delta chain length of two
     # (new_blob_2), so let's verify that actually happens:
     self.assertIn(b'chain length = 2', output)
    def test_fetch_from_dulwich_issue_88_alternative(self):
        # likewise, but the case where the two repos have no common parent
        self._source_repo = self.import_repo(
            'issue88_expect_ack_nak_other.export')
        self._client_repo = self.import_repo(
            'issue88_expect_ack_nak_client.export')
        port = self._start_server(self._source_repo)

        self.assertRaises(KeyError, self._client_repo.get_object,
                          b'02a14da1fc1fc13389bbf32f0af7d8899f2b2323')
        run_git_or_fail(['fetch', self.url(port), 'master'],
                        cwd=self._client_repo.path)
        self.assertEqual(
            b'commit',
            self._client_repo.get_object(
                b'02a14da1fc1fc13389bbf32f0af7d8899f2b2323').type_name)
 def test_copy(self):
     with self.get_pack(pack1_sha) as origpack:
         self.assertSucceeds(origpack.index.check)
         pack_path = os.path.join(self._tempdir, "Elch")
         write_pack(pack_path, origpack.pack_tuples())
         output = run_git_or_fail(['verify-pack', '-v', pack_path])
         orig_shas = set(o.id for o in origpack.iterobjects())
         self.assertEqual(orig_shas, _git_verify_pack_object_list(output))
Esempio n. 13
0
    def test_git_worktree_list(self):
        # 'git worktree list' was introduced in 2.7.0
        require_git_version((2, 7, 0))
        output = run_git_or_fail(['worktree', 'list'], cwd=self._repo.path)
        worktrees = self._parse_worktree_list(output)
        self.assertEqual(len(worktrees), self._number_of_working_tree)
        self.assertEqual(worktrees[0][1], '(bare)')
        self.assertEqual(os.path.normcase(worktrees[0][0]),
                         os.path.normcase(self._mainworktree_repo.path))

        output = run_git_or_fail(['worktree', 'list'],
                                 cwd=self._mainworktree_repo.path)
        worktrees = self._parse_worktree_list(output)
        self.assertEqual(len(worktrees), self._number_of_working_tree)
        self.assertEqual(worktrees[0][1], '(bare)')
        self.assertEqual(os.path.normcase(worktrees[0][0]),
                         os.path.normcase(self._mainworktree_repo.path))
    def test_new_shallow_clone_from_dulwich(self):
        require_git_version(self.min_single_branch_version)
        self._source_repo = self.import_repo('server_new.export')
        self._stub_repo = _StubRepo('shallow')
        self.addCleanup(tear_down_repo, self._stub_repo)
        port = self._start_server(self._source_repo)

        # Fetch at depth 1
        run_git_or_fail([
            'clone', '--mirror', '--depth=1', '--no-single-branch',
            self.url(port), self._stub_repo.path
        ])
        clone = self._stub_repo = Repo(self._stub_repo.path)
        expected_shallow = [
            b'35e0b59e187dd72a0af294aedffc213eaa4d03ff',
            b'514dc6d3fbfe77361bcaef320c4d21b72bc10be9'
        ]
        self.assertEqual(expected_shallow, _get_shallow(clone))
        self.assertReposNotEqual(clone, self._source_repo)
    def test_fetch_full_depth_into_shallow_clone_from_dulwich(self):
        require_git_version(self.min_single_branch_version)
        self._source_repo = self.import_repo('server_new.export')
        self._stub_repo = _StubRepo('shallow')
        self.addCleanup(tear_down_repo, self._stub_repo)
        port = self._start_server(self._source_repo)

        # Fetch at depth 2
        run_git_or_fail([
            'clone', '--mirror', '--depth=2', '--no-single-branch',
            self.url(port), self._stub_repo.path
        ])
        clone = self._stub_repo = Repo(self._stub_repo.path)

        # Fetching at the same depth is a no-op.
        run_git_or_fail(
            ['fetch', '--depth=2', self.url(port)] + self.branch_args(),
            cwd=self._stub_repo.path)

        # The whole repo only has depth 4, so it should equal server_new.
        run_git_or_fail(
            ['fetch', '--depth=4', self.url(port)] + self.branch_args(),
            cwd=self._stub_repo.path)
        self.assertEqual([], _get_shallow(clone))
        self.assertReposEqual(clone, self._source_repo)
    def test_shallow_clone_from_git_is_identical(self):
        require_git_version(self.min_single_branch_version)
        self._source_repo = self.import_repo('server_new.export')
        self._stub_repo_git = _StubRepo('shallow-git')
        self.addCleanup(tear_down_repo, self._stub_repo_git)
        self._stub_repo_dw = _StubRepo('shallow-dw')
        self.addCleanup(tear_down_repo, self._stub_repo_dw)

        # shallow clone using stock git, then using dulwich
        run_git_or_fail([
            'clone', '--mirror', '--depth=1', '--no-single-branch',
            'file://' + self._source_repo.path, self._stub_repo_git.path
        ])

        port = self._start_server(self._source_repo)
        run_git_or_fail([
            'clone', '--mirror', '--depth=1', '--no-single-branch',
            self.url(port), self._stub_repo_dw.path
        ])

        # compare the two clones; they should be equal
        self.assertReposEqual(Repo(self._stub_repo_git.path),
                              Repo(self._stub_repo_dw.path))
    def test_fetch_same_depth_into_shallow_clone_from_dulwich(self):
        require_git_version(self.min_single_branch_version)
        self._source_repo = self.import_repo('server_new.export')
        self._stub_repo = _StubRepo('shallow')
        self.addCleanup(tear_down_repo, self._stub_repo)
        port = self._start_server(self._source_repo)

        # Fetch at depth 2
        run_git_or_fail([
            'clone', '--mirror', '--depth=2', '--no-single-branch',
            self.url(port), self._stub_repo.path
        ])
        clone = self._stub_repo = Repo(self._stub_repo.path)

        # Fetching at the same depth is a no-op.
        run_git_or_fail(
            ['fetch', '--depth=2', self.url(port)] + self.branch_args(),
            cwd=self._stub_repo.path)
        expected_shallow = [
            b'94de09a530df27ac3bb613aaecdd539e0a0655e1',
            b'da5cd81e1883c62a25bb37c4d1f8ad965b29bf8d'
        ]
        self.assertEqual(expected_shallow, _get_shallow(clone))
        self.assertReposNotEqual(clone, self._source_repo)
 def test_deltas_work(self):
     with self.get_pack(pack1_sha) as orig_pack:
         orig_blob = orig_pack[a_sha]
         new_blob = Blob()
         new_blob.data = orig_blob.data + b'x'
         all_to_pack = list(orig_pack.pack_tuples()) + [(new_blob, None)]
     pack_path = os.path.join(self._tempdir, 'pack_with_deltas')
     write_pack(pack_path, all_to_pack, deltify=True)
     output = run_git_or_fail(['verify-pack', '-v', pack_path])
     self.assertEqual(set(x[0].id for x in all_to_pack),
                      _git_verify_pack_object_list(output))
     # We specifically made a new blob that should be a delta
     # against the blob a_sha, so make sure we really got only 3
     # non-delta objects:
     got_non_delta = int(_NON_DELTA_RE.search(output).group('non_delta'))
     self.assertEqual(
         3, got_non_delta,
         'Expected 3 non-delta objects, got %d' % got_non_delta)
 def test_delta_large_object(self):
     # This tests an object set that will have a copy operation
     # 2**25 in size. This is a copy large enough that it requires
     # two copy operations in git's binary delta format.
     raise SkipTest('skipping slow, large test')
     with self.get_pack(pack1_sha) as orig_pack:
         new_blob = Blob()
         new_blob.data = 'big blob' + ('x' * 2**25)
         new_blob_2 = Blob()
         new_blob_2.data = new_blob.data + 'y'
         all_to_pack = list(orig_pack.pack_tuples()) + [(new_blob, None),
                                                        (new_blob_2, None)]
     pack_path = os.path.join(self._tempdir, "pack_with_deltas")
     write_pack(pack_path, all_to_pack, deltify=True)
     output = run_git_or_fail(['verify-pack', '-v', pack_path])
     self.assertEqual(set(x[0].id for x in all_to_pack),
                      _git_verify_pack_object_list(output))
     # We specifically made a new blob that should be a delta
     # against the blob a_sha, so make sure we really got only 4
     # non-delta objects:
     got_non_delta = int(_NON_DELTA_RE.search(output).group('non_delta'))
     self.assertEqual(
         4, got_non_delta,
         'Expected 4 non-delta objects, got %d' % got_non_delta)
Esempio n. 20
0
    def run_backend(self):
        """Call out to git http-backend."""
        # Based on CGIHTTPServer.CGIHTTPRequestHandler.run_cgi:
        # Copyright (c) 2001-2010 Python Software Foundation;
        # All Rights Reserved
        # Licensed under the Python Software Foundation License.
        rest = self.path
        # find an explicit query string, if present.
        i = rest.rfind('?')
        if i >= 0:
            rest, query = rest[:i], rest[i+1:]
        else:
            query = ''

        env = copy.deepcopy(os.environ)
        env['SERVER_SOFTWARE'] = self.version_string()
        env['SERVER_NAME'] = self.server.server_name
        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
        env['SERVER_PROTOCOL'] = self.protocol_version
        env['SERVER_PORT'] = str(self.server.server_port)
        env['GIT_PROJECT_ROOT'] = self.server.root_path
        env["GIT_HTTP_EXPORT_ALL"] = "1"
        env['REQUEST_METHOD'] = self.command
        uqrest = unquote(rest)
        env['PATH_INFO'] = uqrest
        env['SCRIPT_NAME'] = "/"
        if query:
            env['QUERY_STRING'] = query
        host = self.address_string()
        if host != self.client_address[0]:
            env['REMOTE_HOST'] = host
        env['REMOTE_ADDR'] = self.client_address[0]
        authorization = self.headers.get("authorization")
        if authorization:
            authorization = authorization.split()
            if len(authorization) == 2:
                import base64
                import binascii
                env['AUTH_TYPE'] = authorization[0]
                if authorization[0].lower() == "basic":
                    try:
                        authorization = base64.decodestring(authorization[1])
                    except binascii.Error:
                        pass
                    else:
                        authorization = authorization.split(':')
                        if len(authorization) == 2:
                            env['REMOTE_USER'] = authorization[0]
        # XXX REMOTE_IDENT
        content_type = self.headers.get('content-type')
        if content_type:
            env['CONTENT_TYPE'] = content_type
        length = self.headers.get('content-length')
        if length:
            env['CONTENT_LENGTH'] = length
        referer = self.headers.get('referer')
        if referer:
            env['HTTP_REFERER'] = referer
        accept = []
        for line in self.headers.getallmatchingheaders('accept'):
            if line[:1] in "\t\n\r ":
                accept.append(line.strip())
            else:
                accept = accept + line[7:].split(',')
        env['HTTP_ACCEPT'] = ','.join(accept)
        ua = self.headers.get('user-agent')
        if ua:
            env['HTTP_USER_AGENT'] = ua
        co = self.headers.get('cookie')
        if co:
            env['HTTP_COOKIE'] = co
        # XXX Other HTTP_* headers
        # Since we're setting the env in the parent, provide empty
        # values to override previously set values
        for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
                  'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'):
            env.setdefault(k, "")

        self.wfile.write(b"HTTP/1.1 200 Script output follows\r\n")
        self.wfile.write(
            ("Server: %s\r\n" % self.server.server_name).encode('ascii'))
        self.wfile.write(
            ("Date: %s\r\n" % self.date_time_string()).encode('ascii'))

        decoded_query = query.replace('+', ' ')

        try:
            nbytes = int(length)
        except (TypeError, ValueError):
            nbytes = 0
        if self.command.lower() == "post" and nbytes > 0:
            data = self.rfile.read(nbytes)
        else:
            data = None
        # throw away additional data [see bug #427345]
        while select.select([self.rfile._sock], [], [], 0)[0]:
            if not self.rfile._sock.recv(1):
                break
        args = ['http-backend']
        if '=' not in decoded_query:
            args.append(decoded_query)
        stdout = run_git_or_fail(
            args, input=data, env=env, stderr=subprocess.PIPE)
        self.wfile.write(stdout)
Esempio n. 21
0
 def setUp(self):
     self.gitroot = os.path.dirname(
             import_repo_to_dir('server_new.export').rstrip(os.sep))
     self.dest = os.path.join(self.gitroot, 'dest')
     file.ensure_dir_exists(self.dest)
     run_git_or_fail(['init', '--quiet', '--bare'], cwd=self.dest)
Esempio n. 22
0
 def _run_git(self, args):
     return run_git_or_fail(args, cwd=self._repo.path)
 def test_lsremote_from_dulwich(self):
     self._repo = self.import_repo('server_old.export')
     port = self._start_server(self._repo)
     o = run_git_or_fail(['ls-remote', self.url(port)])
     self.assertEqual(len(o.split(b'\n')), 4)