Get all labels in TFS 2010 - tf-cli

Is it possible to get all the labels recursively across nested folders?
When doing something like:
tf history * /recursive
In the labels tab I see
"The parameter filterItem may not contain wildcards"
I've tried various different options, but no luck and I can't find a reference to doing labels recursively in msdn.
EDIT:
To elaborate with the background to my question, we use labels to mark hotfix releases. So a release is a branch, but a hotfix is a label. I want to get all the hotfix labels across the project.

Change to the directory you are interested in and do tf.exe labels and this will show you all labels where the directory is included in. You can than get more detailed information about one label by using tf.exe /format:detailed labelname.

Related

How do I search for specific kinds of merge hyperlinks in clearcase?

Background
I have recently created an erroneous merge hyperlink in clear case. This was the result of a script that automerged several files. Given that a script created the erroneous merge, I am trying to search for other instances of erroneous merge arrows. Below are the constraints I want to put in my search:
All merge hyperlinks created by me.
On a specific date
This question talks about finding a merge hyperlink in one file. However, I am looking for a set of merge hyperlinks that I created.
What I know
I know that you can describe hyperlinks as shown below:
Describe a hyperlink.
cmd-context describe hlink:Merge#516262#/vobs_proj
hyperlink "Merge#516262#/vobs_proj"
created 2006-07-14T16:43:35 by Bill Bo (bill.user#uranus)
Merge#516262#/vobs_proj /vobs_proj/lib/cvt/cvt_cmd.c##/main/v1.1_port/8 ->
/vobs_proj/lib/cvt/cvt_cmd.c##/main/71
But I am looking for how to query for the "created..." field from a set of merge hyperlinks.
Question
How do I query for merge hyperlinks that I created at a specific time?
Consider cleartool find to try and link those hlink
cleartool find . -kind hlink -user <myLogin>
Then try and combine the find with an exec cleartool describe $CLEARCASE_PN, maybe adding queries (as described in the query_language)
If not query is working, at least you could then grep the output for:
your Login
excluding (grep -v) dates which are too old.
Brian Cowan adds in the comments:
I've found that you can use this to get the hlink names, but you have to use $CLEARCASE_PN.
Parsing it is non-trivial because the "hlink" formatting property apparently doesn't work.
You would have to:
Filter the output by date (cleartool desc -fmt "%d %Xn\n" $CLEARCASE_PN)
Describe each desired link and grep for "->"
That'll get you the hyperlink source and destination.
rmver -xhlink would let you remove the merge-created versions
If this was recent enough, you should be able to use cleartool lshistory -minor
I just created a merge hyperlink, and lshist -min -rec on the root of the VOB showed me this.
--09-12T15:57 Brianc make hyperlink "Merge" on version "Documents\libatriadb_ldb.txt##\main\testbr\1"
"Attached hyperlink "Merge#504#\foobarf"."
--09-12T15:57 Brianc make hyperlink "Merge" on version "Documents\libatriadb_ldb.txt##\main\CHECKEDOUT"
"Attached hyperlink "Merge#504#\foobarf"."
A little work with the -fmt option and you may be able to get this formatted how you need it.

VSTS: finding project-wide changes between two change lists or labels

I have a large project that is hosted in VSTS. I'd like see the differences in all files, project-wide, between two change lists. (It would also be helpful to do the same between two labels, since I have labels at the two points of interest.)
We have a problem that manifests between one build of our product and another; one way to go searching for the issue is to comprehensively review the code that changed between those two builds.
How can I show the differences in all files, project-wide, between one change list and another?
I've tried this:
tf diff . /recursive /version:100~150
and it seems to work, but it takes a very long time; and the output is a plain text diff. Can I browse the changes graphically, like in BeyondCompare or the IDE? Anything I can do to speed up the comparison?

Clearcase finding a specific file on any branch

Our clearcase installation has multiple branches covering many years of development. I'm trying to search for a specific file (or part file name) and it could be on a branch that has never been merged back to the integration or MAIN branch.
Branch structure can be
main/branch1
and also
main/integration/branch2
Any thing i've seen on cleartool find needs a view but i've not be able to get a catch all config spec.
Any suggestions.
Thanks
The cleartool find command does not depend always on a view config spec:
find [ pname... ] –a/ll [ –vis/ible | –nvi/sible ]
You can also start with all objects in one or more VOBs, regardless of they are visible in a particular view
So you can use options -all and -nvis in order to search for all elements.
The view gives context for the command find to find the right vob (base on the pname argument.
The -nvis option will find elements, along with their branches and versions, that are not visible (do not have a standard path name) in the view.

Team Foundation Server - Moving Source with History

I was wondering what the best approach might be in moving source code, with history, from one Team Project to another Team Project. I am not concerned with work items, reporting, or SharePoint sites, as the system we are going to be restoring from did not use these functionalities. The reason for wanting to move to a different Team Project also is driven by the fact that the original implementation (being restored from a backup that was maintained by a third party) were using a third-party process template that we do not wish to use going forward. We want to start utilizing work item tracking and reporting after the migration is complete.
The TFS Integration Platform seems to be one likely scenario. It can be used to change the process template, according to the documentation. However, I was curious if the tf.exe move syntax might work? Something like:
tf.exe move $/ProjectA $/ProjectB
It is my understanding that this command operates much like a rename operation, whereas moving with the "Move" context menu item in Source Control Explorer is more like a delete and add operation. Also, would the tf.exe move path actually associate the code under the folders with the appropriate Team Project, assuming that $/ProjectA is the root source control folder for one project and $/ProjectB is the root source control folder for the other? The key is to be able to preserve the history, if possible.
Any advice or tips would be greatly appreciated!
Edit - Could branching to another project handle this scenario - much like Microsoft discusses in the Branching Guidance documentation? I think that this could be the answer, since the history would likely be preserved with the branch. However, I do not have access to a Team Foundation Server 2008 instance at the moment to test it.
Move and Rename are aliases. There is absolutely no difference, in any version of TFS, from the command line or the UI.
Both of them preserve history. At least in 2005/2008, you keep the same physical item in the VersionedItem table no matter how often or how drastically the name and/or parent path changes. There is actually no way to get a "fake" rename (delete + add) without a lot of manual work on your part.
However, while this versioning model is very pure in a theoretical sense, it has some practical gotchas. Because different items can occupy the same name at different points in time, TFS needs the full name + version to uniquely identify any inputs you send it. Normally you don't notice this restriction, but once have you renamed items in the system, if you say tf [doSomething] $/newname -version:oldversion then it will get confused and either throw an error or operate on an item you may not have intended. You have to be careful to pass valid combinations (newname+newversion or oldname+oldversion) to ensure commands behave the way you want.
TFS 2010 changes the story somewhat: it's a branch+delete under the covers, causing the itemID to change. Even so, everyday commands like Get and History are "faked" very well; old clients are about 95% compatible. The advantage is that when you have multiple renames in the system and path-based item lookups start to become ambiguous as alluded to above, the server will simply accept the name you specify and run with it. This improves overall system performance and eliminates several traps that unfamiliar users often fell into, at the cost of not being quite as flexible and not preserving history with 100% precision (eg when there are name collisions during a Merge of two branches).
Returning to the problem at hand...
It's not as simple as saying tf rename $/projectA $/projectB. Top level folders in the source control tree are reserved for the Team Project Creation Wizard; you can't run standard tf commands against them. What you need is a script like:
Get-TfsChildItem $/ProjectA |
select -Skip 1 | # skip the root dir
foreach {
tf rename $_.serveritem $_.serveritem.replace("$/ProjectA", "$/ProjectB")
}
[of course, you can do it by hand if there aren't too many children under $/ProjectA]
As far as the gotchas I mentioned, I'll elaborate on one right now since looking up old history seems very important to you. Once you checkin the rename, tf history $/ProjectA/somefile.cs will NOT work. By default, tf commands assume version = "latest." Any of these alternatives will the full history you want:
tf history $/ProjectA/somefile.cs;1234 where changeset 1234 was before the move
tf history $/ProjectB/somefile.cs;5678 where changeset 5678 was after the move. Or you could just omit the version.
A final alternative for completeness & debugging purposes:
tf history $/ProjectA/somefile.cs -slotmode. You will only see the changes that happened prior to the move; however you'll also see the history of any other items that may have lived in the $/ProjectA/somefile.cs "slot" prior to or subsequent to the item you moved underneath B.
(In TFS 2010, "slot mode" is the default behavior; there's an -ItemMode option to request that your lookup be traced across history like it was 2008 rather than path-based.)
EDIT - no, branching is not a great alternative. While branching does leave enough metadata in the system to trace the full history to & from ProjectB, it's not terribly user friendly in 2008. Plan to spend a lot of time learning the tf merges command (no UI equivalent). 2010 dramatically improves your ability to visualize changes across multiple branches, but it's still not the clean unified experience you'd get from a Rename.
Richard's answer above is well written and explains the situation well. I did have a couple more practical gotcha to add, however.
In TFS2010, the default behavior makes it seem like moving a file causes you to lose all history from before the move. The command my users are likely to use (and the one used, it seems, by the VS2010 GUI) is:
tf history $/ProjectB/somefile.cs
My users intend to get all the history of somefile.cs, both before and after the move. They want "the history of the code that is currently stored in $/ProjectB/somefile.cs", regardless of the filename at any point in time. Maybe other people see it differently.
The first gotcha is that the GUI that appears for me in VS2010 using TFS2010 initally shows only the history since the move. The least-recent item in the list is the rename operation. It can be expanded with a subtle little drop-down arrow. Underneath is the history from the previous location. If you don't know to look for this, it can look like your history is gone.
The second gotcha is that if you later delete ProjectA (because you've finished the migration to ProjectB, say), the history really is gone. Expanding the drop-down in the history for $/ProjectB/somefile.cs doesn't produce the older history.
Another option (and I think easier) is to import to Git then export back to TFS using the Git-TF command line tools.
Install Git-TF from binary, Choclatey or source code.
Clone a TFS folder:
git tf clone https://myAcc.visualstudio.com/mycollection $/TeamProjectA/Main --deep
Disassociate the Git Repo from the TFS server by deleting the .Git/tf folder and the .Git/git-tf file.
Configure the new Git Repo to connect to an empty TFS folder.
git tf configure https://myAcc.visualstudio.com/mycollection $/TeamProjectB/Main --deep
Don't forget the --deep
git tf pull
You should get a message at this point "git-tf: this is a newly configured repository. There is nothing to fetch from tfs."
git commit -a -m "merge commit"
git tf checkin --deep
Regarding the original command above:-
Get-TfsChildItem $/ProjectA |
select -Skip 1 | # skip the root dir
foreach {
tf rename $_.serveritem $_.serveritem.replace("$/ProjectA", "$/ProjectB")
}
Both the source and target names need to be surrounded by quotes in case there are any spaces in the full pathfilename. I found it difficult to do this on $_.ServerItem as surrounding it with escaped " returns that whole child object and not just the .serverItem string. Or if I did manage to get the string, I got unwanted carriage returns such as
"
$proj/folder/file
"
Eventually I got the command to work with the following, but I found that the history still doesn't get transferred, which was the whole point! So I believe this command is the direct equivalent of just using a right mouse click in source explorer and selecting rename (or move).
$tfsServerString = "http://machine:8080/tfs/DefaultCollection"
$tfs = Get-TfsServer $tfsServerString
Get-TfsChildItem -server $tfs "$/Dest Project/MyTestProject" | select -Skip 1 | foreach { $sourceName = $_.serveritem; $targetName = $_.serveritem.replace("$/Dest Project/MyTestProject/", "$/Dest Project/Source/StoreControllers/dSprint/dSprint2/") ; ./tf rename `"$sourceName`" `"$targetName`" /login:myUser }
Also note, it requires use of the backtick ` to escape "

All change comments to perforce branch between 2 labels? (including merges)

Our perforce admin limits "max-row" scans so that my first idea of running the following will not work:
All changes including integrates into a branch at particular label time 1
All changes including integrates into a branch at particular earlier label time 2
Subtract time 2 changes from time 1 to get the new changes with comments.
Is there an alternative way of getting the same result without having such a massive query(when perforce contains 7yrs of history and -i triggers a scan back to the dawn of history)
Based on Gregs comments added this comment:
Basically the point is to see what bugs got fixed in a particular release branch between 2 labels(or more commonly, some old label and today).
I wish to simplify(speedup) way too complex script that we currently have which looks at changes that went into a release branch, it follows files that went into them at least 2 branches up in order to printout all the changeset comments from the original change(the interim merge comments tend to just say something like merge123 etc instead of description of the actual change comments, so we need to walk up the tree to the original comment as well), script finally outputs something like below(we put quality center IDs into changeset comments):
qualityCenterId123 - fixed some bug
in gui qcId124 - fixed some other
bug qcId125 - fixed some other bug
merge123
UPDATE based on comments:
Problem with Toby's approach is that most of the changes into the code branch came via integrations, -i would include those change, but as stated that explodes the query to such a degree that due the load on perforce server our admin won't allow it to run. So this is why I am looking for an alternative approach to get the same result.
I can't see an easy answer to this, but do have a couple more suggestions that perhaps may help point in the right direction.
Persuade your admin to raise the maxscan rows limit. If he is nervous that this will lead to problems with the whole user base, just get him to add you to a new user group (e.g. "Scripting"), and set the limits for just that group. That will have the effect that only members of that group can use the upper limits, and you can then negotiate for suitable times to run the script. You could even do it overnight.
Have a look at the P4 admin guide and see if any of the hints on scripting will help - e.g. maybe a tighter view on the data will limit the query enough to not break the maxscanrows limits.
How's your SQL? You may be able to construct an efficient query using the P4Report tool.
Try asking the question on the Perforce mailing list. It's a very active list that has a lot of very experienced people who are very helpful. See this link for the sign-up page. There's a good chance that they will suggest some good approaches.
Probably too late for yoru existing labels, but consider using the job system to track work. Perforce has inbuilt query tools to track what jobs have made it into different branches. It does require a working-practice change for your team, however.
Sorry I can't provide a more specific answer.
Are your labels more than simply the most recent changelist when they were created? Eg did you really need to record specific files in client workspaces? If not you can very easily compare the two changelists closest to labels.
Say the closest change to your first label date is 23000 and your closes change to your second label date is 25000 then
p4 changes //depot/PATHTOMYCODE/...#23000,#25000
will give you all changes to your code path between these two changelists.
Won't a normal Label-diff do what you want?
From P4V, Tools->Diff. Select the two labels
From P4Win, right click label, select diff files in 2 labels
From command line, p4 diff2 //codeline/...#label1 //codeline/...#label2
Or am I missing exactly what you are after?
Further suggestion after Ville's comment on the above
If you are only after the info per changelist, rather than per file, then try "p4 interchanges" from the command line. This will give you just the summary of what changes in one branch have not happened in another, and you can supply a revision range to limit it to the labels you need.
Do "p4 help interchanges" from command line for details.
Unfortunately the interchanges command is not yet exposed in P4V or P4Win.
Toby Allen's Answer is the best approach if your labels are simple changelists.
If the labels are more complicated, then I think you need to look at all the files in each label and where their versions differ, find the changelist where the version changed.
You can get the file and version lists with:
p4 fstat -Of //...#MyLabel
EDIT:
Consider two complex labels:
VERSION_A:
//depot/file_A.cpp#4
//depot/file_B.cpp#7
//depot/file_C.cpp#1
VERSION_B:
//depot/file_A.cpp#6
//depot/file_B.cpp#5
//depot/file_C.cpp#4
In this example, the labels do not describe a particular changelist, the head change for each file may be different.
If you can have labels like this, then you can run the p4 fstat command on each label and then find the differences. In this example, file_A.cpp has changed twice and file_C.cpp has changed 3 times. file_B.cpp is older in the second label, so it can be ignored.
So now you need to look at the changes that involved these versions:
file_A.cpp#5
file_A.cpp#6
file_C.cpp#2
file_C.cpp#3
file_C.cpp#4
Those changes can be retrieved with p4 filelog, so you want to run something like this:
p4 filelog file_A.cpp#6
p4 filelog file_C.cpp#4
Then you need to remove any duplicates and any history for earlier versions.
Like I said, you only need this if you have messy lables. If there's any way to make your labels represent changelists, you should use Toby Allen's answer.