Merge "Check connection's error stream before reading from it"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java
index 632288e..2fb228e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java
@@ -111,7 +111,7 @@ public void testAddExistingSingleFile() throws IOException, NoFilepatternExcepti
}
@Test
- public void testAddExistingSingleFileWithNewLine() throws IOException,
+ public void testAddExistingSingleSmallFileWithNewLine() throws IOException,
NoFilepatternException {
File file = new File(db.getWorkTree(), "a.txt");
FileUtils.createNewFile(file);
@@ -135,6 +135,35 @@ public void testAddExistingSingleFileWithNewLine() throws IOException,
}
@Test
+ public void testAddExistingSingleMediumSizeFileWithNewLine()
+ throws IOException, NoFilepatternException {
+ File file = new File(db.getWorkTree(), "a.txt");
+ FileUtils.createNewFile(file);
+ StringBuilder data = new StringBuilder();
+ for (int i = 0; i < 1000; ++i) {
+ data.append("row1\r\nrow2");
+ }
+ String crData = data.toString();
+ PrintWriter writer = new PrintWriter(file);
+ writer.print(crData);
+ writer.close();
+ String lfData = data.toString().replaceAll("\r", "");
+ Git git = new Git(db);
+ db.getConfig().setString("core", null, "autocrlf", "false");
+ git.add().addFilepattern("a.txt").call();
+ assertEquals("[a.txt, mode:100644, content:" + data + "]",
+ indexState(CONTENT));
+ db.getConfig().setString("core", null, "autocrlf", "true");
+ git.add().addFilepattern("a.txt").call();
+ assertEquals("[a.txt, mode:100644, content:" + lfData + "]",
+ indexState(CONTENT));
+ db.getConfig().setString("core", null, "autocrlf", "input");
+ git.add().addFilepattern("a.txt").call();
+ assertEquals("[a.txt, mode:100644, content:" + lfData + "]",
+ indexState(CONTENT));
+ }
+
+ @Test
public void testAddExistingSingleBinaryFile() throws IOException,
NoFilepatternException {
File file = new File(db.getWorkTree(), "a.txt");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java
index 0b17972..97d0efe 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java
@@ -109,7 +109,7 @@ public void indexAdd() throws Exception {
File addedFile = writeTrashFile(addedPath, "content2");
git.add().addFilepattern(addedPath).call();
- RevCommit stashed = Git.wrap(db).stashCreate().call();
+ RevCommit stashed = git.stashCreate().call();
assertNotNull(stashed);
assertFalse(addedFile.exists());
@@ -134,7 +134,7 @@ public void indexAdd() throws Exception {
public void indexDelete() throws Exception {
git.rm().addFilepattern("file.txt").call();
- RevCommit stashed = Git.wrap(db).stashCreate().call();
+ RevCommit stashed = git.stashCreate().call();
assertNotNull(stashed);
assertEquals("content", read(committedFile));
@@ -158,7 +158,7 @@ public void indexDelete() throws Exception {
public void workingDirectoryModify() throws Exception {
writeTrashFile("file.txt", "content2");
- RevCommit stashed = Git.wrap(db).stashCreate().call();
+ RevCommit stashed = git.stashCreate().call();
assertNotNull(stashed);
assertEquals("content", read(committedFile));
@@ -187,7 +187,7 @@ public void workingDirectoryModifyInSubfolder() throws Exception {
writeTrashFile(path, "content2");
- RevCommit stashed = Git.wrap(db).stashCreate().call();
+ RevCommit stashed = git.stashCreate().call();
assertNotNull(stashed);
assertEquals("content", read(subfolderFile));
@@ -213,7 +213,7 @@ public void workingDirectoryModifyIndexChanged() throws Exception {
git.add().addFilepattern("file.txt").call();
writeTrashFile("file.txt", "content3");
- RevCommit stashed = Git.wrap(db).stashCreate().call();
+ RevCommit stashed = git.stashCreate().call();
assertNotNull(stashed);
assertEquals("content", read(committedFile));
@@ -240,7 +240,7 @@ public void workingDirectoryCleanIndexModify() throws Exception {
git.add().addFilepattern("file.txt").call();
writeTrashFile("file.txt", "content");
- RevCommit stashed = Git.wrap(db).stashCreate().call();
+ RevCommit stashed = git.stashCreate().call();
assertNotNull(stashed);
assertEquals("content", read(committedFile));
@@ -269,7 +269,7 @@ public void workingDirectoryDeleteIndexAdd() throws Exception {
FileUtils.delete(added);
assertFalse(added.exists());
- RevCommit stashed = Git.wrap(db).stashCreate().call();
+ RevCommit stashed = git.stashCreate().call();
assertNotNull(stashed);
assertFalse(added.exists());
@@ -296,7 +296,7 @@ public void workingDirectoryDeleteIndexEdit() throws Exception {
FileUtils.delete(committedFile);
assertFalse(committedFile.exists());
- RevCommit stashed = Git.wrap(db).stashCreate().call();
+ RevCommit stashed = git.stashCreate().call();
assertNotNull(stashed);
assertEquals("content", read(committedFile));
@@ -323,7 +323,7 @@ public void multipleEdits() throws Exception {
File addedFile = writeTrashFile(addedPath, "content2");
git.add().addFilepattern(addedPath).call();
- RevCommit stashed = Git.wrap(db).stashCreate().call();
+ RevCommit stashed = git.stashCreate().call();
assertNotNull(stashed);
assertTrue(committedFile.exists());
assertFalse(addedFile.exists());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashCreateCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashCreateCommandTest.java
index b91a50a..16fadef 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashCreateCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashCreateCommandTest.java
@@ -54,10 +54,14 @@
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RepositoryTestCase;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.file.ReflogEntry;
+import org.eclipse.jgit.storage.file.ReflogReader;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.util.FileUtils;
@@ -394,4 +398,23 @@ public void multipleEdits() throws Exception {
assertEquals(DiffEntry.ChangeType.ADD, diffs.get(1).getChangeType());
assertEquals("file2.txt", diffs.get(1).getNewPath());
}
+
+ @Test
+ public void refLogIncludesCommitMessage() throws Exception {
+ PersonIdent who = new PersonIdent("user", "user@email.com");
+ deleteTrashFile("file.txt");
+ RevCommit stashed = git.stashCreate().setPerson(who).call();
+ assertNotNull(stashed);
+ assertEquals("content", read(committedFile));
+ validateStashedCommit(stashed);
+
+ ReflogReader reader = new ReflogReader(git.getRepository(),
+ Constants.R_STASH);
+ ReflogEntry entry = reader.getLastEntry();
+ assertNotNull(entry);
+ assertEquals(ObjectId.zeroId(), entry.getOldId());
+ assertEquals(stashed, entry.getNewId());
+ assertEquals(who, entry.getWho());
+ assertEquals(stashed.getFullMessage(), entry.getComment());
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RemoteConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RemoteConfigTest.java
index 03a6c01..0cada5c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RemoteConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RemoteConfigTest.java
@@ -50,6 +50,7 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import java.util.Arrays;
import java.util.List;
import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -455,4 +456,66 @@ public void testSaveTimeout() throws Exception {
+ "\tfetch = +refs/heads/*:refs/remotes/origin/*\n"
+ "\ttimeout = 60\n");
}
+
+ @Test
+ public void noInsteadOf() throws Exception {
+ config.setString("remote", "origin", "url", "short:project.git");
+ config.setString("url", "https://server/repos/", "name", "short:");
+ RemoteConfig rc = new RemoteConfig(config, "origin");
+ assertFalse(rc.getURIs().isEmpty());
+ assertEquals("short:project.git", rc.getURIs().get(0).toASCIIString());
+ }
+
+ @Test
+ public void singleInsteadOf() throws Exception {
+ config.setString("remote", "origin", "url", "short:project.git");
+ config.setString("url", "https://server/repos/", "insteadOf", "short:");
+ RemoteConfig rc = new RemoteConfig(config, "origin");
+ assertFalse(rc.getURIs().isEmpty());
+ assertEquals("https://server/repos/project.git", rc.getURIs().get(0)
+ .toASCIIString());
+ }
+
+ @Test
+ public void multipleInsteadOf() throws Exception {
+ config.setString("remote", "origin", "url", "prefixproject.git");
+ config.setStringList("url", "https://server/repos/", "insteadOf",
+ Arrays.asList("pre", "prefix", "pref", "perf"));
+ RemoteConfig rc = new RemoteConfig(config, "origin");
+ assertFalse(rc.getURIs().isEmpty());
+ assertEquals("https://server/repos/project.git", rc.getURIs().get(0)
+ .toASCIIString());
+ }
+
+ @Test
+ public void noPushInsteadOf() throws Exception {
+ config.setString("remote", "origin", "pushurl", "short:project.git");
+ config.setString("url", "https://server/repos/", "name", "short:");
+ RemoteConfig rc = new RemoteConfig(config, "origin");
+ assertFalse(rc.getPushURIs().isEmpty());
+ assertEquals("short:project.git", rc.getPushURIs().get(0)
+ .toASCIIString());
+ }
+
+ @Test
+ public void singlePushInsteadOf() throws Exception {
+ config.setString("remote", "origin", "pushurl", "short:project.git");
+ config.setString("url", "https://server/repos/", "pushInsteadOf",
+ "short:");
+ RemoteConfig rc = new RemoteConfig(config, "origin");
+ assertFalse(rc.getPushURIs().isEmpty());
+ assertEquals("https://server/repos/project.git", rc.getPushURIs()
+ .get(0).toASCIIString());
+ }
+
+ @Test
+ public void multiplePushInsteadOf() throws Exception {
+ config.setString("remote", "origin", "pushurl", "prefixproject.git");
+ config.setStringList("url", "https://server/repos/", "pushInsteadOf",
+ Arrays.asList("pre", "prefix", "pref", "perf"));
+ RemoteConfig rc = new RemoteConfig(config, "origin");
+ assertFalse(rc.getPushURIs().isEmpty());
+ assertEquals("https://server/repos/project.git", rc.getPushURIs()
+ .get(0).toASCIIString());
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
index 8ead2b5..d5fffb9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
@@ -142,9 +142,11 @@ public StashCreateCommand setWorkingDirectoryMessage(String message) {
* Set the person to use as the author and committer in the commits made
*
* @param person
+ * @return {@code this}
*/
- public void setPerson(PersonIdent person) {
+ public StashCreateCommand setPerson(PersonIdent person) {
this.person = person;
+ return this;
}
/**
@@ -153,9 +155,11 @@ public void setPerson(PersonIdent person) {
* This value defaults to {@link Constants#R_STASH}
*
* @param ref
+ * @return {@code this}
*/
- public void setRef(String ref) {
+ public StashCreateCommand setRef(String ref) {
this.ref = ref;
+ return this;
}
private RevCommit parseCommit(final ObjectReader reader,
@@ -176,10 +180,13 @@ private CommitBuilder createBuilder(ObjectId headId) {
return builder;
}
- private void updateStashRef(ObjectId commitId) throws IOException {
+ private void updateStashRef(ObjectId commitId, PersonIdent refLogIdent,
+ String refLogMessage) throws IOException {
Ref currentRef = repo.getRef(ref);
RefUpdate refUpdate = repo.updateRef(ref);
refUpdate.setNewObjectId(commitId);
+ refUpdate.setRefLogIdent(refLogIdent);
+ refUpdate.setRefLogMessage(refLogMessage, false);
if (currentRef != null)
refUpdate.setExpectedOldObjectId(currentRef.getObjectId());
else
@@ -296,7 +303,8 @@ else if (wtIter == null && headIter != null)
commitId = inserter.insert(builder);
inserter.flush();
- updateStashRef(commitId);
+ updateStashRef(commitId, builder.getAuthor(),
+ builder.getMessage());
} finally {
inserter.release();
cache.unlock();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
index 0355e56..e03fe35 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
@@ -109,6 +109,29 @@ protected ObjectInserter() {
return tempBuffer;
}
+ static private final int tempBufSize;
+ static {
+ String s = System.getProperty("jgit.tempbufmaxsize");
+ if (s != null)
+ tempBufSize = Integer.parseInt(s);
+ else
+ tempBufSize = 1000000;
+ }
+
+ /**
+ * @param hintSize
+ * @return a temporary byte array for use by the caller
+ */
+ protected byte[] buffer(long hintSize) {
+ if (hintSize >= tempBufSize)
+ tempBuffer = new byte[0];
+ else if (tempBuffer == null)
+ tempBuffer = new byte[(int) hintSize];
+ else if (tempBuffer.length < hintSize)
+ tempBuffer = new byte[(int) hintSize];
+ return tempBuffer;
+ }
+
/** @return digest to help compute an ObjectId */
protected MessageDigest digest() {
digest.reset();
@@ -172,7 +195,7 @@ public ObjectId idFor(int objectType, long length, InputStream in)
md.update((byte) ' ');
md.update(Constants.encodeASCII(length));
md.update((byte) 0);
- byte[] buf = buffer();
+ byte[] buf = buffer(length);
while (length > 0) {
int n = in.read(buf, 0, (int) Math.min(length, buf.length));
if (n < 0)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsInserter.java
index 335e284e..e80a324 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsInserter.java
@@ -116,7 +116,7 @@ public ObjectId insert(int type, byte[] data, int off, int len)
@Override
public ObjectId insert(int type, long len, InputStream in)
throws IOException {
- byte[] buf = buffer();
+ byte[] buf = buffer(len);
if (len <= buf.length) {
IO.readFully(in, buf, 0, (int) len);
return insert(type, buf, 0, (int) len);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java
index ffd5c41..75f6b0b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java
@@ -95,8 +95,8 @@ public ObjectId insert(int type, byte[] data, int off, int len)
@Override
public ObjectId insert(final int type, long len, final InputStream is)
throws IOException {
- if (len <= buffer().length) {
- byte[] buf = buffer();
+ byte[] buf = buffer(len);
+ if (len <= buf.length) {
int actLen = IO.readFully(is, buf, 0);
return insert(type, buf, 0, actLen);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
index 3df56c6..f75ac70 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
@@ -49,7 +49,10 @@
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import org.eclipse.jgit.lib.Config;
@@ -84,6 +87,10 @@ public class RemoteConfig implements Serializable {
private static final String KEY_TIMEOUT = "timeout";
+ private static final String KEY_INSTEADOF = "insteadof";
+
+ private static final String KEY_PUSHINSTEADOF = "pushinsteadof";
+
private static final boolean DEFAULT_MIRROR = false;
/** Default value for {@link #getUploadPack()} if not specified. */
@@ -161,14 +168,17 @@ public RemoteConfig(final Config rc, final String remoteName)
String val;
vlst = rc.getStringList(SECTION, name, KEY_URL);
+ Map<String, String> insteadOf = getReplacements(rc, KEY_INSTEADOF);
uris = new ArrayList<URIish>(vlst.length);
for (final String s : vlst)
- uris.add(new URIish(s));
+ uris.add(new URIish(replaceUri(s, insteadOf)));
+ Map<String, String> pushInsteadOf = getReplacements(rc,
+ KEY_PUSHINSTEADOF);
vlst = rc.getStringList(SECTION, name, KEY_PUSHURL);
pushURIs = new ArrayList<URIish>(vlst.length);
for (final String s : vlst)
- pushURIs.add(new URIish(s));
+ pushURIs.add(new URIish(replaceUri(s, pushInsteadOf)));
vlst = rc.getStringList(SECTION, name, KEY_FETCH);
fetch = new ArrayList<RefSpec>(vlst.length);
@@ -260,6 +270,35 @@ private void unset(final Config rc, final String key) {
rc.unset(SECTION, getName(), key);
}
+ private Map<String, String> getReplacements(final Config config,
+ final String keyName) {
+ final Map<String, String> replacements = new HashMap<String, String>();
+ for (String url : config.getSubsections(KEY_URL))
+ for (String insteadOf : config.getStringList(KEY_URL, url, keyName))
+ replacements.put(insteadOf, url);
+ return replacements;
+ }
+
+ private String replaceUri(final String uri,
+ final Map<String, String> replacements) {
+ if (replacements.isEmpty())
+ return uri;
+ Entry<String, String> match = null;
+ for (Entry<String, String> replacement : replacements.entrySet()) {
+ // Ignore current entry if not longer than previous match
+ if (match != null
+ && match.getKey().length() > replacement.getKey().length())
+ continue;
+ if (!uri.startsWith(replacement.getKey()))
+ continue;
+ match = replacement;
+ }
+ if (match != null)
+ return match.getValue() + uri.substring(match.getKey().length());
+ else
+ return uri;
+ }
+
/**
* Get the local name this remote configuration is recognized as.
*