Files
2025-09-29 00:52:08 +02:00

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