1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/*
SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de>
SPDX-FileCopyrightText: 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KDEVPLATFORM_VCSDIFF_H
#define KDEVPLATFORM_VCSDIFF_H
#include <QSharedDataPointer>
#include <QtGlobal>
#include <QMetaType>
#include <QVector>
#include "vcsexport.h"
class QUrl;
class QString;
namespace KDevelop
{
/**
* A class representing a unified diff, possibly with
* conflict markers.
*
* A diff is assumed to be a collection of hunks, where each hunk has the
* following structure:
*
* METADATA
* --- a/SOURCE_PATH
* +++ b/TARGET_PATH
* HUNK1 HEADER
* HUNK1 CONTENT
* [METADATA]
* HUNK2 HEADER
* HUNK2 CONTENT
* ...
*
* METADATA are lines which start with anything except for a '+', '-' and ' '.
* The path specifications may optionally precede a hunk and are assumed to
* apply to all following hunks until a new path specification
* is found. These indicate the files for which the diff is generated.
*
* Hunk Header
* ------------
*
* Each hunk header has the following form
*
* @@ -SRC_OFFSET[, SRC_CHANGES_COUNT] +TGT_OFFSET[, TGT_CHANGES_COUNT] @@ Heading
*
* where the SRC_OFFSET is a 1-based line index pointing to the source file where
* the hunk applies and TGT_OFFSET is a 1-based line index pointing to the target
* file where the hunk applies. The optional SRC_CHANGES_COUNTS (assumed to be 1
* if not present) specifies the number of context lines plus the number of
* deleted lines. Similarly, the optional TGT_CHANGES_COUNT specifies the
* number of context lines plus the number of added lines. The Heading, used as a
* visual aid for users, is supposed to show the line where the nearest enclosing
* function scope of the hunk starts.
*
* Hunk Content
* ------------
*
* The hunk content is a collection of lines which starting with '+' (additions),
* '-' (deletions) and ' ' (context lines; empty lines are also take to be context
* lines). Additionally, a hunk may contain conflict markers which are of the form
*
* >>>>>>> our ref
* our content
* ...
* =======
* their content
* ...
* <<<<<<< their ref
*
* and indicate unresolved conflicts.
*
*/
class KDEVPLATFORMVCS_EXPORT VcsDiff
{
public:
/* Used to represent a patch or its inverse */
enum DiffDirection {
Normal = 0 /**< the unchanged patch */
, Foward = 0 /**< the unchanged patch */
, Reverse = 1 /**< the inverse of the patch (i.e. a new patch which, when applied, undoes the old patch) */
};
VcsDiff();
virtual ~VcsDiff();
VcsDiff( const VcsDiff& );
/**
* @returns the source of the diff.
*/
QString diff() const;
/** @returns the base directory of the diff. */
QUrl baseDiff() const;
/**
* Depth - number of directories to left-strip from paths in the patch - see "patch -p"
* Defaults to 0
*/
uint depth() const;
/** Sets the base directory of the diff to the @p url */
void setBaseDiff(const QUrl& url);
/** Sets the depth of the diff to @p depth */
void setDepth(const uint depth);
/** Sets the diff source and parses it.
*
* @param diff the diff in unified diff format
*/
void setDiff( const QString& diff);
VcsDiff& operator=( const VcsDiff& rhs);
/** @returns whether or not there are changes in the diff */
bool isEmpty() const;
/**
* Creates a standalone diff containing the differences in a given range.
*
* @returns a diff containing only the changes from the current diff
* which are in the range startLine-endLine (in the diff text)
*
* @param startLine 0-based line number (in the diff) of the first line in the range
* @param endLine 0-based line number (in the diff) of the last line in the range
* @param dir if set to Reverse, the role of src and tgt are reversed, i.e. a diff is
* generated which can be applied to the target to get the source.
*/
VcsDiff subDiff(const uint startLine, const uint endLine, DiffDirection dir = Normal) const;
/**
* Creates a new standalone diff from a single hunk identified by a containing line.
*
* @returns a diff containing only the changes from hunk containing
* the line the line
*
* @param line 0-based line number (in the diff) of the line in the hunk
* @param dir if set to Reverse, the role of src and tgt are reversed, i.e. a diff is
* generated which can be applied to the target to get the source.
*/
VcsDiff subDiffHunk(const uint line, DiffDirection dir = Normal) const;
/**
* A struct representing a position in a source file.
*
* @note This should eventually be replaced with a @ref KDevelop::DocumentCursor,
* which, however, currently cannot be used in this file.
*/
struct SourceLocation {
/* Path to the source file (may be relative) */
QString path = {};
/* 0-based line number in the source file */
int line = -1;
};
/**
* Maps a line position in the diff to a corresponding line position in the source file.
*
* @param line a 0-based line position in the diff
* @returns a @ref SourceLocation whose path is the target file path (relative to diff root)
* and line the 0-based line position in the target file or {"", -1} if no such
* position exists.
*/
SourceLocation diffLineToSource (const uint line) const;
/**
* Maps a line position in the diff to a corresponding line position in the target file.
*
* @param line a 0-based line position in the diff
* @returns a @ref SourceLocation whose path is the source file path (relative to diff root)
* and line the 0-based line position in the source file or {"", -1} if no such
* position exists.
*/
SourceLocation diffLineToTarget (const uint line) const;
/**
* Represents a pair of files which are compared
*/
struct FilePair {
QString source;
QString target;
bool operator==(const FilePair p) const {return (source == p.source && target == p.target); }
};
/**
* @returns a list of filename pairs that the patch applies to
*
* @note: Each file-pair is only listed once for each consecutive run
* of hunks which apply to it.
*/
const QVector<FilePair> fileNames() const;
private:
QSharedDataPointer<class VcsDiffPrivate> d;
};
}
Q_DECLARE_METATYPE( KDevelop::VcsDiff )
Q_DECLARE_TYPEINFO( KDevelop::VcsDiff, Q_MOVABLE_TYPE );
Q_DECLARE_TYPEINFO( KDevelop::VcsDiff::FilePair, Q_MOVABLE_TYPE );
#endif
|