ClearCase: Find files having exactly one specific label and not more - clearcase

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

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.

You can do this directly without having to pipe:
cleartool find . -ver "lbtype(LBL_A) && !lbtype(LBL_B)" -print

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"

Related

command in clearcase to get list of all labels applied on an element

I'm trying to get the list of all the labels applied on an element.
I'm using
cleartool desc <element>
This seems to list all the other details of the element as well.
Is there any particular option with desc command that lists only labels?
Thanks
Use cleartool fmt_ccase in order to restrict the describe to only the labels.
cleartool descr -fmt "%l" myFile
You can see that technique used in:
"Which tag or branch is created from a particular branch"
"Command to find labels applied on particular branch"
"Cleartool - List Objects with Their Labels"
For instance, a slightly more complete output would be:
cleartool descr -fmt \"%n labels:%l\n\" myFile
Note: in UCM, a cleartool lsbl would be enough (for listing baselines).
But for base ClearCase, cleartool descr works.
To get labels for all versions of the element, add '-version' and a query to get all versions. My example uses !lbtype(x), since all our versions do NOT have the label 'x'.
cleartool find . -version "!lbtype(x)" -name "yourelement" -exec "cleartool descr -fmt \"%n labels:%l\n\" \"%CLEARCASE_XPN%\""
To output list with space separation, change the -fmt to -> -fmt \"%Nl \".
List could be very long if there are lots of versions and labels.
If you are using dynamic views, you can also use extended naming to see the set of labels applied to versions of the element:
% ls myfile.c##
Note that the output also includes the 'main' branch. You can omit the branch(es) on a non-directory element simply:
% ls -1F myfile.c## | grep -v /
Extra credit - You can also use extended names to see the set of labels applied to versions of a particular branch:
% ls -1F myfile.c##/main/mybranch | grep -v / | grep '[A-Za-z]'
(the trailing 'grep' assumes labels have at least one alphabetic character and will omit version numbers that would otherwise also be included in the output.) That output will also include 'LATEST' but you can easily omit that, too, if desired.

Clear Case/CCRC : Command line usage

I am a new user to Clearcase/CCRC :
I want to learn using cleartool commands in windows platform for CCRC.
I have created a snapshot view using CCRC.
I want to search for a first occurence of a string in a file (in all the branches) using cleartool command.
For eg :
If a func name XXXX is introduced in File Y at version 10, then i want the command which will search for the function XXXX (in file Y) from base version till the version the function is introduced and should output me as version 10.
Please help me to do this.
Once your snapshot view is loaded, you don't need a cleartool command.
You can use a simple grep command in order to search within the files.
A cleartool find command would be useful to search for a string within the message comment of a version of a file, not for the file content itself. See those examples
UNIX/Linux:
cleartool find -all -ver "! lbtype(<non-existing label>)" -exec 'cleartool
desc -fmt "Version: %n\tComment: %c\n\n" $CLEARCASE_XPN' | grep <the string
you are looking for>
Windows:
cleartool find -all -ver "! lbtype(<non-existing label>)" -exec "cleartool
desc -fmt \"Version: %n\tComment: %c\n\n\" %CLEARCASE_XPN%" | findstr "<the
string you are looking for>"
For a given file, you can list all versions with fmt_ccase:
cleartool find -name "yourfile" -exec "cleartool desc -fmt \"%Ln\" \"%CLEARCASE_XPN%\" && cleartool diff -pred \"%CLEARCASE_XPN%\"|grep XXXX"
(note: on Windows, you can use grep with GoW: Gnu on Windows)
The idea is to list all versions for a given file, and for each:
print the version (cleartool desc -fmt "%Ln")
diff with the previous version and grep for XXXX

How to use cleartool find to get files containing a specific string?

I'm trying to search all files in a given branch for a specific string. So far I have
cleartool find . -branch 'brtype(<branch-name>)' -print
This gets all the files in the current directory for branch name "branch-name".
But I want to be able to search/grep those files.
How would yo do this?
You can use an -exec directive of the command cleartool find in order to chain a grep command:
# Windows syntax
cleartool find . -type f -branch 'brtype(MyBranch)' -exec "grep aSpecificString \"%CLEARCASE_PN%\""
# Unix syntax
cleartool find . -type f -branch 'brtype(MyBranch)' -exec 'grep aSpecificString "$CLEARCASE_PN"'
Note the -type f, to limit the search to files (not directories).
Note also that you will get the same file multiple times, if there are several versions of that file in the branch MyBranch.
To limit to one file result per branch, replace -branch by -ele (for 'element')
(as I illustrated in "How to find the files modified under a clearcase branch"):
# Unix syntax
cleartool find . -type f -ele 'brtype(MyBranch)' -exec 'grep aSpecificString "$CLEARCASE_PN"'

Can we print only the directories of branch/latest in clearcase?

How can we print only the directories of branch latest in clearcase .
You can use a cleartool find command in your view (which already selects the right version, like the LATEST from a branch):
cleartool find -type d -print
The '-type d' option will restrict the search for directory elements only.
More generally, in any view, you can try (see "general examples")
cleartool find . -type d -version version(.../yourBranch/LATEST) -print
# or
cleartool find . -type d -element version(.../yourBranch/LATEST) -print
The .../ notation allows you to search for a version in yourBranch, without having to specify parent branches (like /main/yourBranch or /main/anotherBranch/yourBranch)
If you want just the name, and or more details, use the fmt_ccase in a cleartool describe command:
Replace the -print with
# Windows syntax
-exec "cleartool descr -fmt \"%n\n\" \"%CLEARCASE_PN%\""
# Unix syntax
-exec 'cleartool descr -fmt "%n\n" "$CLEARCASE_PN"'

Get list of elements having the specific "Requirement X" comment on elements

I would like to get the list of elements of "myvob/project/" having the comment "Requirement X" with cleartool command.
Is it possible ?
I don't think there is a "cleartool find" query ready for that.
You could combine a cleartool find with the exec part to describe each element with their full name and comment, and then grep on the relevant comment.
See additional find examples:
Find a particular string in a comment by searching all versions of all elements in a VOB.
Note: Example syntax includes formatting for the version and the comment:
UNIX/Linux:
cleartool find -all -ver "! lbtype(<non-existing label>)" \
-exec 'cleartool desc -fmt "Version: %n\tComment: %c\n\n" $CLEARCASE_XPN' \
| grep <the string you are looking for>
Windows:
cleartool find -all -ver "! lbtype(<non-existing label>)" \
-exec "cleartool desc -fmt \"Version: %n\tComment: %c\n\n\" %CLEARCASE_XPN%" \
| findstr "<the string you are looking for>"

Resources