15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
24
from subprocess import Popen, PIPE
26
28
dirname = tempfile.mkdtemp("temp-branch")
123
125
arg_str = " ".join([shell_escape(a) for a in args])
124
126
return os.system(arg_str)
126
def rsync(source, target, ssh=False, excludes=()):
128
class RsyncUnknownStatus(Exception):
129
def __init__(self, status):
130
Exception.__init__(self, "Unknown status: %d" % status)
132
def rsync(source, target, ssh=False, excludes=(), silent=False):
128
134
>>> real_system = os.system
129
135
>>> os.system = sys.stdout.write
139
145
if len(excludes) > 0:
140
146
cmd.extend(('--exclude-from', '-'))
141
147
cmd.extend((source, target))
142
proc = Popen(cmd, stdin=PIPE)
154
proc = Popen(cmd, stdin=PIPE, stderr=stderr, stdout=stdout)
143
155
proc.stdin.write('\n'.join(excludes)+'\n')
144
156
proc.stdin.close()
163
if proc.returncode == 23:
164
raise RsyncNoFile(source)
165
elif proc.returncode != 0:
166
raise RsyncUnknownStatus(proc.returncode)
170
def rsync_ls(source, ssh=False, silent=True):
173
cmd.extend(('-e', 'ssh'))
179
proc = Popen(cmd, stderr=stderr, stdout=PIPE)
180
result = proc.stdout.read()
186
if proc.returncode == 23:
187
raise RsyncNoFile(source)
188
elif proc.returncode != 0:
189
raise RsyncUnknownStatus(proc.returncode)
190
return [l.split(' ')[-1].rstrip('\n') for l in result.splitlines(True)]
148
192
exclusions = ('.bzr/x-push-data', '.bzr/x-pull-data', '.bzr/stat-cache')
151
def push(cur_branch, location=None):
195
def read_revision_history(fname):
196
return [l.rstrip('\r\n') for l in
197
codecs.open(fname, 'rb', 'utf-8').readlines()]
199
class RsyncNoFile(Exception):
200
def __init__(self, path):
201
Exception.__init__(self, "No such file %s" % path)
203
def get_revision_history(location):
204
tempdir = tempfile.mkdtemp('push')
206
history_fname = os.path.join(tempdir, 'revision-history')
207
cmd = rsync(location+'.bzr/revision-history', history_fname,
209
history = read_revision_history(history_fname)
211
shutil.rmtree(tempdir)
214
def history_subset(location, branch):
215
remote_history = get_revision_history(location)
216
local_history = branch.revision_history()
217
if len(remote_history) > len(local_history):
219
for local, remote in zip(remote_history, local_history):
224
def empty_or_absent(location):
226
files = rsync_ls(location)
227
return files == ['.']
231
def push(cur_branch, location=None, overwrite=False):
152
232
push_location = get_push_data(cur_branch)
153
233
if location is not None:
154
234
if not location.endswith('/'):
165
245
Use "bzr status" to list them."""
167
247
non_source.extend(exclusions)
250
if not history_subset(push_location, cur_branch):
251
raise bzrlib.errors.BzrCommandError("Local branch is not a"
252
" newer version of remote"
255
if not empty_or_absent(push_location):
256
raise bzrlib.errors.BzrCommandError("Remote location is not a"
257
" bzr branch (or empty"
169
259
print "Pushing to %s" % push_location
170
260
rsync(cur_branch.base+'/', push_location, ssh=True, excludes=non_source)