/******************************************************************************* Copyright (c) 2011, Perforce Software, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ /******************************************************************************* * Name : DepotFileDiff.cs * * Author : wjb * * Description : Class used to abstract a depot file diff in Perforce. * ******************************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Perforce.P4 { /// /// The types of diffs returned by the server. /// [Flags] public enum DiffType { /// /// File contents are different. /// Content = 0x0000, /// /// File contents are identical but file types are different. /// FileType = 0x0001, /// /// The left file in the diff has no target file at the /// specified name or revision to pair with for a diff. /// LeftOnly = 0x0002, /// /// The right file in the diff has no source file at the /// specified name or revision to pair with for a diff. /// RightOnly = 0x0004, /// /// File content and file types are identical. /// Identical = 0x0008 } /// ///
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> -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 stream's branch view. (See 'p4 ///
help stream'.) The stream is the source, and its parent is the ///
target. -P can be used to specify 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 specifies number of context lines. ///
///
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 ///
but the output can be used by the patch program. ///
///
///
/// /// A diff between depot files in a Perforce repository. /// public class DepotFileDiff { public DepotFileDiff() { } public DepotFileDiff(DiffType type, FileSpec leftfile, FileSpec rightfile, string diff ) { Type = type; LeftFile = leftfile; RightFile = rightfile; Diff = diff; } private StringEnum _type; public DiffType Type { get { return _type; } set { _type = value; } } public FileSpec LeftFile { get; set; } public FileSpec RightFile { get; set; } public string Diff { get; set; } /// /// Read the fields from the tagged output of a diff2 command /// /// Tagged output from the 'diff2' command public void FromGetDepotFileDiffsCmdTaggedOutput(TaggedObject objectInfo, Connection connection, Options options) { DepotFileDiff ParsedDepotFileDiff = new DepotFileDiff(); string ldepotfile = string.Empty; string rdepotfile = string.Empty; int lrev = -1; int rrev = -1; if (objectInfo.ContainsKey("status")) { _type = objectInfo["status"]; } if (objectInfo.ContainsKey("depotFile")) { ldepotfile = objectInfo["depotFile"]; } if (objectInfo.ContainsKey("rev")) { int.TryParse(objectInfo["rev"], out lrev); } if (objectInfo.ContainsKey("depotFile2")) { rdepotfile = objectInfo["depotFile2"]; } if (objectInfo.ContainsKey("rev2")) { int.TryParse(objectInfo["rev2"], out rrev); } LeftFile = new FileSpec(new DepotPath(ldepotfile), new Revision(lrev)); RightFile = new FileSpec(new DepotPath(rdepotfile), new Revision(rrev)); if (objectInfo["status"] == "content") { string filepathl = ldepotfile + "#" + lrev; string filepathr = rdepotfile + "#" + rrev; P4.P4Command getDiffData = new P4Command(connection, "diff2", false, filepathl, filepathr); P4.P4CommandResult r = getDiffData.Run(options); if (r.Success != true) { P4Exception.Throw(r.ErrorList); } if (r.TextOutput != null) { Diff = r.TextOutput.ToString(); } else if (r.InfoOutput != null) { Diff = r.InfoOutput.ToString(); } } ParsedDepotFileDiff = new DepotFileDiff(Type, LeftFile, RightFile, Diff); } } }