/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: 2019-06-03 23:48:08 UTC
  • mfrom: (7316 work)
  • mto: This revision was merged to the branch mainline in revision 7328.
  • Revision ID: jelmer@jelmer.uk-20190603234808-15yk5c7054tj8e2b
Merge trunk.

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