Page MenuHomePhabricator

D18869.id45261.diff
No OneTemporary

D18869.id45261.diff

diff --git a/src/parser/ArcanistBundle.php b/src/parser/ArcanistBundle.php
--- a/src/parser/ArcanistBundle.php
+++ b/src/parser/ArcanistBundle.php
@@ -424,6 +424,9 @@
$cur_target = 'b/'.$cur_path;
}
+ $old_target = $this->encodeGitTargetPath($old_target);
+ $cur_target = $this->encodeGitTargetPath($cur_target);
+
$result[] = "diff --git {$old_index} {$cur_index}".$eol;
if ($type == ArcanistDiffChangeType::TYPE_ADD) {
@@ -591,6 +594,24 @@
return $results;
}
+ private function encodeGitTargetPath($path) {
+ // See T8768. If a target path contains spaces, it must be terminated with
+ // a tab. If we don't do this, Mercurial has the wrong behavior when
+ // applying the patch. This results in a semantic trailing whitespace
+ // character:
+ //
+ // +++ b/X Y.txt\t
+ //
+ // Everyone is at fault here and there are no winners.
+
+ if (strpos($path, ' ') !== false) {
+ $path = $path."\t";
+ }
+
+ return $path;
+ }
+
+
private function getOldPath(ArcanistDiffChange $change) {
$old_path = $change->getOldPath();
$type = $change->getType();
diff --git a/src/parser/__tests__/ArcanistBundleTestCase.php b/src/parser/__tests__/ArcanistBundleTestCase.php
--- a/src/parser/__tests__/ArcanistBundleTestCase.php
+++ b/src/parser/__tests__/ArcanistBundleTestCase.php
@@ -33,6 +33,37 @@
return ArcanistBundle::newFromDiff($diff);
}
+ public function testTabEncoding() {
+ // See T8768. Test that we add semantic trailing tab literals to diffs
+ // touching files with spaces in them. This is a pain to encode using the
+ // support toolset here so just do it manually.
+
+ // Note that the "b/X Y.txt" line has a trailing tab literal.
+
+ $diff = <<<EODIFF
+diff --git a/X Y.txt b/X Y.txt
+new file mode 100644
+--- /dev/null
++++ b/X Y.txt\t
+@@ -0,0 +1 @@
++quack
+
+
+EODIFF;
+
+ $bundle = ArcanistBundle::newFromDiff($diff);
+
+ $changes = $bundle->getChanges();
+ $this->assertEqual(1, count($changes));
+
+ // The path should parse as "X Y.txt" despite the trailing tab.
+ $change = head($changes);
+ $this->assertEqual('X Y.txt', $change->getCurrentPath());
+
+ // The tab should be restored when the diff is output again.
+ $this->assertEqual($diff, $bundle->toGitPatch());
+ }
+
/**
* Unarchive a saved git repository and apply each commit as though via
* "arc patch", verifying that the resulting tree hash is identical to the

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 20, 4:39 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7328514
Default Alt Text
D18869.id45261.diff (2 KB)

Event Timeline