Загрузка файлов депо на локальный диск без клиентского рабочего пространства
Я прочитал еще один пост здесь, где я могу загрузить файл из хранилища Perforce на локальный диск без клиентского рабочего пространства. Чтобы продвинуться дальше, мне нужно загрузить все файлы (текстовые и двоичные) из каталога хранилища на мой локальный диск. Это правильная команда p4, чтобы сделать это?
p4 print // депо /dir1/...
У меня есть несколько вопросов:
- Будет ли загружаться все подкаталоги, а также файлы из //depot/dir1/... или только файлы?
- Сохранит ли он оригинальные имена файлов, которые будут загружены?
- Где находятся файлы, расположенные на локальном диске, если не указан локальный путь?
Я использую библиотеку 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
выведет содержимое на стандартный вывод (см. отличное руководство). Поэтому отвечу на ваши вопросы по порядку:
- Он "загрузит" все файлы во всех подкаталогах, но распечатает содержимое файла только на стандартный вывод. Он не будет генерировать файлы на диске.
- Да, вроде, но не так, как вы себе представляете. В вашем потоке на stdout будут такие строки:
//depot/path/to/file#5 - edit change 430530 (text)
с последующим содержанием этого конкретного файла. - Нигде на диске не будет создано никаких файлов.
Если вы действительно не хотите создавать рабочее пространство клиента для вашей задачи (почему?), Вам нужно будет сделать что-то вроде следующего:
- Получить список файлов с помощью, например,
p4 files
( ручной) - Перебрать этот список и вызвать
p4 print
для каждого файла - Перенаправить вывод
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"')
Получить список файлов из каталога перформанса
Первый столбец вывода - это расположение файла в хранилище, поэтому распакуйте его с помощью
awk
Расположение депо имеет
#revisionNumber
прикрепленный на конце этого, так снимите это сperl
Итак, я потратил некоторое время на то, чтобы заставить это работать в разных сценариях в bash, и, хотя это не относится к dotnet, я подумал, что поделюсь своими результатами, поскольку концепции универсальны.
У вас есть два варианта получения файлов с удаленного устройства:
- Проверьте и синхронизируйте отображение рабочего пространства, используя временный клиент / рабочее пространство, как написал Сэм Стаффорд в своем ответе. Вот это в 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.
- Использовать
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