~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to bzrtools.py

  • Committer: Robert Collins
  • Date: 2006-04-24 01:35:08 UTC
  • mto: (364.1.3 bzrtools)
  • mto: This revision was merged to the branch mainline in revision 366.
  • Revision ID: robertc@robertcollins.net-20060424013508-2d37e47814d9493e
Support importing into empty branches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Aaron Bentley <aaron.bentley@utoronto.ca>
2
 
# Copyright (C) 2007 John Arbash Meinel
 
1
# Copyright (C) 2005 Aaron Bentley
 
2
# <aaron.bentley@utoronto.ca>
3
3
#
4
4
#    This program is free software; you can redistribute it and/or modify
5
5
#    it under the terms of the GNU General Public License as published by
26
26
import bzrlib
27
27
import bzrlib.errors
28
28
from bzrlib.errors import (BzrCommandError, NotBranchError, NoSuchFile,
29
 
                           UnsupportedFormatError, TransportError,
 
29
                           UnsupportedFormatError, TransportError, 
30
30
                           NoWorkingTree, PermissionDenied)
31
31
from bzrlib.bzrdir import BzrDir, BzrDirFormat
32
32
 
40
40
def is_clean(cur_tree):
41
41
    """
42
42
    Return true if no files are modifed or unknown
 
43
    >>> import bzrlib.add
 
44
    >>> tree = temp_tree()
 
45
    >>> is_clean(tree)
 
46
    (True, [])
 
47
    >>> fooname = os.path.join(tree.basedir, "foo")
 
48
    >>> file(fooname, "wb").write("bar")
 
49
    >>> is_clean(tree)
 
50
    (True, [u'foo'])
 
51
    >>> bzrlib.add.smart_add_tree(tree, [tree.basedir])
 
52
    ([u'foo'], {})
 
53
    >>> is_clean(tree)
 
54
    (False, [])
 
55
    >>> tree.commit("added file")
 
56
    >>> is_clean(tree)
 
57
    (True, [])
 
58
    >>> rm_tree(tree)
43
59
    """
 
60
    from bzrlib.diff import compare_trees
44
61
    old_tree = cur_tree.basis_tree()
45
62
    new_tree = cur_tree
46
63
    non_source = []
47
 
    new_tree.lock_read()
48
 
    try:
49
 
        for path, file_class, kind, file_id, entry in new_tree.list_files():
50
 
            if file_class in ('?', 'I'):
51
 
                non_source.append(path)
52
 
        delta = new_tree.changes_from(old_tree, want_unchanged=False)
53
 
    finally:
54
 
        new_tree.unlock()
 
64
    for path, file_class, kind, file_id, entry in new_tree.list_files():
 
65
        if file_class in ('?', 'I'):
 
66
            non_source.append(path)
 
67
    delta = compare_trees(old_tree, new_tree, want_unchanged=False)
55
68
    return not delta.has_changed(), non_source
56
69
 
57
70
def set_push_data(tree, location):
58
 
    tree.branch.control_files.put_utf8("x-push-data", "%s\n" % location)
 
71
    push_file = file (tree.branch.control_files.controlfilename("x-push-data"), "wb")
 
72
    push_file.write("%s\n" % location)
59
73
 
60
74
def get_push_data(tree):
61
75
    """
64
78
    True
65
79
    >>> set_push_data(tree, 'http://somewhere')
66
80
    >>> get_push_data(tree)
67
 
    u'http://somewhere'
 
81
    'http://somewhere'
68
82
    >>> rm_tree(tree)
69
83
    """
70
 
    try:
71
 
        location = tree.branch.control_files.get_utf8('x-push-data').read()
72
 
    except NoSuchFile:
 
84
    filename = tree.branch.control_files.controlfilename("x-push-data")
 
85
    if not os.path.exists(filename):
73
86
        return None
74
 
    return location.rstrip('\n')
 
87
    push_file = file (filename, "rb")
 
88
    (location,) = [f.rstrip('\n') for f in push_file]
 
