Is there a way to apply two ClearCase labels from a command line ( on Windows ) in a single cleartool find command running on a snapshot view ?
Meaning when running this simple command I want that 2 labels (REL3 and REL3_NEW) will be applied and not just REL3
cmd-context find . –version 'version(\main\LATEST) && ! lbtype(REL3)' ^
–exec 'cleartool mklabel –replace REL3 %CLEARCASE_XPN%'
I found this to be working:
cleartool find %1 -cview -version "{brtype(branch) && !version(.../(branch/0) && !version(.../(branch/CHECKEDOUT) && !lbtype(REL3)}" -exec "cleartool mklabel -replace REL3 \"%%CLEARCASE_XPN%%\"" -exec "cleartool mklabel -replace REL3_NEW \"%%CLEARCASE_XPN%%\""
You can try and concatenate the two mklabel:
cleartool find . –version 'version(\main\LATEST) && ! lbtype(REL3)' ^
–exec 'cleartool mklabel –replace REL3 %CLEARCASE_XPN% && cleartool mklabel –replace REL2 %CLEARCASE_XPN%'
(The mklabel command supports only one label-type-selector, and multiple pnames)
Related
On Windows I’m trying to run cleartool find command and get all versions in a branch that have a specific label, the output should include version and user name.
The command works great the problem is how to to redirect the output to a text file.
cleartool find -avobs -branch brtype<BRANCH>) -version "lbtype(<LABEL>)" -exec "cleartool describe -fmt \"%Xn : %u\n\" \"%CLEARCASE_XPN%\"
I have tried using >, >>, |, | tee combinations but nothing works
Any idea how to do that ?
Try to wrap the command in a CMD shell, which can then be redirected:
cmd /C "cleartool find -avobs -branch (brtype<BRANCH>) -version "lbtype(<LABEL>)" -exec "cleartool describe -fmt \"%Xn : %u\n\" \"%CLEARCASE_XPN%\""" > aText
So the typical way I would create a diff log/patch between two branches in clearcase would to simply create two views and do a typical unix diff. But I have to assume that there is a more clearcase way (and also a '1-liner').
so knowing how to get a list of all files that have been modified on a branch:
cleartool find . -type f -branch "brtype(<BRANCH_NAME>)" -print
and knowing how to get the diff formatted output for two separate files:
cleartool diff FILE FILE##/main/PARENT_BRANCH_PATH/LATEST
so does anyone see any issues with the following to get a diff for all files that have been changed in a branch?
cleartool find . -type f -branch "brtype(CHILD_BRANCH)" -exec 'cleartool diff -ser $CLEARCASE_PN `echo $CLEARCASE_XPN | sed "s/CHILD_BRANCH/LATEST/"` ' > diff.log
Any modifications and comments are greatly welcomed
thanks in advance!
update: any ideas on how to get this too be a unix unified diff would also be greatly appreciated.
update2: So I think I have my solution, thanks go to VonC for sending me in the right directions:
cleartool find . -type f -branch "brtype(CHILD_BRANCH)" -exec 'cleartool get -to $CLEARCASE_PN.prev `echo $CLEARCASE_XPN | sed "s/CHILD_BRANCH/LATEST/"`; diff -u $CLEARCASE_PN.prev $CLEARCASE_PN; rm -f $CLEARCASE_PN.prev' > CHILD_BRANCH.diff
the output seems to work, I can read the file in via kompare without complaints.
The idea is sound.
I would simply make sure the $CLEARCASE_PN and $CLEARCASE_XPN are used with double quotes around them, to take into account with potential spaces in the file path or file name (as illustrated in "How do I list ClearCase versions without the Fully-qualified version?").
cleartool find . -type f -branch "brtype(CHILD_BRANCH)" -exec 'cleartool diff -ser "$CLEARCASE_PN" `echo "$CLEARCASE_XPN" | sed "s/CHILD_BRANCH/LATEST/"` ' > diff.log
Using simple quotes for the -exec directive is a good idea, as explained in "CLEARCASE_XPN not parsed as variable in clearcase command".
However, cleartool diff, even with the -ser (-serial) option don't produce exactly an Unix unified diff format (or Unified Format for short).
The -diff(_format) option is the closest, as I mention in "How would you measure inserted / changed / removed code lines (LoC)?"
The -diff_format option causes both the headers and differences to be reported in the style of the UNIX and Linux diff utility, writing a list of the changes necessary to convert the first file being compared into the second file.
One idea would be to not use cleartool diff, but use directly diff, since it can access in a dynamic view the right version through the extended pathname of the elements found.
The OP ckcin's solution is close that what I suggested with cleartool get:
cleartool find . -type f -branch "brtype(CHILD_BRANCH)" -exec 'cleartool get -to $CLEARCASE_PN.prev `echo $CLEARCASE_XPN | sed "s/CHILD_BRANCH/LATEST/"`; diff -u $CLEARCASE_PN.prev $CLEARCASE_PN; rm -f $CLEARCASE_PN.prev' > CHILD_BRANCH.diff
the output seems to work, I can read the file in via kompare without complaints.
In multiple line, for readability:
cleartool find . -type f -branch "brtype(CHILD_BRANCH)"
-exec 'cleartool get -to $CLEARCASE_PN.prev
`echo $CLEARCASE_XPN | sed "s/CHILD_BRANCH/LATEST/"`;
diff -u $CLEARCASE_PN.prev $CLEARCASE_PN;
rm -f $CLEARCASE_PN.prev' > CHILD_BRANCH.diff
(Note that $CLEARCASE_XPN and $CLEARCASE_PN are set by the cleartool find commant, they're not variables you set yourself.)
Transferring the answer from VonC and einpoklum to Windows I came up with the following. Create a separate batch file, which I called diffClearCase.bat, this eases up the command line significantly. It creates a separate tree for all modified files, which I personally liked, but the file and folders can be deleted afterwards.
#echo off
SET PLAINFILE=%1
SET PLAINDIR=%~dp1
SET CLEARCASE_FILE=%2
SET BRANCH_NAME=%3
SET SOURCE_DRIVE=T:
SET TARGET_TEMP_DIR=D:
SET DIFF_TARGET_FILE=D:\allPatch.diff
call set BASE_FILE=%%CLEARCASE_FILE:%BRANCH_NAME%=LATEST%%
call set TARGET_FILE=%%PLAINFILE:%SOURCE_DRIVE%=%TARGET_TEMP_DIR%%%
call set TARGET_DIR=%%PLAINDIR:%SOURCE_DRIVE%=%TARGET_TEMP_DIR%%%
echo Diffing file %PLAINFILE%
IF NOT EXIST %TARGET_DIR% mkdir %TARGET_DIR%
cleartool get -to %TARGET_FILE% %BASE_FILE%
diff -u %TARGET_FILE% %PLAINFILE% >> %DIFF_TARGET_FILE%
rem del /F/Q %TARGET_FILE%
And then I created a second bat file which simply takes the branch name as argument. In our case this directory contains multiple VOBs, so I iterate over them and do this per VOB.
#echo off
SET BRANCHNAME=%1
SET DIFF_TARGET_FILE=D:\allPatch.diff
SET SOURCE_DRIVE=T:
SET DIFF_TOOL=D:\Data\Scripts\diffClearCase.bat
IF EXIST %DIFF_TARGET_FILE% DEL /Q %DIFF_TARGET_FILE%
for /D %%V in ("%SOURCE_DRIVE%\*") DO (
echo Checking VOB %%V
cd %%V
cleartool find %%V -type f -branch "brtype(%BRANCHNAME%)" -exec "%DIFF_TOOL% \"%%CLEARCASE_PN%%\" \"%%CLEARCASE_XPN%%\" %BRANCHNAME%"
)
I want to find all elements in a directory in ClearCase under a branch say BR1 where the label LABEL1 is not on latest of BR1.
cleartool find . -ele "lbtype_sub(LABEL1) && brtype(BR1) && ! version(.../BR1/LATEST)" -print
This doesn't seem to be working.
What is the problem ?
The example of cleartool find for versions not the LATEST is:
cleartool find . -version "{brtype(main_dev) && created_since(30-Apr) &&
(! created_since(31-May)) && (! version(\main\main_dev\LATEST))}" -print
So try:
cleartool find . -ele '{lbtype_sub(LABEL1) && brtype(BR1) && (! version(.../BR1/LATEST))}' -print
If it doesn't work for elements, do the query for version associated with an exec directive, in order to display the name of the element associated with the version found:
(see fmt_ccase)
cleartool find . -ver '{lbtype_sub(LABEL1) && brtype(BR1) && (! version(.../BR1/LATEST))}' -exe 'cleartool descr -fmt "%En"'
And sort the list to remove any duplicate: %En display the name of the element.
Warning: Note that will give you elements that also have a LATEST version on that branch BR1, so you need to make a second query:
cleartool find . -ver '{lbtype_sub(LABEL1) && brtype(BR1) && version(.../BR1/LATEST)}' -exe 'cleartool descr -fmt "%En"'
That will give you all the elements which have a version in BR1/LATEST.
Remove those elements from the first list, and you will get (finally) what you are after.
In short: -ele doesn't work directly for this kind of query.
I modified and checked-in a bunch of files under my branch. Now I need to get the list of files I modified. Is there any scripts to do so?
The cleartool command find should help you find any element (file) with at least one version on a given branch.
The following will find all the files on a branch
cleartool find . -type f -branch "brtype(mybranch)" -print
See find examples or "Additional examples of the cleartool find command" for more examples.
The OP sarath adds:
it gives me a crippled file name with # and other characters. Is it possible to get with normal path?
True, such a command would give you something like (as an example):
.\.checkstyle##\main\MyBranch
.\.classpath##\main\MyBranch_Int\MyBranch
.\.classycle##\main\MyBranch_Int\MyBranch
.\.fbprefs##\main\MyBranch_Int\MyBranch
To get only the path, you have two solutions:
1/ look for elements (and not versions) with the right branch:
cleartool find . -type f -ele "brtype(mybranch)" -print
(note the -ele replacing the -branch)
That would give:
.\.checkstyle##
.\.classpath##
.\.classycle##
.\.fbprefs##
.\.pmd##
But you still have the "ugly" '##'.
2/ combine the find with an exec directive which describe the element found with fmt_ccase format:
cleartool find . -type f -ele "brtype(mybranch)" -exec "cleartool descr -fmt \"%En\n\" \"%CLEARCASE_PN%\""
Multi-line form for readability:
cleartool find . -type f -ele "brtype(mybranch)" \
-exec "cleartool descr -fmt \"%En\n\" \"%CLEARCASE_PN%\""
Please note that all "inner" double quotes need to be escaped.
The %En will give you the name of the element found.
.\.checkstyle
.\.classpath
.\.classycle
.\.fbprefs
.\.pmd
.\.project
.\.settings\dico.txt
The find command is the best source. To address the OPs concerns about getting back a "crippled" name with ## and all of the branch and version information afterwards, the "-nxn" option can be added to not provide this info. This is much easier that doing the element search combined with exec directive to format the output.
cleartool find . -type f -branch "brtype(mybranch)" -nxn -print
The above command will give all the files modified in particular branch(myBranch).
But if you want to find the files modified by particular user in particular date, you would need the following command:
cleartool find . -version "{created_since(28-APRIL-2011.23:00:00) \
&& (!created_since(29-APRIl-2011.23:00:00)) \
&& brtype(BR_test) \
&& created_by(p723029)}" \
-exec "cleartool describe -fmt \nName\t\t:\040%En\nResponsible\t:\040%u\nDate\t\t:\040%d\nComment\t\t:\040%c\n %CLEARCASE_XPN%" \
-print >> D:\test.xls
(in one giant line for copy/paste purpose:)
cleartool find . -version "{created_since(28-APRIL-2011.23:00:00) && (!created_since(29-APRIl-2011.23:00:00)) && brtype(BR_test) && created_by(p723029)}" -exec "cleartool describe -fmt \nName\t\t:\040%En\nResponsible\t:\040%u\nDate\t\t:\040%d\nComment\t\t:\040%c\n %CLEARCASE_XPN%" -print >> D:\test.xls
try this command
cleartool find -avo -nxname -element '{brtype(branch_name)}' -print
Use the following script
#!/bin/sh
display()
{
echo "usage: $0 branchname -v vobs"
echo " branchname: optional, if absent uses the current view-name"
echo " -v vobs: optional, if absent uses default vob list"
}
if [ $# -gt 1 ]; then
if [ $1 == -v ]; then
branch=`basename $CLEARCASE_ROOT`
VOB_LIST=${#:2:($# - 1)}
elif [ $2 == -v ]; then
branch=$1
VOB_LIST=${#:3:($# - 2)}
else
display
exit 1
fi
else
VOB_LIST="/vobs/abc /vobs/def /vobs/ghi /vobs/jkl /vobs/mno"
if [ $# -eq 1 ]; then
if [ $1 == -h ]; then
display
exit 0
else
branch=$1
fi
else
branch=`basename $CLEARCASE_ROOT`
fi
fi
echo "Searching for files of branch <$branch> in following vobs:"
echo "$VOB_LIST"
echo "================================================================"
cleartool find $VOB_LIST -all -version "version(.../$branch/LATEST)" -print
Save this in a file named ctlsbr and use this from the vob you want to find out the list of modified files.
Thanks,
Amit
This part " ( -name *txt -o -name *html ) " confuses me in the code:
find $HOME \( -name \*txt -o -name \*html \) -print0 | xargs -0 grep -li vpn
Can someone explain the the brackets and "-o"? Is "-o" a command or a parameter? I know the brackets are escaped by "\" , but why are they for?
By default, the conditions in the find argument list are 'and'ed together. The -o option means 'or'.
If you wrote:
find $HOME -name \*txt -o -name \*html -print0
then there is no output action associated with the file names end with 'txt', so they would not be printed. By grouping the name options with parentheses, you get both the 'html' and 'txt' files.
Consider the example:
mkdir test-find
cd test-find
cp /dev/null file.txt
cp /dev/null file.html
The comments below have an interesting side-light on this. If the command was:
find . -name '*.txt' -o -name '*.html'
then, since no explicit action is specified for either alternative, the default -print (not -print0!) action is used for both alternatives and both files are listed. With a -print or other explicit action after one of the alternatives (but not the other), then only the alternative with the action takes effect.
find . -name '*.txt' -print -o -name '*.html'
This also suggests that you could have different actions for the different alternatives.
You could also apply other conditions, such as a modification time:
find . \( -name '*.txt' -o -name '*.html' \) -mtime +5 -print0
find . \( -name '*.txt' -mtime +5 -o -name '*.html' \) -print0
The first prints txt or html files older than 5 days (so it prints nothing for the example directory - the files are a few seconds old); the second prints txt files older than 5 days or html files of any age (so just file.html). And so on...
Thanks to DevSolar for his comments leading to this addition.
The "-o" means OR. I.e., name must end in "txt" or "html". The brackets just group the two conditions together.
The ( and ) provide a way to group search parameters for the find command. The -o is an "or" operator.
This find command will find all files ending in "txt" or "html" and pass those as arguments to the grep command.