Загрузка файлов депо на локальный диск без клиентского рабочего пространства

Я прочитал еще один пост здесь, где я могу загрузить файл из хранилища Perforce на локальный диск без клиентского рабочего пространства. Чтобы продвинуться дальше, мне нужно загрузить все файлы (текстовые и двоичные) из каталога хранилища на мой локальный диск. Это правильная команда p4, чтобы сделать это?

p4 print // депо /dir1/...

У меня есть несколько вопросов:

  1. Будет ли загружаться все подкаталоги, а также файлы из //depot/dir1/... или только файлы?
  2. Сохранит ли он оригинальные имена файлов, которые будут загружены?
  3. Где находятся файлы, расположенные на локальном диске, если не указан локальный путь?

Я использую библиотеку 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
        }
    }

Я не уверен, где на локальном диске он будет сбрасывать файлы в?

Спасибо за вашу помощь заранее.

3 ответа

Простое решение, не требующее инструментов для сценариев, специфичных для платформы:

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 указан.

p4 print выведет содержимое на стандартный вывод (см. отличное руководство). Поэтому отвечу на ваши вопросы по порядку:

  1. Он "загрузит" все файлы во всех подкаталогах, но распечатает содержимое файла только на стандартный вывод. Он не будет генерировать файлы на диске.
  2. Да, вроде, но не так, как вы себе представляете. В вашем потоке на stdout будут такие строки: //depot/path/to/file#5 - edit change 430530 (text)с последующим содержанием этого конкретного файла.
  3. Нигде на диске не будет создано никаких файлов.

Если вы действительно не хотите создавать рабочее пространство клиента для вашей задачи (почему?), Вам нужно будет сделать что-то вроде следующего:

  1. Получить список файлов с помощью, например, p4 files ( ручной)
  2. Перебрать этот список и вызвать p4 print для каждого файла
  3. Перенаправить вывод p4 print к файлу на локальном диске, придерживаясь структуры каталогов в депо.

Один лайнер

Для справки, вот один лайнер bash, который выполнит ручную процедуру 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. Получить список файлов из каталога перформанса

  2. Первый столбец вывода - это расположение файла в хранилище, поэтому распакуйте его с помощью awk

  3. Расположение депо имеет #revisionNumber прикрепленный на конце этого, так снимите это с perl

Итак, я потратил некоторое время на то, чтобы заставить это работать в разных сценариях в bash, и, хотя это не относится к dotnet, я подумал, что поделюсь своими результатами, поскольку концепции универсальны.

У вас есть два варианта получения файлов с удаленного устройства:

  1. Проверьте и синхронизируйте отображение рабочего пространства, используя временный клиент / рабочее пространство, как написал Сэм Стаффорд в своем ответе. Вот это в 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. Использовать p4 printчтобы распечатать содержимое каждого файла, как предлагает jhwist, поэтому вам вообще не нужно определять рабочее пространство. Недостатком является то, что вам придется обрабатывать каждый файл индивидуально и создавать любые каталоги самостоятельно.
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

Последняя версия Perforce уже изначально поддерживает его:

https://www.perforce.com/manuals/cmdref/Content/CmdRef/p4_print.html

Другие вопросы по тегам