Skip to content

Commit 4a77434

Browse files
committed
Merge branch 'ld/p4-cleanup-processes'
p4 updates. * ld/p4-cleanup-processes: git-p4: avoid leak of file handle when cloning git-p4: check for access to remote host earlier git-p4: cleanup better on error exit git-p4: create helper function importRevisions() git-p4: disable some pylint warnings, to get pylint output to something manageable git-p4: add P4CommandException to report errors talking to Perforce git-p4: make closeStreams() idempotent
2 parents 8fb3945 + 43f33e4 commit 4a77434

File tree

1 file changed

+110
-71
lines changed

1 file changed

+110
-71
lines changed

git-p4.py

Lines changed: 110 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
# 2007 Trolltech ASA
88
# License: MIT <http://www.opensource.org/licenses/mit-license.php>
99
#
10+
# pylint: disable=invalid-name,missing-docstring,too-many-arguments,broad-except
11+
# pylint: disable=no-self-use,wrong-import-position,consider-iterating-dictionary
12+
# pylint: disable=wrong-import-order,unused-import,too-few-public-methods
13+
# pylint: disable=too-many-lines,ungrouped-imports,fixme,too-many-locals
14+
# pylint: disable=line-too-long,bad-whitespace,superfluous-parens
15+
# pylint: disable=too-many-statements,too-many-instance-attributes
16+
# pylint: disable=too-many-branches,too-many-nested-blocks
17+
#
1018
import sys
1119
if sys.hexversion < 0x02040000:
1220
# The limiter is the subprocess module
@@ -161,6 +169,9 @@ def calcDiskFree():
161169
return st.f_bavail * st.f_frsize
162170

163171
def die(msg):
172+
""" Terminate execution. Make sure that any running child processes have been wait()ed for before
173+
calling this.
174+
"""
164175
if verbose:
165176
raise Exception(msg)
166177
else:
@@ -618,6 +629,14 @@ def __init__(self, exit_code, p4_result, limit):
618629
super(P4RequestSizeException, self).__init__(exit_code, p4_result)
619630
self.limit = limit
620631

632+
class P4CommandException(P4Exception):
633+
""" Something went wrong calling p4 which means we have to give up """
634+
def __init__(self, msg):
635+
self.msg = msg
636+
637+
def __str__(self):
638+
return self.msg
639+
621640
def isModeExecChanged(src_mode, dst_mode):
622641
return isModeExec(src_mode) != isModeExec(dst_mode)
623642

@@ -3539,6 +3558,74 @@ def importHeadRevision(self, revision):
35393558
print("IO error details: {}".format(err))
35403559
print(self.gitError.read())
35413560

