# Task: compare two labels, create report giving # lists of # only in first label # only in second label, # in both, but the revision in the label isn't same. # # status: tested on Win/NT using python 2.0 # tested on Darwin Mac OS X using Python 2.3 # num of calls to 'p4': 2 # # Copyright 2004 Perforce Corporation, Inc. All rights reserved. import getopt import sys, os from readp4marshal import runp4cmd def SubtractTwoHashes(list1, list2): '''find the things in list1 that aren't in list2, those in list2 (but not list1), and in common. Return those three results as a three-tuple. ''' OnlyList1res = [] OnlyList2res = [] Duplicates = [] for l in list1.keys(): if list2.has_key(l) and list2[l]: Duplicates.append(l) else: OnlyList1res.append(l) for l in list2.keys(): if list1.has_key(l) and list1[l]: pass # no need to duplicate the above entirely else: OnlyList2res.append(l) return [OnlyList1res, OnlyList2res, Duplicates] label1 = label2 = None debugOption = 0 defaultPort = None defaultUser = None [options,args] = getopt.getopt(sys.argv[1:], 'du:1:2:p:', [ 'debug', 'user=', 'label1=', 'label2=', 'port=']) for [opt,arg] in options: if opt == "--debug" or opt == '-d': debugOption = 1 if opt == "--user" or opt == '-u': defaultUser = arg if opt == "--port" or opt == '-p': defaultPort = arg if opt == "--label1" or opt == '-1': label1 = arg if opt == "--label2" or opt == '-2': label2 = arg if label1 is None: raise RuntimeError, "--label1 XXXX must be given on command-line" if label2 is None: raise RuntimeError, "--label2 XXXX must be given on command-line" if debugOption: print "label1 =", label1 if debugOption: print "label2 =", label2 # # strategy: # 1. We'll collect Perforce output in "label1list" # 2. To save resources, we'll make a hash/dict that # keeps makes 'lookup by name' very fast. ("label1revbyfname") # (Using this, the questions like 'in label1 not label2' # are computed quickly with that lookup.) # 3. Get the lists we need from "SubtractTwoHashes", # and print out the results. #----------------------------------------------------------- # first call to P4: 'p4 files @label1' #----------------------------------------------------------- label1list = runp4cmd("p4 -G files @%s" % label1) label1revbyfname = {} for f in label1list: label1revbyfname[f['depotFile']] = f['rev'] #----------------------------------------------------------- # second call to P4: 'p4 files @label2' #----------------------------------------------------------- label2list = runp4cmd("p4 -G files @%s" % label2) label2revbyfname = {} for f in label2list: label2revbyfname[f['depotFile']] = f['rev'] (filesOnlyInLabel1, filesOnlyInLabel2, filesInCommon) = SubtractTwoHashes(label1revbyfname, label2revbyfname) # case 1: files in the first label but not the second for fname in filesOnlyInLabel1: print "Only in %s: %s" % (label1, fname) # case 2: files in the first label but not the second for fname in filesOnlyInLabel2: print "Only in %s: %s" % (label2, fname) # case 3: files in both labels, but different revisions print len(filesInCommon), "files in common (but maybe different revs)" for fname in filesInCommon: rev1 = label1revbyfname[fname] rev2 = label2revbyfname[fname] if debugOption: print "Comparing rev1=",rev1, "rev2=",rev2, " for ", fname if rev1 != rev2: print "%s is rev %s in %s but %s in %s" % ( fname,rev1,label1,rev2,label2)