/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to remote.py

Share more code between local and remote classes, support opening remote branches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
 
17
import bzrlib
 
18
from bzrlib import urlutils
17
19
from bzrlib.bzrdir import BzrDir, BzrDirFormat
18
 
from bzrlib.errors import NotLocalUrl
19
 
from bzrlib.foreign import ForeignRepository
 
20
from bzrlib.errors import NoSuchFile, NotLocalUrl
20
21
from bzrlib.lockable_files import TransportLock
21
 
 
22
 
from bzrlib.plugins.git import git
23
 
from bzrlib.plugins.git.repository import GitFormat
 
22
from bzrlib.repository import Repository
24
23
from bzrlib.trace import info
25
24
from bzrlib.transport import Transport
26
25
 
27
 
from git.client import TCPGitClient, TCP_GIT_PORT
 
26
from bzrlib.plugins.git import git
 
27
from bzrlib.plugins.git.branch import GitBranch
 
28
from bzrlib.plugins.git.foreign import ForeignBranch
 
29
from bzrlib.plugins.git.repository import GitFormat, GitRepository
28
30
 
29
31
import urllib
30
32
import urlparse
32
34
 
33
35
class GitSmartTransport(Transport):
34
36
 
35
 
    def __init__(self, url):
 
37
    def __init__(self, url, _client=None):
36
38
        Transport.__init__(self, url)
37
 
        (scheme, netloc, self._path, _, _) = urlparse.urlsplit(url)
 
39
        (scheme, _, loc, _, _) = urlparse.urlsplit(url)
38
40
        assert scheme == "git"
39
 
        (self._host, self._port) = urllib.splitnport(netloc, TCP_GIT_PORT)
40
 
        self._client = TCPGitClient(self._host, self._port)
 
41
        hostport, self._path = urllib.splithost(loc)
 
42
        (self._host, self._port) = urllib.splitnport(hostport, git.protocol.TCP_GIT_PORT)
 
43
        if _client is not None:
 
44
            self._client = _client
 
45
        else:
 
46
            self._client = git.client.TCPGitClient(self._host, self._port)
41
47
 
42
 
    def fetch_pack(self, determine_wants, graph_walker, pack_data):
43
 
        def progress(text):
44
 
            info("git: %s" % text)
 
48
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
 
49
        if progress is None:
 
50
            def progress(text):
 
51
                info("git: %s" % text)
45
52
        self._client.fetch_pack(self._path, determine_wants, graph_walker, 
46
53
                pack_data, progress)
47
54
 
 
55
    def get(self, path):
 
56
        raise NoSuchFile(path)
 
57
 
 
58
    def clone(self, offset=None):
 
59
        """See Transport.clone()."""
 
60
        if offset is None:
 
61
            newurl = self.base
 
62
        else:
 
63
            newurl = urlutils.join(self.base, offset)
 
64
 
 
65
        return GitSmartTransport(newurl, self._client)
 
66
 
48
67
 
49
68
class RemoteGitDir(BzrDir):
50
69
 
51
 
    _gitrepository_class = RemoteGitRepository
52
 
 
53
 
    def __init__(self, transport, lockfiles, gitrepo, format):
 
70
    def __init__(self, transport, lockfiles, format):
54
71
        self._format = format
55
72
        self.root_transport = transport
56
 
        self._git = gitrepo
57
73
        self.transport = transport
58
74
        self._lockfiles = lockfiles
59
75
 
66
82
    def open_branch(self):
67
83
        repo = self.open_repository()
68
84
        # TODO: Support for multiple branches in one bzrdir in bzrlib!
69
 
        return RemoteGitBranch(repo, "HEAD")
 
85
        return RemoteGitBranch(self, repo, "HEAD", self._lockfiles)
70
86
 
71
87
    def open_workingtree(self):
72
88
        raise NotLocalUrl(self.transport.base)
73
89
 
74
 
 
75
 
class RemoteGitRepository(ForeignRepository):
 