3561+
3562+
def importRevisions(self, args, branch_arg_given):
3563+
changes = []
3564+
3565+
if len(self.changesFile) > 0:
3566+
with open(self.changesFile) as f:
3567+
output = f.readlines()
3568+
changeSet = set()
3569+
for line in output:
3570+
changeSet.add(int(line))
3571+
3572+
for change in changeSet:
3573+
changes.append(change)
3574+
3575+
changes.sort()
3576+
else:
3577+
# catch "git p4 sync" with no new branches, in a repo that
3578+
# does not have any existing p4 branches
3579+
if len(args) == 0:
3580+
if not self.p4BranchesInGit:
3581+
raise P4CommandException("No remote p4 branches. Perhaps you never did \"git p4 clone\" in here.")
3582+
3583+
# The default branch is master, unless --branch is used to
3584+
# specify something else. Make sure it exists, or complain
3585+
# nicely about how to use --branch.
3586+
if not self.detectBranches:
3587+
if not branch_exists(self.branch):
3588+
if branch_arg_given:
3589+
raise P4CommandException("Error: branch %s does not exist." % self.branch)
3590+
else:
3591+
raise P4CommandException("Error: no branch %s; perhaps specify one with --branch." %
3592+
self.branch)
3593+
3594+
if self.verbose:
3595+
print("Getting p4 changes for %s...%s" % (', '.join(self.depotPaths),
3596+
self.changeRange))
3597+
changes = p4ChangesForPaths(self.depotPaths, self.changeRange, self.changes_block_size)
3598+
3599+
if len(self.maxChanges) > 0:
3600+
changes = changes[:min(int(self.maxChanges), len(changes))]
3601+
3602+
if len(changes) == 0:
3603+
if not self.silent:
3604+
print("No changes to import!")
3605+
else:
3606+
if not self.silent and not self.detectBranches:
3607+
print("Import destination: %s" % self.branch)
3608+
3609+
self.updatedBranches = set()
3610+
3611+
if not self.detectBranches:
3612+
if args:
3613+
# start a new branch
3614+
self.initialParent = ""
3615+
else:
3616+
# build on a previous revision
3617+
self.initialParent = parseRevision(self.branch)
3618+
3619+
self.importChanges(changes)
3620+
3621+
if not self.silent:
3622+
print("")
3623+
if len(self.updatedBranches) > 0:
3624+
sys.stdout.write("Updated branches: ")
3625+
for b in self.updatedBranches:
3626+
sys.stdout.write("%s " % b)
3627+
sys.stdout.write("\n")
3628+
35423629
def openStreams(self):
35433630
self.importProcess = subprocess.Popen(["git", "fast-import"],
35443631
stdin=subprocess.PIPE,
@@ -3549,11 +3636,14 @@ def openStreams(self):
35493636
self.gitError = self.importProcess.stderr
35503637

35513638
def closeStreams(self):
3639+
if self.gitStream is None:
3640+
return
35523641
self.gitStream.close()
35533642
if self.importProcess.wait() != 0:
35543643
die("fast-import failed: %s" % self.gitError.read())
35553644
self.gitOutput.close()
35563645
self.gitError.close()
3646+
self.gitStream = None
35573647

35583648
def run(self, args):
35593649
if self.importIntoRemotes:
@@ -3737,87 +3827,36 @@ def run(self, args):
37373827
b = b[len(self.projectName):]
37383828
self.createdBranches.add(b)
37393829

3740-
self.openStreams()
3741-
3742-
if revision:
3743-
self.importHeadRevision(revision)
3744-
else:
3745-
changes = []
3746-
3747-
if len(self.changesFile) > 0:
3748-
output = open(self.changesFile).readlines()
3749-
changeSet = set()
3750-
for line in output:
3751-
changeSet.add(int(line))
3752-
3753-
for change in changeSet:
3754-
changes.append(change)
3755-
3756-
changes.sort()
3757-
else:
3758-
# catch "git p4 sync" with no new branches, in a repo that
3759-
# does not have any existing p4 branches
3760-
if len(args) == 0:
3761-
if not self.p4BranchesInGit:
3762-
die("No remote p4 branches. Perhaps you never did \"git p4 clone\" in here.")
3763-
3764-
# The default branch is master, unless --branch is used to
3765-
# specify something else. Make sure it exists, or complain
3766-
# nicely about how to use --branch.
3767-
if not self.detectBranches:
3768-
if not branch_exists(self.branch):
3769-
if branch_arg_given:
3770-
die("Error: branch %s does not exist." % self.branch)
3771-
else:
3772-
die("Error: no branch %s; perhaps specify one with --branch." %
3773-
self.branch)
3830+
p4_check_access()
37743831

3775-
if self.verbose:
3776-
print("Getting p4 changes for %s...%s" % (', '.join(self.depotPaths),
3777-
self.changeRange))
3778-
changes = p4ChangesForPaths(self.depotPaths, self.changeRange, self.changes_block_size)
3832+
self.openStreams()
37793833

3780-
if len(self.maxChanges) > 0:
3781-
changes = changes[:min(int(self.maxChanges), len(changes))]
3834+
err = None
37823835

3783-
if len(changes) == 0:
3784-
if not self.silent:
3785-
print("No changes to import!")
3836+
try:
3837+
if revision:
3838+
self.importHeadRevision(revision)
37863839
else:
3787-
if not self.silent and not self.detectBranches:
3788-
print("Import destination: %s" % self.branch)
3840+
self.importRevisions(args, branch_arg_given)
37893841

3790-
self.updatedBranches = set()
3842+
if gitConfigBool("git-p4.importLabels"):
3843+
self.importLabels = True
37913844

3792-
if not self.detectBranches:
3793-
if args:
3794-
# start a new branch
3795-
self.initialParent = ""
3796-
else:
3797-
# build on a previous revision
3798-
self.initialParent = parseRevision(self.branch)
3845+
if self.importLabels:
3846+
p4Labels = getP4Labels(self.depotPaths)
3847+
gitTags = getGitTags()
37993848

3800-
self.importChanges(changes)
3849+
missingP4Labels = p4Labels - gitTags
3850+
self.importP4Labels(self.gitStream, missingP4Labels)
38013851

3802-
if not self.silent:
3803-
print("")
3804-
if len(self.updatedBranches) > 0:
3805-
sys.stdout.write("Updated branches: ")
3806-
for b in self.updatedBranches:
3807-
sys.stdout.write("%s " % b)
3808-
sys.stdout.write("\n")
3809-
3810-
if gitConfigBool("git-p4.importLabels"):
3811-
self.importLabels = True
3812-
3813-
if self.importLabels:
3814-
p4Labels = getP4Labels(self.depotPaths)
3815-
gitTags = getGitTags()
3852+
except P4CommandException as e:
3853+
err = e
38163854

3817-
missingP4Labels = p4Labels - gitTags
3818-
self.importP4Labels(self.gitStream, missingP4Labels)
3855+
finally:
3856+
self.closeStreams()
38193857

3820-
self.closeStreams()
3858+
if err:
3859+
die(str(err))
38213860

38223861
# Cleanup temporary branches created during import
38233862
if self.tempBranches != []:

0 commit comments

Comments
 (0)