Perforce for Git用户?[关闭]


173

那里有很多“ Git for Perforce用户”文档,但看起来却相反。

我以前只使用过Git,最近又开始工作,不得不大量使用Perforce,发现自己很多时候变得非常困惑。我习惯于Git的概念似乎根本没有映射到Perforce。

有没有人有兴趣为一些习惯了Git的人整理一些使用Perforce的技巧?

Answers:


333

在过去的几周内,我一直在努力进行这项工作。它仍在发展,但可能会有所帮助。请注意,我是Perforce的员工。

Git用户的Perforce简介

说从Git迁移到Perforce或从Perforce迁移到Git是不平凡的,这是轻描淡写的。作为表面上可以做相同事情的两个工具,它们的方法没有什么不同。这篇简短的文章将尝试帮助来自Git的新Perforce用户了解他们所处的新世界。

我们潜入之前先走了一段弯路;如果您喜欢Git,则可以将Perit与Git一起使用。我们提供了一个名为Git Fusion的工具,该工具可以生成与Perforce服务器保持同步的Git存储库。Git和Perforce的人们可以在相同的代码上和谐共处,而不受同事对版本控制的选择的影响。Git Fusions 13.3可从Perforce网站上获得。它确实需要由Perforce管理员安装,但是如果安装它,您会发现它的存储库切片功能对于Git用户而言非常方便。

如果您不能说服管理员安装Git Fusion,则Git本身带有Perforce绑定,称为Git-P4,该绑定使您可以使用Git更改和提交Perforce工作区中的文件。有关更多信息,请访问:https//git.wiki.kernel.org/index.php/GitP4

还在?好,让我们看看Perforce。

一些术语上的区别

在深入探讨细节之前,我们需要简要介绍一下Git和Perforce之间的一些术语差异。

首先是结帐。在Git中,这是将代码从给定分支复制到工作区的方式。在Perforce中,我们从命令行或从GUI P4V“获取最新修订” 将此称为同步。Perforce使用P4V或命令行中的checkout一词p4 edit来表示您打算从版本控制系统中更改文件。在本文档的其余部分中,我将在Perforce的意义上使用结帐。

二是Git的承诺与Perforce公司提交。在Git中提交的位置将在Perforce中提交。由于所有操作都是针对共享的Perforce版本控制服务进行的,因此Perforce没有的等效项git push。同样,我们没有pull; 上面的sync命令负责为我们获取文件。除非您选择使用下面简要介绍的P4Sandbox工具,否则Perforce中没有纯本地提交的概念。

Perforce中的关键概念

如果我将Perforce简化为两个关键概念,则我将专注于软件仓库和工作区。Perforce软件仓库是位于Perforce服务器中的文件存储库。Perforce服务器可以具有任意数量的软件仓库,每个软件仓库可以包含任意数量的文件。通常,您会听到Perforce用户交替使用软件仓库和服务器,但是它们是不同的。Perforce站点可以选择具有多个服务器,但是最常见的是所有文件都位于一台服务器中。

Perforce工作区或客户端是系统中的一个对象,该对象将Perforce服务器中的一组文件映射到用户文件系统上的某个位置。每个用户在使用的每台计算机上都有一个工作区,并且同一用户经常会拥有多个工作区。工作区中最重要的部分是工作区映射或视图。

工作空间视图指定应该在仓库中映射到本地计算机的文件集。这很重要,因为您很可能不希望服务器上所有可用的文件。通过工作空间视图,您可以仅选择您要关注的集合。重要的是要注意,工作空间可以映射来自多个软件仓库的内容,但是只能映射来自一台服务器的内容。

要在这方面比较Perforce和Git,请使用Git选择并选择您感兴趣的Git存储库。通常,每个存储库的范围都非常狭窄,只包含相关文件。这样做的好处是您无需进行任何配置。您对自己关心的事情做了一个git clone,然后就完成了。如果仅使用一个或两个存储库,则特别好。使用Perforce,您需要花费一些时间来选择所需的代码。

许多Perforce商店使用可以自动生成工作空间视图的流,或者使用脚本或模板工作空间来生成视图。同样,许多用户离开他们的用户自己生成工作区。能够在一个工作空间中映射多个模块的优势之一是,您可以在一个签入中轻松修改多个代码模块;您可以确保与客户视图具有相似客户端视图且同步到您签入的任何人都将所有代码处于正确状态。但是,这也可能导致代码过于依赖。强制分离Git可以导致更好的模块化。幸运的是,Perforce还可以支持严格的模块化。这都是您如何选择使用该工具的问题。

