126 lines
4.1 KiB
Ruby
Executable File
126 lines
4.1 KiB
Ruby
Executable File
#
|
|
# File:: %RS_TOOLSLIB%/util/perforce/p4_revert_files.rb
|
|
# Description:: Mass-revert files for a particular user.
|
|
#
|
|
# Author:: David Muir <david.muir@rockstarnorth.com>
|
|
# Date:: 5 March 2012
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses
|
|
#-----------------------------------------------------------------------------
|
|
require 'pipeline/config/projects'
|
|
require 'pipeline/os/getopt'
|
|
require 'pipeline/os/path'
|
|
require 'pipeline/scm/perforce'
|
|
include Pipeline
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Constants
|
|
#-----------------------------------------------------------------------------
|
|
OPTIONS = [
|
|
[ '--user', '-u', OS::Getopt::REQUIRED, 'user changelists to revert.' ],
|
|
[ '--help', '-h', OS::Getopt::BOOLEAN, 'display usage information.' ]
|
|
]
|
|
TRAILING = {
|
|
'paths' => 'paths to revert changelists for.'
|
|
}
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Functions
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# The meat function that handles the revert.
|
|
def revert_changelists_for_user( p4, log, username, path )
|
|
|
|
files_with_rev = []
|
|
files = []
|
|
|
|
count = 0
|
|
flog_records = p4.run_filelog( path )
|
|
flog_records.each do |flog_file|
|
|
log.info( "Processing: #{flog_file.depot_file}..." )
|
|
|
|
# Most recent version is first.
|
|
next unless ( 0 == username.casecmp( flog_file.revisions.first.user ) )
|
|
|
|
# User touched #head revision; we need to revert it.
|
|
log.info( "\tUser #{username} has touched \#head revision!" )
|
|
|
|
# Find revision to revert to; i.e. latest one that user didn't commit.
|
|
rev_revert = nil
|
|
flog_file.revisions.each do |revision|
|
|
next unless ( 0 != username.casecmp( revision.user ) )
|
|
|
|
rev_revert = revision.rev
|
|
break
|
|
end
|
|
|
|
if ( rev_revert.nil? ) then
|
|
log.warn( "\tNo known file revision to revert to." )
|
|
else
|
|
count += 1
|
|
log.info( "\tRevert #{flog_file.depot_file} to revision #{rev_revert}/#{flog_file.revisions.size}." )
|
|
|
|
files_with_rev << "#{flog_file.depot_file}\##{rev_revert}"
|
|
files << flog_file.depot_file
|
|
end
|
|
end
|
|
|
|
# Handle batching of sync, edit and resolve for more efficient Perforce
|
|
# usage.
|
|
changelist = p4.create_changelist( "p4_revert_files: #{count} files for user #{username}." )
|
|
p4.run_sync( *files_with_rev )
|
|
p4.run_edit( '-c', changelist, *files )
|
|
p4.run_sync( *files )
|
|
p4.run_resolve( '-ay', *files )
|
|
|
|
count
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Implementation
|
|
#-----------------------------------------------------------------------------
|
|
|
|
if ( __FILE__ == $0 ) then
|
|
g_AppName = OS::Path::get_filename( __FILE__ )
|
|
g_Config = Pipeline::Config::instance( )
|
|
g_Opts, g_Trailing = OS::Getopt::getopts( OPTIONS )
|
|
g_Log = Log.new( g_AppName )
|
|
if ( g_Opts['help'] ) then
|
|
puts OS::Getopt::usage( OPTIONS, TRAILING )
|
|
exit( 1 )
|
|
end
|
|
if ( not g_Opts.has_key?( 'user' ) ) then
|
|
g_Log.error( "--user option required." )
|
|
puts OS::Getopt::usage( OPTIONS, TRAILING )
|
|
exit( 1 )
|
|
end
|
|
|
|
begin
|
|
user = g_Opts['user']
|
|
|
|
project = Pipeline::Config::instance().project
|
|
project.load_config( )
|
|
p4 = project.scm( )
|
|
p4.connect( )
|
|
|
|
count = 0
|
|
g_Trailing.each do |path|
|
|
count += revert_changelists_for_user( p4, g_Log, user, path )
|
|
end
|
|
g_Log.info( "User #{user} touched #{count} files that are reverted." )
|
|
|
|
p4.disconnect( )
|
|
|
|
rescue SystemExit => ex
|
|
exit( ex.exitstatus )
|
|
rescue Exception => ex
|
|
g_Log.exception( ex, 'Unhandled exception' )
|
|
puts "Press any key to continue..."
|
|
$stdin.gets
|
|
end
|
|
end
|
|
|
|
# %RS_TOOLSLIB%/util/perforce/p4_revert_files.rb
|