89
    return location
75
90
 
76
91
"""
77
92
>>> shell_escape('hello')
99
114
    def __init__(self, rsync_name):
100
115
        Exception.__init__(self, "%s not found." % rsync_name)
101
116
 
102
 
def rsync(source, target, ssh=False, excludes=(), silent=False,
 
117
def rsync(source, target, ssh=False, excludes=(), silent=False, 
103
118
          rsync_name="rsync"):
104
119
    """
105
120
    >>> new_dir = tempfile.mkdtemp()
134
149
    except OSError, e:
135
150
        if e.errno == errno.ENOENT:
136
151
            raise NoRsync(rsync_name)
137
 
 
 
152
            
138
153
    proc.stdin.write('\n'.join(excludes)+'\n')
139
154
    proc.stdin.close()
140
155
    if silent:
176
191
        raise RsyncUnknownStatus(proc.returncode)
177
192
    return [l.split(' ')[-1].rstrip('\n') for l in result.splitlines(True)]
178
193
 
179
 
exclusions = ('.bzr/x-push-data', '.bzr/branch/x-push/data', '.bzr/parent',
 
194
exclusions = ('.bzr/x-push-data', '.bzr/branch/x-push/data', '.bzr/parent', 
180
195
              '.bzr/branch/parent', '.bzr/x-pull-data', '.bzr/x-pull',
181
196
              '.bzr/pull', '.bzr/stat-cache', '.bzr/x-rsync-data',
182
197
              '.bzr/basis-inventory', '.bzr/inventory.backup.weave')
216
231
        return False
217
232
    for local, remote in zip(remote_history, local_history):
218
233
        if local != remote:
219
 
            return False
 
234
            return False 
220
235
    return True
221
236
 
222
237
def empty_or_absent(location):
226
241
    except RsyncNoFile:
227
242
        return True
228
243
 
229
 
def rspush(tree, location=None, overwrite=False, working_tree=True):
 
244
def push(tree, location=None, overwrite=False, working_tree=True):
230
245
    push_location = get_push_data(tree)
231
246
    if location is not None:
232
247
        if not location.endswith('/'):
233
248
            location += '/'
234
249
        push_location = location
235
 
 
 
250
    
236
251
    if push_location is None:
237
 
        raise BzrCommandError("No rspush location known or specified.")
238
 
 
239
 
    if (push_location.find('::') != -1):
240
 
        usessh=False
241
 
    else:
242
 
        usessh=True
243
 
 
244
 
    if (push_location.find('://') != -1 or
245
 
        push_location.find(':') == -1):
246
 
        raise BzrCommandError("Invalid rsync path %r." % push_location)
 
252
        if tree.branch.get_push_location() is None:
 
253
            raise BzrCommandError("No push location known or specified.")
 
254
        else:
 
255
            raise bzrlib.errors.MustUseDecorated
 
256
 
 
257
    if push_location.find('://') != -1:
 
258
        raise bzrlib.errors.MustUseDecorated
 
259
 
 
260
    if push_location.find(':') == -1:
 
261
        raise bzrlib.errors.MustUseDecorated
247
262
 
248
263
    if working_tree:
249
264
        clean, non_source = is_clean(tree)
275
290
                " specified location.  Please ensure that"
276
291
                ' "%s" is of the form "machine:/path".' % push_location)
277
292
    print "Pushing to %s" % push_location
278
 
    rsync(tree.basedir+'/', push_location, ssh=usessh,
 
293
    rsync(tree.basedir+'/', push_location, ssh=True, 
279
294
          excludes=final_exclusions)
280
295
 
281
296
    set_push_data(tree, push_location)
354
369
    except (NoSuchFile, PermissionDenied, TransportError):
355
370
        pass
356
371
 
357
 
 
 
372
    
358
373
def bzrdir_from_transport(t):
359
374
    """Open a bzrdir from a transport (not a location)"""
360
375
    format = BzrDirFormat.find_format(t)