72

我们正在使用 Perforce 和 Visual Studio。每当我们创建一个分支时,除非我们使用“从源代码管理打开”,否则某些项目不会绑定到源代码管理,但其他项目无论如何都可以工作。根据我的调查,我知道其中涉及的一些事情:

在我们的 .csproj 文件中,有以下设置:

  • <Scc项目名称>
  • <SccLocalPath>
  • <SccAuxPath>
  • <SccProvider>

有时它们都设置为“SAK”,有时则不是。如果这些说“SAK”,似乎事情更有可能奏效。

在我们的 .sln 文件中,有许多项目的设置:

  • SccLocalPath#
  • SccProjectFilePathRelativizedFromConnection#
  • SccProjectUniqueName#

(# 是标识每个项目的数字。) SccLocalPath 是相对于解决方案文件的路径。通常是“.”,有时是项目所在的文件夹,有时是“..”或“..\..”,指向上面的文件夹似乎不好解决方案文件夹。相对化的是从该文件夹到项目文件的路径。如果 SccLocalPath 指向项目的文件夹,它将完全丢失。如果 SccLocalPath 中包含“..”,则此路径可能包含分支之间不同的文件夹名称,我认为这会导致问题。

因此,要最终了解我想知道的细节:

  • 当您执行“更改源代码管理”并绑定项目时会发生什么?Visual Studio 如何决定在项目和解决方案文件中放入什么?
  • 当您执行“从源代码管理打开”时会发生什么?
  • SccLocalPath 和 SccProjectFilePathRelativizedFromConnection 所指的“连接”文件夹是什么?Visual Studio/Perforce 如何选择它?
  • 即使创建解决方案的新分支,是否有一些推荐的方法可以使源代码控制绑定继续工作?

2012 年 6 月添加: 我不再使用 Perforce,所以我不能保证,但请看下面KCD 的答案。显然有一个新的 P4 VS 插件正在开发中。希望它应该清除所有这些混乱!

4

9 回答 9

103

介绍

我不同意 Visual Studio 中的 Perforce 集成“糟糕”的说法。相反,我将其定义为“开箱即用的体验不是最佳的”:-)。以下部分讨论了我对项目/解决方案设置的集成和建议的理解。

如果您对源代码控制集成如何工作的细节不感兴趣,您可以跳到此答案的末尾,我在此总结了 Weeble 问题的答案。

免责声明:以下部分只是基于我的经验经验的有根据的猜测,但是我多年来在许多项目中使用了该技术(每个项目都有多个实验/主干/维护/发布分支​​,有时甚至是多个解决方案文件,没有问题)。缺点是您必须手动更新项目文件 - 但 2 分钟的投资在项目的整个生命周期中很好地摊销了,恕我直言 :-)。

解决方案与项目

Visual Studio 在初始解决方案加载期间使用来自解决方案文件和每个项目文件的源代码控制绑定信息。然后将此绑定信息存储在name.suo文件中(假设我们使用name.sln作为解决方案) - 请注意,suo文件标有隐藏标志,因此它们在文件资源管理器中不可见(除非您覆盖“隐藏文件和文件夹”选项)。

如果出现任何问题,重新绑定到源代码控制提供程序的最简单方法是删除相应的suo文件并重新打开解决方案。创建 suo 文件后,对 <Scc*> ​​元素的更改无效。

如果在初始解决方案打开期间,解决方案文件中存储的绑定信息与项目文件中存储的信息之间存在差异,Visual Studio 将尝试修复此问题(有时它甚至会提示您选择是解决方案中的信息还是项目中的信息应用作解决差异的“主”):

替代文字

为什么 Visual Studio 违反 DRY(不要重复自己)原则?我不知道。我认为这是有历史原因的,并且与称为 Visual Source Safe 的噩梦的需求紧密相关 :-)。

如何“正确”设置?

在向 Perforce 添加新的或现有的解决方案/项目时,我总是从创建一个空白解决方案开始(请参阅“源代码控制空白解决方案”部分)。然后我一个接一个地将项目添加到这个空白解决方案中。根据添加的项目是否已经存在(参见“源代码控制现有(未绑定)项目”和“源代码控制现有(绑定)项目”部分)或我需要创建一个新项目(参见“源代码控制新项目”部分)。

源代码控制空白解决方案

