P4Api client.GetFileMappings not returns leading minus/dash sign for branched files

245 Views Asked by At

I have files on P4 server under multiple branches e.g.

//depot/branch1/file.txt
//depot/branch2/file.txt
//depot/branch3/file.txt

assume that file.txt is same file but different branches

When i use commandline

p4 -c testWorkspace where somepath\file.txt

i get following result

-//depot/branch1/file.txt {client path depot path}
-//depot/branch2/file.txt {client path depot path}
//depot/branch3/file.txt {client path depot path}

and from that i can tell that file.txt in client testWorkspace should be accessed via branch3 (so from this depot path i will get FileSpec, Metadata, edit, etc

But when i try to do same via P4api.net and use

Client.GetClientFileMappings("somepath\file.txt")

or

P4Command cmd3 = new P4Command(con, "where", true, "somepath\file.txt");
P4CommandResult result3 = cmd3.Run();

i got similar result but without leading minus (dash -) signs

//depot/branch1/file.txt {client path depot path}
//depot/branch2/file.txt {client path depot path}
//depot/branch3/file.txt {client path depot path}

And i dont know what am i doing wrong here.

What i need is to get information to which branch current file for given workspace belongs, or even better get its correct FileSpec so i can use MoveFile, Add and so on. But i only get paths to all branches and can recognize to which branch it belongs for current workspace

2

There are 2 best solutions below

0
On BEST ANSWER

So i discused this with P4 team member and they confirmed that GetClientFileMappings realy not returns information about exclusion.

They offered me a "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);
            }
        }
    }

which is working for me. In original question, i mentions this not returns leading '-' which is true. But taggedObject instead contains key "unmap" which is enough to determine information.

I didnt notice this for first time, because i passed argument in wrong way. "file1.txt file2.txt" as simple string, not array of strings.

I also figured out one more "workaround" which is much more uglier (use p4 commandline, process.Start() and parse string result)

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>();
}
0
On

Looking at the interface for GetClientFileMappings:

https://www.perforce.com/manuals/v15.1/p4api.net/p4api.net_reference/html/M_Perforce_P4_Client_GetClientFileMappings.htm

It does not look like it actually returns a mapping; it returns a list of FileSpec objects, without information about the mapping type (e.g. -, +, or &). In the C++ API this is represented by the MapType enum:

https://swarm.workshop.perforce.com/projects/perforce_software-p4/files/2018-2/support/mapapi.h#6

In the .NET API there's a similar enum:

https://www.perforce.com/manuals/v15.1/p4api.net/p4api.net_reference/html/T_Perforce_P4_MapType.htm

which is part of the MapEntry type:

https://www.perforce.com/manuals/v15.1/p4api.net/p4api.net_reference/html/M_Perforce_P4_MapEntry__ctor.htm

If you can find anything that returns a list of MapEntrys, that'll be the thing you want, but I can't find anything that does. GetClientFileMappings would seem to be the thing, especially since "Mappings" is in the name, but...