P4Api client.GetFileMappings 不是 returns 分支文件的前导 minus/dash 符号
P4Api client.GetFileMappings not returns leading minus/dash sign for branched files
我在多个分支下的 P4 服务器上有文件,例如
//depot/branch1/file.txt
//depot/branch2/file.txt
//depot/branch3/file.txt
假设file.txt是同一个文件但是不同的分支
当我使用命令行时
p4 -c testWorkspace where somepath\file.txt
我得到以下结果
-//depot/branch1/file.txt {client path depot path}
-//depot/branch2/file.txt {client path depot path}
//depot/branch3/file.txt {client path depot path}
从中我可以看出客户端 testWorkspace 中的 file.txt 应该通过 branch3 访问(因此从这个仓库路径我将获得 FileSpec、元数据、编辑等
但是当我尝试通过 P4api.net 做同样的事情并使用
Client.GetClientFileMappings("somepath\file.txt")
或
P4Command cmd3 = new P4Command(con, "where", true, "somepath\file.txt");
P4CommandResult result3 = cmd3.Run();
我得到了类似的结果,但没有前导减号(破折号 -)
//depot/branch1/file.txt {client path depot path}
//depot/branch2/file.txt {client path depot path}
//depot/branch3/file.txt {client path depot path}
而且我不知道我在这里做错了什么。
我需要的是获取给定工作区的当前文件属于哪个分支的信息,或者更好地获取其正确的 FileSpec,以便我可以使用 MoveFile、Add 等。但我只能获得所有分支的路径,并且可以识别它属于当前工作区的哪个分支
查看 GetClientFileMappings 的界面:
它看起来不像实际上 returns 映射;它 returns 一个 FileSpec 对象的列表,没有关于映射类型的信息(例如 -
、+
或 &
)。在 C++ API 中,这由 MapType
枚举表示:
https://swarm.workshop.perforce.com/projects/perforce_software-p4/files/2018-2/support/mapapi.h#6
在 .NET API 中有一个类似的枚举:
https://www.perforce.com/manuals/v15.1/p4api.net/p4api.net_reference/html/T_Perforce_P4_MapType.htm
属于 MapEntry
类型的一部分:
如果您能找到 returns MapEntry
列表中的任何东西,那将是您想要的东西,但我找不到任何东西。 GetClientFileMappings
似乎是问题,特别是因为名称中有 "Mappings",但是...
所以我与 P4 团队成员讨论了这个问题,他们确认 GetClientFileMappings 确实没有 returns 关于排除的信息。
他们给了我一个 "workaround"
P4Command cmd3 = new P4Command(con, "where", true, "somepath\file.txt");
P4CommandResult result3 = cmd3.Run();
if (result3.TaggedOutput!=null)
{
List<string> depotFiles = new List<string>();
foreach(TaggedObject taggedObject in results3.TaggedOutput)
{
if (taggedObject.ContainsKey("unmap"))
{
continue;
}
else
{
string path = "";
taggedObject.TryGetValue("depotFile", out path);
depotFiles.Add(path);
}
}
}
这对我有用。在最初的问题中,我提到这不是 returns 领先的 '-' 这是真的。但是 taggedObject 却包含足以确定信息的键 "unmap"。
我第一次没有注意到这个,因为我以错误的方式传递参数。
"file1.txt file2.txt" 作为简单的字符串,而不是字符串数组。
我还想出了一个更丑陋的 "workaround"(使用 p4 命令行,process.Start() 并解析字符串结果)
string commandText = $"/C p4 -u {UserName} -c {Client.Name} where {string.Join(" ", filePaths)}";
var process = new Process()
{
StartInfo = new ProcessStartInfo()
{
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = commandText,
RedirectStandardError = true,
RedirectStandardOutput = true
}
};
process.Start();
string processTextResult = process.StandardOutput.ReadToEnd();
var exitCode = process.ExitCode;
var errorMsg = process.StandardError.ReadToEnd();
process.Dispose();
if (exitCode == 0)
{
var resultLines = processTextResult.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
List<FileSpec> fileSpecResults = new List<FileSpec>();
foreach (var resultLine in resultLines)
{
var splitedLine = resultLine.Split(' ');
if (!splitedLine.First().StartsWith("-"))
{
fileSpecResults.Add(new FileSpec(new DepotPath(splitedLine[0]), new ClientPath(splitedLine[1]), new LocalPath(splitedLine[2]), null));
}
}
return fileSpecResults;
}
else
{
Logger.TraceError("P4 error - get file spec :" + errorMsg);
return new List<FileSpec>();
}
我在多个分支下的 P4 服务器上有文件,例如
//depot/branch1/file.txt
//depot/branch2/file.txt
//depot/branch3/file.txt
假设file.txt是同一个文件但是不同的分支
当我使用命令行时
p4 -c testWorkspace where somepath\file.txt
我得到以下结果
-//depot/branch1/file.txt {client path depot path}
-//depot/branch2/file.txt {client path depot path}
//depot/branch3/file.txt {client path depot path}
从中我可以看出客户端 testWorkspace 中的 file.txt 应该通过 branch3 访问(因此从这个仓库路径我将获得 FileSpec、元数据、编辑等
但是当我尝试通过 P4api.net 做同样的事情并使用
Client.GetClientFileMappings("somepath\file.txt")
或
P4Command cmd3 = new P4Command(con, "where", true, "somepath\file.txt");
P4CommandResult result3 = cmd3.Run();
我得到了类似的结果,但没有前导减号(破折号 -)
//depot/branch1/file.txt {client path depot path}
//depot/branch2/file.txt {client path depot path}
//depot/branch3/file.txt {client path depot path}
而且我不知道我在这里做错了什么。
我需要的是获取给定工作区的当前文件属于哪个分支的信息,或者更好地获取其正确的 FileSpec,以便我可以使用 MoveFile、Add 等。但我只能获得所有分支的路径,并且可以识别它属于当前工作区的哪个分支
查看 GetClientFileMappings 的界面:
它看起来不像实际上 returns 映射;它 returns 一个 FileSpec 对象的列表,没有关于映射类型的信息(例如 -
、+
或 &
)。在 C++ API 中,这由 MapType
枚举表示:
https://swarm.workshop.perforce.com/projects/perforce_software-p4/files/2018-2/support/mapapi.h#6
在 .NET API 中有一个类似的枚举:
https://www.perforce.com/manuals/v15.1/p4api.net/p4api.net_reference/html/T_Perforce_P4_MapType.htm
属于 MapEntry
类型的一部分:
如果您能找到 returns MapEntry
列表中的任何东西,那将是您想要的东西,但我找不到任何东西。 GetClientFileMappings
似乎是问题,特别是因为名称中有 "Mappings",但是...
所以我与 P4 团队成员讨论了这个问题,他们确认 GetClientFileMappings 确实没有 returns 关于排除的信息。
他们给了我一个 "workaround"
P4Command cmd3 = new P4Command(con, "where", true, "somepath\file.txt");
P4CommandResult result3 = cmd3.Run();
if (result3.TaggedOutput!=null)
{
List<string> depotFiles = new List<string>();
foreach(TaggedObject taggedObject in results3.TaggedOutput)
{
if (taggedObject.ContainsKey("unmap"))
{
continue;
}
else
{
string path = "";
taggedObject.TryGetValue("depotFile", out path);
depotFiles.Add(path);
}
}
}
这对我有用。在最初的问题中,我提到这不是 returns 领先的 '-' 这是真的。但是 taggedObject 却包含足以确定信息的键 "unmap"。
我第一次没有注意到这个,因为我以错误的方式传递参数。 "file1.txt file2.txt" 作为简单的字符串,而不是字符串数组。
我还想出了一个更丑陋的 "workaround"(使用 p4 命令行,process.Start() 并解析字符串结果)
string commandText = $"/C p4 -u {UserName} -c {Client.Name} where {string.Join(" ", filePaths)}";
var process = new Process()
{
StartInfo = new ProcessStartInfo()
{
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = commandText,
RedirectStandardError = true,
RedirectStandardOutput = true
}
};
process.Start();
string processTextResult = process.StandardOutput.ReadToEnd();
var exitCode = process.ExitCode;
var errorMsg = process.StandardError.ReadToEnd();
process.Dispose();
if (exitCode == 0)
{
var resultLines = processTextResult.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
List<FileSpec> fileSpecResults = new List<FileSpec>();
foreach (var resultLine in resultLines)
{
var splitedLine = resultLine.Split(' ');
if (!splitedLine.First().StartsWith("-"))
{
fileSpecResults.Add(new FileSpec(new DepotPath(splitedLine[0]), new ClientPath(splitedLine[1]), new LocalPath(splitedLine[2]), null));
}
}
return fileSpecResults;
}
else
{
Logger.TraceError("P4 error - get file spec :" + errorMsg);
return new List<FileSpec>();
}