要向源代码管理添加新的空白解决方案,请执行以下操作:

  1. 启动Visual Studio,“新建”->“项目...”->“其他项目类型”->“空白解决方案”;填写解决方案名称和位置,“确定”按钮
  2. “文件”->“源代码管理”->“将解决方案添加到源代码管理...”
  3. 在连接对话框中输入适当的 P4 服务器端口、客户端和用户(请注意,所选客户端的视图必须包含您在步骤 1 中选择的位置)
  4. “查看”->“待签入”->“签入”-> 在提交对话框中而不是点击“提交”按钮,使用“取消”。
    原因:“签入”操作将创建一个新文件“name.vssscc”,然后将“name.sln”和“name.vssscc”都添加到 Perforce 的默认更改列表中;通过取消提交对话框,我们将保持“添加”操作挂起,并且能够在提交到 P4 之前编辑文件
  5. 关闭 Visual Studio
  6. 在您喜欢的编辑器中打开 name.sln 文件(记事本,如果您真的很绝望:-))并添加两个新行(SccProjectName0SccProvider0) - 空白解决方案文件现在应该有一个源代码控制部分,如下所示:

    GlobalSection(SourceCodeControl) = preSolution
        SccNumberOfProjects = 1
        SccLocalPath0 = .
        SccProjectName0 = Tutorial
        SccProvider0 = MSSCCI:Perforce\u0020SCM
    EndGlobalSection
    

    值应选择如下:

    • SccProjectName0:将在“更改源代码管理”对话框中显示为“服务器绑定”的任意字符串。此名称用于确定哪些项目/解决方案文件可以共享相同的源代码控制连接。我建议不要为此名称使用空格,因为解决方案和项目文件中空格的转义规则不同。
    • SccProvider0:硬编码值“MSSCCI:Perforce\u0020SCM”。
  7. 使用您选择的 Perforce 客户端(p4.exe、P4Win、P4V)提交两个待处理文件

您现在可以测试绑定:

  1. 确保 Visual Studio 已关闭
  2. 删除除name.sln以外的**所有*文件(尤其是name.suo)
  3. 打开 Visual Studio 并使用它打开 name.sln
  4. 应该会出现一个连接对话框,使用适当的端口/客户端/用户,然后单击确定
  5. 解决方案资源管理器现在应该显示带有挂锁覆盖图标的解决方案节点: 源头控制空白溶液
  6. 您现在可以使用“文件”->“源代码管理”->“更改源代码管理...”来验证解决方案的源代码管理状态: 空白溶液源头控制状态 注意:“服务器绑定”列显示了我们为“SccProjectName0”选择的值.

源代码控制新项目

如果您正在创建一个全新的项目并希望立即开始在 Perforce 仓库中跟踪它,请按照以下步骤操作:

  1. 在 Visual Studio 中打开源代码控制解决方案
  2. “文件” -> “添加” -> “新建项目...” - 选择您要添加的项目类型、名称和位置(位置应该是存储解决方案文件的目录的子目录)
  3. “文件”->“全部保存”(这会将所有内存更改提交到解决方案文件和新创建的项目文件到磁盘)
  4. 使用您选择的编辑器手动编辑您刚刚创建的项目文件(来吧,记事本再次?;-))。将以下属性元素添加到 PropertyGroup(任何属性组)中:

    <PropertyGroup>
        ...
        <SccProjectName>Tutorial</SccProjectName>
        <SccLocalPath>..\..</SccLocalPath>
        <SccProvider>MSSCCI:Perforce SCM</SccProvider>
        ...
    </PropertyGroup>
    

    值应选择如下:

    • SccProjectName - 这是在“更改源代码管理”对话框中显示为“服务器绑定”的值;应该与您在空白解决方案中用于 SccProjectName0 的值相同;如果不相同,解决方案和此项目将无法共享相同的源代码控制提供程序连接
    • SccLocalPath - 参考目录的相对路径(在“更改源代码管理”对话框中显示为“本地绑定”);因为我建议使用解决方案目录作为参考目录,这实际上是从包含项目文件的目录到包含解决方案文件的目录的相对路径(我的示例是将项目存储在“(solutionDir)/Source/ProjectName/projectName.csproj”中,因此相对路径是“向上两层”)
    • SccProvider - 硬编码值“MSSCCI:Perforce SCM”;这用于确定 SCC* 绑定值对哪些 SCCAPI 提供程序有效
  5. 切换回 Visual Studio;它应该自动检测到项目文件已在外部更新并提供重新加载它(如果没有,请手动卸载并重新加载项目)

  6. “查看”->“待签到”
  7. “签入”-> 我建议右键单击 (solutionName).vssscc 文件并选择“如果未更改则还原”(即使 Visual Studio 打开它进行编辑,它也保持不变);提供描述并提交更改