为什么选择工作区?

我认为,从Git来的时候,很容易感觉到整个工作区概念比它值得的麻烦更多。与克隆一些Git存储库相比,这无疑是正确的。工作区在哪里闪耀,以及Perforce这么多年以来仍在营业的原因是,工作区是为开发人员削减数百万个文件项目的绝妙方法,同时仍使构建和发布变得容易,从而将所有源权威来源。工作区是Perforce能够扩展和扩展的主要原因之一。

工作区也很不错,因为如果需要,软件仓库中的文件布局和用户计算机上的布局可以有所不同。许多公司组织其仓库以反映其公司的组织,以便人们可以轻松地按业务部门或项目查找内容。但是,他们的构建系统对这种层次结构并不关心。工作区允许他们以对其工具有意义的任何方式重新映射其仓库层次结构。我也看到过这种情况,这些公司正在使用极其不灵活的构建系统,这些系统要求代码采用非常人为混淆的非常特定的配置。工作区允许这些公司拥有可导航的源代码层次结构,而其构建工具可获取所需的结构。

Perforce中的工作区不仅用于映射用户想要使用的文件集,而且还被服务器用来跟踪用户已同步的每个文件的修订版本。这允许系统在同步时将正确的文件集发送给用户,而不必扫描文件以查看需要更新的文件。拥有大量数据,这可能是相当大的性能优势。这在审计规则非常严格的行业中也很流行。Perforce管理员可以轻松跟踪和记录哪些开发人员已同步了哪些文件。

有关Perforce工作区的全部功能的更多信息,请阅读“ 配置P4”

显式结帐与隐式结帐

从Git迁移到Perforce的用户面临的最大挑战之一是显式签出的概念。如果您习惯了Git / SVN / CVS的工作流程,即先更改文件,然后告诉版本控制系统查找您所做的事情,那么这将是非常痛苦的过渡。

好消息是,如果您选择这样做,则可以在Perforce中使用Git样式的工作流程。在Perforce中,您可以在工作区上设置“ allwrite”选项。这将告诉Perforce,所有文件都应在可写位设置的情况下写入磁盘。然后,您可以更改任何所需的文件,而无需明确告知Perforce。要使Perforce协调您所做的更改,您可以运行“ p4状态”。它将打开文件以进行添加,编辑和删除(如果适用)。以这种方式工作时,您将要使用“ p4更新”而不是“ p4同步”来从服务器获取新修订。“ p4更新”会在同步之前检查更改,因此如果您尚未运行“ p4状态”,则不会破坏您的本地更改。

为什么要明确结帐?

我经常收到的一个问题是“为什么要使用显式结帐?” 乍一看,这似乎是一个疯狂的设计决定,但是显式签出确实具有一些强大的好处。

使用显式签出的原因之一是,它无需扫描文件来更改内容。尽管在较小的项目中,为每个文件计算哈希值以查找差异是相当便宜的,但我们的许多用户在工作区中都有数百万个文件,并且/或者文件大小为100兆字节(如果不是更大的话)。在这些情况下,计算所有哈希非常耗时。显式检出使Perforce确切知道它需要使用哪些文件。这种行为是Perforce在大型文件行业(例如游戏,电影和硬件行业)中如此受欢迎的原因之一。

显式签出的另一个好处是显式签出提供了一种异步通信形式,使开发人员可以大致了解其同级在做什么,或者至少在什么地方工作。它可以让您知道您可能希望避免在某个特定区域工作,以避免不必要的冲突,或者可以提醒您以下事实:团队中的新开发人员已经漫游到可能不需要的代码中进行编辑。我的个人经验是,我倾向于在Git中工作,或者将Perwrite与allwrite一起用于那些我是唯一的贡献者或不频繁的贡献者的项目,并且在与团队紧密合作时会进行明确的结帐。幸运的是,选择是您的。

显式签出还与Perforce待定变更列表的概念很好地结合在一起。待处理的更改列表是存储桶,您可以将打开的文件放入其中以组织工作。在Git中,您可能会使用不同的分支作为组织工作的存储桶。分支很棒,但是有时最好将工作组织成多个命名的更改,然后再实际提交到服务器。通过将潜在的多个分支或多个项目映射到一个工作区的Perforce模型,挂起的变更列表可以轻松地组织单独的变更。

