抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Perforce入门

Perforce又称P4、P4V

为什么要用P4

游戏开发一定需要一个版本管理工具,除了保留编辑记录外,还可以保护资产,遇到一些严重崩溃可以回退,不然会出现引擎打不开了,蓝图数据全丢了,一天白干的情况

为什么不使用Git呢?因为Git对二进制支持很差,即使使用LFS,对于动辄几十G的项目也无能为力

而且P4与Git不同,Git是在状态间切换,一旦切分支、拉新,就要将所有文件更新到某个状态,而P4可以只更新某个文件

此外P4也有分支、合并等概念,对于代码的处理也是完全可以接受的,因为强推P4

个人P4环境搭建

指服务器和客户端都搭在本机,仅用作版本管理,不考虑协作

1. 下载P4D

Download Helix Core (P4D) | Perforce

这是P4的服务器,一路继续就可以,记住服务器端口(默认是1666)

2. 下载P4V

Download Helix Visual Client (P4V) | Perforce

这是P4客户端,一路继续

3. 创建用户

打开P4V后,会弹出一个连接选项

Server填P4D创建时的端口(这里就是1666),如果是远程服务器,就是远程的链接:端口

点击User右侧的New,创建用户

结束后按OK进行P4V

p4创建用户

4. 创建Depot

此时我们是什么都没有的,所以要先创建一个Depot,这是类似仓库根节点的东西

点击Tools–Administration打开管理员面版

打开管理员面板

p4创建depot

5. 创建Stream

stream很类似于Git的分支,我们回到P4V的窗口,点击一个Depot后创建一个Stream

p4创建stream

Stream是可以衍生出其他子分支的

你可以在Stream Graph窗口查看Stream的关系,注意需要按一下Apply来刷新显示

StreamGraph

Stream上的小显示器,就是当前Workspace所在的位置,你可以拖动显示器到其他Stream,以实现分支切换

6. 创建Workspace

前面的东西都还是在服务端的,Workspace才是本地的东西,对着一个Stream右键,New Workspace

在Advanced里有一些配置,比如文件换行符格式,建议都用Unix

P4使用

拉新

Get Lastest

强制拉新

对着某个文件夹右键——Get Revison

强制拉新

Checkout

俗称锁了,一般这些二进制文件会被设置为只读,被checkout后才可写

一些二进制文件,如果不Checkout,就不能修改

文件被checkout后,其他人也能看到这个文件被谁checkout,有的文件一旦被其他人checkout,就不能对其进行修改,于是经常遇到有人来找你解锁某个文件

收集修改

基本是最常用的功能,尤其是一个人用时

对着某个文件夹右键——Reconcile Offline Work

收集修改

收集的修改会放在Pending中

回退

右键——Revert

提交修改

将Pending中某个修改提交,不要用default提交,注意写提交信息

暂存修改

将某个Pending的修改临时“回退”掉,不过这个回退其实会上传到服务器

这个功能最大的作用其实是私下传递资源,你可以把你的修改给其它他人,而不需要提交、污染主分支

其他人可以通过ID找到这个Shelve,按右键UnShelve就可以将这个Change应用到本地

暂存修改

解决冲突

P4 .Net API

P4所有操作其实都是通过命令实现的,在Log窗口可以看到,使用C# Api可以模拟这些接口,实现一些工具

using Perforce.P4;

namespace P4DoNetApi
{
class P4Utils
{
private string uri;
private string user;
private string workspace;
private Repository repo;
private Connection conn;
public P4Utils(string uri, string user, string workspace)
{
this.uri = uri;
this.user = user;
this.workspace = workspace;
repo = new Repository(new Server(new ServerAddress(uri)));
conn = repo.Connection;
conn.UserName = user;
conn.Client = new Client { Name = workspace };
conn.Connect(null);
}

/// <summary>
/// 获取当前workspace所有changelist描述
/// </summary>
/// <returns>描述名list</returns>
public List<string> getAllChangeListDescription()
{
List<string> result = new List<string>();
// p4 changes -L -c {workspace} -m 10 -u {user}
ChangesCmdOptions options = new ChangesCmdOptions(ChangesCmdFlags.LongDescription, workspace, 10, ChangeListStatus.None, user);
IList<Changelist> changelists = repo.GetChangelists(options, null);
foreach(var change in changelists)
{
result.Add(change.Description);
}
return result;
}

public List<string> getAllFileDepotPathInChangeList(int changelistId)
{
List<string> result = new List<string>();
Changelist changelist = repo.GetChangelist(changelistId);
if(changelist != null)
{
foreach(var fileMetaData in changelist.Files)
{
result.Add(fileMetaData.DepotPath.Path);
}
}
return result;
}
}
}

评论