要验证新添加的项目是否正确绑定,您可以按照以下步骤操作:

  1. 确保 Visual Studio 已关闭
  2. 删除 (solutionName).suo 文件以及 MSSCCPRJ.SCC(在解决方案目录中)
  3. 打开 Visual Studio 并使用它打开 (solutionName).sln
  4. 应该会出现一个连接对话框,使用适当的端口/客户端/用户,然后单击确定
  5. 解决方案资源管理器现在应该显示带有挂锁覆盖图标的项目节点: 源代码控制项目
  6. 您现在可以使用“文件”->“源代码管理”->“更改源代码管理...”来验证解决方案的源代码管理状态: 源代码控制项目的现状

    关于此状态屏幕截图需要注意的一点是,当我选择解决方案行时,所有剩余的行也都被“选中”(蓝色突出显示)。这是因为所有这些条目都具有相同的“服务器绑定”+“本地绑定”,因此共享相同的源控制提供程序 (P4) 连接。

    另请注意,两个项目的“相对路径”有两个级别,并且相对于相同的“本地绑定” - 解决方案文件所在的目录。

源代码控制现有(未绑定)项目

如果您有尚未在任何其他 Perforce 解决方案中使用的现有项目,请按照以下步骤将它们添加到 Perforce(即导入以前没有源代码控制的项目(互联网下载等)或使用不同的源代码控制提供者(Visual Source Safe 等)。

  1. 将项目复制到适当的位置
  2. 清理现有的源代码控制绑定(如果有):
    • 删除现有的项目文件绑定,即所有以“Scc”开头的属性
    • 删除与项目文件相同目录下的文件(projectName).vspscc(如果有)
  3. 在 Visual Studio 中打开源代码控制解决方案
  4. “文件” -> “添加” -> “现有项目...” - 浏览到项目(您在步骤 1 中创建的副本)
  5. “文件”->“全部保存”(这会将所有内存中的更改提交到解决方案文件)
  6. 遵循“源代码控制新项目”中的步骤 4-7(即,您现在将“Scc*”属性元素添加到PropertyGroup中)

验证步骤与“源代码控制新项目”部分中的完全相同。

源代码控制现有(绑定)项目

如果您的项目已经使用此处讨论的技术绑定到 Perforce,并且您想在不同的解决方案中使用它们(新分支、重用项目的替代解决方案等),请使用以下步骤:

  1. 将项目集成到所需位置
  2. 在 Visual Studio 中打开源代码控制解决方案
  3. “文件” -> “添加” -> “现有项目...” - 通过集成浏览到在步骤 1 中创建的项目
  4. “查看”->“待签入”->“签入”-添加描述并提交

概括

  • 源代码管理绑定信息存储在解决方案和项目中,必须同步(如果不同步,Visual Studio 将尝试修复任何差异)
  • 我总是将项目文件视为绑定信息的主要来源,将解决方案文件视为一次性文件,可以通过首先对空白解决方案进行源代码控制然后添加所需项目来轻松重新创建这些文件
  • 解决方案文件应始终具有有效的 SccProvider0SccProjectName0值(必须使用新版本的 P4SCC 插件手动添加)
  • 项目文件应始终具有有效的 SccProjectName(最好与SccProjectName0相同)、SccLocalPathSccProvider值(也必须手动编辑,因为 P4SCC 默认值不好)

我还包括对您原始问题的回答:

当您执行“更改源代码管理”并绑定项目时会发生什么?Visual Studio 如何决定在项目和解决方案文件中放入什么?

这会更新您正在重新绑定的项目文件中的“Scc*”元素;然后解决方案文件也会更新,以便与项目文件绑定同步

当您执行“从源代码管理打开”时会发生什么?

允许您选择要打开的解决方案。之后,解决方案中包含的所有项目都会自动同步到 head。我发现这个功能在 Perforce 世界中不是很有用,无论如何你都必须创建一个客户端,而且你很有可能是从 P4V/P4Win/P4 同步这个客户端,而不是依赖于 Visual Studio。这在没有视图概念的 Visual Source Safe 世界中非常有用,并且您正在定义存储库在签出时间的位置。

SccLocalPath 和 SccProjectFilePathRelativizedFromConnection 所指的“连接”文件夹是什么?Visual Studio/Perforce 如何选择它?

这是 Visual Studio 的簿记。它是根据每个项目文件中的绑定确定的(我猜理论上如果项目文件由于某种原因丢失了绑定信息,它可以从解决方案信息中重建......)

即使创建解决方案的新分支,是否有一些推荐的方法可以使源代码控制绑定继续工作?

我希望上面的部分能让您了解一种对我来说非常有效的方法:-)。

