aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorYuxuan 'fishy' Wang <fishywang@google.com>2014-05-07 17:14:01 -0700
committerYuxuan 'fishy' Wang <fishywang@google.com>2014-05-09 17:25:50 -0700
commit0b15b48f741f87277e0d1c7d29637430b880dbde (patch)
treecc955145f481da1a92b90b30664a6c06eb0724ba /org.eclipse.jgit
parentd998bc938a21cb3871b442a3bb54b5807b6e4ed2 (diff)
downloadjgit-0b15b48f741f87277e0d1c7d29637430b880dbde.tar.gz
jgit-0b15b48f741f87277e0d1c7d29637430b880dbde.zip
Handle repo copyfile in bare repositories.
Change-Id: Ie06f0c3d1bc9b2123102efaa5542ec3c232b72cd Signed-off-by: Yuxuan 'fishy' Wang <fishywang@google.com>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java113
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java25
4 files changed, 106 insertions, 34 deletions
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index bb95fa85fd..b3049b07f4 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -51,6 +51,7 @@ cannotCreateConfig=cannot create config
cannotCreateDirectory=Cannot create directory {0}
cannotCreateHEAD=cannot create HEAD
cannotCreateIndexfile=Cannot create an index file with name {0}
+cannotCreateTempDir=Cannot create a temp dir
cannotDeleteCheckedOutBranch=Branch {0} is checked out and can not be deleted
cannotDeleteFile=Cannot delete file: {0}
cannotDeleteStaleTrackingRef=Cannot delete stale tracking ref {0}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
index b09129adb8..f9893644d7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -42,13 +42,13 @@
*/
package org.eclipse.jgit.gitrepo;
+import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.channels.FileChannel;
-import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -59,8 +59,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.eclipse.jgit.api.AddCommand;
-import org.eclipse.jgit.api.LsRemoteCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.GitCommand;
import org.eclipse.jgit.api.SubmoduleAddCommand;
@@ -78,6 +76,7 @@ import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
@@ -87,6 +86,7 @@ import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.util.FileUtils;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
@@ -121,8 +121,11 @@ public class RepoCommand extends GitCommand<RevCommit> {
* A callback to get ref sha1 of a repository from its uri.
*
* We provided a default implementation {@link DefaultRemoteReader} to
- * use ls-remote command to read the sha1 from the repository. Callers may
- * have their own quicker implementation.
+ * use ls-remote command to read the sha1 from the repository and clone the
+ * repository to read the file. Callers may have their own quicker
+ * implementation.
+ *
+ * @since 3.4
*/
public interface RemoteReader {
/**
@@ -135,6 +138,20 @@ public class RepoCommand extends GitCommand<RevCommit> {
* @return the sha1 of the remote repository
*/
public ObjectId sha1(String uri, String ref) throws GitAPIException;
+
+ /**
+ * Read a file from a remote repository.
+ *
+ * @param uri
+ * The URI of the remote repository
+ * @param ref
+ * The ref (branch/tag/etc.) to read
+ * @param path
+ * The relative path (inside the repo) to the file to read
+ * @return the file content.
+ */
+ public byte[] readFile(String uri, String ref, String path)
+ throws GitAPIException, IOException;
}
/** A default implementation of {@link RemoteReader} callback. */
@@ -153,23 +170,50 @@ public class RepoCommand extends GitCommand<RevCommit> {
Ref r = RefDatabase.findRef(map, ref);
return r != null ? r.getObjectId() : null;
}
+
+ public byte[] readFile(String uri, String ref, String path)
+ throws GitAPIException, IOException {
+ File dir = FileUtils.createTempDir("jgit_", ".git", null); //$NON-NLS-1$ //$NON-NLS-2$
+ Repository repo = Git
+ .cloneRepository()
+ .setBare(true)
+ .setDirectory(dir)
+ .setURI(uri)
+ .call()
+ .getRepository();
+ ObjectReader reader = repo.newObjectReader();
+ byte[] result;
+ try {
+ ObjectId oid = repo.resolve(ref + ":" + path); //$NON-NLS-1$
+ result = reader.open(oid).getBytes(Integer.MAX_VALUE);
+ } finally {
+ reader.release();
+ FileUtils.delete(dir, FileUtils.RECURSIVE);
+ }
+ return result;
+ }
}
private static class CopyFile {
+ final Repository repo;
+ final String path;
final String src;
final String dest;
- final String relativeDest;
CopyFile(Repository repo, String path, String src, String dest) {
- this.src = repo.getWorkTree() + "/" + path + "/" + src; //$NON-NLS-1$ //$NON-NLS-2$
- this.relativeDest = dest;
- this.dest = repo.getWorkTree() + "/" + dest; //$NON-NLS-1$
+ this.repo = repo;
+ this.path = path;
+ this.src = src;
+ this.dest = dest;
}
void copy() throws IOException {
- FileInputStream input = new FileInputStream(src);
+ File srcFile = new File(repo.getWorkTree(),
+ path + "/" + src); //$NON-NLS-1$
+ File destFile = new File(repo.getWorkTree(), dest);
+ FileInputStream input = new FileInputStream(srcFile);
try {
- FileOutputStream output = new FileOutputStream(dest);
+ FileOutputStream output = new FileOutputStream(destFile);
try {
FileChannel channel = input.getChannel();
output.getChannel().transferFrom(channel, 0, channel.size());
@@ -185,9 +229,9 @@ public class RepoCommand extends GitCommand<RevCommit> {
private static class Project {
final String name;
final String path;
+ final String revision;
final Set<String> groups;
final List<CopyFile> copyfiles;
- String revision;
Project(String name, String path, String revision, String groups) {
this.name = name;
@@ -315,26 +359,11 @@ public class RepoCommand extends GitCommand<RevCommit> {
}
for (Project proj : projects) {
if (inGroups(proj)) {
- if (proj.revision == null)
- proj.revision = defaultRevision;
- String url = remoteUrl + proj.name;
- command.addSubmodule(url, proj.path, proj.revision);
- for (CopyFile copyfile : proj.copyfiles) {
- try {
- copyfile.copy();
- } catch (IOException e) {
- throw new SAXException(
- RepoText.get().copyFileFailed, e);
- }
- AddCommand add = command.git
- .add()
- .addFilepattern(copyfile.relativeDest);
- try {
- add.call();
- } catch (GitAPIException e) {
- throw new SAXException(e);
- }
- }
+ command.addSubmodule(remoteUrl + proj.name,
+ proj.path,
+ proj.revision == null ?
+ defaultRevision : proj.revision,
+ proj.copyfiles);
}
}
}
@@ -503,7 +532,7 @@ public class RepoCommand extends GitCommand<RevCommit> {
cfg.setString("submodule", name, "path", name); //$NON-NLS-1$ //$NON-NLS-2$
cfg.setString("submodule", name, "url", uri); //$NON-NLS-1$ //$NON-NLS-2$
// create gitlink
- final DirCacheEntry dcEntry = new DirCacheEntry(name);
+ DirCacheEntry dcEntry = new DirCacheEntry(name);
ObjectId objectId;
if (ObjectId.isId(proj.revision))
objectId = ObjectId.fromString(proj.revision);
@@ -515,6 +544,16 @@ public class RepoCommand extends GitCommand<RevCommit> {
dcEntry.setObjectId(objectId);
dcEntry.setFileMode(FileMode.GITLINK);
builder.add(dcEntry);
+
+ for (CopyFile copyfile : proj.copyfiles) {
+ byte[] src = callback.readFile(
+ uri, proj.revision, copyfile.src);
+ objectId = inserter.insert(Constants.OBJ_BLOB, src);
+ dcEntry = new DirCacheEntry(copyfile.dest);
+ dcEntry.setObjectId(objectId);
+ dcEntry.setFileMode(FileMode.REGULAR_FILE);
+ builder.add(dcEntry);
+ }
}
String content = cfg.toText();
@@ -578,9 +617,11 @@ public class RepoCommand extends GitCommand<RevCommit> {
}
}
- private void addSubmodule(String url, String name, String revision) throws SAXException {
+ private void addSubmodule(String url, String name, String revision,
+ List<CopyFile> copyfiles) throws SAXException {
if (repo.isBare()) {
Project proj = new Project(url, name, revision, null);
+ proj.copyfiles.addAll(copyfiles);
bareProjects.add(proj);
} else {
SubmoduleAddCommand add = git
@@ -597,6 +638,10 @@ public class RepoCommand extends GitCommand<RevCommit> {
sub.checkout().setName(findRef(revision, subRepo)).call();
git.add().addFilepattern(name).call();
}
+ for (CopyFile copyfile : copyfiles) {
+ copyfile.copy();
+ git.add().addFilepattern(copyfile.dest).call();
+ }
} catch (GitAPIException e) {
throw new SAXException(e);
} catch (IOException e) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index 40e74ed892..576ba0f493 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -113,6 +113,7 @@ public class JGitText extends TranslationBundle {
/***/ public String cannotCreateDirectory;
/***/ public String cannotCreateHEAD;
/***/ public String cannotCreateIndexfile;
+ /***/ public String cannotCreateTempDir;
/***/ public String cannotDeleteCheckedOutBranch;
/***/ public String cannotDeleteFile;
/***/ public String cannotDeleteStaleTrackingRef;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
index b77807c701..330cac1543 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
@@ -362,4 +362,29 @@ public class FileUtils {
public static String readSymLink(File path) throws IOException {
return FS.DETECTED.readSymLink(path);
}
+
+ /**
+ * Create a temporary directory.
+ *
+ * @param prefix
+ * @param suffix
+ * @param dir
+ * The parent dir, can be null to use system default temp dir.
+ * @return the temp dir created.
+ * @throws IOException
+ * @since 3.4
+ */
+ public static File createTempDir(String prefix, String suffix, File dir)
+ throws IOException {
+ final int RETRY = 1; // When something bad happens, retry once.
+ for (int i = 0; i < RETRY; i++) {
+ File tmp = File.createTempFile(prefix, suffix, dir);
+ if (!tmp.delete())
+ continue;
+ if (!tmp.mkdir())
+ continue;
+ return tmp;
+ }
+ throw new IOException(JGitText.get().cannotCreateTempDir);
+ }
}