TFS:如何在批处理文件中撤销未修改文件的签出

180
我们使用批处理文件生成代码,并自动从Team Foundation Server(TFS)检出已生成的文件,以便可以重新生成它们。大多数这些文件没有被修改,但生成器事先不知道这一点。
“tfs undo”命令会撤销检出操作,但会提示已被修改的文件(我们不想要此操作)。我们也不想立即检入生成的文件。
是否有一种命令(或一系列命令)可以撤消所有未修改的文件的检出操作而不提示用户?

请注意,手动撤销所有更改并期望在提示有更改的文件时选择“全部不”将无法正确工作,因为它将在不提示的情况下撤消ADD更改(请参见Ray's answer)。 - Elaskanator
12个回答

204

1
这应该被编辑/合并,以包含使用信息作为答案内容的一部分。 - mcw
4
你真的想阅读这篇文章:http://aaubry.net/undo-checkout-on-unchanged-files-tfs.html - Byron Whitlock
19
嗯,几乎每个人每天都会做好几次的事情:“让我们把它放在一个名为Power Tools的单独安装程序中”……叹息。 - vidstige
1
@Mike Chaliy 你会想。我现在正在尝试使用TFS,并且正在搜索如何做到这一点,最终来到了这里。 - vidstige
3
如果您的更改是合并操作,那么tfpt uu命令就不起作用了。似乎tfpt uu命令总是将合并操作视为真正的更改,即使没有文件更改,也没有选项可以更改此行为。这是默认行为,通常情况下没问题,但有时并不是您想要的结果。 - user1164178
显示剩余9条评论

127

安装Team Foundation Server Power Tools,并在项目工作区目录下使用tfpt.exe命令行运行以下操作:

c:\myProject> tfpt uu . /noget /recursive

强烈建议包括/noget选项,因为它可以防止对项目所有文件进行强制“获取最新版本”的操作,从而节省大量时间,特别是当文件总数较多时。


12
应该接受这个答案,因为它包含所有相关的细节(正如更高的得分所证明的那样)。 - rikoe
7
好的。另外,为什么不将此操作加入Visual Studio的永久“外部工具”中呢?以这个为例:http://blog.kurtschindler.net/post/visual-studio-external-tools-for-git-and-more 命令:[你的安装目录] \ TFPT.EXE 参数:uu . /noget /recursive 初始目录:$(SolutionDir) - rohancragg
12
这个问题要求在没有提示的情况下执行此操作,但是没有一个答案似乎涉及到这一点。如果你需要这样做,额外添加 /noprompt 选项就是你要找的。PowerTools 文档中缺少这个!它为一些命令列出了这个选项,但没有针对这个 (UU) 命令。注意! - Johnny Kauffman
1
@user20358 要么使用 cd 命令切换到你的工作区目录(例如,我的是 c:\myProject),要么在 uu 命令后显式地包含它(用它替换句号 .)。 - Ray
这个有强制开关吗,像 /Y 或 /force 吗?我总是被问到是否真的想要撤消它,我希望能自动化。加上 /Y,但它告诉我选项 Y 需要一个值。 - Squirrelkiller
显示剩余2条评论

123

感谢@mike和@ray,

我希望能让它更容易些。

在VS中,在"工具"菜单中,点击"外部工具"。

External Tools

点击"添加"。

输入标题。

命令:tfpt.exe

参数:uu . /noget /recursive

初始目录:[你可以从箭头按钮中选择]。

Undo unchanged in solution

Undo unchanged in project

两个新命令已添加到"工具"菜单中。

需要时使用它们。

享受吧,

Ofir


3
很酷。您还可以再进一步,添加一个快捷方式。注意您新增的命令在列表中排第几(例如可能是第四个)。然后转到“工具”->“选项”->“环境”->“键盘”,在“显示包含命令”的文本框中输入“Tools.External”,并分配一个快捷键。例如,我选择了“Tools.ExternalCommand4”,因为我的新撤销命令是列表中的第四个。然后我分配了快捷键Ctrl + Alt + U,Ctrl + Alt + U。 - Mario
1
我们能否请您提供此的更新版本?我找到了tf.exe,但是uu命令是什么?它告诉我未识别的命令:uu。感谢您的帮助。 - Shay
1
@Shay:我在安装了最新的TFS Power Tools的VS2015中可以使用。 - Igor Malin

30
  1. 右键单击您的项目
  2. 选择撤销检出,然后仅需点击“确定”或其他剩余的确认选项...
  3. 接着,在撤销检出时,对于每个具有实际更改的文件,会提示您确认该文件的检出...只需点击“全部否定”

Visual Studio会知道已检出的文件是否有更改。

警告:此方法还会删除新的文件,即尚未检入TFS的文件。如果要保留这些文件,则只需将它们从您要“撤销”的文件集中排除即可。


14
请注意,该方法还会从TFS中删除尚未签入的添加文件。... 是的,这是一个相当直接的不合格因素。 - shortstuffsushi
1
它适用于我的无基础分支合并。谢谢。通常在这种情况下,VS会将解决方案中的所有文件标记为已更改。 - KoViMa
2
当NuGet检查10000个不需要更新的文件时,这真是一场噩梦。 - Ievgen

23

在使用 TFS2017VS2017/VS2019 时,更新此问题并提供了答案。

Power Tools 已不适用于 TFS 2017,而旧工具无法与其良好配合,但显然大部分功能已移至 VS2017 本身或插件中(见下文)。

Visual Studio 2017/2019 扩展

某些操作,如撤消未更改的文件,已移至VS2017 扩展程序VS2019 扩展程序(如下所示)。

"撤消未更改" 按钮位置:

undo unchanged button location

已知的 bug

必须打开“源代码控制资源管理器”(并将其保持打开状态),才能在“待处理的更改”视图的“操作”菜单中显示“撤消未更改”(在此处报告)

Windows Shell 集成扩展

同时,你仍然可以通过单独的安装程序设置Windows shell集成,这个安装程序不再与TFS Power Tools相关联。

与之前的PowerTools相比,Windows shell集成的功能可能会有所不同,但对于我来说,最重要的操作都能正常使用。


1
在安装了相关扩展之后,我在VS2017中找不到“撤消未更改”选项。我错过了什么吗? - Jonathan F.
我没有使用它太多。当我用它来为我的客户测试时,我不得不在团队资源管理器中四处点击并确保有要撤销的更改。这可能只会在您只有待提交更改排队等候时才出现该选项(或仅针对一个分支的更改)。 - Schwarzie2478
2
@Erzékiel 只有当“解决方案资源管理器”打开并准备好时,该选项才会出现。 - MatrixRonny
我尝试了你们说的,但是什么也没有出现。 - Jonathan F.
1
这个扩展有时候能够工作,它的存在与是否打开TFS源代码控制资源管理器有关,而不是解决方案资源管理器(一些人错误地指出了这一点)-不要混淆这两个不同的控制窗口。然而,当我说有时候,是因为它来了又走。现在我没有它,一个月前我有过。它有一点小bug,我担心其他扩展可能是罪魁祸首,比如Resharper之类的。 - Christian
显示剩余2条评论

8
如果您只是将所有已检出的文件再次检入,TFS足够聪明,可以找出哪些文件发生了更改,并仅在记录在服务器上的变更集中包含它们。TFS通过比较检入前后文件内容的MD5哈希值来实现这一点。
这一切都假设您的生成过程纯粹是更新同一组文件,即您永远不会遇到在下一个生成中不需要先前生成的文件的情况(即您需要为该文件挂起删除),或者文件名称发生更改。
如果您的过程可能需要删除文件,则最好查看Team Foundation Power Tools命令(tfpt),并使用tfpt online命令,该命令仅检出已更改的文件,并且足够聪明以挂起删除任何不再需要或更改名称和挂起添加的文件。
祝好运,
马丁。

6
谢谢您的回复,但是我们不希望在那个时候检入修改后的文件。在完成该功能之前,修改后的文件不应该被检入,但未修改的文件应该被删除,以便开发人员可以审查更改。 - Robert Wagner
如果您有一个带门控的构建,则可以在收到弹出警报时取消(如果它在检测到相同文件时不中止),该警报表示必须先构建更改。 - Elaskanator

6

请注意,TFS的撤销操作不会恢复文件系统中的“修改日期”值。这一点非常令人沮丧,特别是如果您使用像robocopy这样的工具来同步远程机器。即使您撤销了检出操作,如果您保存了文件并更新了“修改日期”值,那么更新后的值将在撤消检出操作后继续存在。


1
要么使用robocopy或VCS,混合使用总会导致不一致。更好的方法是直接从VCS中填充每台机器。 - Richard

4

我看到了Ray LionFang的方法。由于我的声望不足,无法在那里发表评论。虽然我喜欢这种方法,因为不需要对工具进行任何更改......

  1. 右击项目
  2. 选择撤销检出,然后只需点击确定或其他确认......
  3. 然后,在撤消检出时,对于每个实际更改的文件,都会提示您确认该文件的检出...只需单击“全部否”
  4. Visual Studio将知道已检出的文件是否有更改。请注意,此方法还会从TFS中删除尚未签入的添加文件...

.......这种方法存在问题,因为点击“全部否”会保留一些未经修改的文件。它似乎会撤销未修改的文件,直到遇到第一个实际更改的文件,然后忽略其他未修改的文件,如果这有什么意义的话。我只偶尔见到过这种情况。

一个潜在的解决方法是按照上述步骤操作,但是不要点击“全部否”,而是对每个文件点击“否”。由于这可能需要一些时间,具体取决于您正在处理的文件数,所以我通常按住“ALT + N”,它就会在解除所有未修改的文件的同时快速地跳过所有文件。


请注意,这一点无法强调得足够多。使用这种方法还会删除项目中新添加的文件。其他答案中也提到了这一点。 - Christian

4

关于tfpt的uu选项(在大多数其他答案中推荐使用)有几个要点一开始并不清楚。首先,这是可以通过命令tfpt uu /?访问的命令行帮助。

撤销冗余的待处理更改。如果具有待处理更改的项目的状态与服务器上的状态相同,则更改将被撤消。

用法:tfpt uu [/changeset:changesetnum] [/recursive] [/noget] [filespec...]

  • /changeset 将工作区与指定版本的项目状态进行比较,而不是最新版本
  • filespec... 仅检查列出的文件规范以获取冗余更改
  • /recursive 使用完整递归检查指定的文件规范
  • /noget 在检查之前不运行获取

不能在文件规范或/recursive中使用/changeset选项。

现在让我分解一下其他答案中推荐的命令。

tfpt uu . /noget /recursive
  • tfpt uu指定使用“撤消未更改”命令。
  • .表示(我猜)应该使用当前工作目录作为文件规范。
  • /noget确保在撤消未更改的文件之前不会调用“获取最新版本”。
  • /recursive确保不仅考虑文件规范,而且考虑所有递归子文件夹和文件。这似乎取决于文件规范 - 如果没有提供,则处理整个工作区。

因此,有几件事情需要注意关于上面的命令...

  • 它依赖于工作目录。
  • 它不处理整个工作区。

我发现以下命令对我最有效 - 它将处理整个工作区。

tfpt uu /noget

请注意,它仍然依赖于工作目录,因为tfpt使用它来确定应该处理哪个工作区。但只要您提供工作区中文件或文件夹的路径,就可以开始了。


0

我来晚了,但如果您可以控制批处理脚本,您可以在生成过程中检出任何文件,然后运行类似以下的命令:

tf reconcile [path-to-local-folder] /promote /adds /deletes /recursive

确保您只检查要签入的文件。您可以在此处阅读有关reconcile命令及其语法的更多信息:

https://learn.microsoft.com/en-us/azure/devops/repos/tfvc/reconcile-command


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接