In ClearCase, how can I copy files to relative paths using find

c001badg3r5's picture
c001badg3r5 asked on December 7, 2011 - 11:18am | Replies (7).

I want to find all files in a baseline and copy them to a staging area. The command I started with is:
cleartool find . -version "lbtype(BASELINE1)" -exec "cmd /c copy %CLEARCASE_PN% \\share\baselines"

This works but puts all the files into the same directory and the relative paths are lost.
I have also tried :
cleartool find . -version "lbtype(BASELINE1)" -exec "cmd /c copy %CLEARCASE_PN% \\share\baselines\%CLEARCASE_PN%"

But this doesnt work as it copies all files to the same name and you get 1 file in the target dir called %CLEARCASE_PN%. Some help would be great - I am probably missing something small but cant see what it is.

James

7 Answers

Marc Girod's picture
Marc Girod replied on December 7, 2011 - 12:31pm.

Use Perl.

You need to mirror the hierarchy, and just this will be painful with MS tools. In Perl, you'll find make_tree from the File::Path CPAN package. Also, '-ver' will yield you version extended names, which you need thus to strip from the name of the copies. In fact, if your view doesn't match well with the baseline, you'll get extensions within the path, and my naive example below won't work.

use ClearCase::Argv;
use File::Basename;
use File::Path qw(make_tree);
use File::Copy;
my $bl = shift 'ARGV;
my $tgtbase = '\\\\share\\baselines';
my $ct = new ClearCase::Argv({autochomp=>1});
my @match = $ct->find(qw(. -ver), "lbtype($bl)", '-print')->qx;
my %dir;
$dir{dirname($_)++ for grep s/^(.*?)\@/$1/, @match;
make_tree($_) for keys %dir; #could still be optimized...
for my $v (@match) {
my $tgt = $1 if $v =~ /^(.*?)\@/; #always matches
copy $v, join('\\', $tgtbase, $tgt);
}

Something like that (non tested!).

Marc

TechWell Contributor's picture

Hi Marc,

Thanks - I thought about this too and started writing something similar but eventually settled on this as a simpler solution:

if ($deploy_opt == 2) {
my @deploy = `cleartool find . -ver "lbtype($build2_val)" -exec "cmd /c xcopy /r /i /e /c /y \\"%CLEARCASE_PN%\\" \\"f:\\perl\\baselines\\$build2_val\\%CLEARCASE_PN%\\""`;
print @deploy;
}

cheers,

James B)

Marc Girod's picture
Marc Girod replied on December 7, 2011 - 3:08pm.

Congratulations. Indeed, 'xcopy /e' does what you wanted.

My doc says:

NOTE: Xcopy is now deprecated, please use Robocopy.

I believe you should use CLEARCASE_XPN as the source, instead of CLEARCASE_PN. Otherwise you copy the version visible in your view, not the one bearing the label.

Marc

TechWell Contributor's picture

when I use XPN in the source and PN in the target, the copy results in folders representing all the branches too... :huh:

How do I avoid this and only get the results from the integration stream?

Thanks,

James

saku build's picture
saku build replied on January 4, 2012 - 10:18am.

james ,

I tried with all the commands to get the file list for the specific baseline in unix . it's doesn't work .

saku build's picture
saku build replied on January 4, 2012 - 12:35pm.

Hi James,

As i need list of the file changes between two labels and diff of the versions(component) of the two labels in view in unix ,tried the below commands . Can any one pls help better way .

ct find -avobs –nvisible -version "lbtype(label1)" -print | sort > label1.versions
ct find -avobs –nvisible -version "lbtype(label2)" -print | sort > label2.versions
comm -3 label1.versions label2.versions

c001badg3r5's picture

Hi Saku,

No, I would probably try and do this with a perl script to put the output into arrays then sort/compare them. The previous command in this post was used in a perl script too as I find it easier to work with.

regards,

James

CMCrossroads is a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.