/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/plugins/upload/cmds.py

  • Committer: Jelmer Vernooij
  • Date: 2018-05-06 11:48:54 UTC
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@jelmer.uk-20180506114854-h4qd9ojaqy8wxjsd
Move .mailmap to root.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
from __future__ import absolute_import
20
20
 
21
21
from ... import (
 
22
    branch,
22
23
    commands,
23
24
    config,
24
 
    errors,
25
25
    lazy_import,
26
26
    option,
27
 
    osutils,
28
27
    )
29
28
lazy_import.lazy_import(globals(), """
30
29
import stat
 
30
import sys
31
31
 
32
32
from breezy import (
33
33
    controldir,
 
34
    errors,
34
35
    globbing,
35
36
    ignores,
36
37
    revision,
173
174
                    dir = os.path.dirname(dir)
174
175
        return ignored
175
176
 
176
 
    def upload_file(self, old_relpath, new_relpath, mode=None):
 
177
    def upload_file(self, old_relpath, new_relpath, id, mode=None):
177
178
        if mode is None:
178
 
            if self.tree.is_executable(new_relpath):
 
179
            if self.tree.is_executable(new_relpath, id):
179
180
                mode = 0o775
180
181
            else:
181
182
                mode = 0o664
182
183
        if not self.quiet:
183
184
            self.outf.write('Uploading %s\n' % old_relpath)
184
 
        self._up_put_bytes(
185
 
            old_relpath, self.tree.get_file_text(new_relpath), mode)
186
 
 
187
 
    def _force_clear(self, relpath):
 
185
        self._up_put_bytes(old_relpath, self.tree.get_file_text(new_relpath, id), mode)
 
186
 
 
187
    def upload_file_robustly(self, relpath, id, mode=None):
 
188
        """Upload a file, clearing the way on the remote side.
 
189
 
 
190
        When doing a full upload, it may happen that a directory exists where
 
191
        we want to put our file.
 
192
        """
188
193
        try:
189
194
            st = self._up_stat(relpath)
190
195
            if stat.S_ISDIR(st.st_mode):
191
196
                # A simple rmdir may not be enough
192
197
                if not self.quiet:
193
198
                    self.outf.write('Clearing %s/%s\n' % (
194
 
                        self.to_transport.external_url(), relpath))
 
199
                            self.to_transport.external_url(), relpath))
195
200
                self._up_delete_tree(relpath)
196
 
            elif stat.S_ISLNK(st.st_mode):
197
 
                if not self.quiet:
198
 
                    self.outf.write('Clearing %s/%s\n' % (
199
 
                        self.to_transport.external_url(), relpath))
200
 
                self._up_delete(relpath)
201
201
        except errors.PathError:
202
202
            pass
203
 
 
204
 
    def upload_file_robustly(self, relpath, mode=None):
205
 
        """Upload a file, clearing the way on the remote side.
206
 
 
207
 
        When doing a full upload, it may happen that a directory exists where
208
 
        we want to put our file.
209
 
        """
210
 
        self._force_clear(relpath)
211
 
        self.upload_file(relpath, relpath, mode)
212
 
 
213
 
    def upload_symlink(self, relpath, target):
214
 
        self.to_transport.symlink(target, relpath)
215
 
 
216
 
    def upload_symlink_robustly(self, relpath, target):
217
 
        """Handle uploading symlinks.
218
 
        """
219
 
        self._force_clear(relpath)
220
 
        # Target might not be there at this time; dummy file should be
221
 
        # overwritten at some point, possibly by another upload.
222
 
        target = osutils.normpath(osutils.pathjoin(
223
 
            osutils.dirname(relpath),
224
 
            target)
225
 
        )
226
 
        self.upload_symlink(relpath, target)
 
203
        self.upload_file(relpath, relpath, id, mode)
227
204
 
228
205
    def make_remote_dir(self, relpath, mode=None):
229
206
        if mode is None:
241
218
            if not stat.S_ISDIR(st.st_mode):
242
219
                if not self.quiet:
243
220
                    self.outf.write('Deleting %s/%s\n' % (
244
 
                        self.to_transport.external_url(), relpath))
 
221
                            self.to_transport.external_url(), relpath))
245
222
                self._up_delete(relpath)
246
223
            else:
247
224
                # Ok the remote dir already exists, nothing to do
311
288
        self._pending_renames = []
312
289
 
313
290
    def upload_full_tree(self):
314
 
        self.to_transport.ensure_base()  # XXX: Handle errors (add
315
 
        # --create-prefix option ?)
 
291
        self.to_transport.ensure_base() # XXX: Handle errors (add
 
292
                                        # --create-prefix option ?)
316
293
        with self.tree.lock_read():
317
294
            for relpath, ie in self.tree.iter_entries_by_dir():
318
295
                if relpath in ('', '.bzrignore', '.bzrignore-upload'):
325
302
                        self.outf.write('Ignoring %s\n' % relpath)
326
303
                    continue
327
304
                if ie.kind == 'file':
328
 
                    self.upload_file_robustly(relpath)
329
 
                elif ie.kind == 'symlink':
330
 
                    try:
331
 
                        self.upload_symlink_robustly(
332
 
                            relpath, ie.symlink_target)
333
 
                    except errors.TransportNotPossible:
334
 
                        if not self.quiet:
335
 
                            target = self.tree.path_content_summary(relpath)[3]
336
 
                            self.outf.write('Not uploading symlink %s -> %s\n'
337
 
                                            % (relpath, target))
 
305
                    self.upload_file_robustly(relpath, ie.file_id)
338
306
                elif ie.kind == 'directory':
339
307
                    self.make_remote_dir_robustly(relpath)
 
308
                elif ie.kind == 'symlink':
 
309
                    if not self.quiet:
 
310
                        target = self.tree.path_content_summary(relpath)[3]
 
311
                        self.outf.write('Not uploading symlink %s -> %s\n'
 
312
                                        % (relpath, target))
340
313
                else:
341
314
                    raise NotImplementedError
342
315
            self.set_uploaded_revid(self.rev_id)
360
333
                self.outf.write('Remote location already up to date\n')
361
334
 
362
335
        from_tree = self.branch.repository.revision_tree(rev_id)
363
 
        self.to_transport.ensure_base()  # XXX: Handle errors (add
364
 
        # --create-prefix option ?)
 
336
        self.to_transport.ensure_base() # XXX: Handle errors (add
 
337
                                        # --create-prefix option ?)
365
338
        changes = self.tree.changes_from(from_tree)
366
339
        with self.tree.lock_read():
367
 
            for change in changes.removed:
368
 
                if self.is_ignored(change.path[0]):
 
340
            for (path, id, kind) in changes.removed:
 
341
                if self.is_ignored(path):
369
342
                    if not self.quiet:
370
 
                        self.outf.write('Ignoring %s\n' % change.path[0])
 
343
                        self.outf.write('Ignoring %s\n' % path)
371
344
                    continue
372
 
                if change.kind[0] == 'file':
373
 
                    self.delete_remote_file(change.path[0])
374
 
                elif change.kind[0] == 'directory':
375
 
                    self.delete_remote_dir_maybe(change.path[0])
376
 
                elif change.kind[0] == 'symlink':
377
 
                    self.delete_remote_file(change.path[0])
 
345
                if kind is 'file':
 
346
                    self.delete_remote_file(path)
 
347
                elif kind is  'directory':
 
348
                    self.delete_remote_dir_maybe(path)
 
349
                elif kind == 'symlink':
 
350
                    if not self.quiet:
 
351
                        target = self.tree.path_content_summary(path)[3]
 
352
                        self.outf.write('Not deleting remote symlink %s -> %s\n'
 
353
                                        % (path, target))
378
354
                else:
379
355
                    raise NotImplementedError
380
356
 
381
 
            for change in changes.renamed:
382
 
                if self.is_ignored(change.path[0]) and self.is_ignored(change.path[1]):
 
357
            for (old_path, new_path, id, kind,
 
358
                 content_change, exec_change) in changes.renamed:
 
359
                if self.is_ignored(old_path) and self.is_ignored(new_path):
383
360
                    if not self.quiet:
384
 
                        self.outf.write('Ignoring %s\n' % change.path[0])
385
 
                        self.outf.write('Ignoring %s\n' % change.path[1])
 
361
                        self.outf.write('Ignoring %s\n' % old_path)
 
362
                        self.outf.write('Ignoring %s\n' % new_path)
386
363
                    continue
387
 
                if change.changed_content:
388
 
                    # We update the change.path[0] content because renames and
 
364
                if content_change:
 
365
                    # We update the old_path content because renames and
389
366
                    # deletions are differed.
390
 
                    self.upload_file(change.path[0], change.path[1])
391
 
                self.rename_remote(change.path[0], change.path[1])
 
367
                    self.upload_file(old_path, new_path, id)
 
368
                if kind == 'symlink':
 
369
                    if not self.quiet:
 
370
                        self.outf.write('Not renaming remote symlink %s to %s\n'
 
371
                                        % (old_path, new_path))
 
372
                else:
 
373
                    self.rename_remote(old_path, new_path)
392
374
            self.finish_renames()
393
375
            self.finish_deletions()
394
376
 
395
 
            for change in changes.kind_changed:
396
 
                if self.is_ignored(change.path[1]):
397
 
                    if not self.quiet:
398
 
                        self.outf.write('Ignoring %s\n' % change.path[1])
399
 
                    continue
400
 
                if change.kind[0] in ('file', 'symlink'):
401
 
                    self.delete_remote_file(change.path[0])
402
 
                elif change.kind[0] == 'directory':
403
 
                    self.delete_remote_dir(change.path[0])
404
 
                else:
405
 
                    raise NotImplementedError
406
 
 
407
 
                if change.kind[1] == 'file':
408
 
                    self.upload_file(change.path[1], change.path[1])
409
 
                elif change.kind[1] == 'symlink':
410
 
                    target = self.tree.get_symlink_target(change.path[1])
411
 
                    self.upload_symlink(change.path[1], target)
412
 
                elif change.kind[1] == 'directory':
413
 
                    self.make_remote_dir(change.path[1])
414
 
                else:
415
 
                    raise NotImplementedError
416
 
 
417
 
            for change in changes.added + changes.copied:
418
 
                if self.is_ignored(change.path[1]):
419
 
                    if not self.quiet:
420
 
                        self.outf.write('Ignoring %s\n' % change.path[1])
421
 
                    continue
422
 
                if change.kind[1] == 'file':
423
 
                    self.upload_file(change.path[1], change.path[1])
424
 
                elif change.kind[1] == 'directory':
425
 
                    self.make_remote_dir(change.path[1])
426
 
                elif change.kind[1] == 'symlink':
427
 
                    target = self.tree.get_symlink_target(change.path[1])
428
 
                    try:
429
 
                        self.upload_symlink(change.path[1], target)
430
 
                    except errors.TransportNotPossible:
431
 
                        if not self.quiet:
432
 
                            self.outf.write('Not uploading symlink %s -> %s\n'
433
 
                                            % (change.path[1], target))
 
377
            for (path, id, old_kind, new_kind) in changes.kind_changed:
 
378
                if self.is_ignored(path):
 
379
                    if not self.quiet:
 
380
                        self.outf.write('Ignoring %s\n' % path)
 
381
                    continue
 
382
                if old_kind == 'file':
 
383
                    self.delete_remote_file(path)
 
384
                elif old_kind ==  'directory':
 
385
                    self.delete_remote_dir(path)
 
386
                else:
 
387
                    raise NotImplementedError
 
388
 
 
389
                if new_kind == 'file':
 
390
                    self.upload_file(path, path, id)
 
391
                elif new_kind is 'directory':
 
392
                    self.make_remote_dir(path)
 
393
                else:
 
394
                    raise NotImplementedError
 
395
 
 
396
            for (path, id, kind) in changes.added:
 
397
                if self.is_ignored(path):
 
398
                    if not self.quiet:
 
399
                        self.outf.write('Ignoring %s\n' % path)
 
400
                    continue
 
401
                if kind == 'file':
 
402
                    self.upload_file(path, path, id)
 
403
                elif kind == 'directory':
 
404
                    self.make_remote_dir(path)
 
405
                elif kind == 'symlink':
 
406
                    if not self.quiet:
 
407
                        target = self.tree.path_content_summary(path)[3]
 
408
                        self.outf.write('Not uploading symlink %s -> %s\n'
 
409
                                        % (path, target))
434
410
                else:
435
411
                    raise NotImplementedError
436
412
 
437
413
            # XXX: Add a test for exec_change
438
 
            for change in changes.modified:
439
 
                if self.is_ignored(change.path[1]):
 
414
            for (path, id, kind,
 
415
                 content_change, exec_change) in changes.modified:
 
416
                if self.is_ignored(path):
440
417
                    if not self.quiet:
441
 
                        self.outf.write('Ignoring %s\n' % change.path[1])
 
418
                        self.outf.write('Ignoring %s\n' % path)
442
419
                    continue
443
 
                if change.kind[1] == 'file':
444
 
                    self.upload_file(change.path[1], change.path[1])
445
 
                elif change.kind[1] == 'symlink':
446
 
                    target = self.tree.get_symlink_target(change.path[1])
447
 
                    self.upload_symlink(change.path[1], target)
 
420
                if kind == 'file':
 
421
                    self.upload_file(path, path, id)
448
422
                else:
449
423
                    raise NotImplementedError
450
424
 
478
452
        'overwrite',
479
453
        option.Option('full', 'Upload the full working tree.'),
480
454
        option.Option('quiet', 'Do not output what is being done.',
481
 
                      short_name='q'),
 
455
                       short_name='q'),
482
456
        option.Option('directory',
483
457
                      help='Branch to upload from, '
484
458
                      'rather than the one containing the working directory.',
488
462
        option.Option('auto',
489
463
                      'Trigger an upload from this branch whenever the tip '
490
464
                      'revision changes.')
491
 
        ]
 
465
       ]
492
466
 
493
467
    def run(self, location=None, full=False, revision=None, remember=None,
494
468
            directory=None, quiet=False, auto=None, overwrite=False
501
475
             directory)
502
476
 
503
477
        if wt:
 
478
            wt.lock_read()
504
479
            locked = wt
505
480
        else:
 
481
            branch.lock_read()
506
482
            locked = branch
507
 
        with locked.lock_read():
 
483
        try:
508
484
            if wt:
509
485
                changes = wt.changes_from(wt.basis_tree())
510
486
 
511
 
                if revision is None and changes.has_changed():
 
487
                if revision is None and  changes.has_changed():
512
488
                    raise errors.UncommittedChanges(wt)
513
489
 
514
490
            conf = branch.get_config_stack()
520
496
                else:
521
497
                    # FIXME: Not currently tested
522
498
                    display_url = urlutils.unescape_for_display(stored_loc,
523
 
                                                                self.outf.encoding)
 
499
                            self.outf.encoding)
524
500
                    self.outf.write("Using saved location: %s\n" % display_url)
525
501
                    location = stored_loc
526
502
 
529
505
            # Check that we are not uploading to a existing working tree.
530
506
            try:
531
507
                to_bzr_dir = controldir.ControlDir.open_from_transport(
532
 
                    to_transport)
 
508
                        to_transport)
533
509
                has_wt = to_bzr_dir.has_workingtree()
534
510
            except errors.NotBranchError:
535
511
                has_wt = False
562
538
                uploader.upload_full_tree()
563
539
            else:
564
540
                uploader.upload_tree()
 
541
        finally:
 
542
            locked.unlock()
565
543
 
566
544
        # We uploaded successfully, remember it
567
 
        with branch.lock_write():
 
545
        branch.lock_write()
 
546
        try:
568
547
            upload_location = conf.get('upload_location')
569
548
            if upload_location is None or remember:
570
549
                conf.set('upload_location',
571
550
                         urlutils.unescape(to_transport.base))
572
551
            if auto is not None:
573
552
                conf.set('upload_auto', auto)
 
553
        finally:
 
554
            branch.unlock()
 
555