将库文件下载到本地磁盘而不使用客户端工作区

时间:2012-01-31 06:02:27

标签: .net perforce p4api.net

我在这里读到另一篇文章,我可以将文件从Perforce软件仓库下载到没有客户端工作区的本地磁盘中。为了进一步扩展,我需要将所有文件(文本和二进制)从软件仓库目录下载到我的本地磁盘。这是正确的p4命令吗?

p4 print // depot / dir1 /...

我有几个问题:

  1. 是否会从// depot / dir1 / ...或文件中下载所有子目录和文件?
  2. 是否保留将要下载的文件的原始名称?
  3. 如果没有指定本地路径,那么位于本地磁盘上的文件在哪里?
  4. 我正在使用p4api.net库。这段代码会这样做吗?

        public void GetFiles(string DepotFilePath) 
        {
            P4Command cmd = new P4Command( _repository, "print", true, 
            String.Format( "{0}/...", DepotFilePath ));
    
            results = cmd.Run();
            if (results.Success)
            {
                //do something here
            }
        }
    

    我不确定它会将文件转储到本地磁盘的哪个位置?

    提前感谢您的帮助。

5 个答案:

答案 0 :(得分:2)

p4 print会将内容输出到标准输出中(请参阅优秀的manual)。因此,请按顺序回答您的问题:

  1. 它将“下载”所有子目录中的所有文件,但它只会在stdout上打印文件内容。它不会在磁盘上生成文件。
  2. 是的,但不是你想象的那样。在stdout的流中,会出现如下行://depot/path/to/file#5 - edit change 430530 (text),后跟该特定文件的内容。
  3. 无处,磁盘上不会创建任何文件。
  4. 如果您真的不想为您的任务创建客户端工作区(为什么?),那么您必须执行以下操作:

    1. 获取包含以下内容的文件列表: p4 filesmanual
    2. 对此列表进行迭代,并为每个文件调用p4 print
    3. p4 print的输出重定向到本地磁盘上的文件,并遵守软件仓库中的目录结构。

答案 1 :(得分:1)

简单的解决方案,无需特定于平台的脚本工具:

p4 client -df TEMP_CLIENT
p4 -c TEMP_CLIENT --field View="//depot/dir1/... //TEMP_CLIENT/..." client -o | p4 client -i
p4 -c TEMP_CLIENT sync -p
p4 client -d TEMP_CLIENT

这会将//depot/dir1中的所有文件/目录下载到您当前的目录中。如果要指定其他目录,请将--field "Root=C:\Some Path"添加到指定View的同一位置的第一个命令。

答案 2 :(得分:0)

单行

作为参考,这里有一个bash one liner,它将执行手动程序jhwist的答案:

for _file in $(p4 files //depot/dir/... | awk '{print $1}' | perl -ne '/(.*)#\d+$/ && print "$1\n"'); do p4 print -q $_file > /path/to/target/dir/$(basename $_file); done

您需要替换相关目录的唯一位是//depot/dir/path/to/target/dir。注意:目标目录必须已存在。


说明:

拉出for循环迭代的内容:

$(p4 files //depot/dir/... | awk '{print $1}' | perl -ne '/(.*)#\d+$/ && print "$1\n"')
  1. 获取有问题的perforce目录中的文件列表

  2. 输出的第一列是文件的库位,因此使用awk

  3. 提取它
  4. 基地位置在其末尾加#revisionNumber,因此请使用perl

  5. 将其删除

答案 3 :(得分:0)

因此,我花了一些时间使它能够在bash中的不同场景下工作,尽管它不是特定于dotnet的,但我认为我会分享我的结果,因为这些概念是通用的。

从远程获取文件有两种选择:

  1. 使用临时客户端/工作区签出并同步工作区映射,就像Sam Stafford在his answer中写的那样。这是带有评论的bash中的内容:
# p4 uses this global variable as client/workspace name by default.
# Alternatively, you can also use -c in every command.
P4CLIENT="TEMP_SCRIPT_CLIENT"

# mapping remote folder to relative workspace folder  (recursive)
wokspaceMapping="//depot/dir1/... //$P4CLIENT/..."
p4 client -d $P4CLIENT # make sure the workspace does not exist already
# Creating a client on the console gives an editor popup to confirm the
# workspace specification, unless you provide a specification on stdin.
# You can however generate one to stdout, and pipe the result to stdin again.
p4 --field View="$wokspaceMapping" --field Root="/some/local/path" client -o |
  p4 client -i
p4 sync -p # download all the files
p4 client -d $P4CLIENT # remove workspace when you are done.
  1. 按照jhwist wrote的建议使用p4 print打印每个文件的内容,因此您完全不需要定义工作区。缺点是您必须分别处理每个文件,并自己创建任何目录。
p4RemoteRoot="//depot/dir1"
# First, list files and strip output to file path
# because `p4 files` prints something like this:
# //depot/dir1/file1.txt#1 - add change 43444817 (text)
# //depot/dir1/folder/file2.txt#11 - edit change 43783713 (text)
files="$(p4 files $p4RemoteRoot/... | sed 's/\(.*\)#.*/\1/')"
for wsFile in $files; do
  # construct the local path from the remote one
  targetFile="$localPath/${wsFile#$p4RemoteRoot/}"
  # create the parent dir if it doesn't exist. p4 files doesn't list directories
  mkdir -p $(dirname $targetFile)
  # print the file content from remote and write that to the local file.
  p4 print -q $wsFile > $targetFile
done

注意:我找不到--field参数的任何文档,但是看来您可以使用文档中指定的“表单域”中的所有内容:https://www.perforce.com/manuals/v18.2/cmdref/Content/CmdRef/p4_client.html

答案 4 :(得分:0)