RepoCommand: Preserve executable bit in <copyfile>
The copyfile entry in the manifest file copies the contents of the file but doesn't keep the executable flag. This is inconsistent with repo tool behaviour, plus is natural to expect that the copy of a executable file is executable. Transfer the executable bit when copying the file, aligning the RepoCommand with repo tool and user expectations. Change-Id: I01b24f482d5939e01d496f032388b3a5c02a912a Signed-off-by: Ivan Frade <ifrade@google.com>
This commit is contained in:
parent
f648a3bd81
commit
e64ce267f8
|
@ -577,13 +577,69 @@ public void testRepoManifestCopyFile() throws Exception {
|
|||
// The original file should exist
|
||||
File hello = new File(localDb.getWorkTree(), "foo/hello.txt");
|
||||
assertTrue("The original file should exist", hello.exists());
|
||||
assertFalse("The original file should not be executable",
|
||||
hello.canExecute());
|
||||
assertContents(hello.toPath(), "master world");
|
||||
// The dest file should also exist
|
||||
hello = new File(localDb.getWorkTree(), "Hello");
|
||||
assertTrue("The destination file should exist", hello.exists());
|
||||
assertFalse("The destination file should not be executable",
|
||||
hello.canExecute());
|
||||
assertContents(hello.toPath(), "master world");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepoManifestCopyFile_executable() throws Exception {
|
||||
try (Git git = new Git(defaultDb)) {
|
||||
git.checkout().setName("master").call();
|
||||
File f = JGitTestUtil.writeTrashFile(defaultDb, "hello.sh",
|
||||
"content of the executable file");
|
||||
f.setExecutable(true);
|
||||
git.add().addFilepattern("hello.sh").call();
|
||||
git.commit().setMessage("Add binary file").call();
|
||||
}
|
||||
|
||||
Repository localDb = createWorkRepository();
|
||||
StringBuilder xmlContent = new StringBuilder();
|
||||
xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
|
||||
.append("<manifest>")
|
||||
.append("<remote name=\"remote1\" fetch=\".\" />")
|
||||
.append("<default revision=\"master\" remote=\"remote1\" />")
|
||||
.append("<project path=\"foo\" name=\"").append(defaultUri)
|
||||
.append("\">")
|
||||
.append("<copyfile src=\"hello.sh\" dest=\"copy-hello.sh\" />")
|
||||
.append("</project>").append("</manifest>");
|
||||
JGitTestUtil.writeTrashFile(localDb, "manifest.xml",
|
||||
xmlContent.toString());
|
||||
RepoCommand command = new RepoCommand(localDb);
|
||||
command.setPath(
|
||||
localDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
|
||||
.setURI(rootUri).call();
|
||||
|
||||
// The original file should exist and be an executable
|
||||
File hello = new File(localDb.getWorkTree(), "foo/hello.sh");
|
||||
assertTrue("The original file should exist", hello.exists());
|
||||
assertTrue("The original file must be executable", hello.canExecute());
|
||||
try (BufferedReader reader = Files.newBufferedReader(hello.toPath(),
|
||||
UTF_8)) {
|
||||
String content = reader.readLine();
|
||||
assertEquals("The original file should have expected content",
|
||||
"content of the executable file", content);
|
||||
}
|
||||
|
||||
// The destination file should also exist and be an executable
|
||||
hello = new File(localDb.getWorkTree(), "copy-hello.sh");
|
||||
assertTrue("The destination file should exist", hello.exists());
|
||||
assertTrue("The destination file must be executable",
|
||||
hello.canExecute());
|
||||
try (BufferedReader reader = Files.newBufferedReader(hello.toPath(),
|
||||
UTF_8)) {
|
||||
String content = reader.readLine();
|
||||
assertEquals("The destination file should have expected content",
|
||||
"content of the executable file", content);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBareRepo() throws Exception {
|
||||
Repository remoteDb = createBareRepository();
|
||||
|
@ -767,6 +823,68 @@ public void testCopyFileBare() throws Exception {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyFileBare_executable() throws Exception {
|
||||
try (Git git = new Git(defaultDb)) {
|
||||
git.checkout().setName(BRANCH).call();
|
||||
File f = JGitTestUtil.writeTrashFile(defaultDb, "hello.sh",
|
||||
"content of the executable file");
|
||||
f.setExecutable(true);
|
||||
git.add().addFilepattern("hello.sh").call();
|
||||
git.commit().setMessage("Add binary file").call();
|
||||
}
|
||||
|
||||
Repository remoteDb = createBareRepository();
|
||||
Repository tempDb = createWorkRepository();
|
||||
|
||||
StringBuilder xmlContent = new StringBuilder();
|
||||
xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
|
||||
.append("<manifest>")
|
||||
.append("<remote name=\"remote1\" fetch=\".\" />")
|
||||
.append("<default revision=\"master\" remote=\"remote1\" />")
|
||||
.append("<project path=\"foo\" name=\"").append(defaultUri)
|
||||
.append("\" revision=\"").append(BRANCH)
|
||||
.append("\" >")
|
||||
.append("<copyfile src=\"hello.txt\" dest=\"Hello\" />")
|
||||
.append("<copyfile src=\"hello.txt\" dest=\"foo/Hello\" />")
|
||||
.append("<copyfile src=\"hello.sh\" dest=\"copy-hello.sh\" />")
|
||||
.append("</project>").append("</manifest>");
|
||||
JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
|
||||
xmlContent.toString());
|
||||
RepoCommand command = new RepoCommand(remoteDb);
|
||||
command.setPath(
|
||||
tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
|
||||
.setURI(rootUri).call();
|
||||
// Clone it
|
||||
File directory = createTempDirectory("testCopyFileBare");
|
||||
try (Repository localDb = Git.cloneRepository().setDirectory(directory)
|
||||
.setURI(remoteDb.getDirectory().toURI().toString()).call()
|
||||
.getRepository()) {
|
||||
// The Hello file should exist
|
||||
File hello = new File(localDb.getWorkTree(), "Hello");
|
||||
assertTrue("The Hello file should exist", hello.exists());
|
||||
// The foo/Hello file should be skipped.
|
||||
File foohello = new File(localDb.getWorkTree(), "foo/Hello");
|
||||
assertFalse("The foo/Hello file should be skipped",
|
||||
foohello.exists());
|
||||
// The content of Hello file should be expected
|
||||
try (BufferedReader reader = Files.newBufferedReader(hello.toPath(),
|
||||
UTF_8)) {
|
||||
String content = reader.readLine();
|
||||
assertEquals("The Hello file should have expected content",
|
||||
"branch world", content);
|
||||
}
|
||||
|
||||
// The executable file must be there and preserve the executable bit
|
||||
File helloSh = new File(localDb.getWorkTree(), "copy-hello.sh");
|
||||
assertTrue("Destination file should exist", helloSh.exists());
|
||||
assertContents(helloSh.toPath(), "content of the executable file");
|
||||
assertTrue("Destination file should be executable",
|
||||
helloSh.canExecute());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplaceManifestBare() throws Exception {
|
||||
Repository remoteDb = createBareRepository();
|
||||
|
|
|
@ -663,12 +663,13 @@ public RevCommit call() throws GitAPIException {
|
|||
builder.add(dcEntry);
|
||||
|
||||
for (CopyFile copyfile : proj.getCopyFiles()) {
|
||||
byte[] src = callback.readFile(
|
||||
RemoteFile rf = callback.readFileWithMode(
|
||||
url, proj.getRevision(), copyfile.src);
|
||||
objectId = inserter.insert(Constants.OBJ_BLOB, src);
|
||||
objectId = inserter.insert(Constants.OBJ_BLOB,
|
||||
rf.getContents());
|
||||
dcEntry = new DirCacheEntry(copyfile.dest);
|
||||
dcEntry.setObjectId(objectId);
|
||||
dcEntry.setFileMode(FileMode.REGULAR_FILE);
|
||||
dcEntry.setFileMode(rf.getFileMode());
|
||||
builder.add(dcEntry);
|
||||
}
|
||||
for (LinkFile linkfile : proj.getLinkFiles()) {
|
||||
|
|
|
@ -136,6 +136,7 @@ public void copy() throws IOException {
|
|||
FileChannel channel = input.getChannel();
|
||||
output.getChannel().transferFrom(channel, 0, channel.size());
|
||||
}
|
||||
destFile.setExecutable(srcFile.canExecute());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue