mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-29 02:02:40 +01:00
Correctly parse git status --porcelain=2
output with filenames with spaces
Summary: Filenames are last in `git status --porcelain=2` lines; they are not escaped in any way, despite the fields being whitespace-delimited. `explode` thus happily chops apart filenames with spaces in them, causing later git operations to operate only on the filename up to the first space. Split the lines into the right number of elements -- in all cases, this is one more than the index we're using, since filenames come last. Test Plan: Altering a file with a space in its path, and running `arc diff -a`. Added tests. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: Korvin, epriestley Differential Revision: https://secure.phabricator.com/D19389
This commit is contained in:
parent
73f5afd441
commit
ad3087e5e1
3 changed files with 17 additions and 1 deletions
|
@ -660,14 +660,18 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
||||||
$parts = explode("\0", $stdout);
|
$parts = explode("\0", $stdout);
|
||||||
while (count($parts) > 1) {
|
while (count($parts) > 1) {
|
||||||
$entry = array_shift($parts);
|
$entry = array_shift($parts);
|
||||||
$entry_parts = explode(' ', $entry);
|
$entry_parts = explode(' ', $entry, 2);
|
||||||
if ($entry_parts[0] == '1') {
|
if ($entry_parts[0] == '1') {
|
||||||
|
$entry_parts = explode(' ', $entry, 9);
|
||||||
$path = $entry_parts[8];
|
$path = $entry_parts[8];
|
||||||
} else if ($entry_parts[0] == '2') {
|
} else if ($entry_parts[0] == '2') {
|
||||||
|
$entry_parts = explode(' ', $entry, 10);
|
||||||
$path = $entry_parts[9];
|
$path = $entry_parts[9];
|
||||||
} else if ($entry_parts[0] == 'u') {
|
} else if ($entry_parts[0] == 'u') {
|
||||||
|
$entry_parts = explode(' ', $entry, 11);
|
||||||
$path = $entry_parts[10];
|
$path = $entry_parts[10];
|
||||||
} else if ($entry_parts[0] == '?') {
|
} else if ($entry_parts[0] == '?') {
|
||||||
|
$entry_parts = explode(' ', $entry, 2);
|
||||||
$result[$entry_parts[1]] = self::FLAG_UNTRACKED;
|
$result[$entry_parts[1]] = self::FLAG_UNTRACKED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ final class ArcanistRepositoryAPIStateTestCase extends PhutilTestCase {
|
||||||
$this->parseState('git_basic.git.tgz');
|
$this->parseState('git_basic.git.tgz');
|
||||||
$this->parseState('git_submodules_dirty.git.tgz');
|
$this->parseState('git_submodules_dirty.git.tgz');
|
||||||
$this->parseState('git_submodules_staged.git.tgz');
|
$this->parseState('git_submodules_staged.git.tgz');
|
||||||
|
$this->parseState('git_spaces.git.tgz');
|
||||||
} else {
|
} else {
|
||||||
$this->assertSkipped(pht('Git is not installed'));
|
$this->assertSkipped(pht('Git is not installed'));
|
||||||
}
|
}
|
||||||
|
@ -156,6 +157,17 @@ final class ArcanistRepositoryAPIStateTestCase extends PhutilTestCase {
|
||||||
);
|
);
|
||||||
$this->assertEqual($expect_uncommitted, $api->getUncommittedStatus());
|
$this->assertEqual($expect_uncommitted, $api->getUncommittedStatus());
|
||||||
break;
|
break;
|
||||||
|
case 'git_spaces.git.tgz':
|
||||||
|
$expect_working = array(
|
||||||
|
'SPACES ADDED' => $f_add,
|
||||||
|
'SPACES DELETED' => $f_del,
|
||||||
|
'SPACES MODIFIED' => $f_mod,
|
||||||
|
'SPACES UNCOMMITTED' => $f_add | $f_unc,
|
||||||
|
'SPACES UNSTAGED' => $f_add | $f_mod | $f_uns | $f_unc,
|
||||||
|
'SPACES UNTRACKED' => $f_unt,
|
||||||
|
);
|
||||||
|
$this->assertEqual($expect_working, $api->getWorkingCopyStatus());
|
||||||
|
break;
|
||||||
case 'hg_basic.hg.tgz':
|
case 'hg_basic.hg.tgz':
|
||||||
$expect_uncommitted = array(
|
$expect_uncommitted = array(
|
||||||
'UNCOMMITTED' => $f_mod | $f_unc,
|
'UNCOMMITTED' => $f_mod | $f_unc,
|
||||||
|
|
BIN
src/repository/api/__tests__/state/git_spaces.git.tgz
Normal file
BIN
src/repository/api/__tests__/state/git_spaces.git.tgz
Normal file
Binary file not shown.
Loading…
Reference in a new issue