# deepimport.pl -- import history from a remote depot.
#
# Usage:
# deepimport.pl srcPath... tgtPath...
#
# The srcPath should be in a remote depot that maps to a Perforce
# server that you can access directly. You will only need "list"
# access on the remote server, but you will need "admin" access on
# the local server to copy the changelists over.
#
# If you don't set the configuration variables, they'll be read from your
# environment. If you don't specify authentication info
# for the remote server, the local user/password will be used.
$p4 = "p4";
$P4PORT = "";
$P4USER = "";
$P4PASSWD = "";
$P4CLIENT = "";
$P4USER_remote = "";
$P4PASSWD_remote = "";
#####end configuration section###########
if ( !$P4USER_remote ) { $P4USER_remote = $P4USER; }
if ( !$P4PASSWD_remote ) { $P4PASSWD_remote = $P4PASSWD; }
$p4_local = $p4;
$p4_remote = $p4;
if ( $P4PORT ) { $p4_local .= " -p $P4PORT"; }
if ( $P4USER ) { $p4_local .= " -u $P4USER"; }
if ( $P4PASSWD ) { $p4_local .= " -P $P4PASSWD"; }
if ( $P4CLIENT ) { $p4_local .= " -c $P4CLIENT"; }
$source_local = $ARGV[0];
$target_local = $ARGV[1];
if ( !$source_local or !$target_local )
{
die "Please provide a source and target path.";
}
# Resolve $source_local to a depot path.
open WHERE, "$p4_local -Ztag where \"$source_local\" 2>&1|" or die "$!";
while (<WHERE>)
{
chomp;
if ( /\.\.\. depotFile (.*)/ ) { $source_local = $1; last; }
}
close WHERE;
$_ = $source_local;
if ( /^\/\/([^\/]+)/ ) { $depot = $1; }
else { die "Unable to resolve $_ to a depot path." }
# Get remote server information.
$P4PORT_remote = $P4PORT;
$map_remote = "//$depot/...";
open DEPOT, "$p4_local -Ztag depot -o \"$depot\"|" or die "$!";
while (<DEPOT>)
{
chomp;
if ( /\.\.\. Type (.*)/ and $1 ne "remote" ) { last; }
# I was going to throw an error here if Type wasn't remote,
# but maybe somebody will really want to do an import from
# a local depot? Not too hard to allow that; we just bail
# out here and use the local connection settings instead.
if ( /\.\.\. Address (.*)/ ) { $P4PORT_remote = $1; }
if ( /\.\.\. Map (.*)/ ) { $map_remote = $1; }
}
close DEPOT;
if ( $P4PORT_remote ) { $p4_remote .= " -p $P4PORT_remote"; }
if ( $P4USER_remote ) { $p4_remote .= " -u $P4USER_remote"; }
if ( $P4PASSWD_remote ) { $p4_remote .= " -P $P4PASSWD_remote"; }
#Use Map to translate $source_local into $source_remote.
$_ = $map_remote;
if ( !/\.\.\.$/ ) { die "Map field doesn't end in ..."; }
s/\.\.\.$//;
$map_remote = $_;
$map_local = "//$depot/";
$_ = $source_local;
s/$map_local/$map_remote/;
$source_remote = $_;
# Now the fun begins! We're going to connect to the remote server, get
# the list of changes for this path, and start importing.
@changes = ();
open CHANGES, "$p4_remote changes \"$source_remote\"|" or die "$!";
while (<CHANGES>)
{
if ( !/^Change (\d+)/ ) { last; }
# Changes come in reverse order.
unshift @changes, $1;
}
close CHANGES;
$count = 0;
foreach $change ( @changes )
{
#Import the change.
print "Importing change $change...";
`$p4_local integ "$source_local\@$change" "$target_local"`;
`$p4_local resolve -as "$target_local" 2>&1`;
$_ = `$p4_local submit -d "Import $change from $source_local."`;
if ( !/Change (\d+) submitted.$/ ) { last; }
$import = $1;
print " local change $import submitted.\n";
#Try to copy the change description over.
open REMOTE, "$p4_remote change -o $change|" or die "$!";
open LOCAL, "$p4_local change -o $import|" or die "$!";
open EDIT, "|$p4_local change -if" or die "$!";
# Everything before the User: field should remain unchanged.
# Everything after that is either identical or can be
# overwritten. (Note that there is no Files: field.)
while ( <LOCAL> )
{
print EDIT $_;
if ( /^Client:/ ) { last; }
}
while ( <REMOTE> )
{
if ( /^Client:/ ) { last; }
}
while ( <REMOTE> )
{
print EDIT $_;
}
close REMOTE;
close LOCAL;
close EDIT;
$count++;
}
print "$count changes imported.\n";
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #2 | 6324 | Sam Stafford |
Update deepimport to not require "admin" access; the description is now copied in on submit rather than set after the fact, and the user/client/date info is also copied into the description. |
||
| #1 | 6323 | Sam Stafford | A little script to import history from a remote depot. |