@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Inform about moved code and prefer it over copied code

Summary:
Also reduce the memory usage a little bit (before increasing it again).

I use the same CSS class as for the copied code.

Test Plan: Parsed 100 diffs and checked about 10 of them - looks good.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Koolvin

Differential Revision: https://secure.phabricator.com/D2339

vrana e08b4cbb 087cc080

+104 -42
+48
scripts/differential/detect_copied_code.php
··· 1 + #!/usr/bin/env php 2 + <?php 3 + 4 + /* 5 + * Copyright 2012 Facebook, Inc. 6 + * 7 + * Licensed under the Apache License, Version 2.0 (the "License"); 8 + * you may not use this file except in compliance with the License. 9 + * You may obtain a copy of the License at 10 + * 11 + * http://www.apache.org/licenses/LICENSE-2.0 12 + * 13 + * Unless required by applicable law or agreed to in writing, software 14 + * distributed under the License is distributed on an "AS IS" BASIS, 15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 + * See the License for the specific language governing permissions and 17 + * limitations under the License. 18 + */ 19 + 20 + $root = dirname(dirname(dirname(__FILE__))); 21 + require_once $root.'/scripts/__init_script__.php'; 22 + 23 + if ($argc != 3 || !is_numeric($argv[1]) || !is_numeric($argv[2])) { 24 + echo "Usage: {$argv[0]} <diff_id_from> <diff_id_to>\n"; 25 + exit(1); 26 + } 27 + list(, $from, $to) = $argv; 28 + 29 + for ($diff_id = $from; $diff_id <= $to; $diff_id++) { 30 + echo "Processing $diff_id"; 31 + $diff = id(new DifferentialDiff())->load($diff_id); 32 + $diff->attachChangesets($diff->loadChangesets()); 33 + $orig_copy = array(); 34 + foreach ($diff->getChangesets() as $i => $changeset) { 35 + $orig_copy[$i] = idx((array)$changeset->getMetadata(), 'copy:lines'); 36 + $changeset->attachHunks($changeset->loadHunks()); 37 + } 38 + $diff->detectCopiedCode(); 39 + foreach ($diff->getChangesets() as $i => $changeset) { 40 + if (idx($changeset->getMetadata(), 'copy:lines') || $orig_copy[$i]) { 41 + echo "."; 42 + $changeset->save(); 43 + } 44 + } 45 + echo "\n"; 46 + } 47 + 48 + echo "Done.\n";
+16 -16
src/__celerity_resource_map__.php
··· 531 531 ), 532 532 'differential-changeset-view-css' => 533 533 array( 534 - 'uri' => '/res/5c7db62d/rsrc/css/application/differential/changeset-view.css', 534 + 'uri' => '/res/c7edd492/rsrc/css/application/differential/changeset-view.css', 535 535 'type' => 'css', 536 536 'requires' => 537 537 array( ··· 2491 2491 'uri' => '/res/pkg/0c96375e/core.pkg.js', 2492 2492 'type' => 'js', 2493 2493 ), 2494 - '1715d060' => 2494 + 'acdf073e' => 2495 2495 array( 2496 2496 'name' => 'differential.pkg.css', 2497 2497 'symbols' => ··· 2510 2510 11 => 'differential-local-commits-view-css', 2511 2511 12 => 'inline-comment-summary-css', 2512 2512 ), 2513 - 'uri' => '/res/pkg/1715d060/differential.pkg.css', 2513 + 'uri' => '/res/pkg/acdf073e/differential.pkg.css', 2514 2514 'type' => 'css', 2515 2515 ), 2516 2516 70509835 => ··· 2633 2633 'aphront-dialog-view-css' => '9c4e265b', 2634 2634 'aphront-error-view-css' => '9c4e265b', 2635 2635 'aphront-form-view-css' => '9c4e265b', 2636 - 'aphront-headsup-action-list-view-css' => '1715d060', 2636 + 'aphront-headsup-action-list-view-css' => 'acdf073e', 2637 2637 'aphront-headsup-view-css' => '9c4e265b', 2638 2638 'aphront-list-filter-view-css' => '9c4e265b', 2639 2639 'aphront-pager-view-css' => '9c4e265b', ··· 2643 2643 'aphront-tokenizer-control-css' => '9c4e265b', 2644 2644 'aphront-tooltip-css' => '9c4e265b', 2645 2645 'aphront-typeahead-control-css' => '9c4e265b', 2646 - 'differential-changeset-view-css' => '1715d060', 2647 - 'differential-core-view-css' => '1715d060', 2646 + 'differential-changeset-view-css' => 'acdf073e', 2647 + 'differential-core-view-css' => 'acdf073e', 2648 2648 'differential-inline-comment-editor' => '70509835', 2649 - 'differential-local-commits-view-css' => '1715d060', 2650 - 'differential-revision-add-comment-css' => '1715d060', 2651 - 'differential-revision-comment-css' => '1715d060', 2652 - 'differential-revision-comment-list-css' => '1715d060', 2653 - 'differential-revision-detail-css' => '1715d060', 2654 - 'differential-revision-history-css' => '1715d060', 2655 - 'differential-table-of-contents-css' => '1715d060', 2649 + 'differential-local-commits-view-css' => 'acdf073e', 2650 + 'differential-revision-add-comment-css' => 'acdf073e', 2651 + 'differential-revision-comment-css' => 'acdf073e', 2652 + 'differential-revision-comment-list-css' => 'acdf073e', 2653 + 'differential-revision-detail-css' => 'acdf073e', 2654 + 'differential-revision-history-css' => 'acdf073e', 2655 + 'differential-table-of-contents-css' => 'acdf073e', 2656 2656 'diffusion-commit-view-css' => 'c8ce2d88', 2657 2657 'diffusion-icons-css' => 'c8ce2d88', 2658 - 'inline-comment-summary-css' => '1715d060', 2658 + 'inline-comment-summary-css' => 'acdf073e', 2659 2659 'javelin-behavior' => '8a5de8a3', 2660 2660 'javelin-behavior-aphront-basic-tokenizer' => '97f65640', 2661 2661 'javelin-behavior-aphront-drag-and-drop' => '70509835', ··· 2709 2709 'maniphest-task-summary-css' => '7839ae2d', 2710 2710 'maniphest-transaction-detail-css' => '7839ae2d', 2711 2711 'phabricator-app-buttons-css' => '9c4e265b', 2712 - 'phabricator-content-source-view-css' => '1715d060', 2712 + 'phabricator-content-source-view-css' => 'acdf073e', 2713 2713 'phabricator-core-buttons-css' => '9c4e265b', 2714 2714 'phabricator-core-css' => '9c4e265b', 2715 2715 'phabricator-directory-css' => '9c4e265b', ··· 2720 2720 'phabricator-keyboard-shortcut' => '0c96375e', 2721 2721 'phabricator-keyboard-shortcut-manager' => '0c96375e', 2722 2722 'phabricator-menu-item' => '0c96375e', 2723 - 'phabricator-object-selector-css' => '1715d060', 2723 + 'phabricator-object-selector-css' => 'acdf073e', 2724 2724 'phabricator-paste-file-upload' => '0c96375e', 2725 2725 'phabricator-prefab' => '0c96375e', 2726 2726 'phabricator-project-tag-css' => '7839ae2d',
+6 -5
src/applications/differential/parser/changeset/DifferentialChangesetParser.php
··· 1410 1410 $n_text = $this->new[$ii]['text']; 1411 1411 $n_attr = ' class="comment"'; 1412 1412 } else if (isset($copy_lines[$n_num])) { 1413 - list($orig_file, $orig_line) = $copy_lines[$n_num]; 1413 + list($orig_file, $orig_line, $orig_type) = $copy_lines[$n_num]; 1414 + $title = ($orig_type == '-' ? 'Moved' : 'Copied').' from '; 1414 1415 if ($orig_file == '') { 1415 - $title = "line {$orig_line}"; 1416 + $title .= "line {$orig_line}"; 1416 1417 } else { 1417 - $title = 1418 + $title .= 1418 1419 basename($orig_file). 1419 1420 ":{$orig_line} in dir ". 1420 1421 dirname('/'.$orig_file); 1421 1422 } 1423 + $class = ($orig_type == '-' ? 'new-move' : 'new-copy'); 1422 1424 $n_attr = 1423 - ' class="new new-copy"'. 1424 - ' title="Copied from '.phutil_escape_html($title).'"'; 1425 + ' class="'.$class.'" title="'.phutil_escape_html($title).'"'; 1425 1426 } else if (empty($this->old[$ii])) { 1426 1427 $n_attr = ' class="new new-full"'; 1427 1428 } else {
+30 -21
src/applications/differential/storage/diff/DifferentialDiff.php
··· 156 156 return $diff; 157 157 } 158 158 159 - private function detectCopiedCode($min_width = 40, $min_lines = 3) { 159 + public function detectCopiedCode($min_width = 40, $min_lines = 3) { 160 160 $map = array(); 161 161 $files = array(); 162 + $types = array(); 162 163 foreach ($this->changesets as $changeset) { 163 164 $file = $changeset->getFilename(); 164 165 foreach ($changeset->getHunks() as $hunk) { 165 166 $line = $hunk->getOldOffset(); 166 - foreach (explode("\n", $hunk->makeOldFile()) as $code) { 167 - $files[$file][$line] = $code; 168 - if (strlen($code) >= $min_width) { 169 - $map[$code][] = array($file, $line); 167 + foreach (explode("\n", $hunk->getChanges()) as $code) { 168 + $type = (isset($code[0]) ? $code[0] : ''); 169 + if ($type == '-' || $type == ' ') { 170 + $code = (string)substr($code, 1); 171 + $files[$file][$line] = $code; 172 + $types[$file][$line] = $type; 173 + if (strlen($code) >= $min_width) { 174 + $map[$code][] = array($file, $line); 175 + } 176 + $line++; 170 177 } 171 - $line++; 172 178 } 173 179 } 174 180 } ··· 179 185 $added = $hunk->getAddedLines(); 180 186 for (reset($added); list($line, $code) = each($added); next($added)) { 181 187 if (isset($map[$code])) { // We found a long matching line. 182 - $lengths = array(); 183 - $max_offsets = array(); 188 + $best_length = 0; 184 189 foreach ($map[$code] as $val) { // Explore all candidates. 185 190 list($file, $orig_line) = $val; 186 - $lengths["$orig_line:$file"] = 1; 191 + $length = 1; 187 192 // Search also backwards for short lines. 188 193 foreach (array(-1, 1) as $direction) { 189 194 $offset = $direction; ··· 191 196 isset($added[$line + $offset]) && 192 197 idx($files[$file], $orig_line + $offset) === 193 198 $added[$line + $offset]) { 194 - $lengths["$orig_line:$file"]++; 199 + $length++; 195 200 $offset += $direction; 196 201 } 197 202 } 198 - // ($offset - 1) contains number of forward matching lines. 199 - $max_offsets["$orig_line:$file"] = $offset - 1; 203 + if ($length > $best_length || 204 + ($length == $best_length && // Prefer moves. 205 + idx($types[$file], $orig_line) == '-')) { 206 + $best_length = $length; 207 + // ($offset - 1) contains number of forward matching lines. 208 + $best_offset = $offset - 1; 209 + $best_file = $file; 210 + $best_line = $orig_line; 211 + } 200 212 } 201 - $length = max($lengths); // Choose longest candidate. 202 - $val = array_search($length, $lengths); 203 - $offset = $max_offsets[$val]; 204 - list($orig_line, $file) = explode(':', $val, 2); 205 - $save_file = ($file == $changeset->getFilename() ? '' : $file); 206 - for ($i = $length; $i--; ) { 207 - $copies[$line + $offset - $i] = ($length < $min_lines 213 + $file = ($best_file == $changeset->getFilename() ? '' : $best_file); 214 + for ($i = $best_length; $i--; ) { 215 + $type = idx($types[$best_file], $best_line + $best_offset - $i); 216 + $copies[$line + $best_offset - $i] = ($best_length < $min_lines 208 217 ? array() // Ignore short blocks. 209 - : array($save_file, $orig_line + $offset - $i)); 218 + : array($file, $best_line + $best_offset - $i, $type)); 210 219 } 211 - for ($i = 0; $i < $offset; $i++) { 220 + for ($i = 0; $i < $best_offset; $i++) { 212 221 next($added); 213 222 } 214 223 }
+4
webroot/rsrc/css/application/differential/changeset-view.css
··· 84 84 background: #ffffaa; 85 85 } 86 86 87 + .differential-diff td.new-move { 88 + background: #ffddaa; 89 + } 90 + 87 91 .differential-diff td.new-full, 88 92 .differential-diff td.new span.bright { 89 93 background: #aaffaa;