于 2009-02-09T19:34:24.743 回答
22

Milan 的帖子经过精心研究和精心编写,但其篇幅无疑表明 P4SCC 模型已被破坏。在项目和解决方案文件中存储源代码控制绑定信息是荒谬的。(通过 sccprojectname)强制一个项目是一个解决方案的一部分同样荒谬。

此外,P4SCC 在大型解决方案中具有巨大的性能成本,因为它在启动时从每个文件的源代码控制中检索信息,并在整个开发会话期间在内存中维护该状态。它以无信息的 .vsscc 和 vssscc 文件的形式创建额外的文件,以支持 (AFAICT) Perforce 不使用的某些 SCC 功能。

理想的 Perforce 集成如下所示:

  • 如果我创建新的解决方案、项目或项目项,请运行“p4 add”。
  • 如果我更改文件,请运行“p4 编辑”。
  • 一些工具栏/上下文菜单集成,用于修订历史、修订图、延时/责备和“在 P4 gui 中显示”。
  • (很高兴)如果我重命名仓库中存在的文件,请运行“p4 集成”和“p4 删除”。如果我重命名为添加打开的文件,请运行“p4 revert”和“p4 add”。
  • 就这样

我们已经完全摆脱了 P4SCC 及其奇异的要求和负担。相反,我们使用NiftyPerforce。有一些错误,但我们发现解决这些错误要比解决 Perforce<->VSSCC 模型中的设计缺陷更令人沮丧。

于 2010-03-19T23:44:38.093 回答
9

只是为了保持最新——P4VS 插件大约在 2012 年被重写

现在,您可以直接在 IDE 中自然地执行与 Perforce 的所有日常交互,例如签入代码和查看文件历史记录。

如果您是一位需要更多功能的高级用户,P4VS 不会让您失望。P4VS 与 Perforce Streams 完全兼容,并且可以从 IDE 访问 Stream Graph,以及 Time-lapse View 和 Revision Graph。如果你负责分支管理,你也可以从 P4VS 合并。

而且,如果您远程工作或想做一些私有分支,可以通过 P4VS 配置 P4Sandbox。

于 2012-06-21T23:38:10.893 回答
5

使用 P4CONFIG 环境变量可以简化在 Visual Studio 中使用 Perforce。

基本上你进入 Visual Studio,工具 -> 选项 -> 源代码管理 -> 插件设置,高级按钮。这将打开一个特定于 SCC 集成的 Perforce 配置对话框。切换到“连接”选项卡,并选中标题为“绑定与您的 Perforce 环境设置匹配的工作区”的单选按钮。这将告诉 perforce 更喜欢使用 P4CONFIG 环境变量来确定您所处的环境。相同的对话框存在于 P4V 中的 Edit -> Preferences 下,但仅影响 p4v 的行为。

如何设置 P4CONFIG 环境变量在某种程度上取决于您。我喜欢让它们在任何地方都被命名,所以我设置了一个系统范围的环境变量 P4CONFIG 来查找名为 p4config.cfg 的文件。该文件只是一个 ini 样式文件,您可以在其中分配其他变量,例如 P4USER、P4CLIENT、P4HOST 等。Perforce 将在当前目录和所有父目录中搜索该文件,直到遇到一个。基本上你把这个文件放在你的clientspec映射到你硬盘上的最根目录中,不要管它。

这种方法极大地减少了 Visual Studio 中 SCC 配置为了运行而需要的“正确性”数量。(SAK 绑定工作正常等)

如果在第一次从 perforce 同步您的代码或同步到一个完全干净的目录结构之后,并得到一个对话框,抱怨 perforce 想要暂时脱机工作或删除绑定,那么您仍然需要进行一些编辑。主要是 .sln 文件本身需要修改,以便它知道 sln 有自己的 SCC 绑定。这是通过确保将以下字段放置在 .sln 文件中的 SccNumberOfProjects 之后完成的。

