Browse Source

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>
stable-5.2
Ivan Frade 6 years ago
parent
commit
e64ce267f8
  1. 118
      org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
  2. 7
      org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
  3. 1
      org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java

118
org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java

@ -577,13 +577,69 @@ public class RepoCommandTest extends RepositoryTestCase {
// 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 class RepoCommandTest extends RepositoryTestCase {
}
}
@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();

7
org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java

@ -663,12 +663,13 @@ public class RepoCommand extends GitCommand<RevCommit> {
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()) {

1
org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java

@ -136,6 +136,7 @@ public class RepoProject implements Comparable<RepoProject> {
FileChannel channel = input.getChannel();
output.getChannel().transferFrom(channel, 0, channel.size());
}
destFile.setExecutable(srcFile.canExecute());
}
}

Loading…
Cancel
Save