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

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?

Related

Compare two projects using vscode

Is there any way to compare two identical projects (with some differences) in vscode? I want to find the difference in the files (e.g. main.c in the first project vs main.c in the second project and so on recersively)
Note: The are a lot of files. I don't want to compare them one by one (by right-clicking on them and choose the compare with option)
I am unaware of VS Code doing this. Beyond Compare does this very well. (exactly what you are describing)
You can choose two directories. The UI will show two columns, and in each they will be highlighted red if there are discrepancies. You can open each folder to see what the differences are.

how to find the number of lines which got changed from one label to another in clear case?

I would like to find the number of lines of code which got added/modified/deleted between two releases. I have a label which is applied at the end of release.
There is ClearCase Report Viewer which shows list of elements which got modified between two labels. But I am looking for number of files which got changed.
Any solution to this?
The easiest way (without involving any commercial third-party tool) is to use linux commands diff and diffstat and apply it to two dynamic views, each one with their own config spec selecting a label:
element * LABELx
element * /main/LATEST
That way, you can get a full report of the differences between the two diffstat reports.
See "Difference between two versions in ClearCase dynamic view" for a concrete example.
diff -u /view/VIEW1/SOMEVOB/some/dir /view/VIEW2/SOMEVOB/some/dir | diffstat
Note: this is valid for Windows as well, since any Git distribution includes diff.exe, and diffstat is available for Windows.

Search code history for closest matching version based on content

I have a file that was forked from a project at an unknown moment in the past. I want to identify as closely as possible the moment of that fork. The file has been changed since the fork-moment.
Winmerge highlights about about 20% of the lines, with about half of those being just a few characters within the line, a path change or inline function turned into a variable or function call for instance. (20% after ignoring whitespace change and enabling moved-block detection that is, closer to ~40% without that.)
I don't have to worry about branches, the original version control system was CVS. (I don't have access to the CVS file system). I have a git imported version with tags corresponding to the CVS commits, and could generate the same with Mercurial for little effort if need be.
I don't care about matching the specific CSV commit date/time/number/whatever. The goal is to identify when the content of new file started drifting, and step forward through the revision history, cherry picking what to merge to the forked file.
For this project I could brute force it, there only a dozen or so revisions where the fork has mostly likely occurred and the file is less than 500 lines. However it's not hard to imagine a scenario where this is not feasible and I'm curious about what an elegant solution might be.
How would you go about solving this?
"Brute force" sounds as if you were contemplating testing all revisions. Normally one would use a binary search. To decide if it was a good match, I'd normally use just the numbers from diffstat (since you say there are post-fork changes). Accounting for block-moves complicates things, though.

How to join two files in a version control system

I am doing a refactoring of my C++ project containing many source files.
The current refactoring step includes joining two files (say, x.cpp and y.cpp) into a bigger one (say, xy.cpp) with some code being thrown out, and some more code added to it.
I would like to tell my version control system (Perforce, in my case) that the resulting file is based on two previous files, so in future, when i look at the revision history of xy.cpp, i also see all the changes ever done to x.cpp and y.cpp.
Perforce supports renaming files, so if y.cpp didn't exist i would know exactly what to do. Perforce also supports merging, so if i had 2 different versions of xy.cpp it could create one version from it. From this, i figure out that joining two different files is possible (not sure about it); however, i searched through some documentation on Perforce and other source control systems and didn't find anything useful.
Is what i am trying to do possible at all?
Does it have a conventional name (searching the documentation on "merging" or "joining" was unsuccessful)?
You could try integrating with baseless merges (-i on the command line). If I understand the documentation correctly (and I've never used it myself), this will force the integration of two files. You would then need to resolve the integration however you choose, resulting in something close to the file you are envisioning.
After doing this, I assume the Perforce history would show the integration from the unrelated file in it's integration history, allowing you to track back to that file when desired.
I don't think it can be done in a classic VCS.
Those versioning systems come in two flavors (slide 50+ of Getting git by Scott Chacon):
delta-based history: you take one file, and record its delta. In this case, the unit being the file, you cannot associate its history with another file.
DAG-based history: you take one content and record its patches. In this case, the file itself can vary (it can be renamed/moved at will), and it can be the result of two other contents (so it is close of what you want)... but still within the history of one file (the contents coming from different branches of its DAG).
The easy part would be this:
p4 edit x.cpp y.cpp
p4 move x.cpp xy.cpp
p4 move y.cpp xy.cpp
Then the tricky part becomes resolving the move of y.cpp and doing your refactoring. But this will tell Perforce that the files are combined.

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.