1
0
Fork 0
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:
epriestley 2011-03-07 21:33:36 -08:00
parent 12aa487790
commit 692d2a8b6f
2 changed files with 40 additions and 0 deletions

View file

@ -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]);
}
} }

View file

@ -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);