|
There are times when you receive a third party code drop which you wish to
import. The classic method is documented in
Tech Note 15
and its reference to working disconnected (Tech
Note 2). The techniques mentioned work very well to find new files, deleted
files and changed files.
There is sometimes a fly in the ointment to do with keyword expansion. This
is things like a CVS code drop containing expanded keywords:
$Id: //depot/robertcowham.com/main/blog/data/scm/p4_handling_keywords.html#1 $
The Perforce equivalent of this might be:
$Id: //depot/robertcowham.com/main/blog/data/scm/p4_handling_keywords.html#1 $
The simple command to find differences is "p4 diff -se". If your local
version has Perforce keyword expansion turned on then you will get a load of
files spuriously identified as having changed where the only real change is in
the keywords.
Thus we want a simple script to run through the diffs and exclude any diffs
where only keywords are found (note that this includes where the keyword is
embedded, such as in a static variable assignment).
The following simple script is a good base for this. It does the job, and
performs pretty well, handling thousands of files in a few minutes. It makes use
of unified diff format where changed lines have a prefix in the first character
of the output.
# Script to import a set of changed files with existing keywords already expanded
# (either Perforce or CVS).
# Does "diff -se" and processes the output
# Args: current directory to check
require 'P4'
p4 = P4.new
p4.tagged
p4.connect
def process_file(p4, f)
diffs = p4.run_diff("-f", "-du", f)
real_diffs = Array.new
diffs.each { |line|
case line
when /^====/
when /^\@\@/
when /^ /
else
if line !~ /\$Id|\$DateTime|\$Revision|\$Date|\$Author|\$Name|\$RCSfile|\$Source/
real_diffs << line
# puts f, line
end
end
}
if real_diffs.size > 0
print "Editing #{f}\n"
p4.run_edit(f)
end
end
all_files = p4.run_diff("-se", ARGV[0])
print "Processing #{all_files.size}\n"
i = 0
all_files.each{|f|
i += 1
# print"Processing #{i}\r" if i % 10 == 0
# print"Processing #{f['depotFile']}\n"
process_file(p4, f)
}
It is pretty easy to run, e.g.:
diff_se.rb ...
The net result will be a list of files checked out (p4 edit) in the default
changelist.
Note that one of the big advantages of Perforce branching and merging is that
it handles merges neatly when keyword expansion is used between branches (and
thus you don't get spurious conflicts).
CVS Imports
If you use the
cvs2p4 scripts
to import a CVS repository you can end up with a slight problem since the
conversion copies the CVS archive files (in RCS format) and Perforce uses them
unchanged. The problem comes about because CVS stores the keywords already
expanded in the RCS archive. Perforce stores its RCS files with the keywords not
expanded, which makes it easier for it to do the merging between branches
(without keyword conflicts). While Perforce can handle a CVS archive with the
the keywords "pre-expanded", it does lead to spurious merge conflicts. Note that
this problem is only really present during the early merges after the CVS
import. It will no longer be present as soon as the base file for any merge is
fully in Perforce format (i.e. after at least one merge has been done).
|