/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-07-18 23:14:00 UTC
  • mfrom: (7490.40.62 work)
  • mto: This revision was merged to the branch mainline in revision 7519.
  • Revision ID: jelmer@jelmer.uk-20200718231400-jaes9qltn8oi8xss
Merge lp:brz/3.1.

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