/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 commands.py

  • Committer: John Arbash Meinel
  • Date: 2010-01-12 22:51:31 UTC
  • mto: This revision was merged to the branch mainline in revision 4955.
  • Revision ID: john@arbash-meinel.com-20100112225131-he8h411p6aeeb947
Delay grabbing an output stream until we actually go to show a diff.

This makes the test suite happy, but it also seems to be reasonable.
If we aren't going to write anything, we don't need to hold an
output stream open.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2009 Canonical Ltd
2
 
 
3
 
# Authors: Robert Collins <robert.collins@canonical.com>
4
 
#          Jelmer Vernooij <jelmer@samba.org>
5
 
#          John Carr <john.carr@unrouted.co.uk>
6
 
#
7
 
# This program is free software; you can redistribute it and/or modify
8
 
# it under the terms of the GNU General Public License as published by
9
 
# the Free Software Foundation; either version 2 of the License, or
10
 
# (at your option) any later version.
11
 
#
12
 
# This program is distributed in the hope that it will be useful,
13
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
# GNU General Public License for more details.
16
 
#
17
 
# You should have received a copy of the GNU General Public License
18
 
# along with this program; if not, write to the Free Software
19
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
 
21
 
"""Git-specific subcommands for Bazaar."""
22
 
 
23
 
from bzrlib.commands import (
24
 
    Command,
25
 
    display_command,
26
 
    )
27
 
from bzrlib.option import (
28
 
    Option,
29
 
    )
30
 
 
31
 
 
32
 
class cmd_git_import(Command):
33
 
    """Import all branches from a git repository.
34
 
 
35
 
    """
36
 
 
37
 
    takes_args = ["src_location", "dest_location?"]
38
 
 
39
 
    def run(self, src_location, dest_location=None):
40
 
        from collections import defaultdict
41
 
        import os
42
 
        from bzrlib import (
43
 
            controldir,
44
 
            trace,
45
 
            ui,
46
 
            )
47
 
        from bzrlib.bzrdir import (
48
 
            BzrDir,
49
 
            )
50
 
        from bzrlib.errors import (
51
 
            BzrCommandError,
52
 
            NoRepositoryPresent,
53
 
            NotBranchError,
54
 
            )
55
 
        from bzrlib.repository import (
56
 
            InterRepository,
57
 
            Repository,
58
 
            )
59
 
        from bzrlib.transport import get_transport
60
 
        from bzrlib.plugins.git.branch import (
61
 
            GitBranch,
62
 
            extract_tags,
63
 
            )
64
 
        from bzrlib.plugins.git.refs import ref_to_branch_name
65
 
        from bzrlib.plugins.git.repository import GitRepository
66
 
 
67
 
        dest_format = controldir.ControlDirFormat.get_default_format()
68
 
 
69
 
        if dest_location is None:
70
 
            dest_location = os.path.basename(src_location.rstrip("/\\"))
71
 
 
72
 
        dest_transport = get_transport(dest_location)
73
 
 
74
 
        source_repo = Repository.open(src_location)
75
 
        if not isinstance(source_repo, GitRepository):
76
 
            raise BzrCommandError("%r is not a git repository" % src_location)
77
 
        try:
78
 
            target_bzrdir = BzrDir.open_from_transport(dest_transport)
79
 
        except NotBranchError:
80
 
            target_bzrdir = dest_format.initialize_on_transport_ex(
81
 
                dest_transport, shared_repo=True)[1]
82
 
        try:
83
 
            target_repo = target_bzrdir.find_repository()
84
 
        except NoRepositoryPresent:
85
 
            target_repo = target_bzrdir.create_repository(shared=True)
86
 
 
87
 
        if not target_repo.supports_rich_root():
88
 
            raise BzrCommandError("Target repository doesn't support rich roots")
89
 
 
90
 
        interrepo = InterRepository.get(source_repo, target_repo)
91
 
        mapping = source_repo.get_mapping()
92
 
        refs = interrepo.fetch()
93
 
        unpeeled_tags = defaultdict(set)
94
 
        tags = {}
95
 
        for k, (peeled, unpeeled) in extract_tags(refs).iteritems():
96
 
            tags[k] = mapping.revision_id_foreign_to_bzr(peeled)
97
 
            if unpeeled is not None:
98
 
                unpeeled_tags[peeled].add(unpeeled)
99
 
        # FIXME: Store unpeeled tag map
100
 
        pb = ui.ui_factory.nested_progress_bar()
101
 
        try:
102
 
            for i, (name, ref) in enumerate(refs.iteritems()):
103
 
                try:
104
 
                    ref_to_branch_name(name)
105
 
                except ValueError:
106
 
                    # Not a branch, ignore
107
 
                    continue
108
 
                pb.update("creating branches", i, len(refs))
109
 
                head_transport = dest_transport.clone(name)
110
 
                try:
111
 
                    head_bzrdir = BzrDir.open_from_transport(head_transport)
112
 
                except NotBranchError:
113
 
                    head_bzrdir = dest_format.initialize_on_transport_ex(
114
 
                        head_transport, create_prefix=True)[1]
115
 
                try:
116
 
                    head_branch = head_bzrdir.open_branch()
117
 
                except NotBranchError:
118
 
                    head_branch = head_bzrdir.create_branch()
119
 
                revid = mapping.revision_id_foreign_to_bzr(ref)
120
 
                source_branch = GitBranch(source_repo.bzrdir, source_repo,
121
 
                    name, None, tags)
122
 
                source_branch.head = ref
123
 
                if head_branch.last_revision() != revid:
124
 
                    head_branch.generate_revision_history(revid)
125
 
                source_branch.tags.merge_to(head_branch.tags)
126
 
        finally:
127
 
            pb.finished()
