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

  • Committer: Jelmer Vernooij
  • Date: 2020-02-07 02:14:30 UTC
  • mto: This revision was merged to the branch mainline in revision 7492.
  • Revision ID: jelmer@jelmer.uk-20200207021430-m49iq3x4x8xlib6x
Drop python2 support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2006-2009 Canonical Ltd
 
2
# Copyright (C) 2012-2018 Jelmer Vernooij <jelmer@jelmer.uk>
2
3
 
3
4
# Authors: Robert Collins <robert.collins@canonical.com>
4
5
#          Jelmer Vernooij <jelmer@samba.org>
16
17
#
17
18
# You should have received a copy of the GNU General Public License
18
19
# 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
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21
 
21
22
"""Git-specific subcommands for Bazaar."""
22
23
 
23
 
from bzrlib.commands import (
 
24
from __future__ import absolute_import
 
25
 
 
26
import breezy.bzr  # noqa: F401
 
27
from breezy import controldir
 
28
from ..commands import (
24
29
    Command,
25
30
    display_command,
26
31
    )
27
 
from bzrlib.option import (
 
32
from ..option import (
28
33
    Option,
 
34
    RegistryOption,
29
35
    )
30
36
 
31
37
 
36
42
 
37
43
    takes_args = ["src_location", "dest_location?"]
38
44
 
39
 
    def run(self, src_location, dest_location=None):
 
45
    takes_options = [
 
46
        Option('colocated', help='Create colocated branches.'),
 
47
        RegistryOption('dest-format',
 
48
                       help='Specify a format for this branch. '
 
49
                       'See "help formats" for a full list.',
 
50
                       lazy_registry=('breezy.controldir', 'format_registry'),
 
51
                       converter=lambda name: controldir.format_registry.make_controldir(
 
52
                            name),
 
53
                       value_switches=True,
 
54
                       title="Branch format",
 
55
                       ),
 
56
        ]
 
57
 
 
58
    def _get_colocated_branch(self, target_controldir, name):
 
59
        from ..errors import NotBranchError
 
60
        try:
 
61
            return target_controldir.open_branch(name=name)
 
62
        except NotBranchError:
 
63
            return target_controldir.create_branch(name=name)
 
64
 
 
65
    def _get_nested_branch(self, dest_transport, dest_format, name):
 
66
        from ..controldir import ControlDir
 
67
        from ..errors import NotBranchError
 
68
        head_transport = dest_transport.clone(name)
 
69
        try:
 
70
            head_controldir = ControlDir.open_from_transport(head_transport)
 
71
        except NotBranchError:
 
72
            head_controldir = dest_format.initialize_on_transport_ex(
 
73
                head_transport, create_prefix=True)[1]
 
74
        try:
 
75
            return head_controldir.open_branch()
 
76
        except NotBranchError:
 
77
            return head_controldir.create_branch()
 
78
 
 
79
    def run(self, src_location, dest_location=None, colocated=False, dest_format=None):
40
80
        import os
41
 
        from bzrlib import (
 
81
        from .. import (
 
82
            controldir,
 
83
            trace,
42
84
            ui,
43
85
            urlutils,
44
86
            )
45
 
        from bzrlib.bzrdir import (
46
 
            BzrDir,
 
87
        from ..controldir import (
 
88
            ControlDir,
47
89
            )
48
 
        from bzrlib.errors import (
 
90
        from ..errors import (
 
91
            BzrError,
49
92
            BzrCommandError,
50
93
            NoRepositoryPresent,
51
94
            NotBranchError,
52
95
            )
53
 
        from bzrlib.repository import (
 
96
        from ..i18n import gettext
 
97
        from ..repository import (
54
98
            InterRepository,
55
99
            Repository,
56
100
            )
57
 
        from bzrlib.plugins.git.branch import (
58
 
            GitBranch,
59
 
            extract_tags,
60
 
            )
61
 
        from bzrlib.plugins.git.repository import GitRepository
 
101
        from ..transport import get_transport
 
102
        from .branch import (
 
103
            LocalGitBranch,
 
104
            )
 
105
        from .refs import (
 
106
            ref_to_branch_name,
 
107
            )
 
108
        from .repository import GitRepository
 
109
 
 
110
        if dest_format is None:
 
111
            dest_format = controldir.format_registry.make_controldir('default')
62
112
 
63
113
        if dest_location is None:
64
114
            dest_location = os.path.basename(src_location.rstrip("/\\"))
65
115
 
 
116
        dest_transport = get_transport(dest_location)
 
117
 
66
118
        source_repo = Repository.open(src_location)
67
119
        if not isinstance(source_repo, GitRepository):
68
 
            raise BzrCommandError("%r is not a git repository" % src_location)
 
120
            raise BzrCommandError(
 
121
                gettext("%r is not a git repository") % src_location)
69
122
        try:
70
 
            target_bzrdir = BzrDir.open(dest_location)
 
123
            target_controldir = ControlDir.open_from_transport(dest_transport)
71
124
        except NotBranchError:
72
 
            target_bzrdir = BzrDir.create(dest_location)
 
125
            target_controldir = dest_format.initialize_on_transport_ex(
 
126
                dest_transport, shared_repo=True)[1]
73
127
        try:
74
 
            target_repo = target_bzrdir.find_repository()
 
128
            target_repo = target_controldir.find_repository()
75
129
        except NoRepositoryPresent:
76
 
            target_repo = target_bzrdir.create_repository(shared=True)
 
130
            target_repo = target_controldir.create_repository(shared=True)
77
131
 
78
132
        if not target_repo.supports_rich_root():
79
 
            raise BzrCommandError("Target repository doesn't support rich roots")
 
133
            raise BzrCommandError(
 
134
                gettext("Target repository doesn't support rich roots"))
80
135
 
81
136
        interrepo = InterRepository.get(source_repo, target_repo)
82
137
        mapping = source_repo.get_mapping()
83
 
        refs = interrepo.fetch()
84
 
        tags = {}
85
 
        for k, v in extract_tags(refs).iteritems():
86
 
            tags[k] = mapping.revision_id_foreign_to_bzr(v)
87
 
        pb = ui.ui_factory.nested_progress_bar()
88
 
        try:
89
 
            for i, (name, ref) in enumerate(refs.iteritems()):
90
 
                if name.startswith("refs/tags/"):
 
138
        result = interrepo.fetch()
 
139
        with ui.ui_factory.nested_progress_bar() as pb:
 
140
            for i, (name, sha) in enumerate(result.refs.items()):
 
141
                try:
 
142
                    branch_name = ref_to_branch_name(name)
 
143
                except ValueError:
 
144
                    # Not a branch, ignore
91
145
                    continue
92
 
                pb.update("creating branches", i, len(refs))
93
 
                head_loc = os.path.join(dest_location, name)
94
 
                try:
95
 
                    head_bzrdir = BzrDir.open(head_loc)
96
 
                except NotBranchError:
97
 
                    parent_path = urlutils.dirname(head_loc)
98
 
                    if not os.path.isdir(parent_path):
99
 
                        os.makedirs(parent_path)
100
 
                    head_bzrdir = BzrDir.create(head_loc)
101
 
                try:
102
 
                    head_branch = head_bzrdir.open_branch()
103
 
                except NotBranchError:
104
 
                    head_branch = head_bzrdir.create_branch()
105
 
                revid = mapping.revision_id_foreign_to_bzr(ref)
106
 
                source_branch = GitBranch(source_repo.bzrdir, source_repo,
107
 
                    name, None, tags)
108
 
                source_branch.head = ref
 
146
                pb.update(gettext("creating branches"), i, len(result.refs))
 
147
                if (getattr(target_controldir._format, "colocated_branches",
 
148
                            False) and colocated):
 
149
                    if name == "HEAD":
 
150
                        branch_name = None
 
151
                    head_branch = self._get_colocated_branch(
 
152
                        target_controldir, branch_name)
 
153
                else:
 
154
                    head_branch = self._get_nested_branch(
 
155
                        dest_transport, dest_format, branch_name)
 
156
                revid = mapping.revision_id_foreign_to_bzr(sha)
 
157
                source_branch = LocalGitBranch(
 
158
                    source_repo.controldir, source_repo, sha)
109
159
                if head_branch.last_revision() != revid:
110
160
                    head_branch.generate_revision_history(revid)
111
161
                source_branch.tags.merge_to(head_branch.tags)
112
 
        finally:
113
 
            pb.finished()
 
162
                if not head_branch.get_parent():
 
163
                    url = urlutils.join_segment_parameters(
 
164
                        source_branch.base,
 
165
                        {"branch": urlutils.escape(branch_name)})
 
166
                    head_branch.set_parent(url)
 
167
        trace.note(gettext(
 
168
            "Use 'bzr checkout' to create a working tree in "
 
169
            "the newly created branches."))
114
170
 
115
171
 
116
172
class cmd_git_object(Command):
125
181
    aliases = ["git-objects", "git-cat"]
126
182
    takes_args = ["sha1?"]
127
183
    takes_options = [Option('directory',
128
 
        short_name='d',
129
 
        help='Location of repository.', type=unicode),
130
 
        Option('pretty', help='Pretty-print objects.')]
 
184
                            short_name='d',
 
185
                            help='Location of repository.', type=str),
 
186
                     Option('pretty', help='Pretty-print objects.')]
131
187
    encoding_type = 'exact'
132
188
 
133
189
    @display_command
134
190
    def run(self, sha1=None, directory=".", pretty=False):
135
 
        from bzrlib.errors import (
 
191
        from ..errors import (
136
192
            BzrCommandError,
137
193
            )
138
 
        from bzrlib.bzrdir import (
139
 
            BzrDir,
 
194
        from ..controldir import (
 
195
            ControlDir,
140
196
            )
141
 
        bzrdir, _ = BzrDir.open_containing(directory)
142
 
        repo = bzrdir.find_repository()
143
 
        from bzrlib.plugins.git.object_store import (
 
197
        from .object_store import (
144
198
            get_object_store,
145
199
            )
 
200
        from ..i18n import gettext
 
201
        controldir, _ = ControlDir.open_containing(directory)
 
202
        repo = controldir.find_repository()
146
203
        object_store = get_object_store(repo)
147
 
        repo.lock_read()
148
 
        try:
 
204
        with object_store.lock_read():
149
205
            if sha1 is not None:
150
206
                try:
151
 
                    obj = object_store[str(sha1)]
 
207
                    obj = object_store[sha1.encode('ascii')]
152
208
                except KeyError:
153
 
                    raise BzrCommandError("Object not found: %s" % sha1)
 
209
                    raise BzrCommandError(
 
210
                        gettext("Object not found: %s") % sha1)
154
211
                if pretty:
155
212
                    text = obj.as_pretty_string()
156
213
                else:
158
215
                self.outf.write(text)
159
216
            else:
160
217
                for sha1 in object_store:
161
 
                    self.outf.write("%s\n" % sha1)
162
 
        finally:
163
 
            repo.unlock()
 
218
                    self.outf.write("%s\n" % sha1.decode('ascii'))
164
219
 
165
220
 
166
221
class cmd_git_refs(Command):
170
225
 
171
226
    hidden = True
172
227
 
173
 
    takes_options = [Option('directory',
174
 
        short_name='d',
175
 
        help='Location of repository.', type=unicode)]
 
228
    takes_args = ["location?"]
176
229
 
177
230
    @display_command
178
 
    def run(self, directory="."):
179
 
        from bzrlib.bzrdir import (
180
 
            BzrDir,
181
 
            )
182
 
        from bzrlib.plugins.git.refs import (
183
 
            BazaarRefsContainer,
184
 
            )
185
 
        from bzrlib.plugins.git.object_store import (
 
231
    def run(self, location="."):
 
232
        from ..controldir import (
 
233
            ControlDir,
 
234
            )
 
235
        from .refs import (
 
236
            get_refs_container,
 
237
            )
 
238
        from .object_store import (
186
239
            get_object_store,
187
240
            )
188
 
        bzrdir, _ = BzrDir.open_containing(directory)
189
 
        repo = bzrdir.find_repository()
190
 
        repo.lock_read()
191
 
        try:
192
 
            object_store = get_object_store(repo)
193
 
            refs = BazaarRefsContainer(bzrdir, object_store)
194
 
            for k, v in refs.as_dict().iteritems():
195
 
                self.outf.write("%s -> %s\n" % (k, v))
196
 
        finally:
197
 
            repo.unlock()
 
241
        controldir, _ = ControlDir.open_containing(location)
 
242
        repo = controldir.find_repository()
 
243
        object_store = get_object_store(repo)
 
244
        with object_store.lock_read():
 
245
            refs = get_refs_container(controldir, object_store)
 
246
            for k, v in sorted(refs.as_dict().items()):
 
247
                self.outf.write("%s -> %s\n" %
 
248
                                (k.decode('utf-8'), v.decode('utf-8')))
198
249
 
199
250
 
200
251
class cmd_git_apply(Command):
201
252
    """Apply a series of git-am style patches.
202
253
 
203
 
    This command will in the future probably be integrated into 
204
 
    "bzr pull".
 
254
    This command will in the future probably be integrated into "bzr pull".
205
255
    """
206
256
 
 
257
    takes_options = [
 
258
        Option('signoff', short_name='s', help='Add a Signed-off-by line.'),
 
259
        Option('force',
 
260
               help='Apply patches even if tree has uncommitted changes.')
 
261
        ]
207
262
    takes_args = ["patches*"]
208
263
 
209
 
    def _apply_patch(self, wt, f):
 
264
    def _apply_patch(self, wt, f, signoff):
 
265
        """Apply a patch.
 
266
 
 
267
        :param wt: A Bazaar working tree object.
 
268
        :param f: Patch file to read.
 
269
        :param signoff: Add Signed-Off-By flag.
 
270
        """
210
271
        from dulwich.patch import git_am_patch_split
 
272
        from breezy.patch import patch_tree
211
273
        (c, diff, version) = git_am_patch_split(f)
212
 
        # FIXME: Process diff
213
 
        wt.commit(committer=c.committer,
214
 
                  message=c.message)
 
274
        # FIXME: Cope with git-specific bits in patch
 
275
        # FIXME: Add new files to working tree
 
276
        patch_tree(wt, [diff], strip=1, out=self.outf)
 
277
        message = c.message.decode('utf-8')
 
278
        if signoff:
 
279
            signed_off_by = wt.branch.get_config().username()
 
280
            message += "Signed-off-by: %s\n" % (signed_off_by, )
 
281
        wt.commit(authors=[c.author.decode('utf-8')], message=message)
215
282
 
216
 
    def run(self, patches_list=None):
217
 
        from bzrlib.workingtree import WorkingTree
 
283
    def run(self, patches_list=None, signoff=False, force=False):
 
284
        from ..errors import UncommittedChanges
 
285
        from ..workingtree import WorkingTree
218
286
        if patches_list is None:
219
287
            patches_list = []
220
 
        
 
288
 
221
289
        tree, _ = WorkingTree.open_containing(".")
222
 
        tree.lock_write()
223
 
        try:
 
290
        if tree.basis_tree().changes_from(tree).has_changed() and not force:
 
291
            raise UncommittedChanges(tree)
 
292
        with tree.lock_write():
224
293
            for patch in patches_list:
225
 
                f = open(patch, 'r')
226
 
                try:
227
 
                    self._apply_patch(tree, f)
228
 
                finally:
229
 
                    f.close()
230
 
        finally:
231
 
            tree.unlock()
 
294
                with open(patch, 'r') as f:
 
295
                    self._apply_patch(tree, f, signoff=signoff)
 
296
 
 
297
 
 
298
class cmd_git_push_pristine_tar_deltas(Command):
 
299
    """Push pristine tar deltas to a git repository."""
 
300
 
 
301
    takes_options = [Option('directory',
 
302
                            short_name='d',
 
303
                            help='Location of repository.', type=str)]
 
304
    takes_args = ['target', 'package']
 
305
 
 
306
    def run(self, target, package, directory='.'):
 
307
        from ..branch import Branch
 
308
        from ..errors import (
 
309
            BzrCommandError,
 
310
            NoSuchRevision,
 
311
            )
 
312
        from ..trace import warning
 
313
        from ..repository import Repository
 
314
        from .object_store import get_object_store
 
315
        from .pristine_tar import (
 
316
            revision_pristine_tar_data,
 
317
            store_git_pristine_tar_data,
 
318
            )
 
319
        source = Branch.open_containing(directory)[0]
 
320
        target_bzr = Repository.open(target)
 
321
        target = getattr(target_bzr, '_git', None)
 
322
        if target is None:
 
323
            raise BzrCommandError("Target not a git repository")
 
324
        git_store = get_object_store(source.repository)
 
325
        with git_store.lock_read():
 
326
            tag_dict = source.tags.get_tag_dict()
 
327
            for name, revid in tag_dict.iteritems():
 
328
                try:
 
329
                    rev = source.repository.get_revision(revid)
 
330
                except NoSuchRevision:
 
331
                    continue
 
332
                try:
 
333
                    delta, kind = revision_pristine_tar_data(rev)
 
334
                except KeyError:
 
335
                    continue
 
336
                gitid = git_store._lookup_revision_sha1(revid)
 
337
                if (not (name.startswith('upstream/') or
 
338
                         name.startswith('upstream-'))):
 
339
                    warning(
 
340
                        "Unexpected pristine tar revision tagged %s. "
 
341
                        "Ignoring.", name)
 
342
                    continue
 
343
                upstream_version = name[len("upstream/"):]
 
344
                filename = '%s_%s.orig.tar.%s' % (
 
345
                    package, upstream_version, kind)
 
346
                if gitid not in target:
 
347
                    warning(
 
348
                        "base git id %s for %s missing in target repository",
 
349
                        gitid, filename)
 
350
                store_git_pristine_tar_data(target, filename.encode('utf-8'),
 
351
                                            delta, gitid)