mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-29 02:02:40 +01:00
Arcanist: Apply symlink patches correctly
Summary: When an arcbundle includes a symlink, we fail to apply it correctly when applying to a subversion working copy. Test Plan: created a diff which added a symlink, removed it locally, bundled and applied the patch, got a good symlink out Reviewed By: aran Reviewers: aran CC: epriestley, aran Differential Revision: 63
This commit is contained in:
parent
12aa487790
commit
692d2a8b6f
2 changed files with 40 additions and 0 deletions
|
@ -225,5 +225,18 @@ class ArcanistDiffChange {
|
||||||
return implode("\n", $summary);
|
return implode("\n", $summary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSymlinkTarget() {
|
||||||
|
if ($this->getFileType() != ArcanistDiffChangeType::FILE_SYMLINK) {
|
||||||
|
throw new Exception("Not a symlink!");
|
||||||
|
}
|
||||||
|
$hunks = $this->getHunks();
|
||||||
|
$hunk = reset($hunks);
|
||||||
|
$corpus = $hunk->getCorpus();
|
||||||
|
$match = null;
|
||||||
|
if (!preg_match('/^\+(?:link )?(.*)$/m', $corpus, $match)) {
|
||||||
|
throw new Exception("Failed to extract link target!");
|
||||||
|
}
|
||||||
|
return trim($match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,11 +177,21 @@ EOTEXT
|
||||||
$patches = array();
|
$patches = array();
|
||||||
$propset = array();
|
$propset = array();
|
||||||
$adds = array();
|
$adds = array();
|
||||||
|
$symlinks = array();
|
||||||
|
|
||||||
$changes = $bundle->getChanges();
|
$changes = $bundle->getChanges();
|
||||||
foreach ($changes as $change) {
|
foreach ($changes as $change) {
|
||||||
$type = $change->getType();
|
$type = $change->getType();
|
||||||
$should_patch = true;
|
$should_patch = true;
|
||||||
|
|
||||||
|
$filetype = $change->getFileType();
|
||||||
|
switch ($filetype) {
|
||||||
|
case ArcanistDiffChangeType::FILE_SYMLINK:
|
||||||
|
$should_patch = false;
|
||||||
|
$symlinks[] = $change;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case ArcanistDiffChangeType::TYPE_MOVE_AWAY:
|
case ArcanistDiffChangeType::TYPE_MOVE_AWAY:
|
||||||
case ArcanistDiffChangeType::TYPE_MULTICOPY:
|
case ArcanistDiffChangeType::TYPE_MULTICOPY:
|
||||||
|
@ -270,6 +280,23 @@ EOTEXT
|
||||||
$delete));
|
$delete));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($symlinks as $symlink) {
|
||||||
|
$link_target = $symlink->getSymlinkTarget();
|
||||||
|
$link_path = $symlink->getCurrentPath();
|
||||||
|
switch ($symlink->getType()) {
|
||||||
|
case ArcanistDiffChangeType::TYPE_ADD:
|
||||||
|
case ArcanistDiffChangeType::TYPE_MODIFY:
|
||||||
|
case ArcanistDiffChangeType::TYPE_MOVE_HERE:
|
||||||
|
case ArcanistDiffChangeType::TYPE_COPY_HERE:
|
||||||
|
execx(
|
||||||
|
'(cd %s && ln -sf %s %s)',
|
||||||
|
$repository_api->getPath(),
|
||||||
|
$link_target,
|
||||||
|
$link_path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($patches as $path => $patch) {
|
foreach ($patches as $path => $patch) {
|
||||||
$tmp = new TempFile();
|
$tmp = new TempFile();
|
||||||
Filesystem::writeFile($tmp, $patch);
|
Filesystem::writeFile($tmp, $patch);
|
||||||
|
|
Loading…
Reference in a new issue