如果您使用IDE进行开发,例如Visual Studio或Eclipse,我强烈建议您为IDE安装Perforce插件。当您开始编辑文件时,大多数IDE插件都会自动签出文件,从而使您不必自己进行签出。

Perforce替代Git功能

  • git stash ==> p4 shelve
  • git local branching ==> Perforce架子或任务分支
  • git blame==> p4 annotate或从GUI进行Perforce Timelapse视图

工作断开

与Perforce版本控制服务断开连接有两种选择(这是我们对Perforce服务器的幻想)。

1)使用P4Sandbox具有完整的本地版本控制和本地分支

2)根据需要编辑文件,然后使用“ p4状态”告诉Perforce您所做的事情

使用以上两个选项,您可以选择在工作区中使用“ allwrite”设置,从而不必解锁文件。在这种模式下工作时,您将要使用“ p4 update”命令来同步新文件,而不是“ p4 sync”。“ p4更新”将在同步文件之前检查文件是否有更改。

Perforce快速入门

以下所有示例将通过命令行进行。

1)配置与Perforce的连接

export P4USER=matt
export P4CLIENT=demo-workspace
export P4PORT=perforce:1666

您可以将这些设置p4 set保留在shell配置文件中,用于将其保存在Windows和OS X上,或使用Perforce配置文件。

1)创建一个工作区

p4 workspace

# set your root to where your files should live:
Root: /Users/matt/work

# in the resulting editor change your view to map the depot files you care about
//depot/main/... //demo-workspace/main/...
//depot/dev/...  //demo-workspace/dev/...

2)从服务器获取文件

cd /Users/matt/work
p4 sync

3)签出您要处理的文件并对其进行修改

p4 edit main/foo; 
echo cake >> main/foo

4)提交给服务器

p4 submit -d "A trivial edit"

5)运行p4 help simple以查看使用Perforce所需的基本命令。


5
很棒的概述。我将保存此内容(或网站上的最终结果),以赠送给我们的一些新员工。
Caleb Huitt-cjhuitt

@Matt说:“来自Git,很容易感觉到整个工作区概念比它值得的麻烦更多。” 可能-但多年来我一直在RCS和CVS中进行这种映射。不使用CVS模块,而是通过创建指向一个或多个CVS存储库的符号链接树。稀疏树,不包含所有目录。出于很多原因,您描述了Perforce这样做的原因。在CVS中维持这一点可能会很痛苦。(还有git,hg和bzr ...不确定bzr。)
Krazy Glew 2014年

感谢Matt,这本非常有用的读物​​。我仍然认为版本控制系统应该告诉我与远程
仓库

1
确实!幸运的是,您可以使用Perforce做到这一点;我已经好几年没有运行“ p4编辑”了。perforce.com/blog/131112/say-goodbye-p4-edit
马特

8
谢谢,但有个建议。“强大”一词颇为狡猾,使我倾向于无视该声明的宣传。如果您先解释了该功能,然后让我确定它是否功能强大,我希望您能选择它。
达米安

24

git和p4之间的最大区别(现有答案均未解决)是它们使用不同的抽象单位。

  • 在git中,抽象是补丁(又名diff,又名changeset)。git中的提交本质上是在提交diff的文件的先前状态和当前状态之间运行的输出。
  • 在perforce中,抽象是file。p4中的提交是该时间点提交中文件的完整内容。它被组织成一个变更列表,但是修订本身是按文件存储的,而变更列表只是将文件的不同修订汇总在一起。

其他一切都源于这种差异。在git中进行分支和合并很容易,因为从git的抽象角度来看,每个文件都可以按顺序应用一组补丁来完全重建,因此要合并两个分支,您只需要在源分支上应用所有补丁即可没有以正确的顺序出现在目标分支中的目标分支(假设两个分支上没有重叠的补丁)。

Perforce分支不同。perforce中的分支操作会将文件从一个子文件夹复制到另一个子文件夹,然后使用服务器上的元数据标记文件之间的链接。从一个分支合并文件到另一个(integrationPerforce中的术语),Perforce公司将着眼于完整内容的文件在对源科的“头”和完整内容的文件,在目标分支的头如有必要,请使用共同祖先合并。它无法像git can一样一一应用补丁程序,这意味着手动合并发生的频率更高(并且更加痛苦)。