128
 
        trace.note("Use 'bzr checkout' to create a working tree in "
129
 
                   "the newly created branches.")
130
 
 
131
 
 
132
 
 
133
 
class cmd_git_object(Command):
134
 
    """List or display Git objects by SHA.
135
 
 
136
 
    Cat a particular object's Git representation if a SHA is specified.
137
 
    List all available SHAs otherwise.
138
 
    """
139
 
 
140
 
    hidden = True
141
 
 
142
 
    aliases = ["git-objects", "git-cat"]
143
 
    takes_args = ["sha1?"]
144
 
    takes_options = [Option('directory',
145
 
        short_name='d',
146
 
        help='Location of repository.', type=unicode),
147
 
        Option('pretty', help='Pretty-print objects.')]
148
 
    encoding_type = 'exact'
149
 
 
150
 
    @display_command
151
 
    def run(self, sha1=None, directory=".", pretty=False):
152
 
        from bzrlib.errors import (
153
 
            BzrCommandError,
154
 
            )
155
 
        from bzrlib.bzrdir import (
156
 
            BzrDir,
157
 
            )
158
 
        bzrdir, _ = BzrDir.open_containing(directory)
159
 
        repo = bzrdir.find_repository()
160
 
        from bzrlib.plugins.git.object_store import (
161
 
            get_object_store,
162
 
            )
163
 
        object_store = get_object_store(repo)
164
 
        object_store.lock_read()
165
 
        try:
166
 
            if sha1 is not None:
167
 
                try:
168
 
                    obj = object_store[str(sha1)]
169
 
                except KeyError:
170
 
                    raise BzrCommandError("Object not found: %s" % sha1)
171
 
                if pretty:
172
 
                    text = obj.as_pretty_string()
173
 
                else:
174
 
                    text = obj.as_raw_string()
175
 
                self.outf.write(text)
176
 
            else:
177
 
                for sha1 in object_store:
178
 
                    self.outf.write("%s\n" % sha1)
179
 
        finally:
180
 
            object_store.unlock()
181
 
 
182
 
 
183
 
class cmd_git_refs(Command):
184
 
    """Output all of the virtual refs for a repository.
185
 
 
186
 
    """
187
 
 
188
 
    hidden = True
189
 
 
190
 
    takes_options = [Option('directory',
191
 
        short_name='d',
192
 
        help='Location of repository.', type=unicode)]
193
 
 
194
 
    @display_command
195
 
    def run(self, directory="."):
196
 
        from bzrlib.bzrdir import (
197
 
            BzrDir,
198
 
            )
199
 
        from bzrlib.plugins.git.refs import (
200
 
            BazaarRefsContainer,
201
 
            )
202
 
        from bzrlib.plugins.git.object_store import (
203
 
            get_object_store,
204
 
            )
205
 
        bzrdir, _ = BzrDir.open_containing(directory)
206
 
        repo = bzrdir.find_repository()
207
 
        object_store = get_object_store(repo)
208
 
        object_store.lock_read()
209
 
        try:
210
 
            refs = BazaarRefsContainer(bzrdir, object_store)
211
 
            for k, v in refs.as_dict().iteritems():
212
 
                self.outf.write("%s -> %s\n" % (k, v))
213
 
        finally:
214
 
            object_store.unlock()
215
 
 
216
 
 
217
 
class cmd_git_apply(Command):
218
 
    """Apply a series of git-am style patches.
219
 
 
220
 
    This command will in the future probably be integrated into 
221
 
    "bzr pull".
222
 
    """
223
 
 
224
 
    takes_options = [
225
 
        Option('signoff', short_name='s', help='Add a Signed-off-by line.'),
226
 
        'force']
227
 
    takes_args = ["patches*"]
228
 
 
229
 
    def _apply_patch(self, wt, f, signoff):
230
 
        """Apply a patch.
231
 
 
232
 
        :param wt: A Bazaar working tree object.
233
 
        :param f: Patch file to read.
234
 
        :param signoff: Add Signed-Off-By flag.
235
 
        """
236
 
        from bzrlib.errors import BzrCommandError
237
 
        from dulwich.patch import git_am_patch_split
238
 
        import subprocess
239
 
        (c, diff, version) = git_am_patch_split(f)
240
 
        # FIXME: Cope with git-specific bits in patch
241
 
        # FIXME: Add new files to working tree
242
 
        p = subprocess.Popen(["patch", "-p1"], stdin=subprocess.PIPE,
243
 
            cwd=wt.basedir)
244
 
        p.communicate(diff)
245
 
        exitcode = p.wait()
246
 
        if exitcode != 0:
247
 
            raise BzrCommandError("error running patch")
248
 
        message = c.message
249
 
        if signoff:
250
 
            signed_off_by = wt.branch.get_config().username()
251
 
            message += "Signed-off-by: %s\n" % signed_off_by.encode('utf-8')
252
 
        wt.commit(authors=[c.author], message=message)
253
 
 
254
 
    def run(self, patches_list=None, signoff=False, force=False):
255
 
        from bzrlib.errors import UncommittedChanges
256
 
        from bzrlib.workingtree import WorkingTree
257
 
        if patches_list is None:
258
 
            patches_list = []
259
 
 
260
 
        tree, _ = WorkingTree.open_containing(".")
261
 
        if tree.basis_tree().changes_from(tree).has_changed() and not force:
262
 
            raise UncommittedChanges(tree)
263
 
        tree.lock_write()
264
 
        try:
265
 
            for patch in patches_list:
266
 
                f = open(patch, 'r')
267
 
                try:
268
 
                    self._apply_patch(tree, f, signoff=signoff)
269
 
                finally:
270
 
                    f.close()
271
 
        finally:
272
 
            tree.unlock()