SccProjectName0 = Perforce\u0020Project
SccProvider0 = MSSCCI:Perforce\u0020SCM

如果您使用的是 P4CONFIG 方法,则所有单个项目都可以使用默认的“SAK 绑定”正常工作。修复这个问题应该允许 Perforce 完美地从干净的同步中工作,并且还消除了每个项目目录中 MSSCCPRJ.SCC 的生成。

于 2011-07-06T07:16:15.510 回答
4

如果使用 Visual Studio P4 插件集成,对重命名文件或将其移动到新文件夹目录的支持非常糟糕和痛苦。不存在提醒 P4 重命名文件或文件已被移动的内置功能。

问题是重命名文件不仅需要更新关联的 VS 项目文件,而且如果您想维护正确的修订历史记录,还需要通知 Perforce 更改。

目前,如果使用 VS 集成,我看不到在单个操作中完成这两项操作的方法。相反,您必须:

  1. 从 Perforce 客户端中重命名/移动文件
  2. 删除VS中项目文件中的旧文件名引用
  3. 在 VS 的项目文件中添加新的文件名引用
  4. 提交您的更改

如果您使用持续集成构建过程并在最后一步之前的任何时间提交更改,则可以保证构建损坏。

该问题显着放大了需要重命名或移动的更多文件。这无论如何都不是一个顺利的过程。

于 2008-11-26T22:35:53.280 回答
3

在尝试了 Milan Gardian 的内容丰富的答案之后,我想我可以提供一个更简单的解决方案来让它运行良好。

正如 Weeble 所提到的,当其他一切都正确设置时,SAK 值可以正常工作,并且它们通常是默认值(但我认为这取决于它是哪种项目类型)。如果它们没有出现在您的项目中,只需粘贴到此属性组中。

<PropertyGroup>
    <SccProjectName>SAK</SccProjectName>
    <SccProvider>SAK</SccProvider>
    <SccAuxPath>SAK</SccAuxPath>
    <SccLocalPath>SAK</SccLocalPath>
</PropertyGroup>

将这两行添加到 SourceCodeControl GlobalSection 中的 *.sln。只要项目文件具有 SAK 值,它们就应该从解决方案继承名称。

SccProjectName0 = Perforce\u0020Project
SccProvider0 = MSSCCI:Perforce\u0020SCM

不需要签入 *.vsscc、*.vspscc 或 *.SCC 文件(尽管它们将在打开解决方案时生成)。

于 2011-03-03T17:42:24.397 回答
2

很差。我知道这不是您正在寻找的问题的答案(将来,也许您可​​以缩小焦点?),但是与 Visual Studio 的源代码控制集成很糟糕。原因是他们都必须使用微软糟糕的 SCC 界面。这是可悲的!他们将源代码控制信息放在项目文件中!他们为什么要那样做?

只需放弃 Visual Studio 集成并使用 Perforce 客户端。没有那么多额外的工作。您不能每天花 30 秒切换到 Perforce 客户端并从那里签入/签出文件吗?

于 2008-11-07T04:16:27.600 回答
1

我可以回答最后一个。

为了使源代码控制绑定即使在您创建新分支时也能正常工作,请遵循严格的层次结构:

/Solution
  /library1
  /library2
  /product1
  /product2
  /subsolution
    /sublibrary1
    /subproduct1

每个文件必须恰好位于一个 .vcproj 中。您可以在同一目录中拥有多个 .vcproj,但如果它们共享文件,则共享文件必须进入它们自己的 .vcproj。

如果您对此坚持不懈,那么所有 Scc 内容都将是相对路径,因此新分支将起作用(因为它仅更改最顶层的目录)。

于 2008-11-06T12:52:39.023 回答
-1

这不是 Perforce 问题,而是 Visual Studio 问题。修改源文件以允许 Visual Studio 了解正在使用的 SCM 工具的荒谬要求是愚蠢的。

简单的答案是“停止使用 Visual Studio 源代码控制集成”。这简直糟透了。即使使用 TFS,它也很糟糕。

如果您希望能够从 Visual Studio 中签出,只需创建一个自定义工具。只需使用适当的 VS 变量简单地调用“p4 edit”即可。想要还原文件?同样的想法...调用 p4 revert 并使用适当的变量。完毕。

使用 p4v 来管理您的源代码控制需求(提交、历史记录、差异等)。Visual Studio 就像一个源代码编辑器。它作为一个单片机接口很糟糕。

于 2013-06-11T17:20:26.173 回答