6

I'd like to find files in ClearCase that are labeled with a specific label but that do not have any other labels set.

For example, if I have files labeled like this:

file1 LBL_A, LBL_B
file2 LBL_A

I'd like to have a query that gives me just file2 and not file1.

Is there a way to do this with cleartool find? If this is not possible to do with a single query, I'd also be happy for any ideas how to do this in several steps (I'll be calling cleartool from a perl script, so it will be easy to save lists of files temporarily and run further commands on them).

Thanks a lot in advance!

Jan

Jan
  • 2,480
  • 2
  • 17
  • 19

3 Answers3

7

Assuming LBL_A is the (only) label you want running

cleartool find /some/dir -version 'lbtype(LBL_A)' -print | xargs cleartool describe -fmt "%n: %l"

should give

file1: (LBL_A, LBL_B)
file2: (LBL_A)

as output which you then can check in your perl script or filter through sed -n 's/\(.*\): (LBL_A)/\1/p' (assuming no colons in filenames).

Update: As VonC correctly points out, the command above will fail for files with spaces in. To handle that run as:

cleartool find ... -print | tr '\012' '\000' | xargs -0 cleartool ....

which will translate newlines into ascii null and then have xargs use that as delimiter.

hlovdal
  • 26,565
  • 10
  • 94
  • 165
  • @hlovdal you did not miss anything (like I did). I just canceled the downvote and rewrite my post :) – VonC Jun 24 '09 at 13:19
  • @hlovdal I fix my post and propose another (simple) way to filter the result. Since your post follow is essentially correct: +1 – VonC Jun 24 '09 at 13:40
6

You can do this directly without having to pipe:

cleartool find . -ver "lbtype(LBL_A) && !lbtype(LBL_B)" -print
sth
  • 222,467
  • 53
  • 283
  • 367
Garen
  • 941
  • 2
  • 9
  • 20
  • Did anyone verify whether this actually works? Sounds like a much more efficient solution than filtering the cleartool output after the fact. Of course this method doesn't exactly answer the question, unless one knows exactly what labels may occur. – clacke Oct 01 '15 at 09:44
  • I can assure you it does, which doesn't create an additional process to do the filtering. Of course, it requires knowing in advance which labels to filter out. Some combination of this method plus some post-processing (as in other answers) might be required. – Garen Sep 30 '22 at 21:07
2

hlovdal's answer illustrates that, in this case, you have to find more elements than you need, and then filter them (despite all the ClearCase find features).

Note:

 cleartool find . -type f -element 'lbtype_sub(LBL_A)' -print

could give you directly the elements (and not the version which may not be interesting in this case). You can find the version with -version and a format directive as explained below.

With the help of fmt_ccase, you can tailor the output to get precisely what your perl script will need to go on:

 cleartool find . -type f -element 'lbtype_sub(LBL_A)' -exec 'cleartool describe -fmt "%En %Cl\n" \"$CLEARCASE_XPN\"' | grep -v ","
  • -fmt "%En %l\n" will display the full path of the element (instead of the version: /a/b/myFile@@/main/myVersion) => /a/b/myFile'. the '\n` ensure one result per line.
  • -version and -fmt "%n %l\n" would display the version
  • \"$CLEARCASE_XPN\": the double quotes arount the extended path of the version found ensure a file with spaces in its name will still work.
  • grep -v ",": if there is any comma, that means "more than one label"
  • %Cl: avoid displaying the all list of labels. Anyway, if there are more than one, you are not interested!

So, for finding the exact version:

 cleartool find . -type f -version 'lbtype_sub(LBL_A)' -exec 'cleartool describe -fmt "%n %Cl\n" \"$CLEARCASE_XPN\"' | grep -v ","|awk '{sub(/ \(.*/,"");print}'

Note:
The above works with unix syntax. The windows syntax would be:

cleartool find . -type f -element "lbtype(LBL_A)" -exec "cleartool describe -fmt \"%n %Cl\n\" \"%CLEARCASE_XPN%\"" | grep -v "," | gawk "{gsub(/ \(.*,"");print}"

, which would list the version of files with only one (correct) label.

  • awk '{sub(/ \(.*/,"");print}' will transform "myFile@@/main/myVersion (LBL_A)" into "myFile@@/main/myVersion"
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Eh, did I miss something? The question says "any other labels", you are only explicitly testing LBL_B. – hlovdal Jun 24 '09 at 12:59
  • @hlovdal You are correct, and and have rewritten my answer to actually respond to the OP ;) – VonC Jun 24 '09 at 13:40
  • thanks to you, too - because I need the version, hlovdal's version suits me better, but also the link to of fmtccase was very helpful! – Jan Jun 24 '09 at 13:57