1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-22 14:52:40 +01:00

Use a temporary file to execute arc patch

Summary:
Piping data around on Windows doesn't work well when it contains zany characters like "null" and "newline". Fixes T3266.

Instead of piping data into `git apply`, write to a temporary file.

Test Plan:
Ran `arc patch`, got good results.

  >>> [17] <exec> $ git apply --index --reject -- '/private/var/folders/8k/c3vkmjy5335gcxdzxkhwq82w0000gn/T/7z9iea6srikoo0sc/4266-ZEyvz9'

Reviewers: btrahan, hach-que

Reviewed By: hach-que

CC: aran

Maniphest Tasks: T3266

Differential Revision: https://secure.phabricator.com/D6070
This commit is contained in:
epriestley 2013-05-30 21:03:21 -07:00
parent 50419e584d
commit ae66d4caa9
4 changed files with 38 additions and 24 deletions

View file

@ -101,12 +101,7 @@ final class ArcanistJSHintLinter extends ArcanistLinter {
return $bin; return $bin;
} }
// Look for globally installed JSHint if (!Filesystem::binaryExists($bin)) {
list($err) = (phutil_is_windows()
? exec_manual('where %s', $bin)
: exec_manual('which %s', $bin));
if ($err) {
throw new ArcanistUsageException( throw new ArcanistUsageException(
"JSHint does not appear to be installed on this system. Install it ". "JSHint does not appear to be installed on this system. Install it ".
"(e.g., with 'npm install jshint -g') or configure ". "(e.g., with 'npm install jshint -g') or configure ".

View file

@ -29,6 +29,27 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
return $future; return $future;
} }
public function execPassthru($pattern /* , ... */) {
$args = func_get_args();
static $git = null;
if ($git === null) {
if (phutil_is_windows()) {
// NOTE: On Windows, phutil_passthru() uses 'bypass_shell' because
// everything goes to hell if we don't. We must provide an absolute
// path to Git for this to work properly.
$git = Filesystem::resolveBinary('git');
$git = csprintf('%s', $git);
} else {
$git = 'git';
}
}
$args[0] = $git.' '.$args[0];
return call_user_func_array('phutil_passthru', $args);
}
public function getSourceControlSystemName() { public function getSourceControlSystemName() {
return 'git'; return 'git';

View file

@ -45,7 +45,7 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
$args[0] = 'HGPLAIN=1 hg '.$args[0]; $args[0] = 'HGPLAIN=1 hg '.$args[0];
} }
return call_user_func_array("phutil_passthru", $args); return call_user_func_array('phutil_passthru', $args);
} }
public function getSourceControlSystemName() { public function getSourceControlSystemName() {

View file

@ -672,26 +672,24 @@ EOTEXT
return $patch_err; return $patch_err;
} else if ($repository_api instanceof ArcanistGitAPI) { } else if ($repository_api instanceof ArcanistGitAPI) {
$future = $repository_api->execFutureLocal(
'apply --index --reject');
$future->write($bundle->toGitPatch());
try { $patchfile = new TempFile();
$future->resolvex(); Filesystem::writeFile($patchfile, $bundle->toGitPatch());
} catch (CommandException $ex) {
$err = $repository_api->execPassthru(
'apply --index --reject -- %s',
$patchfile);
if ($err) {
echo phutil_console_format( echo phutil_console_format(
"\n<bg:red>** Patch Failed! **</bg>\n"); "\n<bg:red>** Patch Failed! **</bg>\n");
$stderr = $ex->getStdErr();
if (preg_match('/already exists in working directory/', $stderr)) { // NOTE: Git patches may fail if they change the case of a filename
echo phutil_console_wrap( // (for instance, from 'example.c' to 'Example.c'). As of now, Git
phutil_console_format( // can not apply these patches on case-insensitive filesystems and
"\n<bg:yellow>** WARNING **</bg> This patch may have failed ". // there is no way to build a patch which works.
"because it attempts to change the case of a filename (for ".
"instance, from 'example.c' to 'Example.c'). Git cannot apply ". throw new ArcanistUsageException("Unable to apply patch!");
"patches like this on case-insensitive filesystems. You must ".
"apply this patch manually.\n"));
}
throw $ex;
} }
if ($this->shouldCommit()) { if ($this->shouldCommit()) {