"""Pulls changelists from Perforce into a Bazaar shared repository.
For example,
> pull.py //depot/project C:\\repo
Requires that the P4PORT and P4USER environment variables are set.
Requires that bzrp4 is installed as a Bazaar plugin.
"""
import os
import os.path
import P4
import subprocess
import sys
def p4_fast_export_path():
dir = os.path.dirname(__file__)
return os.path.join(dir, 'p4-fast-export.py')
def last_change_in_source_depot_path(src):
p4 = P4.P4()
p4.connect()
result = p4.run_changes('-m', '1', p4_wildcard(src))
p4.disconnect()
return result[0]['change']
def parse_change_from_marks_line(line):
return int(line[1:line.find(' ')])
def last_change_in_marks_file(dest):
last_change = 0
try:
marks_file = open(marks_file_path(dest), 'r')
for line in marks_file:
if ':' == line[0]:
change = parse_change_from_marks_line(line)
if change > last_change:
last_change = change
except IOError:
pass
return last_change
def range_begin(dest):
last_change = last_change_in_marks_file(dest)
return str(last_change + 1)
def range_end(src):
return last_change_in_source_depot_path(src)
def p4_wildcard(path):
return '%s/...' % path
def manual_range(src):
return -1 != src.find('@')
def computed_range(src):
return not manual_range(src)
def depot_path_and_range(src, dest):
if manual_range(src):
return src
else:
return '%s@%s,%s' % (src, range_begin(dest), range_end(src))
def marks_file_path(dest):
return os.path.join(dest, '.bzr', 'repository', 'fastimport-id-map')
def export_file_path(dest):
return os.path.join(dest, '.bzr', 'repository', 'p4-fastexport')
def bzr_fast_import_command(dest):
# TODO: Make this portable, not Windows-specific.
command = ['bzr.bat', 'fast-import', '-']
return command
def pull(src, dest):
print depot_path_and_range(src, dest)
if computed_range(src) and range_begin(dest) > range_end(src):
return
export_file = open(export_file_path(dest), 'ab')
try:
export_file.seek(0, os.SEEK_END)
proc1 = subprocess.Popen(['python', p4_fast_export_path(),
depot_path_and_range(src, dest)],
stdout=export_file)
if 0 != proc1.wait():
raise IOError()
except Exception, e:
raise e
finally:
export_file.close()
import_file = open(export_file_path(dest), 'rb')
try:
proc2 = subprocess.Popen(bzr_fast_import_command(dest),
stdin=import_file,
cwd=dest)
if 0 != proc2.wait():
raise IOError()
except Exception, e:
raise e
finally:
import_file.close()
def main(args):
pull_src = args[0]
pull_dest = args[1]
pull(pull_src, pull_dest)
if __name__ == '__main__':
main(sys.argv[1:])
# |
Change |
User |
Description |
Committed |
|
#3
|
7138 |
Matt McClure |
Changes the condition for short-circuiting pull so that it continues if the beginning and end of the range are equal. |
|
|
#2
|
7136 |
Matt McClure |
Pull doesn't create extra Bazaar revisions on incremental imports from Perforce. |
|
|
#1
|
7127 |
Matt McClure |
Implements a pull program sufficient for mirroring bzrp4 from Perforce on the public depot to Bazaar on Launchpad. |
|
|