HADOOP-8176. Disambiguate the destination of FsShell copies (Daryn Sharp via bobby)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1301612 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3e8c273f37
commit
af3163d1d1
|
@ -381,6 +381,9 @@ Release 0.23.2 - UNRELEASED
|
||||||
|
|
||||||
HADOOP-8175. Add -p option to mkdir in FsShell. (Daryn Sharp via szetszwo)
|
HADOOP-8175. Add -p option to mkdir in FsShell. (Daryn Sharp via szetszwo)
|
||||||
|
|
||||||
|
HADOOP-8176. Disambiguate the destination of FsShell copies (Daryn Sharp
|
||||||
|
via bobby)
|
||||||
|
|
||||||
Release 0.23.1 - 2012-02-17
|
Release 0.23.1 - 2012-02-17
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -200,6 +200,8 @@ abstract class CommandWithDestination extends FsCommand {
|
||||||
// a child path if dst is a dir; after recursion, it's always a dir
|
// a child path if dst is a dir; after recursion, it's always a dir
|
||||||
if ((getDepth() > 0) || (dst.exists && dst.stat.isDirectory())) {
|
if ((getDepth() > 0) || (dst.exists && dst.stat.isDirectory())) {
|
||||||
target = dst.getPathDataForChild(src);
|
target = dst.getPathDataForChild(src);
|
||||||
|
} else if (dst.representsDirectory()) { // see if path looks like a dir
|
||||||
|
target = dst.getPathDataForChild(src);
|
||||||
} else {
|
} else {
|
||||||
target = dst;
|
target = dst;
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,12 +188,21 @@ public class PathData implements Comparable<PathData> {
|
||||||
* @throws IOException upon unexpected error
|
* @throws IOException upon unexpected error
|
||||||
*/
|
*/
|
||||||
public boolean parentExists() throws IOException {
|
public boolean parentExists() throws IOException {
|
||||||
|
return representsDirectory()
|
||||||
|
? fs.exists(path) : fs.exists(path.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the path represents a directory as determined by the basename
|
||||||
|
* being "." or "..", or the path ending with a directory separator
|
||||||
|
* @return boolean if this represents a directory
|
||||||
|
*/
|
||||||
|
public boolean representsDirectory() {
|
||||||
String uriPath = uri.getPath();
|
String uriPath = uri.getPath();
|
||||||
String name = uriPath.substring(uriPath.lastIndexOf("/")+1);
|
String name = uriPath.substring(uriPath.lastIndexOf("/")+1);
|
||||||
// Path will munch off the chars that indicate a dir, so there's no way
|
// Path will munch off the chars that indicate a dir, so there's no way
|
||||||
// to perform this test except by examining the raw basename we maintain
|
// to perform this test except by examining the raw basename we maintain
|
||||||
return (name.isEmpty() || name.equals(".") || name.equals(".."))
|
return (name.isEmpty() || name.equals(".") || name.equals(".."));
|
||||||
? fs.exists(path) : fs.exists(path.getParent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -225,6 +225,54 @@ public class TestFsShellCopy {
|
||||||
assertEquals(exitCode, gotExit);
|
assertEquals(exitCode, gotExit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRepresentsDir() throws Exception {
|
||||||
|
Path subdirDstPath = new Path(dstPath, srcPath.getName());
|
||||||
|
String argv[] = null;
|
||||||
|
lfs.delete(dstPath, true);
|
||||||
|
assertFalse(lfs.exists(dstPath));
|
||||||
|
|
||||||
|
argv = new String[]{ "-put", srcPath.toString(), dstPath.toString() };
|
||||||
|
assertEquals(0, shell.run(argv));
|
||||||
|
assertTrue(lfs.exists(dstPath) && lfs.isFile(dstPath));
|
||||||
|
|
||||||
|
lfs.delete(dstPath, true);
|
||||||
|
assertFalse(lfs.exists(dstPath));
|
||||||
|
|
||||||
|
// since dst path looks like a dir, it should not copy the file and
|
||||||
|
// rename it to what looks like a directory
|
||||||
|
lfs.delete(dstPath, true); // make copy fail
|
||||||
|
for (String suffix : new String[]{ "/", "/." } ) {
|
||||||
|
argv = new String[]{
|
||||||
|
"-put", srcPath.toString(), dstPath.toString()+suffix };
|
||||||
|
assertEquals(1, shell.run(argv));
|
||||||
|
assertFalse(lfs.exists(dstPath));
|
||||||
|
assertFalse(lfs.exists(subdirDstPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
// since dst path looks like a dir, it should not copy the file and
|
||||||
|
// rename it to what looks like a directory
|
||||||
|
for (String suffix : new String[]{ "/", "/." } ) {
|
||||||
|
// empty out the directory and create to make copy succeed
|
||||||
|
lfs.delete(dstPath, true);
|
||||||
|
lfs.mkdirs(dstPath);
|
||||||
|
argv = new String[]{
|
||||||
|
"-put", srcPath.toString(), dstPath.toString()+suffix };
|
||||||
|
assertEquals(0, shell.run(argv));
|
||||||
|
assertTrue(lfs.exists(subdirDstPath));
|
||||||
|
assertTrue(lfs.isFile(subdirDstPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure .. is interpreted as a dir
|
||||||
|
String dotdotDst = dstPath+"/foo/..";
|
||||||
|
lfs.delete(dstPath, true);
|
||||||
|
lfs.mkdirs(new Path(dstPath, "foo"));
|
||||||
|
argv = new String[]{ "-put", srcPath.toString(), dotdotDst };
|
||||||
|
assertEquals(0, shell.run(argv));
|
||||||
|
assertTrue(lfs.exists(subdirDstPath));
|
||||||
|
assertTrue(lfs.isFile(subdirDstPath));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCopyMerge() throws Exception {
|
public void testCopyMerge() throws Exception {
|
||||||
Path root = new Path(testRootDir, "TestMerge");
|
Path root = new Path(testRootDir, "TestMerge");
|
||||||
|
|
Loading…
Reference in New Issue