mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-10 08:52:39 +01:00
Added support for 'hg export' diff format
Summary: This diff format is used by de-facto mercurial GUI called "TortoiseHG". It is available as the only way to copy diff into clipboard (right click commit, select "export", select "copy patch". I added this format support into arcanist so revisions in Differential can be created from TortoiseHG via simple copy- paste. Unit test added, manually tested. See: https://github.com/facebook/arcanist/pull/46 Reviewed by: epriestley
This commit is contained in:
parent
8d9e1d8479
commit
414e1e3e40
3 changed files with 76 additions and 13 deletions
|
@ -26,6 +26,7 @@ final class ArcanistDiffParser {
|
|||
protected $api;
|
||||
protected $text;
|
||||
protected $line;
|
||||
protected $lineSaved;
|
||||
protected $isGit;
|
||||
protected $isMercurial;
|
||||
protected $detectBinaryFiles = false;
|
||||
|
@ -234,22 +235,28 @@ final class ArcanistDiffParser {
|
|||
'(?P<type>diff -r) (?P<hgrev>[a-f0-9]+) (?:-r [a-f0-9]+ )?(?P<cur>.+)',
|
||||
);
|
||||
|
||||
$ok = false;
|
||||
$line = $this->getLine();
|
||||
$match = null;
|
||||
foreach ($patterns as $pattern) {
|
||||
$ok = preg_match('@^'.$pattern.'$@', $line, $match);
|
||||
if ($ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$ok = $this->tryMatchHeader($patterns, $line, $match);
|
||||
|
||||
if (!$ok) {
|
||||
$this->didFailParse(
|
||||
"Expected a hunk header, like 'Index: /path/to/file.ext' (svn), ".
|
||||
"'Property changes on: /path/to/file.ext' (svn properties), ".
|
||||
"'commit 59bcc3ad6775562f845953cf01624225' (git show), ".
|
||||
"'diff --git' (git diff), or '--- filename' (unified diff).");
|
||||
if (!$ok && $this->isFirstNonEmptyLine()) {
|
||||
// 'hg export' command creates so called "extended diff" that
|
||||
// contains some meta information and comment at the beginning
|
||||
// (isFirstNonEmptyLine() to check for beginning). Actual mercurial
|
||||
// code detects where comment ends and unified diff starts by
|
||||
// searching "diff -r" in the text.
|
||||
$this->saveLine();
|
||||
$line = $this->nextLineThatLooksLikeDiffStart();
|
||||
if (!$this->tryMatchHeader($patterns, $line, $match)) {
|
||||
// Restore line before guessing to display correct error.
|
||||
$this->restoreLine();
|
||||
$this->didFailParse(
|
||||
"Expected a hunk header, like 'Index: /path/to/file.ext' (svn), ".
|
||||
"'Property changes on: /path/to/file.ext' (svn properties), ".
|
||||
"'commit 59bcc3ad6775562f845953cf01624225' (git show), ".
|
||||
"'diff --git' (git diff), '--- filename' (unified diff), or " .
|
||||
"'diff -r' (hg diff or patch).");
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($match['type'])) {
|
||||
|
@ -325,6 +332,15 @@ final class ArcanistDiffParser {
|
|||
return $this->changes;
|
||||
}
|
||||
|
||||
protected function tryMatchHeader($patterns, $line, &$match) {
|
||||
foreach ($patterns as $pattern) {
|
||||
if (preg_match('@^'.$pattern.'$@', $line, $match)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function parseCommitMessage(ArcanistDiffChange $change) {
|
||||
$change->setType(ArcanistDiffChangeType::TYPE_MESSAGE);
|
||||
|
||||
|
@ -1026,6 +1042,34 @@ final class ArcanistDiffParser {
|
|||
return $this->getLine();
|
||||
}
|
||||
|
||||
protected function nextLineThatLooksLikeDiffStart() {
|
||||
while (($line = $this->nextLine()) !== null) {
|
||||
if (preg_match('/^\s*diff\s+-r/', $line)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $this->getLine();
|
||||
}
|
||||
|
||||
protected function saveLine() {
|
||||
$this->lineSaved = $this->line;
|
||||
}
|
||||
|
||||
protected function restoreLine() {
|
||||
$this->line = $this->lineSaved;
|
||||
}
|
||||
|
||||
protected function isFirstNonEmptyLine() {
|
||||
$count = count($this->text);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if (strlen(trim($this->text[$i])) != 0) {
|
||||
return ($i == $this->line);
|
||||
}
|
||||
}
|
||||
// Entire file is empty.
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function didFinishParse() {
|
||||
$this->text = null;
|
||||
}
|
||||
|
|
|
@ -537,6 +537,9 @@ EOTEXT
|
|||
'Test.java',
|
||||
$change->getCurrentPath());
|
||||
break;
|
||||
case 'hg-patch.hgdiff':
|
||||
$this->assertEqual(1, count($changes));
|
||||
break;
|
||||
default:
|
||||
throw new Exception("No test block for diff file {$diff_file}.");
|
||||
break;
|
||||
|
|
16
src/parser/__tests__/diff/hg-patch.hgdiff
Normal file
16
src/parser/__tests__/diff/hg-patch.hgdiff
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Some meta information
|
||||
Some
|
||||
multiline comment
|
||||
|
||||
with empty strings.
|
||||
|
||||
diff -r b073ee763933 -r 36fbb0c6c48a vim_nix.rb
|
||||
--- a/vim_nix.rb Wed Jul 04 11:28:53 2012 +0400
|
||||
+++ b/vim_nix.rb Wed Jul 25 23:14:44 2012 +0400
|
||||
@@ -11,6 +11,3 @@
|
||||
`sudo apt-get install vim-gtk`
|
||||
end
|
||||
|
||||
-File.delete( File.expand_path( "~/.vimrc" ) ) rescue
|
||||
-File.link( "#{DirDropbox()}/cfg/vim/_vimrc", File.expand_path( "~/.vimrc" ) )
|
||||
-
|
Loading…
Reference in a new issue