90
    def cloning_metadir(self, stacked=False):
 
91
        """Produce a metadir suitable for cloning with."""
 
92
        if stacked:
 
93
            return bzrlib.bzrdir.format_registry.make_bzrdir("1.6.1-rich-root")
 
94
        else:
 
95
            return bzrlib.bzrdir.format_registry.make_bzrdir("rich-root-pack")
 
96
 
 
97
 
 
98
class RemoteGitRepository(GitRepository):
76
99
 
77
100
    def __init__(self, gitdir, lockfiles):
78
 
        Repository.__init__(self, GitFormat(), gitdir, lockfiles)
 
101
        GitRepository.__init__(self, gitdir, lockfiles)
79
102
 
80
103
    def fetch_pack(self, determine_wants, graph_walker, pack_data):
81
104
        self._transport.fetch_pack(determine_wants, graph_walker, pack_data)
82
105
 
83
106
 
84
 
def RemoteGitBranch(ForeignBranch):
85
 
 
86
 
    def __init__(self, repository, name):
87
 
        super(RemoteGitBranch, self).__init__(repository.get_mapping())
88
 
        self.repository = repository
89
 
        self.name = name
90
 
 
91
 
 
92
 
class RemoteGitBzrDirFormat(BzrDirFormat):
93
 
    """The .git directory control format."""
94
 
 
95
 
    _gitdir_class = RemoteGitDir
96
 
    _lock_class = TransportLock
97
 
 
98
 
    @classmethod
99
 
    def _known_formats(self):
100
 
        return set([GitBzrDirFormat()])
101
 
 
102
 
    def open(self, transport, _found=None):
103
 
        """Open this directory.
104
 
 
105
 
        """
106
 
        from bzrlib.plugins.git import git
107
 
        # we dont grok readonly - git isn't integrated with transport.
108
 
        url = transport.base
109
 
        if url.startswith('readonly+'):
110
 
            url = url[len('readonly+'):]
111
 
 
112
 
        try:
113
 
            gitrepo = git.repo.Repo(transport.local_abspath("."))
114
 
        except errors.bzr_errors.NotLocalUrl:
115
 
            raise errors.bzr_errors.NotBranchError(path=transport.base)
116
 
        lockfiles = GitLockableFiles(transport, GitLock())
117
 
        return self._gitdir_class(transport, lockfiles, gitrepo, self)
118
 
 
119
 
    @classmethod
120
 
    def probe_transport(klass, transport):
121
 
        """Our format is present if the transport ends in '.not/'."""
122
 
        # little ugly, but works
123
 
        format = klass()
124
 
        # delegate to the main opening code. This pays a double rtt cost at the
125
 
        # moment, so perhaps we want probe_transport to return the opened thing
126
 
        # rather than an openener ? or we could return a curried thing with the
127
 
        # dir to open already instantiated ? Needs more thought.
128
 
        try:
129
 
            format.open(transport)
130
 
            return format
131
 
        except Exception, e:
132
 
            raise errors.bzr_errors.NotBranchError(path=transport.base)
133
 
        raise errors.bzr_errors.NotBranchError(path=transport.base)
134
 
 
135
 
    def get_format_description(self):
136
 
        return "Remote Git Repository"
137
 
 
138
 
    def get_format_string(self):
139
 
        return "Remote Git Repository"
140
 
 
141
 
    def initialize_on_transport(self, transport):
142
 
        raise UninitializableFormat(self)
143
 
 
144
 
    def is_supported(self):
145
 
        return True
 
107
class RemoteGitBranch(GitBranch):
 
108
 
 
109
    def __init__(self, bzrdir, repository, name, lockfiles):
 
110
        def determine_wants(heads):
 
111
            self._ref = heads[name]
 
112
        bzrdir.root_transport.fetch_pack(determine_wants, None, lambda x: None, 
 
113
                             lambda x: mutter("git: %s" % x))
 
114
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
 
115
 
 
116
    def last_revision(self):
 
117
        return self._ref