This question is related to the last change set id available in TFS, my query is, our tfs collection has multiple branches. I create a work space for each branch and build them.
Now my question is: I wanted to know the last local changeset id of the workspace with which I build the solution.
For example, I build MAIN branch 2 days back, now I wanted to know the last local change set id that is available locally. I used History command but some how it is giving the server changeset not the local changeset id.
Here are my arguments
tf history $/MAIN /collection:tfscollection /format:Detailed /sort:Descending /stopafter:1" ;
In this case, you want to look at the history of your workspace version. TFS tracks (server-side) the versions of files you have locally and defines your workspace version to be the version of the files that you have locally. Contrast that with the latest version which is the current version on the server.
You can use a version spec to indicate what version you want to query, T for the latest version and W for your workspace version.
Another problem, however, is that your current query will only look at the history for the folder you're specifying - that is, when it was added or branched. You will need to perform a recursive query to example all changesets that affect (are beneath) the specified folder.
Thus, your query to get the latest version on the server becomes:
tf history $/MAIN /collection:tfscollection /version:T /recursive /stopafter:1 /format:detailed /noprompt
And to get your workspace version:
tf history $/MAIN /collection:tfscollection /version:W /recursive /stopafter:1 /format:detailed /noprompt
Related
I have this workspace on this machine that is not updated for some days. I want to know the latest changeset Id that exists on this machine.
Let's say the latest changeset that is checked-in is 8400. I want to somehow find the current changeset id of the workspace on this machine, that might be say for example 8329.
Yeah, the tf history command can achieve that.
For your convenience, you can simply copy below strings and save as a cmd/bat file, then run it directly to get the latest changeset ID under the specific directory within the local workspace. (In your scenario you need to enter the root path of your workspace)
ECHO OFF
SET "VSDir=C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer" :: For VS 2017
:: For VS 2015: SET "VSDir=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE"
CD %VSDir%
SET /p LocalPath=Enter LocalPath:
ECHO.
tf history %LocalPath% /r /noprompt /stopafter:1 /version:W
ECHO.
PAUSE
Besides, you can also use the Version Control client API to achieve that.
For more information please refer to: How to determine the latest changeset in your workspace
You may use tf history command. Go to root workspace folder and:
tf history . /recursive /noprompt /stopafter:1 /version:W
I am having difficulty to phrase the command
tf.exe branch olditem newitem [/version:versionspec]
Especially, I don't know what to put for "versionspec"
I tried this from Powershell:
.\Tf.exe branch $/ProjectA/DEV $/ProjectB/DEV1 /workspace
but I got the below error:
Unrecognized command option 'workspace'.
Can anybody help me set the full command with an example?
If you want to create branch for latest version of your source code you may use branch command without versionspec: https://learn.microsoft.com/en-us/vsts/tfvc/branch-command
If no version is provided, Team Foundation uses the following logic to decide which version of the item to copy to the new branch:
•If a Team Foundation version control server path is specified, then Team Foundation branches the item at the latest Team Foundation version control server version. For example, tf branch $/projects/help.cs uses the server version.
•If a local path is specified for the source, Team Foundation uses the local, workspace version to create the new branch. For example, tf branch C:\314.cs uses the local workspace version.
The branch command copies an item or set of items, including metadata and version control history, from one location to another in the Team Foundation version control server and in the local workspace.
As for what to put for "versionspec", please refer below tutorials:
Versionspecs
A versionspec specifies the version of an item that you want to work
with. You can specify versions in a command either by including the
versionspec as part of the version option (for example,
/version:C1256) or by appending the versionspec to a file name with a
semicolon (for example, filename;Lmylabel).
Source Link
If you want to specify the workspace, you are lacking a W in front of the workspace name. For example: Workspace (Wworkspacename)
A sample full command in cmd with using tf.exe branch command for your reference(my worksace name is PATRICK-W10 in this case):
tf branch $/ScrumProject/TestCaseProject $/ScrumProject/Test /v:WPATRICK-W10
I have Dev and Release Branches in tfs.
I use release branch only for critical fixes after I release a version
Before each release I want to overwrite all changes made in Release branch with Dev branch. After that Release and Dev branches should be equal.
I'm using following commands to do so:
tf merge DEV RELEASE -r -force -version:1~T -noprompt
tf resolve RELEASE -r -auto:acceptTheirs
The problem is, that all files are in pending changes with "merge" change. I also see this in tfs history of file after check in.
Is this correct approach? Should I do things differently, e.g check in only changesets from last release? does it have any side effects?
You are using the -force parameter. That is the result of that c command.
"Ignores the merge history and merges the specified changes from the source into the destination, even if some or all these changes have been merged before"
https://msdn.microsoft.com/en-us/library/bd6dxhfy(v=vs.100).aspx
If you remove the -force option it will only merge the changes.
Here is the simplified version of our gated check-in flow for a successful check-in:
Apply shelveset (build agent)
Build (build agent)
Revert Shelveset from Workspace (build agent)
Check in gated changes (CheckInGatedChanges activity on the controller)
Get the Changeset resulted from checking in the gated changes. (build agent)
This flow is very problematic. Indeed, suppose user A commits (submits to the gate) 100 source files affecting all the projects in the solution and then user B commits just 1 source file affecting just one project. How big would be the gated check-in build for the user B on the build agent?
The answer is that user B is going to "suffer" the same build as the user A.
The root cause: we undo the shelveset before checking in the gated changes and then get them again, this time in the form of a changeset. This bumps up the timestamps of the source files, making them newer then the binaries produced a moment ago from the same files.
That is a problem.
How do I solve it?
EDIT
Here what happens if I do not revert the shelveset, but get the respective changeset right away:
PS D:\tfs\DFGatedCheckInTest2> dir 1.txt
Directory: D:\tfs\DFGatedCheckInTest2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 10/24/2014 10:36 AM 12 1.txt
PS D:\tfs\DFGatedCheckInTest2> tf get /version:C105656
D:\TFS\DFGatedCheckInTest2:
Conflict 1.txt - Unable to perform the get operation because you have a conflicting edit
Automatically resolved conflict: edit: D:\TFS\DFGatedCheckInTest2\1.txt as TakeTheirs
Undoing edit: 1.txt
PS D:\tfs\DFGatedCheckInTest2> dir 1.txt
Directory: D:\tfs\DFGatedCheckInTest2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar-- 10/24/2014 11:42 AM 12 1.txt
PS D:\tfs\DFGatedCheckInTest2>
Notice the timestamp of the file. It was bumped up. We achieved nothing.
The reason why tf get /version:C12345 updates the time stamp is due to that being the default behavior for it in 2010. This was changed in 2012 and made configurable.
In Visual Studio 2012/TFS 2012 a feature was added that controls the file timestamp on get, read from Brian Harry's post from way back then:
Restore file modification time
When TFS gets files on to your local disk, it always sets the file modification time to the date/time that the get operation happened. There are some work practices where this is problematic. Some practices use the date stamp on the file for incremental deployment or other kinds of change management. SourceSafe had 3 options for setting the time stamp on files:
The time the file is gotten (this was the default and works very well in concert with make and other similar build dependency trackers).
The modification time that the file had when it was last edited before checkin.
The date/time that the file was checked in.
TFS 2010 and before only supported option #1. In TFS 11, we have added support for option #3. It can be set on a workspace by workspace basis. We plan to add support for #2 in the future but haven’t gotten there yet.
source
Back to the source of the issue
As you mention in your other question, you're using tf checkin /shelfset /force, which is where your problem lies. As the answer in your other question explains, that checkin goes directly against the server, the workspace on the server is unaffected and as such is left with the pending changes of unshelving that same shelfset.
tf checkin /force is also very dangerous in case anther developer had used by-pass gated build to check in changes. TFS will assume you know what you're doing and will overwrite these changes. So:
Developer 1 checks in filaA.txt
Build server starts gated checkin
Developer 2 checks in fileA.txt and bypasses gated checkin
Build server finishes and uses tf checkin /shelfset /force and thus overwrites the changes from developer 2
Instead, what the normal TFS workflow does, is check in the local changes on the workspace of the build agent. tf checkin $/ /recursive and it deletes the shelfset at the end of the build, in case of a succesful build and checkin.
This tells the build server to check-in the local changes in the workspace, and it will now know that it has the latest version, and won't have to update the time stamp. Next time the build is triggered the build agent will start with a get latest (to ensure that any bypass checkins are also fetched) and it will know these files are already up to date.
So in general your workflow, on the agent, should look like:
If workspace does not exist, create workspace and mappings
If there are any pending changes, undo them tf undo $/ /recursive
Perform tf get /recursive /version:T (get latest)
Unshelve your shelfset to the workspace of the agent
Build the code
Check in the local pending changes (tf checkin $/ /recursive), don't use /force
If all of that's succesful, delete the shelfset
If anything fails:
Undo all pending changes to reconcile the workspace
Leave the shelfset in tact
Fail the build.
That way the local workspace will better reflect what's going on and you won't have to perform a tf get /version:c12345 to mess up your dates.
I'm trying to use tfpt to migrate a shelveset from a source branch into a target branch, but it doesn't appear to do anything...not that I'd expect much more...but any chance anyone knows what's wrong? I'm following the instructions correctly I think...
I've got:
tfpt unshelve "DbMigrations" /migrate /source:$/TeamProject/Main /target:$/TeamProject/Releases/7.20
What happens after you run the command? You need to have a few things set up before migrating:
A workspace that encompasses both the source and target branches.
You need to run the command in a folder within the source.
Once you run the command you should be asked to merge the changes from the original shelfset into the destination branch and resolve any conflicts, which finally pends a changeset on your client. Nothing is touched on the server until you check that changeset into TFS itself.
I experienced the same problem and I could not get it to work by specifying the shelveset name. However, I discovered that if you remove the name of the shelveset altogether, TFS will pop up a window with a selection list of available shelvesets to choose from. Select the desired shelveset and perform all other merge operations as per normal.
Example: c:[mapped workspace target path] > tfpt unshelve /migrate /source:"$/Sourcepath" /target:"$/targetpath"
You need to use the branch paths on the TFS server, not your local machine. To find the paths, go to source control explorer in visual studio, right click the branch, advanced > properties, and you want the branch name, not the local path. If the path has spaces, wrap it in double quotes.