127 lines
4.4 KiB
Ruby
Executable File
127 lines
4.4 KiB
Ruby
Executable File
#
|
|
# File:: p4SyncToRevAfterPurge.rb
|
|
# Description:: Takes any number of P4 depot paths and syncs any files without a local revision (i.e. rev 0/###) to the revision just above the last purged revision.
|
|
# Useful if you have lost files locally due to a labelled revision being purged.
|
|
#
|
|
# Author:: John Ricchio <john.ricchio@rockstarsandiego.com>
|
|
# Date:: 09 March 2013
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Constants
|
|
#-----------------------------------------------------------------------------
|
|
sUsage = 'usage: p4SyncToRevAfterPurge.rb [any number of valid P4 paths] [OPTIONAL: -noprompt]'
|
|
doSync = "" #"1" means sync & "2" means no sync...set to "1" by -noprompt param
|
|
sFileStatInfo = ENV['TEMP'] + '\p4SyncToRevAfterPurge_fstatInfo.txt'
|
|
sCmd = 'p4 fstat -T "depotFile headRev haveRev headType" -F "headAction=edit" '
|
|
# Example sFileStatInfo format:
|
|
#... depotFile //depot/gta5/build/dev/ps3/levels/gta5/_hills/country_06/cs6_02.rpf
|
|
#... headType binary+S16w
|
|
#... headRev 390
|
|
#... haveRev 378
|
|
#
|
|
#... depotFile //depot/gta5/build/dev/ps3/levels/gta5/_hills/country_06/cs6_03.rpf
|
|
#... headType binary+S16w
|
|
#... headRev 456
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Functions
|
|
#-----------------------------------------------------------------------------
|
|
def sys(cmd)
|
|
puts "\n(#{cmd})"
|
|
res = system(cmd)
|
|
raise "\nFATAL ERROR: (#{cmd}) did not complete successfully. EXITING." if not res
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Entry
|
|
#-----------------------------------------------------------------------------
|
|
# get params
|
|
abort "\n#{sUsage}\n" if ARGV.empty? #bail if we don't have any params
|
|
aCleanParams = Array.new
|
|
ARGV.each { |param|
|
|
sParam = param.dup #needed in case we modify the param coming in
|
|
case sParam
|
|
when /-noprompt/i
|
|
doSync = "1" #assume that they want to sync if they don't want a prompt
|
|
next
|
|
when /\/$/
|
|
sParam.gsub!(/\/$/,'/...') #assume "..." for any params that end in "/" (depot paths)
|
|
when /\\$/
|
|
sParam.gsub!(/\\$/,'\...') #assume "..." for any params that end in "\" (workspace paths)
|
|
end
|
|
aCleanParams.push(sParam)
|
|
}
|
|
abort "\n#{sUsage}\n" if aCleanParams.empty? #bail if we don't have any directories to fstat
|
|
|
|
puts "\nLooking in..."
|
|
aCleanParams.sort!.each { |param| puts param }
|
|
|
|
#find purged revisions
|
|
sCmd = sCmd + aCleanParams.join(' ') + " > " + sFileStatInfo
|
|
sys(sCmd)
|
|
aP4Lines = IO.readlines("#{sFileStatInfo}")
|
|
|
|
sFile = ""
|
|
iRevLimit = iHaveRev = iHeadRev = 0
|
|
hSyncLines = Hash.new
|
|
|
|
aP4Lines.each { |line|
|
|
case line
|
|
when /\.\.\.\sdepotFile\s([^\n]+)/ #get the depot path for the file
|
|
sFile = $1
|
|
|
|
when /\.\.\.\sheadType\s[^\d]+(\d*)/ #get the revision limit
|
|
iRevLimit = $1.to_i if ($1)
|
|
|
|
when /\.\.\.\sheadRev\s([^\n]+)/ #get the head revision
|
|
iHeadRev = $1.to_i if ($1)
|
|
|
|
when /\.\.\.\shaveRev\s([^\n]+)/ #get the have revision
|
|
iHaveRev = $1.to_i if ($1)
|
|
|
|
when /^\s$/ #end of fstat section, setup the sync line, if necessary
|
|
if (iHaveRev == 0)
|
|
if (iHeadRev > 0) && (iRevLimit > 0)
|
|
iLastUnpurged = (iHeadRev - iRevLimit) + 1
|
|
sSync = "p4 sync -f #{sFile}\##{iLastUnpurged}"
|
|
hSyncLines[sFile] = sSync
|
|
else
|
|
raise "\nERROR: We don't have a local revision, but one of these is 0: Head Revision is (#{iHeadRev}) / Rev Limit is (#{iRevLimit})."
|
|
end
|
|
else
|
|
# We already have a local revision
|
|
end
|
|
|
|
# reset variables for next fstat group
|
|
sFile = ""
|
|
iRevLimit = iHaveRev = iHeadRev = 0
|
|
end
|
|
}
|
|
|
|
#sync purged revisions to the version just after the purge
|
|
iPurgeCnt = hSyncLines.values.count
|
|
if (iPurgeCnt > 0)
|
|
#check to see if they want to force sync
|
|
puts "\nThe following files were found to have been deleted locally:"
|
|
hSyncLines.keys.each { |key| puts key }
|
|
until doSync.match /^[12]$/ #only match 1 or 2
|
|
puts "\nChoose an action:"
|
|
puts "1 - Force sync to last unpurged revision"
|
|
puts "2 - Exit without syncing"
|
|
doSync = STDIN.gets.chomp
|
|
end
|
|
exit if doSync == "2" #bail if they chose to exit
|
|
|
|
#sync em!
|
|
hSyncLines.values.sort.each { |val| sys(val) }
|
|
puts "\n(#{iPurgeCnt}) Purged file(s) synced to last unpurged revision(s).\n"
|
|
else
|
|
puts "\nNo purged revisions found.\n"
|
|
end
|
|
|
|
#clear out temp file
|
|
File.delete(sFileStatInfo) if File.exist?(sFileStatInfo)
|
|
|
|
# p4SyncToRevAfterPurge.rb |