4
* Represents a change to an individual path.
6
final class ArcanistDiffChange {
8
protected $metadata = array();
11
protected $currentPath;
12
protected $awayPaths = array();
14
protected $oldProperties = array();
15
protected $newProperties = array();
17
protected $commitHash;
18
protected $type = ArcanistDiffChangeType::TYPE_CHANGE;
19
protected $fileType = ArcanistDiffChangeType::FILE_TEXT;
21
protected $hunks = array();
23
private $needsSyntheticGitHunks;
25
private $currentFileData;
26
private $originalFileData;
28
public function setOriginalFileData($original_file_data) {
29
$this->originalFileData = $original_file_data;
33
public function getOriginalFileData() {
34
return $this->originalFileData;
37
public function setCurrentFileData($current_file_data) {
38
$this->currentFileData = $current_file_data;
42
public function getCurrentFileData() {
43
return $this->currentFileData;
46
public function toDictionary() {
48
foreach ($this->hunks as $hunk) {
49
$hunks[] = $hunk->toDictionary();
53
'metadata' => $this->metadata,
54
'oldPath' => $this->oldPath,
55
'currentPath' => $this->currentPath,
56
'awayPaths' => $this->awayPaths,
57
'oldProperties' => $this->oldProperties,
58
'newProperties' => $this->newProperties,
59
'type' => $this->type,
60
'fileType' => $this->fileType,
61
'commitHash' => $this->commitHash,
66
public static function newFromDictionary(array $dict) {
68
foreach ($dict['hunks'] as $hunk) {
69
$hunks[] = ArcanistDiffHunk::newFromDictionary($hunk);
72
$obj = new ArcanistDiffChange();
73
$obj->metadata = $dict['metadata'];
74
$obj->oldPath = $dict['oldPath'];
75
$obj->currentPath = $dict['currentPath'];
76
// TODO: The backend is shipping down some bogus data, e.g. diff 199453.
77
// Should probably clean this up.
78
$obj->awayPaths = nonempty($dict['awayPaths'], array());
79
$obj->oldProperties = nonempty($dict['oldProperties'], array());
80
$obj->newProperties = nonempty($dict['newProperties'], array());
81
$obj->type = $dict['type'];
82
$obj->fileType = $dict['fileType'];
83
$obj->commitHash = $dict['commitHash'];
89
public static function newFromConduit(array $dicts) {
91
foreach ($dicts as $dict) {
92
$changes[] = self::newFromDictionary($dict);
97
public function getChangedLines($type) {
99
foreach ($this->hunks as $hunk) {
100
$lines += $hunk->getChangedLines($type);
105
public function getAllMetadata() {
106
return $this->metadata;
109
public function setMetadata($key, $value) {
110
$this->metadata[$key] = $value;
114
public function getMetadata($key) {
115
return idx($this->metadata, $key);
118
public function setCommitHash($hash) {
119
$this->commitHash = $hash;
123
public function getCommitHash() {
124
return $this->commitHash;
127
public function addAwayPath($path) {
128
$this->awayPaths[] = $path;
132
public function getAwayPaths() {
133
return $this->awayPaths;
136
public function setFileType($type) {
137
$this->fileType = $type;
141
public function getFileType() {
142
return $this->fileType;
145
public function setType($type) {
150
public function getType() {
154
public function setOldProperty($key, $value) {
155
$this->oldProperties[$key] = $value;
159
public function setNewProperty($key, $value) {
160
$this->newProperties[$key] = $value;
164
public function getOldProperties() {
165
return $this->oldProperties;
168
public function getNewProperties() {
169
return $this->newProperties;
172
public function setCurrentPath($path) {
173
$this->currentPath = $this->filterPath($path);
177
public function getCurrentPath() {
178
return $this->currentPath;
181
public function setOldPath($path) {
182
$this->oldPath = $this->filterPath($path);
186
public function getOldPath() {
187
return $this->oldPath;
190
public function addHunk(ArcanistDiffHunk $hunk) {
191
$this->hunks[] = $hunk;
195
public function dropHunks() {
196
$this->hunks = array();
200
public function getHunks() {
205
* @return array $old => array($new, )
207
public function buildLineMap() {
211
foreach ($this->getHunks() as $hunk) {
212
for ($n = $old; $n < $hunk->getOldOffset(); $n++) {
213
$line_map[$n] = array($n + $new - $old);
215
$old = $hunk->getOldOffset();
216
$new = $hunk->getNewOffset();
219
$lines = explode("\n", $hunk->getCorpus());
220
foreach ($lines as $line) {
221
$type = substr($line, 0, 1);
222
if ($type == '-' || $type == ' ') {
226
if ($type == '+' || $type == ' ') {
230
if ($type == ' ' || $type == '') {
231
$line_map += array_fill_keys($olds, $news);
240
public function convertToBinaryChange(ArcanistRepositoryAPI $api) {
242
// Fill in the binary data from the working copy.
244
$this->setOriginalFileData(
245
$api->getOriginalFileData(
246
$this->getOldPath()));
248
$this->setCurrentFileData(
249
$api->getCurrentFileData(
250
$this->getCurrentPath()));
252
$this->hunks = array();
253
$this->setFileType(ArcanistDiffChangeType::FILE_BINARY);
257
protected function filterPath($path) {
258
if ($path == '/dev/null') {
264
public function renderTextSummary() {
266
$type = $this->getType();
267
$file = $this->getFileType();
269
$char = ArcanistDiffChangeType::getSummaryCharacterForChangeType($type);
270
$attr = ArcanistDiffChangeType::getShortNameForFileType($file);
272
$attr = '('.$attr.')';
276
$summary[] = sprintf(
280
$this->getCurrentPath());
281
if (ArcanistDiffChangeType::isOldLocationChangeType($type)) {
282
foreach ($this->getAwayPaths() as $path) {
283
$summary[] = ' to: '.$path;
286
if (ArcanistDiffChangeType::isNewLocationChangeType($type)) {
287
$summary[] = ' from: '.$this->getOldPath();
290
return implode("\n", $summary);
293
public function getSymlinkTarget() {
294
if ($this->getFileType() != ArcanistDiffChangeType::FILE_SYMLINK) {
295
throw new Exception('Not a symlink!');
297
$hunks = $this->getHunks();
298
$hunk = reset($hunks);
299
$corpus = $hunk->getCorpus();
301
if (!preg_match('/^\+(?:link )?(.*)$/m', $corpus, $match)) {
302
throw new Exception('Failed to extract link target!');
304
return trim($match[1]);
307
public function setNeedsSyntheticGitHunks($needs_synthetic_git_hunks) {
308
$this->needsSyntheticGitHunks = $needs_synthetic_git_hunks;
312
public function getNeedsSyntheticGitHunks() {
313
return $this->needsSyntheticGitHunks;