TF Merge Command - tfs

I use the following command to merge a single changeset from Source to target branch:
result = BatchCommand(#"tf merge /version:" + chgnumber + "~" + chgnumber + #" """ + Source + #""" """ + Target + #""" /recursive /login:" + UID + "," + PWD + "", SourceTar[2]);
BatchCommand is another method which executes the command in cmd in my workspace SourceTar[2].
in some cases I get the error where I need to overwrite files. How can I do this automatically (Overwrite files).
Should I use /force for that? It definetly will resolve that overwrite conflict but will it also resolve other conflict(I don't want that).
I only want to overwrite files if that error occurs, other conflicts are resolved programmatically. Any suggestion would be helpful;

You need to work with tf resolve command to resolve conflicts. Your commands can be the similar to:
tf merge $/TeamProjectRoot/Branches/Source $/TeamProjectRoot/Branches/Target
tf resolve $/TeamProjectRoot/Branches/Target /r /i /auto:TakeTheirs
/auto:TakeTheirs option accepts the changes from the source of the merge and overwrites the changes in the target.
/auto:KeepYours option discards the changes from the source of the merge and leaves the target unchanged.

Related

Can I prevent clang-format from formatting some (generated) files?

Some of the C source files in my project are generated. They obviously are not formatted to the standard in the .clang-format file.
If I just clang-format or git clang-format that generate source is re-formatted causing unnecessary clutter in the commits.
Is there a way to specify that some files should be ignored by clang-format?
In the default implementation of the git clang-format there is no flag or something to ignore autogenerated files .
but it can be achieved by implementing a wrapper script ( I will show how to do that in bash) that will clean the files that you don't want to format and then using the git clang-format.
for example:
1.first of all lets say your generated files include a pattern for example auto_gen or generated .
2.define a regex exp for the auto generated patterns in our example
it can be : pattern_to_exclude_from_clang='.*auto_gen|.*generated'
3.define allfiles = git diff --name-only - this will give you all
the files that your commit change.
4.filter out generated files allfiles ( exclude generated files)
5.run git clang-format --diff -- ${wantedfiles[#]}
so the final script can be :
#!/bin/bash
pattern_to_exclude_from_clang='.*auto_gen|.*generated'
allfiles=`git diff --name-only`
files_array=($allfiles)
for i in "${!files_array[#]}":
do
if [[ "${files_array[$i]}" =~ $pattern_to_exclude_from_clang ]];then
printf "%s %s" "${files_array[$i]" "this file will be skipped by clang"
unset files_array[$i]
fi
done
git clang-format --diff -- ${allfiles[#]}

TFS build write message to summary

I want add a message (link) in the build summary (can be a new section also, doesn't really matter):
Based on this: https://blogs.objectsharp.com/post/2017/04/25/Writing-to-the-Build-Report-in-TFS-2015.aspx,
I've added this line in my Powershell script:
Write-Host "##vso[task.addattachment type=Distributedtask.Core.Summary;name=DotCover Results;]"
However I get an error message:
Unable to process command '##vso[task.addattachment
type=Distributedtask.Core.Summary;name=DotCover Results;]'
successfully. Please reference documentation
(http://go.microsoft.com/fwlink/?LinkId=817296) Cannot upload task
attachment file, attachment file location is not specified or
attachment file not exist on disk
How would one add a text/link/href in the summary of the build? (powershell or other method?)
EDIT:
Please see edit below. I run this script from PowerShell during the build step:
$path = $sourcesFolder + "file:///C:/Temp/dotCover-xunit.html"
Write-Host "##vso[task.addattachment type=Distributedtask.Core.Summary;name=DotCover Results;]$path"
EDIT 2: (tried a simple text)
function AddSummaryMessage{
$filePath = "somestring"
Write-Host "##vso[task.uplaodsummary]$filePath"
}
also tried with "hellomessage" as string in there:
Error message:
2019-04-27T01:49:01.1513980Z ##[error]Unable to process command
'##vso[task.addattachment
type=Distributedtask.Core.Summary;name=DotCover Results;]hellomessage'
successfully. Please reference documentation
(http://go.microsoft.com/fwlink/?LinkId=817296)
2019-04-27T01:49:01.1516289Z ##[error]Cannot upload task attachment
file, attachment file location is not specified or attachment file not
exist on disk
EDIT 3:
function AddSummaryMessage{
$file = Get-ChildItem $outputFolder -name "dotcover.html";
if ($file){
LogMessage("Found dotcover report file: " + ($outputFolder + $file))
$path = ($outputFolder + $file)
Write-Host "##vso[task.uplaodsummary]$path"
}
}
OUTPUT:
9:27:01 AM add summary message
9:27:01 AM Found dotcover report file: C:\Builds\tfsbuilddev02\Agent1\110\s\dotCover\dotcover.html
The "hellomessage" can't work because you must give a file path and not just a string.
In the attempt with the PowerShell script you have a problem in the file path.
I don't know what the value of the sourcesFolder and I can't understand what is the + file ....
I tried to concatenate the file path in this way:
$filePath = $(Build.SourcesDirectory)\test.html
# Verify the path is correct:
Write-Host $filePath
# Output: D:\a\1\s\test.html
And I upload the file to the Summary page in this way:
Write-Host "##vso[task.uplaodsummary]$filePath"
The upload succeeded and the test.html exist in the build summary page.
So in your case you must to check the file path and fix it, after it the upload will work (you can try also put hard coded path and check if it works).
P.S - The task.uploadsuammry is a short hand to task.addattachment type=Distributedtask.Core.Summary.

TFS 2015 build vNext update file version with commit id

Do you know how inject commit id into file version, so every assembly would heve version like 2.0.6565.0 where 6565 is related to C6565commit ID in TFS ?
It looks some power shell script is needed.
If your question is similar to your another post TFS 2015. the $(var.SourceLocation) variable is not available at gated-check in, that want to get the changeset id that hasn't checked in during gated check-in, then it's impossible in a single build.
If you don't use gated check in, then you can use $Env:BUILD_SOURCEVERSION in a powershell script to set the AssemblyVersion. Here is already a script at the website below, you can refer to it:
https://github.com/wulfland/ScriptRepository/blob/master/TFSBuild/TFSBuild/AssemblyVersion/Set-AssemblyVersion/Set-AssemblyVersion.ps1
Finally I created my own PS script based on this post.
The idea update version in all files with assembly info
$CommitId = ([string]$env:BUILD_SOURCEVERSION) -replace "[^0-9]+", ""
$AllVersionFiles = Get-ChildItem $SourceDir AssemblyInfo.cs -recurse
$regexToFindVersion = "Version\(""([0-9]+)\.([0-9]+).+"""
foreach ($file in $AllVersionFiles)
{
Write-Host "Processing " $file.FullName
(Get-Content $file.FullName) |
%{$_ -replace $regexToFindVersion, ('Version("$1.$2.0.' + $CommitId + '"') } |
Set-Content $file.FullName -Force
}
Full script can be found here.
The script must be placed before building project:

tf resolve conflicting merge automated

I am trying to automate creating TFS scenarios without the use of the UI dialogs that appear during merge, rollback, resolve, etc. I have a case where I neither want to AcceptYours or AcceptTheirs. I want to accept a manual merge as if the UI appeared and gave the user the chance to edit the file and accept the merge; but it's gotta be automated, no UI.
In the code below I create a 'copy' file that contains the final content I want as the manual merge for a rollback of a particular edit. As expected I get a conflict. I've tried all the tf resolve /auto: options and I can't resolve the conflict so the content from my 'copy' file is taken as though the user edited the conflict and accepted the manual merge.
KeepYours - will Undo the merge
TakeTheirs takes the server version
AutoMerge(Forced) - doesn't resolve the conflict
OverwriteLocal - doesn't resolve the conflict
AcceptYours - takes the version on disk but changes the change type from rollback,edit to edit
How can I reproduce a manual merge using the command line tf tool only without using the UI?
Here's an example to repro:
SET WSPATH=C:\MyMappedWorkspacePath
SET F=%WSPATH%\%RANDOM%%RANDOM%
SET TF=%ProgramFiles(x86)%\Microsoft Visual Studio 11.0\Common7\IDE\TF.exe
SET TMPFILE=%TEMP%\tf-resolve-test.txt
ECHO Hello > "%F%"
"%TF%" add "%F%"
"%TF%" checkin /comment:"add file" /noprompt "%F%" > %TMPFILE%
"%TF%" checkout "%F%"
ECHO // Change 1 >> "%F%"
COPY "%F%" "%F%-copy" > nul
"%TF%" checkin /comment:"edit 1" /noprompt "%F%" > %TMPFILE%
"%TF%" checkout "%F%"
ECHO // Change 2 >> "%F%"
"%TF%" checkin /comment:"edit 2" /noprompt "%F%" > %TMPFILE%
FOR /f %i IN ('PowerShell.exe -Command "select-string -Path %TMPFILE% -Pattern 'Changeset #(?<changeset>[0-9]*) .*' | %{$_.Matches} | %{$_.Groups['changeset']} | %{$_.Value}"') DO SET ROLLBACKCHANGESET=%i
"%TF%" checkout "%F%"
ECHO // Change 3 >> "%F%"
ECHO // Change 3 >> "%F%-copy"
"%TF%" checkin /comment:"edit 3" /noprompt "%F%" > %TMPFILE%
"%TF%" rollback /changeset:%ROLLBACKCHANGESET%~%ROLLBACKCHANGESET% "%F%" /keepmergehistory /noautoresolve /noprompt
"%TF%" resolve "%F%" /auto:DeleteConflict
DEL /F "%F%"
MOVE "%F%-copy" "%F%"
ATTRIB +R "%F%"
"%TF%" rollback /changeset:%ROLLBACKCHANGESET%~%ROLLBACKCHANGESET% "%F%" /keepmergehistory /noautoresolve /noprompt
"%TF%" resolve "%F%" /auto:AutoMergeForced /noprompt
You place to edited contents on disk, in the appropriate location, then you resolve with AcceptYours.
AcceptYours means to take your contents, as they appear on disk, not the contents of the source of the conflict.
I would also investigate the (command line) only option of /discard.
http://teamfoundation.blogspot.com/2007/03/discarding-changes-in-merge.html
The best way to do that is to use discard option of the merge command. The option is available only through command-line client (tf.exe) and basically performs merge without taking any changes from the source to target; its only purpose is to update the merge history between source and target and thus prevent the discarded changeset appearance in the future.
"tf.exe" merge /recursive /noprompt /discard /version:C1001~C1001 "$Source/" "$Destination/"
or
"tf.exe" merge /recursive /noprompt /discard "$Source/" "$Destination/"

How can I bulk rename files using PowerShell?

I'm trying to recursively rename a bunch of TFS folders using tf rename, PowerShell and a regular expression but I'm having some issues with PowerShell as I haven't spent much time with it. This is what I've put together so far to replace a leading 5 with 2.3.2 but it isn't working:
dir | foreach { tf rename $_ { $_.Name -replace '^5', '2.3.2' } }
Actual result:
Unrecognized command option 'encodedCommand'.
Unrecognized command option 'encodedCommand'.
Unrecognized command option 'encodedCommand'.
Unrecognized command option 'encodedCommand'.
...etc.
Update:
I got a little closer by doing the following instead:
dir | foreach { $newname = $_.Name -replace "^5", "2.3.2"; tf rename $_ $newname }
My next goal is to make this recurse subdirectories but this seems a bit more challenging (changing it to dir -recurse makes it quit after the parent folders for some reason).
I would first filter by 5* so you only process names that start with 5. Also, in this case since tf.exe isn't a PowerShell cmdlet, you don't want to use a scriptblock to determine a new name. Just use a grouping expression like so:
dir -filter 5* | foreach { tf rename $_ ($_.Name -replace '^5', '2.3.2')}
BTW, when you are trying to debug parameter passing to a native EXE like this it is immensely helpful to use the echoargs.exe utilty from the PowerShell Community Extensions. This is what it told me about your original approach:
6# dir -filter 5* | foreach { echoargs rename $_ { $_.Name -replace '^5', '2.3.2' } }
Arg 0 is <rename>
Arg 1 is <5foo.txt>
Arg 2 is <-encodedCommand>
Arg 3 is <IAAkAF8ALgBOAGEAbQBlACAALQByAGUAcABsAGEAYwBlACAAJwBeADUAJwAsACAAJwAyAC4AMwAuADIAJwAgAA==>
Arg 4 is <-inputFormat>
Arg 5 is <xml>
Arg 6 is <-outputFormat>
Arg 7 is <text>
Notes:
TFS has native cmdlets -- no need for tf.exe in most cases.
The time complexity of workspace operations depends on the number of pending renames already in the workspace. In TFS 2005/2008 it's significantly worse than linear. Bottom line, you should really consider batching up renames into multiple checkins if you have a large # of items, otherwise every single "tf rename" (or New-TfsPendingChange -Rename if using the cmdlets) will start taking minutes.
Try this:
dir . | foreach { $newname = $_.Name -replace "^5", "2.3.2"; tf rename $_ $newname }
Running the above commands requires the tf.exe to have been aliased as 'tf'.. or it did on my machine at least.
Run this command:
Set-Alias tf "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\tf.exe"
Update the path to tf.exe as appropriate
Also consider adding the line to your profile for future use
notepad $PROFILE

Resources