我希望提交一个包含多个文件规范的更改列表,例如 ...this... ...file.h ...theother.... Perforce 不会让我这样做。我可以从文件创建更改列表,但我确实希望有机会查看文件并输入评论。这是一个命令行解决方案。
9 回答
如果您正在寻找 UNIX/*NIX 命令行解决方案,这将为您提供一个新的、干净的更改列表并将编号保留在$cl
:
export cl=`p4 change -o | grep '^\(Change\|Client\|User\|Description\)' | p4 change -i | cut -d ' ' -f 2`
这是一个无穷无尽的令人沮丧的问题。您应该能够从 Windows 命令行创建 p4 更改列表,而无需通过执行以下操作调用编辑器:
p4 change -o
| findstr /C:Description: /C:Change: /C:Client: /C:User: /C:Status:
| p4 change -i
返回字符串类似于“已创建更改 1500”。您可以解析更改列表。然后,您可以通过执行以下操作添加单个文件规范:
p4 edit -c 1500 //depot/base/...files.c
或者类似的东西。这种解决方案比较显着的问题是无法修改描述。或者,您可以使用必要的描述、更改、客户端等字符串创建一个临时文件,并通过以下方式创建更改列表:
p4 change -i < tempfile.txt
这似乎有些草率,但可能是脚本解决方案的最佳替代方案。
根据 Michael Gilbert 的回答,您可以像这样在 powershell 中编辑描述:
$newCLFormat = p4 change -o | select-string -pattern change, client, status
$newCLFormat += "Description: " + $myDescription
$newCLFormat | p4 change -i
要提取新的变更列表编号:
$newCLFormat | p4 change -i | select-string "\b(\d)+" | %{$_.matches[0].value}
现在必须有一种更快、更简洁的方法来提取那个数字?
编辑:将 findstr 重构为选择字符串
编辑:检索更改列表的更简洁方法:
$newCLFormat | p4 change -i | %{ $_.split()[1] }
您可以创建一个挂起的更改列表,然后在提交之前将您想要的所有文件移到该列表中。即使从命令行,虽然我发现 p4V 更容易用于此功能。
http://www.perforce.com/perforce/doc.current/manuals/cmdref/change.html#1040665
p4 change
创建挂起的更改列表。
p4 reopen
将文件移动到挂起的更改列表中。
我今天刚遇到这个问题,@Martin 的回答非常有帮助。我想创建一个带有描述的更改列表,而不是将其留空,所以我以他的命令为起点并将其调整为:
export cl=`p4 change -o | sed 's/<enter description here>/"Change list description"/' | sed '/^#/d' | sed '/^$/d' | p4 change -i | cut -d ' ' -f 2`
这是一个仅使用 p4 命令行和 Windows 标准 findstr 实用程序在 Windows cmd shell 中工作的单行程序,不需要任何临时文件。
(p4 change -o | findstr /v "enter description here" & echo ○My new changelist)|p4 change -i
这会:
- 生成变更列表规范(“p4 change -o”)
- 删除“在此处输入描述”行(“findstr -v”)
- 附加您的新描述(“回声”)
- 最后创建新的变更列表(“p4 change -i”)
请注意,描述必须以制表符开头,即那个小“○”家伙。如果格式在到达 shell 的途中中断,您可以使用 Alt-9 键入制表符。
Here is my rough first pass at a Perl wrapper around p4 commands.
It would be most useful if you had a LOT of files to check in.
The form editor is NOT invoked.
#
# p4checkoutfiles.pl -
#
# Will check out all files in current directory.
# Print newly-created changelist number to display, for p4submitfiles.pl.
# Optional command line parameter for Description, e.g. "Modifications from 07/25/2011".
#
# USAGE:
# 1. Copy this script to a new folder.
# 2. Copy all files to be checked in to this same folder.
# 3. Run this script to check out all the files, as follows:
#
# p4checkoutfiles.pl <clientspec> <changelist_description>
#
# For example:
#
# p4checkoutfiles.pl ClientSpec-Mike "Modifications from 07/25/2011".
#
#
# 4. Manually copy these files over their older versions, in the correct workspace directory.
# 5. Run p4checkinfiles.pl.
#
#
use strict;
use warnings;
################################################################################
# Save any command line parameters in local variables.
################################################################################
my $Client = shift;
die unless $Client;
my $ChangelistDescription = shift;
################################################################################
# Read default p4 form from pipe that executes p4 change command.
################################################################################
my $DefaultChangelistForm = "";
my $PrintDefaultChangelistCommand = "p4 change -o |";
open (PRINTDEFAULTCHANGELISTCOMMAND, $PrintDefaultChangelistCommand);
while (<PRINTDEFAULTCHANGELISTCOMMAND>)
{
if (($_ !~ "Client") &&
($_ !~ "User") &&
($_ !~ "Status"))
{
$DefaultChangelistForm .= $_;
}
}
# print "\$DefaultChangelistForm is: " . $DefaultChangelistForm;
close PRINTDEFAULTCHANGELISTCOMMAND;
################################################################################
# Swap in any command line parameter for Description
################################################################################
if ($ChangelistDescription)
{
$DefaultChangelistForm =~ s/<enter description here>/$ChangelistDescription/
}
################################################################################
# Write modified form values to disk, to be read by following p4 change -i.
################################################################################
open (FORMFORNEWCHANGELIST, ">formfornewchangelist.txt");
print FORMFORNEWCHANGELIST $DefaultChangelistForm;
close (FORMFORNEWCHANGELIST);
################################################################################
# Create new changelist using FORMFORNEWCHANGELIST.
# Read new changelist number from pipe that creates new changelist.
################################################################################
print "Creating new changelist...\n";
my $NewChangeList = "";
my $NewChangeListNumber = "";
my $CreateNewChangeListCommand = "";
$CreateNewChangeListCommand = "p4 -c ";
$CreateNewChangeListCommand .= $Client;
$CreateNewChangeListCommand .= " change -i < formfornewchangelist.txt |";
open (CREATENEWCHANGELISTCOMMAND, $CreateNewChangeListCommand);
while (<CREATENEWCHANGELISTCOMMAND>)
{
if ($_ =~ "created")
{
# Save new change list number for below.
$NewChangeListNumber = $_;
print $_;
}
}
close CREATENEWCHANGELISTCOMMAND;
################################################################################
# Save new changelist number to disk file newchangelistnumber.txt.
################################################################################
# Just parse numbers from string.
if ($NewChangeListNumber =~ /(\d+)/)
{
$NewChangeListNumber = $1;
}
open (NEWCHANGELISTNUMBER, ">newchangelistnumber.txt");
print NEWCHANGELISTNUMBER $NewChangeListNumber;
close (NEWCHANGELISTNUMBER);
################################################################################
# Read workspace root from pipe that executes p4 client command.
################################################################################
my $WorkspaceRoot = "";
my $PrintClientCommand = "p4 client -o ";
$PrintClientCommand .= $Client;
$PrintClientCommand .= " |";
open (PRINTCLIENTCOMMAND, $PrintClientCommand);
while (<PRINTCLIENTCOMMAND>)
{
# Save workspace root for edit command, below.
if ($_ =~ "Root:")
{
$WorkspaceRoot = $_;
# Just parse stuff after Root:
if ($WorkspaceRoot =~ /Root:\s*(.*)/)
{
$WorkspaceRoot = $1;
}
}
}
close PRINTCLIENTCOMMAND;
die unless length($WorkspaceRoot) > 0;
# print "WorkspaceRoot is: " . $WorkspaceRoot;
################################################################################
# For each file (other than newchangelistnumber.txt),
# check out that file into newly-created changelist.
# NOTE: THIS CODE ASSUMES THE FILES HAVE ALREADY BEEN ADDED TO PERFORCE.
# Enhancement: Fix above constraint.
################################################################################
print "Checking out all files in this subdirectory already in Perforce...\n";
my $directory = '.';
opendir (DIR, $directory) or die $!;
while (my $file = readdir(DIR))
{
# We only want files
next unless (-f "$directory/$file");
# Skip text files.
next if ($file =~ m/\.txt$/);
# Skip Perl files.
next if ($file =~ m/\.pl$/);
my $CheckOutFileCommand = "";
$CheckOutFileCommand = "p4 -c ";
$CheckOutFileCommand .= $Client;
$CheckOutFileCommand .= " edit ";
$CheckOutFileCommand .= " -c " . $NewChangeListNumber . " ";
$CheckOutFileCommand .= $WorkspaceRoot . "\\" . $file;
$CheckOutFileCommand .= " | ";
open (CHECKOUTFILECOMMAND, $CheckOutFileCommand);
while (<CHECKOUTFILECOMMAND>)
{
print $_;
}
close CHECKOUTFILECOMMAND;
}
closedir(DIR);
类型
p4 submit
如果你的 P4EDITOR 是 vim,那么你会得到一个 vim 编辑窗口。转到命令模式并通过键入选择“文件:”行之后的所有行
v followed by PgDown until you're done selecting all the files
然后做
:g!/.*pattern1.*#/d
如果你有多个这样的模式,
:g!/.*pattern1.*#\|.*pattern2.*#\|.*pattern3.*#/d etc...
希望这可以帮助!
这是 Maya (MEL) 的实现:
proc string jp_newChangeList()
{
//This will return the file format as a string
string $changelist = `system("p4 change -o || p4 change -i")`;
//Break up the string by line
string $breakChange[]; tokenize $changelist "\n" $breakChange;
//Find the line called "enter description here" and edit it with your text (precede text with 4 SPACES to preserve format!!!)
int $count = 0;
int $mine = 0;
for($lii in $breakChange)
{
$lii = `strip $lii`;
if($lii == "<enter description here>") $mine = $count;
$count++;
}
$breakChange[$mine] = " User enters text for description here";
//get a local dummy file location and call it "p4.txt". We will use this to generate a changelist
$exampleFileName = ( `internalVar -userTmpDir` + "p4.txt" );
$fileId=`fopen $exampleFileName "w"`;
int $printCount = 0;
//Print string array, one line at a time, until you pass the description string (leaving the "files" part unspecified)
while($printCount <= $mine)
{
fprint $fileId ($breakChange[$printCount] + "\n");
$printCount++;
}
//close the text file
fclose $fileId;
//Read the text file to return the changelist number
string $changelist = `system("p4 change -i < " + $exampleFileName)`;
//Parse return statement to isolate changelist number
string $changeNum[]; tokenize $changelist " " $changeNum;
string $changeListNumber = $changeNum[1];
return $changeListNumber;
}