Fix an edge case in hg remove handling.

Summary:
The check on the type of an exception was inverted, which meant
`hg remove <path>` would throw an exception if the parent directory of `path`
did not exist. This is not correct because the user should be able to expect
to do:

```
mkdir -p /tmp/example
cd /tmp/example
hg init
mkdir mydir
touch mydir/a
hg add mydir/a
rm -rf mydir/a
hg rm mydir/a
```

In this scenario, `mydir` does not exist when `hg rm` is called, but the command
should succeed, making `mydir/a` no longer tracked.

Reviewed By: simpkins

Differential Revision: D4268451

fbshipit-source-id: 517d81252aa8e4b6bd1a32dece14776a9f7dd6f7
This commit is contained in:
Michael Bolin 2016-12-09 16:11:04 -08:00 committed by Facebook Github Bot
parent c58ab82952
commit ab750945fe
2 changed files with 22 additions and 1 deletions

View File

@ -693,7 +693,7 @@ void Dirstate::remove(RelativePathPiece path, bool force) {
parent = mount_->getTreeInode(path.dirname());
} catch (const std::system_error& e) {
auto value = e.code().value();
if (value == ENOENT || value == ENOTDIR) {
if (value != ENOENT && value != ENOTDIR) {
throw;
}
}

View File

@ -238,6 +238,27 @@ TEST(Dirstate, createDirstateHgAddFileRemoveItThenHgRemoveIt) {
verifyEmptyDirstate(dirstate);
}
TEST(Dirstate, createDirstateHgAddFileRemoveItThenHgRemoveItInSubdirectory) {
TestMountBuilder builder;
auto testMount = builder.build();
auto dirstate = testMount->getDirstate();
testMount->mkdir("dir1");
testMount->mkdir("dir1/dir2");
testMount->addFile("dir1/dir2/hello.txt", "I will be added.");
dirstate->add(RelativePathPiece("dir1/dir2/hello.txt"));
verifyExpectedDirstate(
dirstate, {{"dir1/dir2/hello.txt", HgStatusCode::ADDED}});
testMount->deleteFile("dir1/dir2/hello.txt");
testMount->rmdir("dir1/dir2");
verifyExpectedDirstate(
dirstate, {{"dir1/dir2/hello.txt", HgStatusCode::MISSING}});
dirstate->remove(RelativePathPiece("dir1/dir2/hello.txt"), /* force */ false);
verifyEmptyDirstate(dirstate);
}
TEST(Dirstate, createDirstateHgAddFileThenHgRemoveIt) {
TestMountBuilder builder;
auto testMount = builder.build();