using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace Perforce.P4 { /// /// Represents a Perforce server and connection. /// public partial class Repository : IDisposable { /// /// Create a repository on the specified server. /// /// The repository server. public Repository (Server server) { Server = server; } /// /// Represents a specific Perforce server. /// public Server Server {get; private set;} private Connection _connection; /// /// Represents the logical connection between a specific Perforce Server /// instance and a specific client application. /// public Connection Connection { get { if (_connection == null) { _connection = new Connection(Server); } return _connection; } } /// /// Return a list of FileSpecs of files in the depot that correspond /// to the passed-in FileSpecs. /// /// /// /// /// ///
p4 help files ///
///
files -- List files in the depot ///
///
p4 files [ -a ] [ -A ] [ -e ] [ -m max ] file[revRange] ... ///
p4 files -U unloadfile ... ///
///
List details about specified files: depot file name, revision, ///
file, type, change action and changelist number of the current ///
head revision. If client syntax is used to specify the file ///
argument, the client view mapping is used to determine the ///
corresponding depot files. ///
///
By default, the head revision is listed. If the file argument ///
specifies a revision, then all files at that revision are listed. ///
If the file argument specifies a revision range, the highest revision ///
in the range is used for each file. For details about specifying ///
revisions, see 'p4 help revisions'. ///
///
The -a flag displays all revisions within the specific range, rather ///
than just the highest revision in the range. ///
///
The -A flag displays files in archive depots. ///
///
The -e flag displays files with an action of anything other than ///
deleted, purged or archived. Typically this revision is always ///
available to sync or integrate from. ///
///
The -m flag limits files to the first 'max' number of files. ///
///
The -U option displays files in the unload depot (see 'p4 help ///
unload' for more information about the unload depot). ///
///
/// /// To get a maximum of 10 files from the repository: /// /// /// GetDepotFilesCmdOptions opts = /// new GetDepotFilesCmdOptions(GetDepotFilesCmdFlags.None, 10); /// FileSpec fs = new FileSpec(new DepotPath("//depot/..."), null); /// List<FileSpec> lfs = new List<FileSpec>(); /// lfs.Add(fs); /// IList<FileSpec> files = Repository.GetDepotFiles(lfs, opts); /// /// /// /// public IList GetDepotFiles(IList filespecs, Options options) { P4.P4Command filesCmd = new P4Command(this, "files", true, FileSpec.ToStrings(filespecs)); P4.P4CommandResult r = filesCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } List value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { string path = obj["depotFile"]; PathSpec ps = new DepotPath(path); int rev = 0; int.TryParse(obj["rev"], out rev); FileSpec fs = new FileSpec(ps, new Revision(rev)); value.Add(fs); } return value; } /// /// Return a list of Files opened by users / clients. /// /// /// /// /// ///
p4 help opened ///
///
opened -- List open files and display file status ///
///
p4 opened [-a -c changelist# -C client -u user -m max -s] [file ...] ///
p4 opened [-a -x -m max ] [file ...] ///
///
Lists files currently opened in pending changelists, or, for ///
specified files, show whether they are currently opened or locked. ///
If the file specification is omitted, all files open in the current ///
client workspace are listed. ///
///
Files in shelved changelists are not displayed by this command. To ///
display shelved changelists, see 'p4 changes -s shelved'; to display ///
the files in those shelved changelists, see 'p4 describe -s -S'. ///
///
The -a flag lists opened files in all clients. By default, only ///
files opened by the current client are listed. ///
///
The -c changelist# flag lists files opened in the specified ///
changelist#. ///
///
The -C client flag lists files open in the specified client workspace. ///
///
The -u user flag lists files opened by the specified user. ///
///
The -m max flag limits output to the first 'max' number of files. ///
///
The -s option produces 'short' and optimized output when used with ///
the -a (all clients) option. For large repositories '-a' can take ///
a long time when compared to '-as'. ///
///
The -x option lists files that are opened 'exclusive'. This option ///
only applies to a distributed installation where global tracking of ///
these file types is necessary across servers. The -x option implies ///
the -a option. ///
///
/// /// To get a maximum of 10 opened files from the repository, opened by /// user fred, opened with any client: /// /// /// FileSpec fs = new FileSpec(new DepotPath("//..."), null); /// /// List<FileSpec> lfs = new List<FileSpec>(); /// lfs.Add(fs); /// /// // null for changelist and client options /// GetOpenedFilesOptions opts = /// new GetOpenedFilesOptions(GetOpenedFilesCmdFlags.AllClients, /// null, null, "fred", 10); /// /// IList<File> target = Repository.GetOpenedFiles(lfs, opts); /// /// /// public IList GetOpenedFiles(IList filespecs, Options options) { P4.P4Command openedCmd = new P4Command(this, "opened", true, FileSpec.ToStrings(filespecs)); P4.P4CommandResult r = openedCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } List value = new List(); DepotPath dps = null; ClientPath cps = null; int revision = 0; Revision rev = new Revision(0); Revision haveRev = new Revision(0); StringEnum action = null; int change = -1; FileType type = null; DateTime submittime = DateTime.MinValue; string user = string.Empty; string client = string.Empty; foreach (P4.TaggedObject obj in r.TaggedOutput) { if (obj.ContainsKey("depotFile")) { dps = new DepotPath(obj["depotFile"]); } if (obj.ContainsKey("clientFile")) { cps = new ClientPath(obj["clientFile"]); } if (obj.ContainsKey("rev")) { int.TryParse(obj["rev"], out revision); rev = new Revision(revision); } if (obj.ContainsKey("haveRev")) { int.TryParse(obj["haveRev"], out revision); haveRev = new Revision(revision); } if (obj.ContainsKey("action")) { action = obj["action"]; } if (obj.ContainsKey("change")) { int.TryParse(obj["change"], out change); } if (obj.ContainsKey("type")) { type = new FileType(obj["type"]); } if (obj.ContainsKey("user")) { user = obj["user"]; } if (obj.ContainsKey("client")) { client = obj["client"]; } File f = new File(dps, cps, rev, haveRev, change, action, type, submittime, user, client); value.Add(f); } return value; } /// /// Use the p4 fstat command to get the file metadata for the files /// matching the FileSpec. /// /// /// /// /// ///
p4 help fstat ///
///
fstat -- Dump file info ///
///
p4 fstat [-F filter -L -T fields -m max -r] [-c | -e changelist#] ///
[-Ox -Rx -Sx] file[rev] ... ///
///
Fstat lists information about files, one line per file. Fstat is ///
intended for use in Perforce API applications, where the output can ///
be accessed as variables, but its output is also suitable for parsing ///
from the client command output in scripts. ///
///
The fields that fstat displays are: ///
///
attr-<name> -- attribute value for <name> ///
attrProp-<name> -- set if attribute <name> is propagating ///
clientFile -- local path (host or Perforce syntax) ///
depotFile -- name in depot ///
movedFile -- name in depot of moved to/from file ///
path -- local path (host syntax) ///
isMapped -- set if mapped client file is synced ///
shelved -- set if file is shelved ///
headAction -- action at head rev, if in depot ///
headChange -- head rev changelist#, if in depot ///
headRev -- head rev #, if in depot ///
headType -- head rev type, if in depot ///
headCharset -- head charset, for unicode type ///
headTime -- head rev changelist time, if in depot ///
headModTime -- head rev mod time, if in depot ///
movedRev -- head rev # of moved file ///
haveRev -- rev had on client, if on client ///
desc -- change description ///
digest -- MD5 digest (fingerprint) ///
fileSize -- file size ///
action -- open action, if opened ///
type -- open type, if opened ///
charset -- open charset, for unicode type ///
actionOwner -- user who opened file, if opened ///
change -- open changelist#, if opened ///
resolved -- resolved integration records ///
unresolved -- unresolved integration records ///
reresolvable -- reresolvable integration records ///
otherOpen -- set if someone else has it open ///
otherOpen# -- list of user@client with file opened ///
otherLock -- set if someone else has it locked ///
otherLock# -- user@client with file locked ///
otherAction# -- open action, if opened by someone else ///
otherChange# -- changelist, if opened by someone else ///
openattr-<name> -- attribute value for <name> ///
openattrProp-<name> -- set if attribute <name> is propagating ///
ourLock -- set if this user/client has it locked ///
resolveAction# -- pending integration record action ///
resolveBaseFile# -- pending integration base file ///
resolveBaseRev# -- pending integration base rev ///
resolveFromFile# -- pending integration from file ///
resolveStartFromRev# -- pending integration from start rev ///
resolveEndFromRev# -- pending integration from end rev ///
totalFileCount -- total no. of files, if sorted ///
///
The -A <pattern> flag restricts displayed attributes to those ///
that match 'pattern'. ///
///
The -F flag lists only files satisfying the filter expression. This ///
filter syntax is similar to the one used for 'jobs -e jobview' and is ///
used to evaluate the contents of the fields in the preceding list. ///
Filtering is case-sensitive. ///
///
Example: -Ol -F "fileSize > 1000000 & headType=text" ///
///
Note: filtering is not optimized with indexes for performance. ///
///
The -L flag can be used with multiple file arguments that are in ///
full depot syntax and include a valid revision number. When this ///
flag is used the arguments are processed together by building an ///
internal table similar to a label. This file list processing is ///
significantly faster than having to call the internal query engine ///
for each individual file argument. However, the file argument syntax ///
is strict and the command will not run if an error is encountered. ///
///
The -T fields flag returns only the specified fields. The field names ///
can be specified using a comma- or space-delimited list. ///
///
Example: -Ol -T "depotFile, fileSize" ///
///
The -m max flag limits output to the specified number of files. ///
///
The -r flag sorts the output in reverse order. ///
///
The -c changelist# flag displays files modified after the specified ///
changelist was submitted. This operation is much faster than using ///
a revision range on the affected files. ///
///
The -e changelist# flag lists files modified by the specified ///
changelist. When used with the -Ro flag, only pending changes are ///
considered, to ensure that files opened for add are included. This ///
option also displays the change description. ///
///
The -O options modify the output as follows: ///
///
-Oa output attributes set by 'p4 attribute'. ///
///
-Od output the digest of the attribute. ///
///
-Oe output attribute values encoded as hex ///
///
-Of output all revisions for the given files (this ///
option suppresses other* and resolve* fields) ///
///
-Ol output a fileSize and digest field for each revision ///
(this may be expensive to compute) ///
///
-Op output the local file path in both Perforce syntax ///
(//client/) as 'clientFile' and host form as 'path' ///
///
-Or output pending integration record information for ///
files opened on the current client, or if used with ///
'-e <change> -Rs', on the shelved change ///
///
-Os exclude client-related data from output ///
///
The -R option limits output to specific files: ///
///
-Rc files mapped in the client view ///
-Rh files synced to the client workspace ///
-Rn files opened not at the head revision ///
-Ro files opened ///
-Rr files opened that have been resolved ///
-Rs files shelved (requires -e) ///
-Ru files opened that need resolving ///
///
The -S option changes the order of output: ///
///
-St sort by filetype ///
-Sd sort by date ///
-Sr sort by head revision ///
-Sh sort by have revision ///
-Ss sort by filesize ///
///
The -U flag displays information about unload files in the unload ///
depot (see 'p4 help unload'). ///
///
For compatibility, the following flags are also supported: ///
-C (-Rc) -H (-Rh) -W (-Ro) -P (-Op) -l (-Ol) -s (-Os). ///
///
///
/// /// To get FileMetaData for //depot/ReadMe.txt: /// /// /// FileSpec fs = new FileSpec(new DepotPath("//depot/MyCode/ReadMe.txt"), null); /// /// GetFileMetaDataCmdOptions opts = /// new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.None, /// null, null, 0, null, null, null); /// /// IList<FileMetaData> target = Repository.GetFileMetaData(opts, fs); /// /// To get FileMetaData for files in the depot that need resolving: /// /// /// FileSpec fs = new FileSpec(new DepotPath("//..."), null); /// /// GetFileMetaDataCmdOptions opts = /// new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.NeedsResolve, /// null, null, 0, null, null, null); /// /// IList<FileMetaData> target = Repository.GetFileMetaData(opts, fs); /// /// To get FileMetaData for files in the depot that are over a specific file /// size and of file type, text: /// /// /// FileSpec fs = new FileSpec(new DepotPath("//..."), null); /// /// GetFileMetaDataCmdOptions opts = /// new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.None, /// "fileSize > 1000000 & headType=text", null, 0, null, null, null); /// /// IList<FileMetaData> target = Repository.GetFileMetaData(opts, fs); /// /// To get FileMetaData for files in the depot that have been modified at or /// after changelist 20345 and are mapped to the client view: /// /// /// FileSpec fs = new FileSpec(new DepotPath("//..."), null); /// /// GetFileMetaDataCmdOptions opts = /// new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.ClientMapped, /// null, null, 20345, null, null, null); /// /// IList<FileMetaData> target = Repository.GetFileMetaData(opts, fs); /// /// To get FileMetaData for files in the depot including attributes which match /// the pattern "tested": /// /// /// FileSpec fs = new FileSpec(new DepotPath("//..."), null); /// /// GetFileMetaDataCmdOptions opts = /// new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.Attributes, /// null, null, 0, null, null, "tested"); /// /// IList<FileMetaData> target = Repository.GetFileMetaData(opts, fs); /// /// /// public IList GetFileMetaData(Options options, params FileSpec[] filespecs) { string[] paths = FileSpec.ToEscapedStrings(filespecs); P4.P4Command fstatCmd = new P4Command(this, "fstat", true, paths); P4.P4CommandResult r = fstatCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } List value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { if ((obj.Count <=2) && (obj.ContainsKey("desc"))) { // hack, but this not really a file, it's just a // the description of the change if -e option is // specified, so skip it continue; } FileMetaData fmd = new FileMetaData(); fmd.FromFstatCmdTaggedData(obj); value.Add(fmd); } return value; } /// /// Use the p4 fstat command to get the file metadata for the files /// matching the FileSpec. /// /// /// /// /// ///
p4 help fstat ///
///
fstat -- Dump file info ///
///
p4 fstat [-F filter -L -T fields -m max -r] [-c | -e changelist#] ///
[-Ox -Rx -Sx] file[rev] ... ///
///
Fstat lists information about files, one line per file. Fstat is ///
intended for use in Perforce API applications, where the output can ///
be accessed as variables, but its output is also suitable for parsing ///
from the client command output in scripts. ///
///
The fields that fstat displays are: ///
///
attr-<name> -- attribute value for <name> ///
attrProp-<name> -- set if attribute <name> is propagating ///
clientFile -- local path (host or Perforce syntax) ///
depotFile -- name in depot ///
movedFile -- name in depot of moved to/from file ///
path -- local path (host syntax) ///
isMapped -- set if mapped client file is synced ///
shelved -- set if file is shelved ///
headAction -- action at head rev, if in depot ///
headChange -- head rev changelist#, if in depot ///
headRev -- head rev #, if in depot ///
headType -- head rev type, if in depot ///
headCharset -- head charset, for unicode type ///
headTime -- head rev changelist time, if in depot ///
headModTime -- head rev mod time, if in depot ///
movedRev -- head rev # of moved file ///
haveRev -- rev had on client, if on client ///
desc -- change description ///
digest -- MD5 digest (fingerprint) ///
fileSize -- file size ///
action -- open action, if opened ///
type -- open type, if opened ///
charset -- open charset, for unicode type ///
actionOwner -- user who opened file, if opened ///
change -- open changelist#, if opened ///
resolved -- resolved integration records ///
unresolved -- unresolved integration records ///
reresolvable -- reresolvable integration records ///
otherOpen -- set if someone else has it open ///
otherOpen# -- list of user@client with file opened ///
otherLock -- set if someone else has it locked ///
otherLock# -- user@client with file locked ///
otherAction# -- open action, if opened by someone else ///
otherChange# -- changelist, if opened by someone else ///
openattr-<name> -- attribute value for <name> ///
openattrProp-<name> -- set if attribute <name> is propagating ///
ourLock -- set if this user/client has it locked ///
resolveAction# -- pending integration record action ///
resolveBaseFile# -- pending integration base file ///
resolveBaseRev# -- pending integration base rev ///
resolveFromFile# -- pending integration from file ///
resolveStartFromRev# -- pending integration from start rev ///
resolveEndFromRev# -- pending integration from end rev ///
totalFileCount -- total no. of files, if sorted ///
///
The -A <pattern> flag restricts displayed attributes to those ///
that match 'pattern'. ///
///
The -F flag lists only files satisfying the filter expression. This ///
filter syntax is similar to the one used for 'jobs -e jobview' and is ///
used to evaluate the contents of the fields in the preceding list. ///
Filtering is case-sensitive. ///
///
Example: -Ol -F "fileSize > 1000000 & headType=text" ///
///
Note: filtering is not optimized with indexes for performance. ///
///
The -L flag can be used with multiple file arguments that are in ///
full depot syntax and include a valid revision number. When this ///
flag is used the arguments are processed together by building an ///
internal table similar to a label. This file list processing is ///
significantly faster than having to call the internal query engine ///
for each individual file argument. However, the file argument syntax ///
is strict and the command will not run if an error is encountered. ///
///
The -T fields flag returns only the specified fields. The field names ///
can be specified using a comma- or space-delimited list. ///
///
Example: -Ol -T "depotFile, fileSize" ///
///
The -m max flag limits output to the specified number of files. ///
///
The -r flag sorts the output in reverse order. ///
///
The -c changelist# flag displays files modified after the specified ///
changelist was submitted. This operation is much faster than using ///
a revision range on the affected files. ///
///
The -e changelist# flag lists files modified by the specified ///
changelist. When used with the -Ro flag, only pending changes are ///
considered, to ensure that files opened for add are included. This ///
option also displays the change description. ///
///
The -O options modify the output as follows: ///
///
-Oa output attributes set by 'p4 attribute'. ///
///
-Od output the digest of the attribute. ///
///
-Oe output attribute values encoded as hex ///
///
-Of output all revisions for the given files (this ///
option suppresses other* and resolve* fields) ///
///
-Ol output a fileSize and digest field for each revision ///
(this may be expensive to compute) ///
///
-Op output the local file path in both Perforce syntax ///
(//client/) as 'clientFile' and host form as 'path' ///
///
-Or output pending integration record information for ///
files opened on the current client, or if used with ///
'-e <change> -Rs', on the shelved change ///
///
-Os exclude client-related data from output ///
///
The -R option limits output to specific files: ///
///
-Rc files mapped in the client view ///
-Rh files synced to the client workspace ///
-Rn files opened not at the head revision ///
-Ro files opened ///
-Rr files opened that have been resolved ///
-Rs files shelved (requires -e) ///
-Ru files opened that need resolving ///
///
The -S option changes the order of output: ///
///
-St sort by filetype ///
-Sd sort by date ///
-Sr sort by head revision ///
-Sh sort by have revision ///
-Ss sort by filesize ///
///
The -U flag displays information about unload files in the unload ///
depot (see 'p4 help unload'). ///
///
For compatibility, the following flags are also supported: ///
-C (-Rc) -H (-Rh) -W (-Ro) -P (-Op) -l (-Ol) -s (-Os). ///
///
///
/// /// To get FileMetaData for //depot/ReadMe.txt: /// /// /// FileSpec fs = new FileSpec(new DepotPath("//depot/MyCode/ReadMe.txt"), null); /// IList<FileSpec> lfs = new List<FileSpec>(); /// lfs.Add(fs); /// /// GetFileMetaDataCmdOptions opts = /// new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.None, /// null, null, 0, null, null, null); /// /// IList<FileMetaData> target = Repository.GetFileMetaData(lfs, opts); /// /// To get FileMetaData for files in the depot that need resolving: /// /// /// FileSpec fs = new FileSpec(new DepotPath("//..."), null); /// IList<FileSpec> lfs = new List<FileSpec>(); /// lfs.Add(fs); /// /// GetFileMetaDataCmdOptions opts = /// new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.NeedsResolve, /// null, null, 0, null, null, null); /// /// IList<FileMetaData> target = Repository.GetFileMetaData(lfs, opts); /// /// To get FileMetaData for files in the depot that are over a specific file /// size and of file type, text: /// /// /// FileSpec fs = new FileSpec(new DepotPath("//..."), null); /// IList<FileSpec> lfs = new List<FileSpec>(); /// lfs.Add(fs); /// /// GetFileMetaDataCmdOptions opts = /// new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.None, /// "fileSize > 1000000 & headType=text", null, 0, null, null, null); /// /// IList<FileMetaData> target = Repository.GetFileMetaData(lfs, opts); /// /// To get FileMetaData for files in the depot that have been modified at or /// after changelist 20345 and are mapped to the client view: /// /// /// FileSpec fs = new FileSpec(new DepotPath("//..."), null); /// IList<FileSpec> lfs = new List<FileSpec>(); /// lfs.Add(fs); /// /// GetFileMetaDataCmdOptions opts = /// new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.ClientMapped, /// null, null, 20345, null, null, null); /// /// IList<FileMetaData> target = Repository.GetFileMetaData(lfs, opts); /// /// To get FileMetaData for files in the depot including attributes which match /// the pattern "tested": /// /// /// FileSpec fs = new FileSpec(new DepotPath("//..."), null); /// IList<FileSpec> lfs = new List<FileSpec>(); /// lfs.Add(fs); /// /// GetFileMetaDataCmdOptions opts = /// new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.Attributes, /// null, null, 0, null, null, "tested"); /// /// IList<FileMetaData> target = Repository.GetFileMetaData(lfs, opts); /// /// /// public IList GetFileMetaData(IList filespecs, Options options) { return GetFileMetaData(options, filespecs.ToArray()); } /// /// Return a list of Files in the depot that correspond to the passed-in /// FileSpecs. /// /// ///
p4 help files ///
///
files -- List files in the depot ///
///
p4 files [ -a ] [ -A ] [ -e ] [ -m max ] file[revRange] ... ///
p4 files -U unloadfile ... ///
///
List details about specified files: depot file name, revision, ///
file, type, change action and changelist number of the current ///
head revision. If client syntax is used to specify the file ///
argument, the client view mapping is used to determine the ///
corresponding depot files. ///
///
By default, the head revision is listed. If the file argument ///
specifies a revision, then all files at that revision are listed. ///
If the file argument specifies a revision range, the highest revision ///
in the range is used for each file. For details about specifying ///
revisions, see 'p4 help revisions'. ///
///
The -a flag displays all revisions within the specific range, rather ///
than just the highest revision in the range. ///
///
The -A flag displays files in archive depots. ///
///
The -e flag displays files with an action of anything other than ///
deleted, purged or archived. Typically this revision is always ///
available to sync or integrate from. ///
///
The -m flag limits files to the first 'max' number of files. ///
///
The -U option displays files in the unload depot (see 'p4 help unload' ///
for more information about the unload depot). ///
///
///
/// /// To get Files in local depot //depot/...: /// /// GetDepotFilesCmdOptions opts = /// new GetDepotFilesCmdOptions(GetDepotFilesCmdFlags.None, 0); /// /// FileSpec fs = new FileSpec(new DepotPath("//depot/..."), null); /// /// IList<File> target = Repository.GetFiles(opts, fs); /// /// To get Files in unload depot //Unloaded/...: /// /// GetDepotFilesCmdOptions opts = /// new GetDepotFilesCmdOptions(GetDepotFilesCmdFlags.InUnloadDepot, 0); /// /// FileSpec fs = new FileSpec(new DepotPath("//Unloaded/..."), null); /// /// IList<File> target = Repository.GetFiles(opts, fs); /// /// /// public IList GetFiles(Options options, params FileSpec[] filespecs) { P4.P4Command fstatCmd = new P4Command(this, "files", true, FileSpec.ToStrings(filespecs)); P4.P4CommandResult r = fstatCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } List value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { File val = new File(); val.ParseFilesCmdTaggedData(obj); value.Add(val); } return value; } /// /// Return a list of Files in the depot that correspond to the passed-in /// FileSpecs. /// /// ///
p4 help files ///
///
files -- List files in the depot ///
///
p4 files [ -a ] [ -A ] [ -e ] [ -m max ] file[revRange] ... ///
p4 files -U unloadfile ... ///
///
List details about specified files: depot file name, revision, ///
file, type, change action and changelist number of the current ///
head revision. If client syntax is used to specify the file ///
argument, the client view mapping is used to determine the ///
corresponding depot files. ///
///
By default, the head revision is listed. If the file argument ///
specifies a revision, then all files at that revision are listed. ///
If the file argument specifies a revision range, the highest revision ///
in the range is used for each file. For details about specifying ///
revisions, see 'p4 help revisions'. ///
///
The -a flag displays all revisions within the specific range, rather ///
than just the highest revision in the range. ///
///
The -A flag displays files in archive depots. ///
///
The -e flag displays files with an action of anything other than ///
deleted, purged or archived. Typically this revision is always ///
available to sync or integrate from. ///
///
The -m flag limits files to the first 'max' number of files. ///
///
The -U option displays files in the unload depot (see 'p4 help unload' ///
for more information about the unload depot). ///
///
///
/// /// To get Files in local depot //depot/...: /// /// FileSpec fs = new FileSpec(new DepotPath("//depot/..."), null); /// IList<FileSpec> lfs = new List<FileSpec>(); /// lfs.Add(fs); /// /// GetDepotFilesCmdOptions opts = /// new GetDepotFilesCmdOptions(GetDepotFilesCmdFlags.None, 0); /// /// IList<File> target = Repository.GetFiles(lfs, opts); /// /// To get Files in unload depot //Unloaded/...: /// /// FileSpec fs = new FileSpec(new DepotPath("//Unloaded/..."), null); /// IList<FileSpec> lfs = new List<FileSpec>(); /// lfs.Add(fs); /// /// GetDepotFilesCmdOptions opts = /// new GetDepotFilesCmdOptions(GetDepotFilesCmdFlags.InUnloadDepot, 0); /// /// IList<File> target = Repository.GetFiles(lfs, opts); /// /// /// public IList GetFiles(IList filespecs, Options options) { return GetFiles(options, filespecs.ToArray()); } /// /// List selected directory paths in the repository. /// /// /// /// /// ///
p4 help dirs ///
///
dirs -- List depot subdirectories ///
///
p4 dirs [-C -D -H] [-S stream] dir[revRange] ... ///
///
List directories that match the specified file pattern (dir). ///
This command does not support the recursive wildcard (...). ///
Use the * wildcard instead. ///
///
Perforce does not track directories individually. A path is treated ///
as a directory if there are any undeleted files with that path as a ///
prefix. ///
///
By default, all directories containing files are listed. If the dir ///
argument includes a revision range, only directories containing files ///
in the range are listed. For details about specifying file revisions, ///
see 'p4 help revisions'. ///
///
The -C flag lists only directories that fall within the current ///
client view. ///
///
The -D flag includes directories containing only deleted files. ///
///
The -H flag lists directories containing files synced to the current ///
client workspace. ///
///
The -S flag limits output to depot directories mapped in a stream's ///
client view. ///
///
///
/// /// To get dirs on the server that fall within the current client view: /// /// GetDepotDirsCmdOptions opts = /// new GetDepotDirsCmdOptions(GetDepotDirsCmdFlags.CurrentClientOnly, null); /// /// IList<String> target = Repository.GetDepotDirs(opts, "//* ); /// /// To get dirs on the server that contain files synced to the current /// client workspace: /// /// GetDepotDirsCmdOptions opts = /// new GetDepotDirsCmdOptions(GetDepotDirsCmdFlags.SyncedDirs, null); /// /// IList<String> target = Repository.GetDepotDirs(opts, "//* ); /// /// To get dirs on the server that fall under the path //depot/main/: /// /// GetDepotDirsCmdOptions opts = /// new GetDepotDirsCmdOptions(GetDepotDirsCmdFlags.None, null); /// /// IList<String> target = Repository.GetDepotDirs(opts, "//depot/main/* ); /// /// /// public IList GetDepotDirs(Options options, params string[] dirs) { P4.P4Command dirsCmd = new P4Command(this, "dirs", false, dirs); P4.P4CommandResult r = dirsCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } List value = new List(); foreach (P4.P4ClientInfoMessage l in r.InfoOutput) { value.Add(l.Message); } return value; } /// /// List selected directory paths in the repository. /// /// /// /// /// ///
p4 help dirs ///
///
dirs -- List depot subdirectories ///
///
p4 dirs [-C -D -H] [-S stream] dir[revRange] ... ///
///
List directories that match the specified file pattern (dir). ///
This command does not support the recursive wildcard (...). ///
Use the * wildcard instead. ///
///
Perforce does not track directories individually. A path is treated ///
as a directory if there are any undeleted files with that path as a ///
prefix. ///
///
By default, all directories containing files are listed. If the dir ///
argument includes a revision range, only directories containing files ///
in the range are listed. For details about specifying file revisions, ///
see 'p4 help revisions'. ///
///
The -C flag lists only directories that fall within the current ///
client view. ///
///
The -D flag includes directories containing only deleted files. ///
///
The -H flag lists directories containing files synced to the current ///
client workspace. ///
///
The -S flag limits output to depot directories mapped in a stream's ///
client view. ///
///
///
/// /// To get dirs on the server that fall within the current client view: /// /// GetDepotDirsCmdOptions opts = /// new GetDepotDirsCmdOptions(GetDepotDirsCmdFlags.CurrentClientOnly, null); /// /// IList<String> dirs = new List<String>() /// dirs.Add("//*"); /// /// IList<String> target = Repository.GetDepotDirs(dirs, opts); /// /// To get dirs on the server that contain files synced to the current /// client workspace: /// /// GetDepotDirsCmdOptions opts = /// new GetDepotDirsCmdOptions(GetDepotDirsCmdFlags.SyncedDirs, null); /// /// IList<String> dirs = new List<String>() /// dirs.Add("//*"); /// /// IList<String> target = Repository.GetDepotDirs(dirs, opts); /// /// To get dirs on the server that fall under the path //depot/main/: /// /// GetDepotDirsCmdOptions opts = /// new GetDepotDirsCmdOptions(GetDepotDirsCmdFlags.None, null); /// /// IList<String> dirs = new List<String>() /// dirs.Add("//depot/main/*"); /// /// IList<String> target = Repository.GetDepotDirs(dirs, opts); /// /// /// public IList GetDepotDirs(IList dirs, Options options) { return GetDepotDirs(options, dirs.ToArray()); } /// /// Return the contents of the files identified by the passed-in file specs. /// /// /// /// /// GetFileContents /// ///
p4 help print ///
///
print -- Write a depot file to standard output ///
///
p4 print [-a -o localFile -q] file[revRange] ... ///
///
Retrieve the contents of a depot file to the client's standard output. ///
The file is not synced. If file is specified using client syntax, ///
Perforce uses the client view to determine the corresponding depot ///
file. ///
///
By default, the head revision is printed. If the file argument ///
includes a revision, the specified revision is printed. If the ///
file argument has a revision range, then only files selected by ///
that revision range are printed, and the highest revision in the ///
range is printed. For details about revision specifiers, see 'p4 ///
help revisions'. ///
///
The -a flag prints all revisions within the specified range, rather ///
than just the highest revision in the range. ///
///
The -o localFile flag redirects the output to the specified file on ///
the client filesystem. ///
///
The -q flag suppresses the initial line that displays the file name ///
and revision. ///
///
///
/// /// To get the contents of the file //depot/MyCode/README.txt: /// /// GetFileContentsCmdOptions opts = /// new GetFileContentsCmdOptions(GetFileContentsCmdFlags.None, null); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// /// IList<String> target = Repository.GetFileContents(opts, filespec); /// /// To get the contents of the file //depot/MyCode/README.txt redirecting the /// contents to local file C:\Doc\README.txt and supressing the file name /// and revision line: /// /// GetFileContentsCmdOptions opts = /// new GetFileContentsCmdOptions(GetFileContentsCmdFlags.Suppress, /// "C:\\Doc\\README.txt"); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// /// IList<String> target = Repository.GetFileContents(opts, filespec); /// /// /// public IList GetFileContents(Options options, params FileSpec[] filespecs) { P4.P4Command printCmd = new P4Command(this, "print", true, FileSpec.ToEscapedStrings(filespecs)); P4.P4CommandResult r = printCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } IList value = new List(); if (r.TaggedOutput != null) { if ((options == null) || (options.ContainsKey("-q") == false)) { foreach (P4.TaggedObject obj in r.TaggedOutput) { string path = string.Empty; string rev = string.Empty; if (obj.ContainsKey("depotFile")) { value.Add(obj["depotFile"]); } } } } value.Add(r.TextOutput); return value; } /// /// Return the contents of the files identified by the passed-in file specs. /// /// /// /// /// GetFileContents /// ///
p4 help print ///
///
print -- Write a depot file to standard output ///
///
p4 print [-a -o localFile -q] file[revRange] ... ///
///
Retrieve the contents of a depot file to the client's standard output. ///
The file is not synced. If file is specified using client syntax, ///
Perforce uses the client view to determine the corresponding depot ///
file. ///
///
By default, the head revision is printed. If the file argument ///
includes a revision, the specified revision is printed. If the ///
file argument has a revision range, then only files selected by ///
that revision range are printed, and the highest revision in the ///
range is printed. For details about revision specifiers, see 'p4 ///
help revisions'. ///
///
The -a flag prints all revisions within the specified range, rather ///
than just the highest revision in the range. ///
///
The -o localFile flag redirects the output to the specified file on ///
the client filesystem. ///
///
The -q flag suppresses the initial line that displays the file name ///
and revision. ///
///
///
/// /// To get the contents of the file //depot/MyCode/README.txt: /// /// GetFileContentsCmdOptions opts = /// new GetFileContentsCmdOptions(GetFileContentsCmdFlags.None, null); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<String> target = Repository.GetFileContents(filespecs, opts); /// /// To get the contents of the file //depot/MyCode/README.txt redirecting the /// contents to local file C:\Doc\README.txt and supressing the file name /// and revision line: /// /// GetFileContentsCmdOptions opts = /// new GetFileContentsCmdOptions(GetFileContentsCmdFlags.Suppress, /// "C:\\Doc\\README.txt"); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<String> target = Repository.GetFileContents(filespecs, opts); /// /// /// public IList GetFileContents(IList filespecs, Options options) { return GetFileContents(options, filespecs.ToArray()); } /// /// Return the contents of the files identified by the passed-in file specs. /// /// /// /// /// GetFileContentsEx /// ///
p4 help print ///
///
print -- Write a depot file to standard output ///
///
p4 print [-a -o localFile -q] file[revRange] ... ///
///
Retrieve the contents of a depot file to the client's standard output. ///
The file is not synced. If file is specified using client syntax, ///
Perforce uses the client view to determine the corresponding depot ///
file. ///
///
By default, the head revision is printed. If the file argument ///
includes a revision, the specified revision is printed. If the ///
file argument has a revision range, then only files selected by ///
that revision range are printed, and the highest revision in the ///
range is printed. For details about revision specifiers, see 'p4 ///
help revisions'. ///
///
The -a flag prints all revisions within the specified range, rather ///
than just the highest revision in the range. ///
///
The -o localFile flag redirects the output to the specified file on ///
the client filesystem. ///
///
The -q flag suppresses the initial line that displays the file name ///
and revision. ///
///
///
/// /// To get the contents of the file //depot/MyCode/README.txt: /// /// GetFileContentsCmdOptions opts = /// new GetFileContentsCmdOptions(GetFileContentsCmdFlags.None, null); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// /// IList<String> target = Repository.GetFileContents(opts, filespec); /// /// To get the contents of the file //depot/MyCode/README.txt redirecting the /// contents to local file C:\Doc\README.txt and supressing the file name /// and revision line: /// /// GetFileContentsCmdOptions opts = /// new GetFileContentsCmdOptions(GetFileContentsCmdFlags.Suppress, /// "C:\\Doc\\README.txt"); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// /// IList<String> target = Repository.GetFileContents(opts, filespec); /// /// /// public IList GetFileContentsEx(Options options, params FileSpec[] filespecs) { P4.P4Command printCmd = new P4Command(this, "print", true, FileSpec.ToEscapedStrings(filespecs)); P4.P4CommandResult r = printCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } IList value = new List(); if (r.TaggedOutput != null) { if ((options == null) || (options.ContainsKey("-q") == false)) { foreach (P4.TaggedObject obj in r.TaggedOutput) { string path = string.Empty; string revStr = string.Empty; int rev = -1; if (obj.ContainsKey("depotFile")) { string s = obj["depotFile"]; int idx = s.LastIndexOf('#'); if (idx > 0) { path = s.Substring(0, idx); revStr = s.Substring(idx + 1); int.TryParse(revStr, out rev); } else { path = s; } if (rev >= 0) { value.Add(FileSpec.DepotSpec(path, rev)); } else { value.Add(FileSpec.DepotSpec(path)); } } } } } if (r.BinaryOutput != null) { value.Add(r.BinaryOutput); } else { value.Add(r.TextOutput); } return value; } /// /// Return the contents of the files identified by the passed-in file specs. /// /// /// /// /// GetFileContentsEx /// ///
p4 help print ///
///
print -- Write a depot file to standard output ///
///
p4 print [-a -o localFile -q] file[revRange] ... ///
///
Retrieve the contents of a depot file to the client's standard output. ///
The file is not synced. If file is specified using client syntax, ///
Perforce uses the client view to determine the corresponding depot ///
file. ///
///
By default, the head revision is printed. If the file argument ///
includes a revision, the specified revision is printed. If the ///
file argument has a revision range, then only files selected by ///
that revision range are printed, and the highest revision in the ///
range is printed. For details about revision specifiers, see 'p4 ///
help revisions'. ///
///
The -a flag prints all revisions within the specified range, rather ///
than just the highest revision in the range. ///
///
The -o localFile flag redirects the output to the specified file on ///
the client filesystem. ///
///
The -q flag suppresses the initial line that displays the file name ///
and revision. ///
///
///
/// /// To get the contents of the file //depot/MyCode/README.txt: /// /// GetFileContentsCmdOptions opts = /// new GetFileContentsCmdOptions(GetFileContentsCmdFlags.None, null); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<String> target = Repository.GetFileContents(filespecs, opts); /// /// To get the contents of the file //depot/MyCode/README.txt redirecting the /// contents to local file C:\Doc\README.txt and supressing the file name /// and revision line: /// /// GetFileContentsCmdOptions opts = /// new GetFileContentsCmdOptions(GetFileContentsCmdFlags.Suppress, /// "C:\\Doc\\README.txt"); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<String> target = Repository.GetFileContents(filespecs, opts); /// /// /// public IList GetFileContentsEx(IList filespecs, Options options) { return GetFileContentsEx(options, filespecs.ToArray()); } /// /// Get the revision history data for the passed-in file specs. /// /// /// /// /// ///
p4 help filelog ///
///
filelog -- List revision history of files ///
///
p4 filelog [-c changelist# -h -i -l -L -t -m maxRevs -s] file[revRange] ... ///
///
List the revision history of the specified files, from the most ///
recent revision to the first. If the file specification includes ///
a revision, the command lists revisions at or prior to the specified ///
revision. If the file specification includes a revision range, ///
the command lists only the specified revisions. See 'p4 help revisions' ///
for details. ///
///
The -c changelist# flag displays files submitted at the specified ///
changelist number. ///
///
The -i flag includes inherited file history. If a file was created by ///
branching (using 'p4 integrate'), filelog lists the revisions of the ///
file's ancestors up to the branch points that led to the specified ///
revision. File history inherited by renaming (using 'p4 move') is ///
always displayed regardless of whether -i is specified. ///
///
The -h flag displays file content history instead of file name ///
history. The list includes revisions of other files that were ///
branched or copied (using 'p4 integrate' and 'p4 resolve -at') to ///
the specified revision. Revisions that were replaced by copying ///
or branching are omitted, even if they are part of the history of ///
the specified revision. ///
///
The -t flag displays the time as well as the date. ///
///
The -l flag lists the full text of the changelist descriptions. ///
///
The -L flag lists the full text of the changelist descriptions, ///
truncated to 250 characters if longer. ///
///
The -m maxRevs displays at most 'maxRevs' revisions per file of ///
the file[rev] argument specified. ///
///
The -s flag displays a shortened form of filelog that omits ///
non-contributory integrations. ///
///
///
/// /// To get the file history of the file //depot/MyCode/README.txt /// submitted at change 43578 and showing the full changelist description: /// /// GetFileHistoryCmdOptions opts = /// new GetFileHistoryCmdOptions(GetFileHistoryCmdFlags.FullDescription /// 43578, 0); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// /// IList<String> target = Repository.GetFileHistory(opts, filespec); /// /// To get the file history of the file //depot/MyCode/README.txt /// showing both time and date for the 10 latest revisions: /// /// GetFileHistoryCmdOptions opts = /// new GetFileHistoryCmdOptions(GetFileHistoryCmdFlags.Time, /// 0, 10) /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// /// IList<String> target = Repository.GetFileHistory(opts, filespec); /// /// /// /// public IList GetFileHistory(Options options, params FileSpec[] filespecs) { P4.P4Command filesCmd = new P4Command(this, "filelog", true, FileSpec.ToEscapedStrings(filespecs)); P4.P4CommandResult r = filesCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } IList value = new List(); bool dst_mismatch = false; string offset = string.Empty; if (Server != null && Server.Metadata != null) { offset = Server.Metadata.DateTimeOffset; dst_mismatch = FormBase.DSTMismatch(Server.Metadata); } foreach (P4.TaggedObject obj in r.TaggedOutput) { int idx = 0; while (true) { string key = String.Format("rev{0}", idx); int revision = -1; if (obj.ContainsKey(key)) int.TryParse(obj[key], out revision); else break; int changelistid = -1; key = String.Format("change{0}", idx); if (obj.ContainsKey(key)) int.TryParse(obj[key], out changelistid); StringEnum action = "None"; key = String.Format("action{0}", idx); if (obj.ContainsKey(key)) action = obj[key]; DateTime date = new DateTime(); long unixTime = 0; key = String.Format("time{0}", idx); if (obj.ContainsKey(key)) unixTime = Int64.Parse(obj[key]); DateTime UTC = FormBase.ConvertUnixTime(unixTime); DateTime GMT = new DateTime(UTC.Year, UTC.Month, UTC.Day, UTC.Hour, UTC.Minute, UTC.Second, DateTimeKind.Unspecified); date = FormBase.ConvertFromUTC(GMT, offset, dst_mismatch); string username = null; key = String.Format("user{0}", idx); if (obj.ContainsKey(key)) username = obj[key]; string description = null; key = String.Format("desc{0}", idx); if (obj.ContainsKey(key)) description = obj[key]; string digest = null; key = String.Format("digest{0}", idx); if (obj.ContainsKey(key)) digest = obj[key]; long filesize = -1; key = String.Format("fileSize{0}", idx); if (obj.ContainsKey(key)) long.TryParse(obj[key], out filesize); string clientname = null; key = String.Format("client{0}", idx); if (obj.ContainsKey(key)) clientname = obj[key]; PathSpec depotpath = new DepotPath(obj["depotFile"]); FileType filetype = null; key = String.Format("type{0}", idx); if (obj.ContainsKey(key)) filetype = new FileType(obj[key]); List integrationsummaries = new List(); int idx2 = 0; key = String.Format("how{0},{1}", idx, idx2); while (obj.ContainsKey(key)) { string how = obj[key]; key = String.Format("file{0},{1}", idx, idx2); string frompath = obj[key]; key = String.Format("srev{0},{1}", idx, idx2); string srev = obj[key]; VersionSpec startrev = new Revision(-1); if (srev.StartsWith("#h") | srev.StartsWith("#n")) { if (srev.Contains("#none")) { startrev = Revision.None; } if (srev.Contains("#have")) { startrev = Revision.Have; } if (srev.Contains("#head")) { startrev = Revision.Head; } } else { srev = srev.Trim('#'); int rev = Convert.ToInt16(srev); startrev = new Revision(rev); } key = String.Format("erev{0},{1}", idx, idx2); string erev = obj[key]; VersionSpec endrev = new Revision(-1); if (erev.StartsWith("#h") | erev.StartsWith("#n")) { if (erev.Contains("#none")) { endrev = Revision.None; } if (srev.Contains("#have")) { endrev = Revision.Have; } if (srev.Contains("#head")) { endrev = Revision.Head; } } else { erev = erev.Trim('#'); int rev = Convert.ToInt16(erev); endrev = new Revision(rev); } RevisionIntegrationSummary integrationsummary = new RevisionIntegrationSummary( new FileSpec(new DepotPath(frompath), new VersionRange(startrev, endrev)), how); integrationsummaries.Add(integrationsummary); idx2++; key = String.Format("how{0},{1}", idx, idx2); } FileHistory fh = new FileHistory(revision, changelistid, action, date, username, filetype, description, digest, filesize, depotpath, clientname, integrationsummaries); value.Add(fh); idx++; } } return value; } /// /// Get the revision history data for the passed-in file specs. /// /// /// /// /// ///
p4 help filelog ///
///
filelog -- List revision history of files ///
///
p4 filelog [-c changelist# -h -i -l -L -t -m maxRevs -s] file[revRange] ... ///
///
List the revision history of the specified files, from the most ///
recent revision to the first. If the file specification includes ///
a revision, the command lists revisions at or prior to the specified ///
revision. If the file specification includes a revision range, ///
the command lists only the specified revisions. See 'p4 help revisions' ///
for details. ///
///
The -c changelist# flag displays files submitted at the specified ///
changelist number. ///
///
The -i flag includes inherited file history. If a file was created by ///
branching (using 'p4 integrate'), filelog lists the revisions of the ///
file's ancestors up to the branch points that led to the specified ///
revision. File history inherited by renaming (using 'p4 move') is ///
always displayed regardless of whether -i is specified. ///
///
The -h flag displays file content history instead of file name ///
history. The list includes revisions of other files that were ///
branched or copied (using 'p4 integrate' and 'p4 resolve -at') to ///
the specified revision. Revisions that were replaced by copying ///
or branching are omitted, even if they are part of the history of ///
the specified revision. ///
///
The -t flag displays the time as well as the date. ///
///
The -l flag lists the full text of the changelist descriptions. ///
///
The -L flag lists the full text of the changelist descriptions, ///
truncated to 250 characters if longer. ///
///
The -m maxRevs displays at most 'maxRevs' revisions per file of ///
the file[rev] argument specified. ///
///
The -s flag displays a shortened form of filelog that omits ///
non-contributory integrations. ///
///
///
/// /// To get the file history of the file //depot/MyCode/README.txt /// submitted at change 43578 and showing the full changelist description: /// /// GetFileHistoryCmdOptions opts = /// new GetFileHistoryCmdOptions(GetFileHistoryCmdFlags.FullDescription /// 43578, 0); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<String> target = Repository.GetFileHistory(filespecs, opts); /// /// To get the file history of the file //depot/MyCode/README.txt /// showing both time and date for the 10 latest revisions: /// /// GetFileHistoryCmdOptions opts = /// new GetFileHistoryCmdOptions(GetFileHistoryCmdFlags.Time, /// 0, 10) /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<String> target = Repository.GetFileHistory(filespecs, opts); /// /// /// /// public IList GetFileHistory(IList filespecs, Options options) { return GetFileHistory(options, filespecs.ToArray()); } /// /// Get content and existence diff details for two depot files. /// /// /// /// /// /// ///
p4 help diff2 ///
///
diff2 -- Compare one set of depot files to another ///
///
p4 diff2 [options] fromFile[rev] toFile[rev] ///
p4 diff2 [options] -b branch [[fromFile[rev]] toFile[rev]] ///
p4 diff2 [options] -S stream [-P parent] [[fromFile[rev]] toFile[rev]] ///
///
options: -d<flags>> -Od -q -t -u ///
///
'p4 diff2' runs on the server to compare one set of depot files (the ///
'source') to another (the 'target'). Source and target file sets ///
can be specified on the 'p4 diff2' command line or through a branch ///
view. ///
///
With a branch view, fromFile and toFile are optional; fromFile limits ///
the scope of the source file set, and toFile limits the scope of the ///
target. If only one file argument is given, it is assumed to be ///
toFile. ///
///
fromFile and toFile can include revision specifiers; by default, the ///
head revisions are diffed. See 'p4 help revisions' for details ///
about specifying file revisions. ///
///
'p4 diff2' precedes each diffed file pair with a header line of the ///
following form: ///
///
==== source#rev (type) - target#rev (type) ==== summary ///
///
A source or target file shown as '<none>' means there is no file ///
at the specified name or revision to pair with its counterpart. ///
The summary status is one of the following: 'identical' means file ///
contents and types are identical, 'types' means file contents are ///
identical but the types are different, and 'content' means file ///
contents are different. ///
///
The -b flag makes 'p4 diff2' use a user-defined branch view. (See ///
'p4 help branch'.) The left side of the branch view is the source ///
and the right side is the target. ///
///
The -S flag makes 'p4 diff2' use a generated branch view that maps ///
a stream (or its underlying real stream) to its parent. -P can be ///
used to generate the branch view using a parent stream other than ///
the stream's actual parent. ///
///
The -d<flags> modify the output of diffs as follows: ///
///
-dn (RCS) ///
-dc[n] (context) ///
-ds (summary) ///
-du[n] (unified) ///
-db (ignore whitespace changes) ///
-dw (ignore whitespace) ///
-dl (ignore line endings). ///
///
The optional argument to -dc/-du specifies number of context lines. ///
///
The -Od flag limits output to files that differ. ///
///
The -q omits files that have identical content and types and ///
suppresses the actual diff for all files. ///
///
The -t flag forces 'p4 diff2' to diff binary files. ///
///
The -u flag uses the GNU diff -u format and displays only files ///
that differ. The file names and dates are in Perforce syntax, but ///
the output can be used by the patch program. ///
///
///
/// /// To get the depot file diffs between //depot/main/Program.cs and /// //depot/rel/Program.cs and ignore whitespace changes: /// /// GetDepotFileDiffsCmdOptions opts = /// new GetDepotFileDiffsCmdOptions(GetDepotFileDiffsCmdFlags.IgnoreWhitespaceChanges, /// 0, 0, null,null,null); /// /// IList<DepotFileDiff> target = /// Repository.GetDepotFileDiffs(//depot/main/Program.cs, /// //depot/rel/Program.cs, opts); /// /// To get the depot files that differ between all files under //depot/main/... and /// //depot/rel/... and display in GNU format only listing files that differ: /// /// GetDepotFileDiffsCmdOptions opts = /// new GetDepotFileDiffsCmdOptions(GetDepotFileDiffsCmdFlags.GNU, /// 0, 0, null,null,null); /// /// IList<DepotFileDiff> target = /// Repository.GetDepotFileDiffs(//depot/main/..., //depot/rel/..., opts); /// /// /// public IList GetDepotFileDiffs(string filespecleft, string filespecright, Options options) { P4.P4Command GetDepotFileDiffs = new P4Command(this, "diff2", true, filespecleft, filespecright); P4.P4CommandResult r = GetDepotFileDiffs.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } IList value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { DepotFileDiff val = new DepotFileDiff(); val.FromGetDepotFileDiffsCmdTaggedOutput(obj, _connection, options); value.Add(val); } return value; } /// /// Return FileAnnotation objects for the listed FileSpecs. /// /// /// /// /// ///
p4 help annotate ///
///
annotate -- Print file lines and their revisions ///
///
p4 annotate [-aciIq -d<flags>] file[revRange] ... ///
///
Prints all lines of the specified files, indicating the revision that ///
introduced each line into the file. ///
///
If the file argument includes a revision, then only revisions up to ///
the specified revision are displayed. If the file argument has a ///
revision range, only revisions within that range are displayed. For ///
details about specifying revisions, see 'p4 help revisions'. ///
///
The -a flag includes both deleted files and lines no longer present ///
at the head revision. In the latter case, both the starting and ending ///
revision for each line is displayed. ///
///
The -c flag directs the annotate command to output changelist numbers ///
rather than revision numbers for each line. ///
///
The -d<flags> change the way whitespace and/or line endings are ///
treated: -db (ignore whitespace changes), -dw (ignore whitespace), ///
-dl (ignore line endings). ///
///
The -i flag follows branches. If a file was created by branching, ///
'p4 annotate' includes the revisions of the source file up to the ///
branch point, just as 'p4 filelog -i' does. If a file has history ///
prior to being created by branching (such as a file that was branched ///
on top of a deleted file), -i ignores those prior revisions and ///
follows the source. -i implies -c. ///
///
The -I flag follows all integrations into the file. If a line was ///
introduced into the file by a merge, the source of the merge is ///
displayed as the changelist that introduced the line. If the source ///
itself was the result of an integration, that source is used instead, ///
and so on. -I implies -c. ///
///
The -q flag suppresses the one-line header that is displayed by ///
default for each file. ///
///
///
/// /// To get the file annotations of the file //depot/MyCode/README.txt: /// /// GetFileAnnotationsCmdOptions opts = /// new GetFileAnnotationsCmdOptions(GetFileAnnotationsCmdFlags.None, null); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<FileAnnotation> target = Repository.GetFileAnnotations(filespecs, opts); /// /// To get the file annotations of the file //depot/MyCode/README.txt redirecting the /// contents to local file C:\Doc\README.txt and supressing the one-line header: /// /// GetFileAnnotationsCmdOptions opts = /// new GetFileAnnotationsCmdOptions(GetFileAnnotationsCmdFlags.Suppress, /// "C:\\Doc\\README.txt"); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<FileAnnotation> target = Repository.GetFileAnnotations(filespecs, opts); /// /// /// public IList GetFileAnnotations(IList filespecs, Options options) { P4.P4Command annotateCmd = new P4Command(this, "annotate", true, FileSpec.ToStrings(filespecs)); P4.P4CommandResult r = annotateCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } bool changelist = false; string opts; if (options != null) { opts = options.Keys.ToString(); if (opts.Contains("c")) { changelist = true; } } string dp = null; string line = null; int lower = -1; int upper = -1; IList value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { if (obj.ContainsKey("depotFile")) { dp = obj["depotFile"]; line = null; lower = -1; upper = -1; continue; } if (obj.ContainsKey("lower")) { int l = -1; int.TryParse(obj["lower"], out l); lower = l; } if (obj.ContainsKey("upper")) { int u = -1; int.TryParse(obj["upper"], out u); upper = u; } if (obj.ContainsKey("data")) { line = obj["data"]; } if (dp != null && line != null && lower != -1 && upper != -1) { FileSpec fs = new FileSpec(); if (changelist == true) { fs = new FileSpec(new DepotPath(dp), new VersionRange(new ChangelistIdVersion(lower), new ChangelistIdVersion(upper))); } else { fs = new FileSpec(new DepotPath(dp), new VersionRange(new Revision(lower), new Revision(upper))); } FileAnnotation fa = new FileAnnotation(fs, line); value.Add(fa); } } return value; } /// /// Tag depot files with the passed-in label. /// /// /// /// /// /// ///
p4 help tag ///
///
tag -- Tag files with a label ///
///
p4 tag [-d -n] -l label file[revRange] ... ///
///
Tag associates the named label with the file revisions specified by ///
the file argument. After file revisions are tagged with a label, ///
revision specifications of the form '@label' can be used to refer ///
to them. ///
///
If the file argument does not include a revision specification, the ///
head revisions is tagged. See 'p4 help revisions' for revision ///
specification options. ///
///
If the file argument includes a revision range specification, only ///
the files with revisions in that range are tagged. Files with more ///
than one revision in the range are tagged at the highest revision. ///
///
The -d deletes the association between the specified files and the ///
label, regardless of revision. ///
///
The -n flag previews the results of the operation. ///
///
Tag can be used with an existing label (see 'p4 help labels') or ///
with a new one. An existing label can be used only by its owner, ///
and only if it is unlocked. (See 'p4 help label'). ///
///
To list the file revisions tagged with a label, use 'p4 files ///
@label'. ///
///
///
/// /// To tag the file //depot/MyCode/README.txt with build_label: /// /// TagCmdOptions opts = /// new TagCmdOptions(TagFilesCmdFlags.None, null); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<FileSpec> target = /// Repository.TagFiles(filespecs, "build_label", opts); /// /// To remove the association between the file //depot/MyCode/README.txt /// and build_label: /// /// TagCmdOptions opts = /// new TagCmdOptions(TagFilesCmdFlags.Delete, null); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/MyCode/README.txt"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<FileSpec> target = /// Repository.TagFiles(filespecs, "build_label", opts); /// /// To get a preview list of the files that would be tagged in path /// //depot/main/src with build_label: /// /// TagCmdOptions opts = /// new TagCmdOptions(TagFilesCmdFlags.ListOnly, null); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/main/src/..."), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<FileSpec> target = /// Repository.TagFiles(filespecs, "build_label", opts); /// /// /// public IList TagFiles(IList filespecs, string labelid, Options options) { P4.P4Command tagCmd = new P4Command(this, "tag", true, FileSpec.ToStrings(filespecs)); options["-l"] = labelid; P4.P4CommandResult r = tagCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } IList value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { string revision = obj["rev"]; int rev = Convert.ToInt16(revision); VersionSpec version = new Revision(rev); DepotPath path = new DepotPath(obj["depotFile"]); FileSpec fs = new FileSpec(path, version); value.Add(fs); } return value; } /// /// List fixes affecting files and / or jobs and / or changelists. /// /// /// /// /// ///
p4 help fixes ///
///
fixes -- List jobs with fixes and the changelists that fix them ///
///
p4 fixes [-i -m max -c changelist# -j jobName] [file[revRange] ...] ///
///
'p4 fixes' list fixed jobs and the number of the changelist that ///
contains the fix.Fixes are associated with changelists using the ///
'p4 fix' command or by editing and submitting changelists. ///
///
The 'p4 fixes' command lists both submitted and pending changelists. ///
///
By default, 'p4 fixes' lists all fixes. This list can be limited ///
as follows: to list fixes for a specified job, use the -j jobName ///
flag. To list fixes for a specified changelist, use -c changelist#. ///
To list fixes that affect specified files, include the file argument. ///
The file pattern can include wildcards and revision specifiers. For ///
details about revision specifiers, see 'p4 help revisions' ///
///
The -i flag also includes any fixes made by changelists integrated ///
into the specified files. ///
///
The -m max flag limits output to the specified number of job ///
fixes. ///
///
///
/// /// To list the fixes related to job000001: /// /// GetFixesCmdOptions opts = /// new GetFixesCmdOptions(GetFixesCmdFlags.None, 0, "job000001", 0); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//..."), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<Fix> target = Repository.GetFixes(filespecs, opts); /// /// To list the fixes related to changelist 47921: /// /// GetFixesCmdOptions opts = /// new GetFixesCmdOptions(GetFixesCmdFlags.None, 47921, null, 0); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//..."), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<Fix> target = Repository.GetFixes(filespecs, opts); /// /// To list the fixes related to path //depot/rel/src that occurred /// between 2014/1/1 and 2014/1/31: /// /// GetFixesCmdOptions opts = /// new GetFixesCmdOptions(GetFixesCmdFlags.None, 0, null, 0); /// /// VersionRange vr = new VersionRange(new DateTimeVersion(new DateTime(2014, 1, 1)), /// new DateTimeVersion(new DateTime(2014, 1, 31))); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//..."), vr); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<Fix> target = Repository.GetFixes(filespecs, opts); /// /// /// public IList GetFixes(IList filespecs, Options options) { P4.P4Command fixesCmd = new P4Command(this, "fixes", true, FileSpec.ToStrings(filespecs)); P4.P4CommandResult r = fixesCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } IList value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { bool dst_mismatch = false; string offset = string.Empty; if (Server != null && Server.Metadata != null) { offset = Server.Metadata.DateTimeOffset; dst_mismatch = FormBase.DSTMismatch(Server.Metadata); } value.Add(Fix.FromFixesCmdTaggedOutput(obj,offset,dst_mismatch)); } return value; } /// /// Get a list of matching lines in the passed-in file specs. /// /// /// /// /// /// ///
p4 help grep ///
///
grep -- Print lines matching a pattern ///
///
p4 grep [options] -e pattern file[revRange]... ///
///
options: -a -i -n -A <num> -B <num> -C <num> -t -s (-v|-l|-L) (-F|-G) ///
///
Searches files for lines that match the specified regular expression, ///
which can contain wildcards. The parser used by the Perforce server ///
is based on V8 regexp and might not be compatible with later parsers, ///
but the majority of functionality is available. ///
///
By default the head revision is searched. If the file argument includes ///
a revision specification, all corresponding revisions are searched. ///
If the file argument includes a revision range, only files in that ///
range are listed, and the highest revision in the range is searched. ///
For details about revision specifiers, see 'p4 help revisions'. ///
///
The -a flag searches all revisions within the specified range. By ///
default only the highest revision in the range is searched. ///
///
The -i flag causes the pattern matching to be case-insensitive. By ///
default, matching is case-sensitive. ///
///
The -n flag displays the matching line number after the file revision ///
number. By default, matches are displayed as revision#: <text>. ///
///
The -v flag displays files with non-matching lines. ///
///
The -F flag is used to interpret the pattern as a fixed string. ///
///
The -G flag is used to interpret the pattern as a regular expression, ///
which is the default behavior. ///
///
The -L flag displays the name of each selected file from which no ///
output would normally have been displayed. Scanning stops on the ///
first match. ///
///
The -l flag display the name of each selected file containing ///
matching text. Scanning stops on the first match. ///
///
The -s flag suppresses error messages that result from abandoning ///
files that have a maximum number of characters in a single line that ///
are greater than 4096. By default, an error is reported when grep ///
abandons such files. ///
///
The -t flag searches binary files. By default, only text files are ///
searched. ///
///
The -A <num> flag displays the specified number of lines of trailing ///
context after matching lines. ///
///
The -B <num> flag displays the specified number of lines of leading ///
context before matching lines. ///
///
The -C <num> flag displays the specified number of lines of output ///
context. ///
///
Regular expressions: ///
///
A regular expression is zero or more branches, separated by `|'. It ///
matches anything that matches one of the branches. ///
///
A branch is zero or more pieces, concatenated. It matches a match ///
for the first, followed by a match for the second, etc. ///
///
A piece is an atom possibly followed by `*', `+', or `?'. An atom ///
followed by `*' matches a sequence of 0 or more matches of the atom. ///
An atom followed by `+' matches a sequence of 1 or more matches of ///
the atom. An atom followed by `?' matches a match of the atom, or ///
the null string. ///
///
An atom is a regular expression in parentheses (matching a match for ///
the regular expression), a range (see below), `.' (matching any ///
single character), `^' (matching the null string at the beginning ///
of the input string), `$' (matching the null string at the end of ///
the input string), a `\' followed by a single character (matching ///
that character), or a single character with no other significance ///
(matching that character). ///
///
A range is a sequence of characters enclosed in `[]'. It normally ///
matches any single character from the sequence. If the sequence ///
begins with `^', it matches any single character not from the rest ///
of the sequence. If two characters in the sequence are separated by ///
`-', this is shorthand for the full list of ASCII characters between ///
them (e.g. `[0-9]' matches any decimal digit). To include a literal ///
`]' in the sequence, make it the first character (following a possible ///
`^'). To include a literal `-', make it the first or last character. ///
///
///
/// /// To get the file line matches for the pattern "OpenConnection" in the /// file //depot/main/Program.cs with case-insensitive search: /// /// GetFileLineMatchesCmdOptions opts = /// new GetFileLineMatchesCmdOptions(GetFileLineMatchesCmdFlags.CaseInsensitive, /// 0, 0, 0); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/main/Program.cs"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<FileLineMatch> target = /// Repository.GetFileLineMatches(filespecs, "OpenConnection" opts); /// /// To get the file line matches for the pattern "OpenConnection" in the /// file //depot/main/Program.cs showing 2 lines before and after the found /// pattern and showing line numbers: /// /// GetFileLineMatchesCmdOptions opts = /// new GetFileLineMatchesCmdOptions(GetFileLineMatchesCmdFlags.IncludeLineNumbers, /// 2, 2, 0); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/main/Program.cs"), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<FileLineMatch> target = /// Repository.GetFileLineMatches(filespecs, "OpenConnection" opts); /// /// /// public IList GetFileLineMatches(IList filespecs, string pattern, Options options) { P4.P4Command grepCmd = new P4Command(this, "grep", true, FileSpec.ToStrings(filespecs)); options["-e"] = pattern; P4.P4CommandResult r = grepCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } IList value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { FileLineMatch val = new FileLineMatch(); val.ParseGrepCmdTaggedData(obj); value.Add(val); } return value; } /// /// Get a list of submitted integrations for the passed-in file specs. /// /// /// /// /// ///
p4 help integrated ///
///
integrated -- List integrations that have been submitted ///
///
p4 integrated [-r] [-b branch] [file ...] ///
///
The p4 integrated command lists integrations that have been submitted. ///
To list unresolved integrations, use 'p4 resolve -n'. To list ///
resolved but unsubmitted integrations, use 'p4 resolved'. ///
///
If the -b branch flag is specified, only files integrated from the ///
source to target files in the branch view are listed. Qualified ///
files are listed, even if they were integrated without using the ///
branch view. ///
///
The -r flag reverses the mappings in the branch view, swapping the ///
target files and source files. The -b branch flag is required. ///
///
///
/// /// To get the file intergration records for the path //depot/rel defined /// by branch specification main_to_rel: /// /// GetSubmittedIntegrationsCmdOptions opts = /// new GetSubmittedIntegrationsCmdOptions(GetSubmittedIntegrationsCmdFlags.None, /// "main_to_rel"); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/rel/..."), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<FileIntegrationRecord> target = /// Repository.GetSubmittedIntegrations(filespecs, opts); /// /// To get the file intergration records for the path //depot/main defined /// by branch specification main_to_rel in reverse direction: /// /// GetSubmittedIntegrationsCmdOptions opts = /// new GetSubmittedIntegrationsCmdOptions(GetSubmittedIntegrationsCmdFlags.ReverseMappings, /// "main_to_rel"); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/rel/..."), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<FileIntegrationRecord> target = /// Repository.GetSubmittedIntegrations(filespecs, opts); /// /// /// public IList GetSubmittedIntegrations(IList filespecs, Options options) { P4.P4Command integratedCmd = new P4Command(this, "integrated", true, FileSpec.ToStrings(filespecs)); P4.P4CommandResult r = integratedCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } IList value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { FileIntegrationRecord val = new FileIntegrationRecord(); val.ParseIntegratedCmdTaggedData(obj); value.Add(val); } return value; } /// /// Get a list of Perforce protection entries for the passed-in file specs /// /// /// /// /// ///
p4 help protects ///
///
protects -- Display protections defined for a specified user and path ///
///
p4 protects [-a | -g group | -u user] [-h host] [-m] [file ...] ///
///
'p4 protects' displays the lines from the protections table that ///
apply to the current user. The protections table is managed using ///
the 'p4 protect' command. ///
///
If the -a flag is specified, protection lines for all users are ///
displayed. If the -g group flag or -u user flag is specified, ///
protection lines for that group or user are displayed. ///
///
If the -h host flag is specified, the protection lines that apply ///
to the specified host (IP address) are displayed. ///
///
If the -m flag is given, a single word summary of the maximum ///
access level is reported. Note that this summary does not take ///
exclusions into account. ///
///
If the file argument is specified, protection lines that apply to ///
the specified files are displayed. ///
///
The -a/-g/-u flags require 'super' access granted by 'p4 protect'. ///
///
///
/// /// To get the protections for the user tim for the entire server: /// /// GetProtectionEntriesCmdOptions opts = /// new GetProtectionEntriesCmdOptions(GetProtectionEntriesCmdFlags.None, /// null, "tim", null); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//..."), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<ProtectionEntry> target = /// Repository.GetProtectionEntries(filespecs, opts); /// /// To get the protections summary for the group development tim for the entire server /// when connecting from IP address 10.24.4.6: /// /// GetProtectionEntriesCmdOptions opts = /// new GetProtectionEntriesCmdOptions(GetProtectionEntriesCmdFlags.AccessSummary, /// "development", null, "10.24.4.6"); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//..."), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<ProtectionEntry> target = /// Repository.GetProtectionEntries(filespecs, opts); /// /// /// public IList GetProtectionEntries(IList filespecs, Options options) { P4.P4Command protectsCmd = new P4Command(this, "protects", true, FileSpec.ToStrings(filespecs)); P4.P4CommandResult r = protectsCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } IList value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { StringEnum mode = obj["perm"]; StringEnum type = "User"; if (obj.ContainsKey("isgroup")) { type = "Group"; } string name = obj["user"]; string host = obj["host"]; string path = obj["depotFile"]; ProtectionEntry pte = new ProtectionEntry(mode, type, name, host, path); value.Add(pte); } return value; } /// /// List Perforce users assigned to review files. /// /// /// /// /// ///
p4 help reviews ///
///
reviews -- List the users who are subscribed to review files ///
///
p4 reviews [-c changelist#] [file ...] ///
///
'p4 reviews' lists all users who have subscribed to review the ///
specified files, the files in the specified changelist, or all files ///
(the default). To subscribe to review files, issue the 'p4 user' ///
command and edit the 'Reviews field'. ///
///
///
/// /// To get the list of users who are reviewing submits to //depot/main/src: /// /// GetReviewersCmdOptions opts = /// new GetReviewersCmdOptions(GetReviewersCmdFlags.None, 0); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//depot/main/src/..."), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<ProtectionEntry> target = /// Repository.GetProtectionEntries(filespecs, opts); /// /// To get the list of users who are reviewing submitted changelist 83476: /// /// GetReviewersCmdOptions opts = /// new GetReviewersCmdOptions(GetReviewersCmdFlags.None, 83476); /// /// FileSpec filespec = /// new FileSpec(new DepotPath("//..."), null); /// IList<FileSpec> filespecs = new List<FileSpec>(); /// filespecs.Add(filespec); /// /// IList<ProtectionEntry> target = /// Repository.GetProtectionEntries(filespecs, opts); /// /// /// public IList GetReviewers(IList filespecs, Options options) { P4.P4Command reviewsCmd = new P4Command(this, "reviews", true, FileSpec.ToStrings(filespecs)); P4.P4CommandResult r = reviewsCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } List value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { string id = obj["user"]; string fullname = obj["name"]; string password = string.Empty; string emailaddress = obj["email"]; DateTime updated = DateTime.MinValue; DateTime accessed = DateTime.MinValue; string jobview = string.Empty; List reviews = new List(); UserType type = UserType.Standard; FormSpec spec = new FormSpec(null,null, null, null, null, null, null); User user = new User(id, fullname, password, emailaddress, updated, accessed, jobview, reviews, type, spec); value.Add(user); } return value; } /// /// Get a FormSpec of the specified form type. /// /// /// /// /// ///
p4 help spec ///
///
spec -- Edit spec definitions (unsupported) ///
///
p4 spec [-d -i -o] type ///
///
Edit any type of specification: branch, change, client, depot, ///
group, job, label, spec, stream, trigger, typemap, or user. Only ///
the comments and the formatting hints can be changed. Any fields ///
that you add during editing are discarded when the spec is saved. ///
///
'p4 jobspec' is equivalent to 'p4 spec job', and any custom spec ///
(include the job spec) can be deleted with 'p4 spec -d type'. ///
///
///
/// /// To get the FormSpec for changelist: /// /// Options ops = new Options(); /// ops["-o"] = null; /// /// FormSpec target = Repository.GetFormSpec(ops, "change"); /// /// To get the FormSpec for client: /// /// Options ops = new Options(); /// ops["-o"] = null; /// /// FormSpec target = Repository.GetFormSpec(ops, "clinet"); /// /// To get the FormSpec for user: /// /// Options ops = new Options(); /// ops["-o"] = null; /// /// FormSpec target = Repository.GetFormSpec(ops, "user"); /// /// public FormSpec GetFormSpec(Options options, string spectype) { StringList cmdArgs = new StringList(); cmdArgs.Add(spectype); P4.P4Command specCmd = new P4Command(this, "spec", true, cmdArgs); P4.P4CommandResult r = specCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } foreach (P4.TaggedObject obj in r.TaggedOutput) { FormSpec val = FormSpec.FromSpecCmdTaggedOutput(obj); return val; } return null; } /// /// Get the repository's trigger table. /// /// /// /// ///
p4 help triggers ///
///
triggers -- Modify list of server triggers ///
///
p4 triggers ///
p4 triggers -o ///
p4 triggers -i ///
///
'p4 triggers' edits the table of triggers, which are used for ///
change submission validation, form validation, external authentication, ///
external job fix integration, and external archive integration. ///
///
Triggers are administrator-defined commands that the server runs ///
to perform the following: ///
///
Validate changelist submissions. ///
///
The server runs changelist triggers before the file transfer, ///
between file transfer and changelist commit, or after the commit ///
///
Validate shelve operations. ///
///
The server runs shelve triggers before files are shelved, after ///
files are shelved, or when shelved files have been discarded ///
(via shelve -d). ///
///
Manipulate and validate forms. ///
///
The server runs form-validating triggers between generating ///
and outputting the form, between inputting and parsing the ///
form, between parsing and saving the form, or when deleting ///
the form. ///
///
Authenticate or change a user password. ///
///
The server runs authentication triggers to either validate ///
a user password during login or when setting a new password. ///
///
Intercept job fix additions or deletions. ///
///
The server run fix triggers prior to adding or deleting a fix ///
between a job and changelist. ///
///
Access external archive files. ///
///
For files with the +X filetype modifier, the server runs an ///
archive trigger to read, write, or delete files in the archive. ///
///
Command execution policy. ///
///
Command triggers can be specified to run before and after ///
processing of user requests. Pre-execution triggers can ///
prevent the command from running. ///
///
The trigger form has a single entry 'Triggers', followed by any ///
number of trigger lines. Triggers are executed in the order listed ///
and if a trigger fails, subsequent triggers are not run. A trigger ///
succeeds if the executed command exits returning 0 and fails otherwise. ///
Normally the failure of a trigger prevents the operation from ///
completing, except for the commit triggers, which run after the ///
operation is complete. ///
///
Each trigger line contains a trigger name, a trigger type, a depot ///
file path pattern or form type, and a command to run. ///
///
Name: The name of the trigger. For change triggers, a run of the ///
same trigger name on contiguous lines is treated as a single ///
trigger so that multiple paths can be specified. Only the ///
command of the first such trigger line is used. ///
///
Type: When the trigger is to execute: ///
///
archive: ///
Execute an archive trigger for the server to access ///
any file with the +X filetype modifier. ///
///
auth-check: ///
service-check: ///
Execute an authentication check trigger to verify a ///
user's password against an external password manager ///
during login or when setting a new password. ///
///
auth-check-sso: ///
Facilitate a single sign-on user authentication. This ///
configuration requires two programs or scripts to run; ///
one on the client, the other on the server. ///
///
client: ///
Set the environment variable 'P4LOGINSSO' to point to ///
a script that can be executed to obtain the user's ///
credentials or other information that the server ///
trigger can verify. The client-side script must ///
write the message to the standard output ///
(max length 128K). ///
///
Example: P4LOGINSSO=/Users/joe/bin/runsso ///
///
The 'server address' can be optionally passed to the ///
client script by appending %serverAddress% to the ///
client command string, as in: ///
///
P4LOGINSSO="/Users/joe/bin/runsso %serverAddress%" ///
///
server: ///
Execute an authentication (sso) trigger that gets ///
this message from the standard input and returns an ///
exit status of 0 (for verified) or otherwise failed. ///
///
Example: ///
sso auth-check-sso auth "/secure/verify %user%" ///
///
The user must issue the 'p4 login' command, but no ///
password prompting is invoked. If the server ///
determines that the user is valid, they are issued a ///
Perforce ticket just as if they had logged in with a ///
password. ///
///
Pre-2007.2 clients cannot run a client-side single ///
sign-on. Specifying an 'auth-check' trigger as a backup ///
for a user to gain access will prompt the user for a ///
password if it's an older client or P4LOGINSSO has not ///
been configured. ///
///
Unlike passwords which are encrypted, the sso message is ///
sent to the server in clear text. ///
///
auth-set: ///
Execute an authentication set trigger to send a new ///
password to an external password manager. ///
///
change-submit: ///
Execute pre-submit trigger after changelist has been ///
created and files locked but prior to file transfer. ///
///
change-content: ///
Execute mid-submit trigger after file transfer but prior ///
to commit. Files can be accessed by the 'p4 diff2', ///
'p4 files', 'p4 fstat', and 'p4 print' commands using ///
the revision specification '@=change', where 'change' is ///
the pending changelist number passed as %changelist%. ///
///
change-commit: ///
Execute post-submit trigger after changelist commit. ///
///
change-failed: ///
Executes only if the changelist commit failed. ///
Note that this trigger only fires on errors ///
occurring after a commit process has started. It does ///
not fire for early usage errors, or due to errors from ///
the submit form. In short, if an edge-* or change-* ///
trigger could have run, then the change-failed trigger ///
will fire if that commit fails. ///
///
command: ///
Execute pre/post trigger when users run commands. ///
///
edge-submit: ///
Execute pre-submit trigger on Edge Server after changelist ///
has been created but prior to file transfer. ///
///
edge-content: ///
Execute mid-submit trigger on Edge Server after file ///
transfer but prior to beginning submit on Commit Server. ///
///
fix-add: ///
Execute fix trigger prior to adding a fix. The special ///
variable %jobs% is available for expansion and must be ///
the last argument to the trigger as it expands to one ///
argument for each job listed on the 'p4 fix' command. ///
///
fix-delete: ///
Execute fix trigger prior to deleting a fix. The special ///
variable %jobs% is available for expansion and must be ///
the last argument to the trigger as it expands to one ///
argument for each job listed on the 'p4 fix -d' command. ///
///
form-out: ///
Execute form trigger on generation of form. Trigger may ///
modify form. ///
///
form-in: ///
Execute form trigger on input of form before its contents ///
are parsed and validated. Trigger may modify form. ///
///
form-save: ///
Execute form trigger prior to save of form after its ///
contents are parsed. ///
///
form-commit: ///
Execute form trigger after it has been committed, allowing ///
access to automatically generated fields (jobname, dates ///
etc). It cannot modify the form. This trigger for job ///
forms is run by 'p4 job' and 'p4 fix' (after the status ///
is updated), 'p4 change' (if the job is added or deleted) ///
and 'p4 submit' (if the job is associated with the change). ///
The 'form-commit' trigger has access to the new job name ///
created with 'p4 job', while the 'form-in' and 'form-save' ///
triggers are run before the job name is created. The ///
special variable %action% is available on the job ///
'form-commit' trigger command line, and is expanded when ///
the job is modified by a fix. ///
///
form-delete: ///
Execute form trigger prior to delete of form after its ///
contents are parsed. ///
///
shelve-submit: ///
Execute pre-shelve trigger after changelist has been ///
created but prior to file transfer. ///
///
shelve-commit: ///
Execute post-shelve trigger after files are shelved. ///
///
shelve-delete: ///
Execute shelve trigger prior to discarding shelved files. ///
///
Path: For change and submit triggers, a file pattern to match files ///
in the changelist. This file pattern can be an exclusion ///
mapping (-pattern), to exclude files. For form triggers, the ///
name of the form (branch, client, etc). For fix triggers ///
'fix' is required as the path value. For authentication ///
triggers, 'auth' is required as the path value. For archive ///
triggers, a file pattern to match the name of the file being ///
accessed in the archive. Note that, due to lazy copying when ///
branching files, the name of the file in the archive can not ///
be the same as the name of the file in the depot. ///
///
Command: The OS command to run for validation. If the command ///
contains spaces, enclose it in double quotes. The ///
following variables are expanded in the command string. ///
Use of the triggers.io configurable with a value greater than ///
zero is recommended, as some vars may be empty or contain ///
shell metacharacters. ///
///
%//depot/trigger.exe% -- depot paths within %vars% ///
are filled with the path to a temporary file containing ///
the referenced file's contents. Only standard and stream ///
depot files whose contents is available are valid. ///
%argc% -- number of command arguments ///
%args% -- command argument string ///
%client% -- the client issuing the command ///
%clientcwd% -- client current working directory ///
%clienthost% -- the hostname of the client ///
%clientip% -- the IP address of the client ///
%clientprog% -- the program name of the client ///
%clientversion% -- the version of the client ///
%command% -- name of command being run ///
%groups% -- list of groups user is a member of ///
%intermediateService% -- presence of a Broker/Proxy/etc ///
%maxErrorSeverity% -- highest error seen for this cmd ///
%maxErrorText% -- text and errno for highest error ///
%maxLockTime% -- user-specified override of group value ///
%maxResults% -- user-specified override of group value ///
%maxScanRows% -- user-specified override of group value ///
%quote% -- double quote character ///
%serverhost% -- the hostname of the server ///
%serverid% -- the value of the server's server.id ///
%serverip% -- the IP address of the server ///
%servername% -- the value of the server's $P4NAME ///
%serverpid% -- the PID of the server ///
%serverport% -- the IP address:port of the server ///
preceded by the transport prefix, ///
if needed (i.e. P4PORT) ///
%serverroot% -- the value of the server's $P4ROOT ///
%serverservices% -- the services provided by the server ///
%serverVersion% -- the server's version string ///
%terminated% -- if the command was forced to quit early ///
%termReason% -- reason for early termination ///
%triggerMeta_action% -- command to execute by trigger ///
%triggerMeta_depotFile% -- third field in trigger def. ///
%triggerMeta_name% -- name from trigger definition ///
%triggerMeta_trigger% -- second field in trigger definition ///
%user% -- the user issuing the command ///
///
%changelist% -- the changelist being submitted ///
%changeroot% -- the root path of files submitted ///
%oldchangelist% -- the pre-commit changelist number ///
///
(More information can be gathered about the ///
changelist being submitted by running ///
'p4 describe %changelist%'.) ///
///
%formfile% -- path to temp file containing form ///
%formname% -- the form's name (branch name, etc) ///
%formtype% -- the type of form (branch, etc) ///
%action% -- added/deleted/submitted on job form-commit ///
///
%jobs% -- list of job names for fix triggers ///
///
%op% -- read/write/delete for archive access ///
%file% -- name of archive file ///
%rev% -- revision of archive file ///
///
If the command was sent via a proxy, broker, or replica: ///
%peerhost% -- the hostname of the proxy/broker/replica ///
%peerip% -- the IP address of the proxy/broker/replica ///
If the command was sent directly, %peerhost% and ///
%peerip% match %clienthost% and %clientip%. ///
///
For a change-* trigger in a distributed installation, ///
%submitserverid% -- the server.id where submit was run ///
///
Note that not all variables are available for every ///
trigger type. E.g. argc and argv only show up for ///
pre-user-$cmd and change-submit (and so on), but not for ///
post-user-$cmd or change-commit. ///
///
The command's standard input depends on the value of the ///
triggers.io configurable. When it is set to zero, stdin is ///
empty for change, shelve, fix, command, and auth triggers, it ///
is the file content for the archive trigger. When triggers.io ///
is set to 1, (except for archive triggers,) stdin is a textual ///
dictionary containing connection information that the trigger. ///
must read. ///
///
If the command fails, the command's standard output (not ///
error output) is sent to the client as the text of a trigger ///
failure error message. ///
///
If the command succeeds, the command's standard output is ///
sent as an unadorned message to the client for all triggers ///
except archive triggers; for archive triggers, the command's ///
standard output is the file content. ///
///
The -o flag writes the trigger table to the standard output. ///
The user's editor is not invoked. ///
///
The -i flag reads the trigger table from the standard input. ///
The user's editor is not invoked. ///
///
'p4 triggers' requires 'super' access granted by 'p4 protect'. ///
///
///
/// /// To get the trigger table: /// /// GetTriggerTableCmdOptions opts = /// new GetTriggerTableCmdOptions(GetTriggerTableCmdFlags.Output); /// /// IList<Trigger> target = Repository.GetTriggerTable(opts); /// /// /// public IList GetTriggerTable(Options options) { P4.P4Command triggersCmd = new P4Command(this, "triggers", true); P4.P4CommandResult r = triggersCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } List value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { System.Text.StringBuilder sb = new StringBuilder(); foreach (KeyValuePair key in obj) { sb.Remove(0, sb.Length); sb.AppendLine((string.Format("{0} {1}", key.Key.ToString(), key.Value))); string line = sb.ToString(); if (line.StartsWith("Triggers")) { line = line.Trim(); string[] entries = line.Split(' '); string name = entries[1]; string ent = entries[2]; ent = ent.Replace("-",""); StringEnum type = ent; string path = entries[3]; string command = entries[4] + " " + entries[5]; string ord = entries[0]; ord = ord.Remove(0, 8); int order = 0; order = Convert.ToInt16(ord); Trigger trig = new Trigger(name, order, type, path, command); value.Add(trig); } } } return value; } /// /// Get the repository's type map. /// /// /// /// runs the command p4 typemap -o /// /// ///
p4 help typemap ///
///
typemap -- Edit the filename-to-filetype mapping table ///
///
p4 typemap ///
p4 typemap -o ///
p4 typemap -i ///
///
'p4 typemap' edits a name-to-type mapping table for 'p4 add', which ///
uses the table to assign a file's filetype based on its name. ///
///
The typemap form has a single field, 'TypeMap', followed by any ///
number of typemap lines. Each typemap line contains a filetype ///
and a depot file path pattern: ///
///
Filetype: See 'p4 help filetypes' for a list of valid filetypes. ///
///
Path: Names to be mapped to the filetype. The mapping is ///
a file pattern in depot syntax. When a user adds a file ///
matching this pattern, its default filetype is the ///
file type specified in the table. To exclude files from ///
the typemap, use exclusionary (-pattern) mappings. ///
To match all files anywhere in the depot hierarchy, ///
the pattern must begin with '//...'. To match files ///
with a specified suffix, use '//.../*.suffix' or ///
use '//....suffix' (four dots). ///
///
Later entries override earlier entries. If no matching entry is found ///
in the table, 'p4 add' determines the filetype by examining the file's ///
contents and execution permission bits. ///
///
The -o flag writes the typemap table to standard output. The user's ///
editor is not invoked. ///
///
The -i flag reads the typemap table from standard input. The user's ///
editor is not invoked. ///
///
'p4 typemap' requires 'admin' access, which is granted by 'p4 protect'. ///
///
///
/// /// To get the typemap table: /// /// IList<TypeMapEntry> target = Repository.GetTypeMap(); /// /// public IList GetTypeMap() { P4.P4Command typemapCmd = new P4Command(this, "typemap", true, "-o"); P4.P4CommandResult r = typemapCmd.Run(); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } List value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { int ord = 0; string key = String.Format("TypeMap{0}", ord); while (obj.ContainsKey(key)) { value.Add(new TypeMapEntry(obj[key])); ord++; key = String.Format("TypeMap{0}", ord); } return value; } return value; } /// /// Get the repository's protection table. /// /// /// /// ///
p4 help protect ///
///
protect -- Modify protections in the server namespace ///
///
p4 protect ///
p4 protect -o ///
p4 protect -i ///
///
'p4 protect' edits the protections table in a text form. ///
///
Each line in the table contains a protection mode, a group/user ///
indicator, the group/user name, client host ID and a depot file ///
path pattern. Users receive the highest privilege that is granted ///
on any line. ///
///
Note: remote depot are accessed using the pseudo-user 'remote'. ///
To control access from other servers that define your server as ///
a remote server, grant appropriate permissions to the 'remote' user. ///
///
Mode: The permission level or right being granted or denied. ///
Each permission level includes all the permissions above ///
it, except for 'review'. Each permission only includes ///
the specific right and no lesser rights. This approach ///
enables you to deny individual rights without having to ///
re-grant lesser rights. Modes prefixed by '=' are rights. ///
All other modes are permission levels. ///
///
Valid modes are: ///
///
list - users can see names but not contents of files; ///
users can see all non-file related metadata ///
(clients, users, changelists, jobs, etc.) ///
///
read - users can sync, diff, and print files ///
///
open - users can open files (add, edit. delete, ///
integrate) ///
///
write - users can submit open files ///
///
admin - permits those administrative commands and ///
command options that don't affect the server's ///
security. ///
///
super - access to all commands and command options. ///
///
review - permits access to the 'p4 review' command; ///
implies read access ///
///
=read - if this right is denied, users can't sync, ///
diff, or print files ///
///
=branch - if this right is denied, users are not ///
permitted to use files as a source ///
for 'p4 integrate' ///
///
=open = if this right is denied, users cannot open ///
files (add, edit, delete, integrate) ///
///
=write = if this right is denied, users cannot submit ///
open files ///
///
Group/User indicator: specifies the grantee is a group or user. ///
///
Name: A Perforce group or user name; can include wildcards. ///
///
Host: The IP address of a client host; can include wildcards. ///
///
Path: The part of the depot to which access is being granted ///
or denied. To deny access to a depot path, preface the ///
path with a "-" character. These exclusionary mappings ///
apply to all access levels, even if only one access ///
level is specified in the first field. ///
///
The -o flag writes the protection table to the standard output. ///
The user's editor is not invoked. ///
///
The -i flag reads the protection table from the standard input. ///
The user's editor is not invoked. ///
///
After protections are defined, 'p4 protect' requires 'super' ///
access. ///
///
///
/// /// To get the protections table: /// /// GetProtectionTableCmdOptions opts = /// new GetProtectionTableCmdOptions(GetProtectionTableCmdFlags.Output); /// /// IList<ProtectionEntry> target = Repository.GetProtectionTable(opts); /// /// /// public IList GetProtectionTable(Options options) { P4.P4Command protectCmd = new P4Command(this, "protect", true); P4.P4CommandResult r = protectCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } List value = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { System.Text.StringBuilder sb = new StringBuilder(); foreach (KeyValuePair key in obj) { sb.Remove(0, sb.Length); sb.AppendLine((string.Format("{0} {1}", key.Key.ToString(), key.Value))); string line = sb.ToString(); if (line.StartsWith("Protections")) { line = line.Trim(); string[] entries = line.Split(' '); StringEnum mode = entries[1]; StringEnum type = entries[2]; string grouporusername = entries[3]; string host = entries[4]; string path = entries[5]; ProtectionEntry pe = new ProtectionEntry(mode, type, grouporusername, host, path); value.Add(pe); } } } return value; } /// /// Get the Perforce counters for this repository. /// /// /// /// ///
p4 help counters ///
///
counters -- Display list of known counters ///
///
p4 counters [-e nameFilter -m max] ///
///
Lists the counters in use by the server. The server ///
uses the following counters directly: ///
///
change Current change number ///
job Current job number ///
journal Current journal number ///
lastCheckpointAction Data about the last complete checkpoint ///
logger Event log index used by 'p4 logger' ///
traits Internal trait lot number used by 'p4 attribute' ///
upgrade Server database upgrade level ///
///
The -e nameFilter flag lists counters with a name that matches ///
the nameFilter pattern, for example: -e 'mycounter-*'. ///
///
The -m max flag limits the output to the first 'max' counters. ///
///
The names 'minClient', 'minClientMessage', 'monitor', ///
'security', and 'unicode' are reserved names: do not use them ///
as ordinary counters. ///
///
For general-purpose server configuration, see 'p4 help configure'. ///
///
///
/// /// To get the counters on the server: /// /// IList<Counter> target = Repository.GetCounters(null); /// /// To get the counters on the server that start with the name "build_": /// /// Options opts = new Options(); /// opts["-e"] = "build_*"; /// IList<Counter> target = Repository.GetCounters(opts); /// /// public IList GetCounters(Options options) { P4.P4Command countersCmd = new P4Command(this, "counters", true); P4.P4CommandResult r = countersCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } IList val = new List(); foreach (P4.TaggedObject obj in r.TaggedOutput) { string name = obj["counter"]; string value = obj["value"]; Counter counter = new Counter(name, value); val.Add(counter); } return val; } /// /// Get a named Perforce counter value from the repository. /// /// /// /// /// ///
p4 help counter ///
///
counter -- Display, set, or delete a counter ///
///
p4 counter name ///
p4 counter [-f] name value ///
p4 counter [-f] -d name ///
p4 counter [-f] -i name ///
p4 counter [-f] -m [ pair list ] ///
///
The first form displays the value of the specified counter. ///
///
The second form sets the counter to the specified value. ///
///
The third form deletes the counter. This option usually has the ///
same effect as setting the counter to 0. ///
///
The -f flag sets or deletes counters used by Perforce, which are ///
listed by 'p4 help counters'. Important: Never set the 'change' ///
counter to a value that is lower than its current value. ///
///
The -i flag increments a counter by 1 and returns the new value. ///
This option is used instead of a value argument and can only be ///
used with numeric counters. ///
///
The fifth form allows multiple operations in one command. ///
With this, the list is pairs of arguments. Each pair is either ///
counter value or '-' counter. To set a counter use a name and value. ///
To delete a counter use a '-' followed by the name. ///
Counters can be assigned textual values as well as numeric ones, ///
despite the name 'counter'. ///
///
Counters can be assigned textual values as well as numeric ones, ///
despite the name 'counter'. ///
///
'p4 counter' requires 'review' access granted by 'p4 protect'. ///
The -f flag requires that the user be an operator or have 'super' ///
access. ///
///
///
/// /// To get the job counter: /// /// Counter target = Repository.GetCounter("job", null); /// /// To get the change counter: /// /// Counter target = Repository.GetCounter("change", null); /// /// To get the journal counter: /// /// Counter target = Repository.GetCounter("journal", null); /// /// public Counter GetCounter(String name, Options options) { P4.P4Command counterCmd = new P4.P4Command(_connection, "counter", true, name); P4.P4CommandResult r = counterCmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } if ((r.TaggedOutput == null) || (r.TaggedOutput.Count <= 0)) { return null; } foreach (P4.TaggedObject obj in r.TaggedOutput) { string countername = obj["counter"]; string value = obj["value"]; Counter counter = new Counter(countername, value); return counter; } return null; } /// /// Delete a Perforce counter from the repository. /// /// /// /// /// ///
p4 help counter ///
///
counter -- Display, set, or delete a counter ///
///
p4 counter name ///
p4 counter [-f] name value ///
p4 counter [-f] -d name ///
p4 counter [-f] -i name ///
p4 counter [-f] -m [ pair list ] ///
///
The first form displays the value of the specified counter. ///
///
The second form sets the counter to the specified value. ///
///
The third form deletes the counter. This option usually has the ///
same effect as setting the counter to 0. ///
///
The -f flag sets or deletes counters used by Perforce, which are ///
listed by 'p4 help counters'. Important: Never set the 'change' ///
counter to a value that is lower than its current value. ///
///
The -i flag increments a counter by 1 and returns the new value. ///
This option is used instead of a value argument and can only be ///
used with numeric counters. ///
///
The fifth form allows multiple operations in one command. ///
With this, the list is pairs of arguments. Each pair is either ///
counter value or '-' counter. To set a counter use a name and value. ///
To delete a counter use a '-' followed by the name. ///
Counters can be assigned textual values as well as numeric ones, ///
despite the name 'counter'. ///
///
'p4 counter' requires 'review' access granted by 'p4 protect'. ///
The -f flag requires that the user be an operator or have 'super' ///
access. ///
///
///
/// /// To delete a counter named test: /// /// Counter target = Repository.DeleteCounter("test", null); /// /// To delete a counter named build using -f with a user with /// super access: /// /// Options opts = new Options(); /// opts["-f"] = null; /// Counter target = Repository.DeleteCounter("build", opts); /// /// public Object DeleteCounter(String name, Options options) { if (options==null) { options = new Options(); } options["-d"] = null; P4.P4Command Cmd = new P4Command(this, "counter", false, name); P4.P4CommandResult r = Cmd.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); return null; } return r.InfoOutput; } #region IDisposable Members public void Dispose() { _connection.Dispose(); } #endregion } }