diff options
Diffstat (limited to 'contrib/p4import/git-p4import.py')
-rw-r--r-- | contrib/p4import/git-p4import.py | 365 |
1 files changed, 0 insertions, 365 deletions
diff --git a/contrib/p4import/git-p4import.py b/contrib/p4import/git-p4import.py deleted file mode 100644 index 593d6a0682..0000000000 --- a/contrib/p4import/git-p4import.py +++ /dev/null @@ -1,365 +0,0 @@ -#!/usr/bin/env python -# -# This tool is copyright (c) 2006, Sean Estabrooks. -# It is released under the Gnu Public License, version 2. -# -# Import Perforce branches into Git repositories. -# Checking out the files is done by calling the standard p4 -# client which you must have properly configured yourself -# - -import marshal -import os -import sys -import time -import getopt - -if sys.hexversion < 0x02020000: - # The behavior of the marshal module changed significantly in 2.2 - sys.stderr.write("git-p4import.py: requires Python 2.2 or later.\n") - sys.exit(1) - -from signal import signal, \ - SIGPIPE, SIGINT, SIG_DFL, \ - default_int_handler - -signal(SIGPIPE, SIG_DFL) -s = signal(SIGINT, SIG_DFL) -if s != default_int_handler: - signal(SIGINT, s) - -def die(msg, *args): - for a in args: - msg = "%s %s" % (msg, a) - print "git-p4import fatal error:", msg - sys.exit(1) - -def usage(): - print "USAGE: git-p4import [-q|-v] [--authors=<file>] [-t <timezone>] [//p4repo/path <branch>]" - sys.exit(1) - -verbosity = 1 -logfile = "/dev/null" -ignore_warnings = False -stitch = 0 -tagall = True - -def report(level, msg, *args): - global verbosity - global logfile - for a in args: - msg = "%s %s" % (msg, a) - fd = open(logfile, "a") - fd.writelines(msg) - fd.close() - if level <= verbosity: - print msg - -class p4_command: - def __init__(self, _repopath): - try: - global logfile - self.userlist = {} - if _repopath[-1] == '/': - self.repopath = _repopath[:-1] - else: - self.repopath = _repopath - if self.repopath[-4:] != "/...": - self.repopath= "%s/..." % self.repopath - f=os.popen('p4 -V 2>>%s'%logfile, 'rb') - a = f.readlines() - if f.close(): - raise - except: - die("Could not find the \"p4\" command") - - def p4(self, cmd, *args): - global logfile - cmd = "%s %s" % (cmd, ' '.join(args)) - report(2, "P4:", cmd) - f=os.popen('p4 -G %s 2>>%s' % (cmd,logfile), 'rb') - list = [] - while 1: - try: - list.append(marshal.load(f)) - except EOFError: - break - self.ret = f.close() - return list - - def sync(self, id, force=False, trick=False, test=False): - if force: - ret = self.p4("sync -f %s@%s"%(self.repopath, id))[0] - elif trick: - ret = self.p4("sync -k %s@%s"%(self.repopath, id))[0] - elif test: - ret = self.p4("sync -n %s@%s"%(self.repopath, id))[0] - else: - ret = self.p4("sync %s@%s"%(self.repopath, id))[0] - if ret['code'] == "error": - data = ret['data'].upper() - if data.find('VIEW') > 0: - die("Perforce reports %s is not in client view"% self.repopath) - elif data.find('UP-TO-DATE') < 0: - die("Could not sync files from perforce", self.repopath) - - def changes(self, since=0): - try: - list = [] - for rec in self.p4("changes %s@%s,#head" % (self.repopath, since+1)): - list.append(rec['change']) - list.reverse() - return list - except: - return [] - - def authors(self, filename): - f=open(filename) - for l in f.readlines(): - self.userlist[l[:l.find('=')].rstrip()] = \ - (l[l.find('=')+1:l.find('<')].rstrip(),l[l.find('<')+1:l.find('>')]) - f.close() - for f,e in self.userlist.items(): - report(2, f, ":", e[0], " <", e[1], ">") - - def _get_user(self, id): - if not self.userlist.has_key(id): - try: - user = self.p4("users", id)[0] - self.userlist[id] = (user['FullName'], user['Email']) - except: - self.userlist[id] = (id, "") - return self.userlist[id] - - def _format_date(self, ticks): - symbol='+' - name = time.tzname[0] - offset = time.timezone - if ticks[8]: - name = time.tzname[1] - offset = time.altzone - if offset < 0: - offset *= -1 - symbol = '-' - localo = "%s%02d%02d %s" % (symbol, offset / 3600, offset % 3600, name) - tickso = time.strftime("%a %b %d %H:%M:%S %Y", ticks) - return "%s %s" % (tickso, localo) - - def where(self): - try: - return self.p4("where %s" % self.repopath)[-1]['path'] - except: - return "" - - def describe(self, num): - desc = self.p4("describe -s", num)[0] - self.msg = desc['desc'] - self.author, self.email = self._get_user(desc['user']) - self.date = self._format_date(time.localtime(long(desc['time']))) - return self - -class git_command: - def __init__(self): - try: - self.version = self.git("--version")[0][12:].rstrip() - except: - die("Could not find the \"git\" command") - try: - self.gitdir = self.get_single("rev-parse --git-dir") - report(2, "gdir:", self.gitdir) - except: - die("Not a git repository... did you forget to \"git init\" ?") - try: - self.cdup = self.get_single("rev-parse --show-cdup") - if self.cdup != "": - os.chdir(self.cdup) - self.topdir = os.getcwd() - report(2, "topdir:", self.topdir) - except: - die("Could not find top git directory") - - def git(self, cmd): - global logfile - report(2, "GIT:", cmd) - f=os.popen('git %s 2>>%s' % (cmd,logfile), 'rb') - r=f.readlines() - self.ret = f.close() - return r - - def get_single(self, cmd): - return self.git(cmd)[0].rstrip() - - def current_branch(self): - try: - testit = self.git("rev-parse --verify HEAD")[0] - return self.git("symbolic-ref HEAD")[0][11:].rstrip() - except: - return None - - def get_config(self, variable): - try: - return self.git("config --get %s" % variable)[0].rstrip() - except: - return None - - def set_config(self, variable, value): - try: - self.git("config %s %s"%(variable, value) ) - except: - die("Could not set %s to " % variable, value) - - def make_tag(self, name, head): - self.git("tag -f %s %s"%(name,head)) - - def top_change(self, branch): - try: - a=self.get_single("name-rev --tags refs/heads/%s" % branch) - loc = a.find(' tags/') + 6 - if a[loc:loc+3] != "p4/": - raise - return int(a[loc+3:][:-2]) - except: - return 0 - - def update_index(self): - self.git("ls-files -m -d -o -z | git update-index --add --remove -z --stdin") - - def checkout(self, branch): - self.git("checkout %s" % branch) - - def repoint_head(self, branch): - self.git("symbolic-ref HEAD refs/heads/%s" % branch) - - def remove_files(self): - self.git("ls-files | xargs rm") - - def clean_directories(self): - self.git("clean -d") - - def fresh_branch(self, branch): - report(1, "Creating new branch", branch) - self.git("ls-files | xargs rm") - os.remove(".git/index") - self.repoint_head(branch) - self.git("clean -d") - - def basedir(self): - return self.topdir - - def commit(self, author, email, date, msg, id): - self.update_index() - fd=open(".msg", "w") - fd.writelines(msg) - fd.close() - try: - current = self.get_single("rev-parse --verify HEAD") - head = "-p HEAD" - except: - current = "" - head = "" - tree = self.get_single("write-tree") - for r,l in [('DATE',date),('NAME',author),('EMAIL',email)]: - os.environ['GIT_AUTHOR_%s'%r] = l - os.environ['GIT_COMMITTER_%s'%r] = l - commit = self.get_single("commit-tree %s %s < .msg" % (tree,head)) - os.remove(".msg") - self.make_tag("p4/%s"%id, commit) - self.git("update-ref HEAD %s %s" % (commit, current) ) - -try: - opts, args = getopt.getopt(sys.argv[1:], "qhvt:", - ["authors=","help","stitch=","timezone=","log=","ignore","notags"]) -except getopt.GetoptError: - usage() - -for o, a in opts: - if o == "-q": - verbosity = 0 - if o == "-v": - verbosity += 1 - if o in ("--log"): - logfile = a - if o in ("--notags"): - tagall = False - if o in ("-h", "--help"): - usage() - if o in ("--ignore"): - ignore_warnings = True - -git = git_command() -branch=git.current_branch() - -for o, a in opts: - if o in ("-t", "--timezone"): - git.set_config("perforce.timezone", a) - if o in ("--stitch"): - git.set_config("perforce.%s.path" % branch, a) - stitch = 1 - -if len(args) == 2: - branch = args[1] - git.checkout(branch) - if branch == git.current_branch(): - die("Branch %s already exists!" % branch) - report(1, "Setting perforce to ", args[0]) - git.set_config("perforce.%s.path" % branch, args[0]) -elif len(args) != 0: - die("You must specify the perforce //depot/path and git branch") - -p4path = git.get_config("perforce.%s.path" % branch) -if p4path == None: - die("Do not know Perforce //depot/path for git branch", branch) - -p4 = p4_command(p4path) - -for o, a in opts: - if o in ("-a", "--authors"): - p4.authors(a) - -localdir = git.basedir() -if p4.where()[:len(localdir)] != localdir: - report(1, "**WARNING** Appears p4 client is misconfigured") - report(1, " for sync from %s to %s" % (p4.repopath, localdir)) - if ignore_warnings != True: - die("Reconfigure or use \"--ignore\" on command line") - -if stitch == 0: - top = git.top_change(branch) -else: - top = 0 -changes = p4.changes(top) -count = len(changes) -if count == 0: - report(1, "Already up to date...") - sys.exit(0) - -ptz = git.get_config("perforce.timezone") -if ptz: - report(1, "Setting timezone to", ptz) - os.environ['TZ'] = ptz - time.tzset() - -if stitch == 1: - git.remove_files() - git.clean_directories() - p4.sync(changes[0], force=True) -elif top == 0 and branch != git.current_branch(): - p4.sync(changes[0], test=True) - report(1, "Creating new initial commit"); - git.fresh_branch(branch) - p4.sync(changes[0], force=True) -else: - p4.sync(changes[0], trick=True) - -report(1, "processing %s changes from p4 (%s) to git (%s)" % (count, p4.repopath, branch)) -for id in changes: - report(1, "Importing changeset", id) - change = p4.describe(id) - p4.sync(id) - if tagall : - git.commit(change.author, change.email, change.date, change.msg, id) - else: - git.commit(change.author, change.email, change.date, change.msg, "import") - if stitch == 1: - git.clean_directories() - stitch = 0 |