TFS UNDO其他结账 - 递归所有用户

时间:2015-03-06 15:53:22

标签: tfs tfs2010 tfs2012 tfs2013 tfs-power-tools

作为TFS管理员,我必须一次又一次地将分支存档/移动到其他文件夹,以确保我们的TFS文件夹不会被旧的未使用的分支混乱。但是当我尝试移动分支时,如果任何开发人员在他们的工作区中检出了该分支的文件,那么TFS不允许我完成操作。在移动分支之前,我必须撤消所有这些签出(由所有用户)。

TFS电动工具在这里提供了一些缓解。它可以帮助您从Visual Studio(或命令行)中撤消其他签出。右键单击分支 - >查找 - >通过Wildcard查找。你可以看到下面的截图:

enter image description here

enter image description here

但问题是,它一次只能为一个用户执行UNDO操作。因此,在一个大型组织中,如果您有100-200名开发人员在分支机构工作,这意味着如果100名开发人员分别从分支机构检出了1个文件,那么我将不得不按下UNDO按钮100次以使分支机构免费结账。

我进行了广泛的搜索,无法找到任何开箱即用的解决方案。最后我为此创建了一个解决方案来创建一个powershell脚本,该脚本查询TFS(针对特定分支)以查找签出给用户的文件列表,然后循环遍历用户列表和UNDO所有检查的文件 - 分支下的那个用户。

有没有人有更好/更容易的解决方案?我会等待输入,如果我没有看到太多响应,我会在这里添加脚本,以便处于类似情况的人可以使用它。

2 个答案:

答案 0 :(得分:3)

您应该使用TFS Sidekicks。他们有能力轻松发现和撤消这些变化。

http://www.attrice.info/cm/tfs/

然而,我会质疑“移动”分支的可行性,因为TFS在封面下执行“分支+删除”。你最好删除分支并使用'show deleted items'切换来查看旧的东西......

答案 1 :(得分:1)

正如@MrHinsh所提到的,您可以安装TFSSideKicks来解决问题。谢谢MrHinsh。

如果您不想安装其他工具,可以使用以下powershell脚本实现相同的功能。更新脚本中的以下参数并运行它:

  1. TF位置
  2. 分行名称
  3. TFS集合名称
  4. 临时日志文件位置
  5. 
    
    $tfLocation = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE" 
    $tfsBranchName = “{enter your TFS branch/folder/file location}“ 
    $tfsCollectionName = "http://tfsserver:8080/tfscollection” 
    $logFile = “{log file location}“ 
    Function GetUserFileList($tfsBranchName) 
    { 
    	try{
            # Array to hold the object (user/file/workspace) objects 
            $arrayFileUserMapping = @(); 
            
            If (Test-Path $logFile) 
            { 
                    Remove-Item $logFile; 
            } 
            
            Set-Location $tfLocation; 
            
            .\tf.exe status $tfsBranchName /collection:$tfsCollectionName /user:* /format:detailed /recursive >> $logFile; 
            
            Set-Location $PSScriptRoot; 
            
            foreach ($line in Get-Content $logFile) 
            {         
                    If($line.StartsWith("$")) 
                    { 
                            $objCurrFile = New-Object System.Object; 
                            $splitStringFile = $line -Split ";"; 
                            $objCurrFile | Add-Member -type NoteProperty -name FileName -value $splitStringFile[0];                         
                    } 
                    Else 
                    { 
                            foreach ($singleLine in $line){ 
                                    If($singleLine.StartsWith("  User")) 
                                    { 
                                            $splitStringUser = $singleLine -Split ":"; 
                                            $objCurrFile | Add-Member -type NoteProperty -name User -value $splitStringUser[1];                                                                                 
                                    } 
                                    ElseIf($singleLine.StartsWith("  Workspace")) 
                                    { 
                                            $splitStringWS = $singleLine -Split ":"; 
                                            $objCurrFile | Add-Member -type NoteProperty -name Workspace -value $splitStringWS[1];                                 
                                    } 
                            } 
                    } 
                    
                    $arrayFileUserMapping += $objCurrFile; 
            }         
                    
            $uniqueWorkspaceArray = $arrayFileUserMapping | Group Workspace 
            $uniqueUserArray = $arrayFileUserMapping | Group User 
            
            for($i=0;$i -lt $uniqueUserArray.count; $i++) 
            { 
                    $workspaceWOSpace = $uniqueWorkspaceArray[$i].Name.Trim() 
                    $userWOSpace = $uniqueUserArray[$i].Name.Trim() 
                    $workspace = $workspaceWOSpace + ";" + $userWOSpace; 
                    
                    Set-Location $tfLocation; 
                    .\tf.exe undo $tfsBranchName /collection:$tfsCollectionName /workspace:""$workspace"" /recursive /noprompt;                 
                    Set-Location $PSScriptRoot; 
            } 
    	}
    	Catch [system.exception]
     	{
      		"Oops, something's wrong!!!"
     	}
    } 
    GetUserFileList($tfsBranchName);