10
我认为此描述不是完全准确的-git存储所有文件的完整快照,并在文件更改时创建一个新快照(在频繁更改大型二进制文件的情况下这很昂贵),因此提交仅包含(通过散列)链接到所有文件的当前状态。这就是为什么在git中切换分支通常非常快的原因-它只需要将哈希已更改的所有文件的引用版本复制到工作区中。仅在需要比较和合并/重新设置基准时才动态创建差异。
ChrAfonso

3
不管幕后如何精确实现,从最终用户的角度来看,git中的合并命令(尤其是琐碎的合并或快速转发)似乎都可以使用补丁来运行,这就是我要提出的重点。
达米安2015年

Perforce可以进行变更列表(变更集)合并。这是一个关于堆栈溢出的问题。stackoverflow.com/questions/6158916/perforce-merge-changelist/…–
Br.Bill

5
@ Br.Bill再说一遍,我要说的不是P4是否有能力做事(当然是因为!)。关键在于抽象,即用户需要内部化模型以了解其工作方式。
达米安

1
这次真是万分感谢。它立即说明了如何获取特定文件的最新版本,如何获取特定的更改列表。对于我来说,这是我最困惑的部分,因为我来自git。
阿卜杜勒斯塔特·穆罕默德

20

这样的文档可能不多,因为Perforce是一个非常传统的版本控制系统(更接近CVS,Subversion等),通常被认为比现代的分布式版本控制系统复杂。

尝试将命令从一个映射到另一个是不正确的方法。集中式与分布式修订控制系统的概念并不相同。相反,我将在Perforce中描述一个典型的工作流程:

  1. p4 edit在要编辑的每个文件上运行。您需要告诉Perforce您正在编辑哪些文件。如果要添加新文件,请使用p4 add。如果要删除文件,请使用p4 delete
  2. 进行代码更改。
  3. 运行p4 change以创建一个变更集。在这里,您可以创建更改描述,也可以选择从更改集中添加或删除文件。p4 change CHANGE_NUMBER如有必要,您可以稍后运行以编辑描述。
  4. 如果需要,可以更改其他代码。如果您需要添加/编辑/删除其他文件,可以使用p4 {add,edit,delete} -c CHANGE_NUMBER FILE
  5. 运行p4 sync以从服务器获取最新更改。
  6. 运行p4 resolve以解决同步中的所有冲突。
  7. 准备好提交更改时,请运行p4 submit -c CHANGE_NUMBER

您可以p4 revert用来将更改还原到文件。

请注意,只要没有文件重叠,就可以同时处理多个变更集。(您只能一次在一个变更集中打开Perforce客户端中的文件。)如果您进行小的,独立的变更,这有时会很方便。

如果您发现自己需要编辑已经在另一个变更集中打开的文件,则可以创建一个单独的Perforce客户端,也可以将现有的变更集存储起来,以备后用p4 shelve。(与一样git stash,搁架不会还原本地树中的文件,因此您必须单独还原它们。)


3
抱歉,我不明白这一点:现代系统是否必须比传统系统更复杂?简单性始终是软件工程中的原则。从某种意义上说,我认为P4在概念和可用性(以及可维护性)方面都比Git更现代。我不讨厌Git,但是可以看到,经过30多年的软件工程发展,人们被迫诉诸于基于文本的控制台来发布VCS命令,这是人类进化中的退化!
Dejavu 2014年

5
@Dejavu与其说是传统,不如说是现代。它更多地是关于集中式与分布式的(而分布式的恰好更现代)。分布式的不一定复杂,但是我特别说过,“ Perforce ...被认为不那么复杂...”,这是观点的陈述,不是事实,也不是一概而论。关于所有系统的声明。我个人认为git更复杂,因为它增加了更多的概念(例如推,拉,变基),并且有些事情不那么简单(例如,用散列代替全局变更数字)。
jamesdlin 2014年

2
谢谢您的澄清,詹姆斯!最近,我有点受侮辱,看到所有同事都必须接受git hacker的培训,他们应该知道很多git hacking技能,以解决使用Perforce时感到如此直观的一些问题。
Dejavu 2014年

4
@Dejavu,考虑到现代IDE的图形支持,您的评论没有任何意义git,而且他们已经这样做了多年。
Acumenus '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.