From adbcbc791b854071f0d2ca60a85832a025982ef8 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 21 May 2015 16:15:06 -0700 Subject: [PATCH 01/29] Expose Sets helper to tests outside org.eclipse.jgit.api A later patch will make use of this class in a org.eclipse.jgit.lib test. Change-Id: I2b268e6a5dbf12174201f45259f9f007686708d2 Signed-off-by: Jonathan Nieder --- org.eclipse.jgit.test/pom.xml | 1 + .../eclipse/jgit/api => src/org/eclipse/jgit/lib}/Sets.java | 6 +++--- .../tst/org/eclipse/jgit/api/MergeCommandTest.java | 1 + .../tst/org/eclipse/jgit/api/StatusCommandTest.java | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) rename org.eclipse.jgit.test/{tst/org/eclipse/jgit/api => src/org/eclipse/jgit/lib}/Sets.java (95%) diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml index 0e1419a16..da700939c 100644 --- a/org.eclipse.jgit.test/pom.xml +++ b/org.eclipse.jgit.test/pom.xml @@ -102,6 +102,7 @@ + src/ tst/ diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/Sets.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java similarity index 95% rename from org.eclipse.jgit.test/tst/org/eclipse/jgit/api/Sets.java rename to org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java index edfab551a..731685731 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/Sets.java +++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java @@ -41,13 +41,13 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.eclipse.jgit.api; +package org.eclipse.jgit.lib; import java.util.HashSet; import java.util.Set; -class Sets { - static Set of(T... elements) { +public class Sets { + public static Set of(T... elements) { Set ret = new HashSet(); for (T element : elements) ret.add(element); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java index 761aafa3f..0c0c6e5b5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java @@ -62,6 +62,7 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; +import org.eclipse.jgit.lib.Sets; import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; import org.eclipse.jgit.revwalk.RevCommit; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java index 47650232b..c70604ecb 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java @@ -53,6 +53,7 @@ import org.eclipse.jgit.api.errors.NoFilepatternException; import org.eclipse.jgit.errors.NoWorkTreeException; import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.lib.Sets; import org.junit.Test; public class StatusCommandTest extends RepositoryTestCase { From 02418ede592c9c6fc22a957d237c2f217fdb582d Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Mon, 18 May 2015 18:28:31 -0700 Subject: [PATCH 02/29] Add tests for ObjectFilter Test that - the default ObjectFilter is ALL - ObjectFilter affects nextObject() and not next() - omitting a tree implies omitting its subtrees - a blob or tree reached by another path is still returned - ObjectFilter can be mixed with RevFilter Change-Id: I144a53fe677070fff8c3ddf8cba07a848773bc1b Signed-off-by: Jonathan Nieder --- .../jgit/revwalk/ObjectWalkFilterTest.java | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkFilterTest.java diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkFilterTest.java new file mode 100644 index 000000000..55117b78e --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkFilterTest.java @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2015, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; +import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.Sets; +import org.eclipse.jgit.revwalk.ObjectWalk; +import org.eclipse.jgit.revwalk.filter.MessageRevFilter; +import org.eclipse.jgit.revwalk.filter.NotRevFilter; +import org.eclipse.jgit.revwalk.filter.ObjectFilter; + +import java.io.IOException; +import java.util.Set; + +public class ObjectWalkFilterTest { + private TestRepository tr; + private ObjectWalk rw; + + // 3 commits, 2 top-level trees, 4 subtrees, 3 blobs + private static final int OBJECT_COUNT = 12; + + @Before + public void setUp() throws Exception { + tr = new TestRepository<>(new InMemoryRepository( + new DfsRepositoryDescription("test"))); + rw = new ObjectWalk(tr.getRepository()); + + rw.markStart(tr.branch("master").commit() + .add("a/a", "1") + .add("b/b", "2") + .add("c/c", "3") + .message("initial commit") + + .child() + .rm("a/a") + .add("a/A", "1") + .message("capitalize a/a") + + .child() + .rm("a/A") + .add("a/a", "1") + .message("make a/A lowercase again") + .create()); + } + + @After + public void tearDown() { + rw.close(); + tr.getRepository().close(); + } + + private static class BlacklistObjectFilter extends ObjectFilter { + final Set badObjects; + + BlacklistObjectFilter(Set badObjects) { + this.badObjects = badObjects; + } + + @Override + public boolean include(ObjectWalk walker, AnyObjectId o) { + return !badObjects.contains(o); + } + } + + private AnyObjectId resolve(String revstr) throws Exception { + return tr.getRepository().resolve(revstr); + } + + private int countObjects() throws IOException { + int n = 0; + while (rw.next() != null) { + n++; + } + while (rw.nextObject() != null) { + n++; + } + return n; + } + + @Test + public void testDefaultFilter() throws Exception { + assertTrue("filter is ALL", + rw.getObjectFilter() == ObjectFilter.ALL); + assertEquals(OBJECT_COUNT, countObjects()); + } + + @Test + public void testObjectFilterCanFilterOutBlob() throws Exception { + AnyObjectId one = rw.parseAny(resolve("master:a/a")); + AnyObjectId two = rw.parseAny(resolve("master:b/b")); + rw.setObjectFilter(new BlacklistObjectFilter(Sets.of(one, two))); + + // 2 blobs filtered out + assertEquals(OBJECT_COUNT - 2, countObjects()); + } + + @Test + public void testFilteringCommitsHasNoEffect() throws Exception { + AnyObjectId initial = rw.parseCommit(resolve("master^^")); + rw.setObjectFilter(new BlacklistObjectFilter(Sets.of(initial))); + assertEquals(OBJECT_COUNT, countObjects()); + } + + @Test + public void testRevFilterAndObjectFilterCanCombine() throws Exception { + AnyObjectId one = rw.parseAny(resolve("master:a/a")); + AnyObjectId two = rw.parseAny(resolve("master:b/b")); + rw.setObjectFilter(new BlacklistObjectFilter(Sets.of(one, two))); + rw.setRevFilter(NotRevFilter.create( + MessageRevFilter.create("capitalize"))); + + // 2 blobs, one commit, two trees filtered out + assertEquals(OBJECT_COUNT - 5, countObjects()); + } + + @Test + public void testFilteringTreeFiltersSubtrees() throws Exception { + AnyObjectId capitalizeTree = rw.parseAny(resolve("master^:")); + rw.setObjectFilter(new BlacklistObjectFilter( + Sets.of(capitalizeTree))); + + // trees "master^:" and "master^:a" filtered out + assertEquals(OBJECT_COUNT - 2, countObjects()); + } + + @Test + public void testFilteringTreeFiltersReferencedBlobs() throws Exception { + AnyObjectId a1 = rw.parseAny(resolve("master:a")); + AnyObjectId a2 = rw.parseAny(resolve("master^:a")); + rw.setObjectFilter(new BlacklistObjectFilter(Sets.of(a1, a2))); + + // 2 trees, one blob filtered out + assertEquals(OBJECT_COUNT - 3, countObjects()); + } +} From d5a34551d595a348eb6234b9cf295a584a5cb1d6 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Sat, 11 Apr 2015 23:56:41 +0200 Subject: [PATCH 03/29] Fix potential null pointer access in IndexDiffFilter Change-Id: I39c2ea6b3090d7028cc1e246af6e3cc4e7bc70c2 Signed-off-by: Matthias Sohn --- .../src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java index 3ef3d9791..42725bc76 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java @@ -224,7 +224,8 @@ public boolean include(TreeWalk tw) throws MissingObjectException, // Only one chance left to detect a diff: between index and working // tree. Make use of the WorkingTreeIterator#isModified() method to // avoid computing SHA1 on filesystem content if not really needed. - return wi.isModified(di.getDirCacheEntry(), true, tw.getObjectReader()); + return wi.isModified(di == null ? null : di.getDirCacheEntry(), true, + tw.getObjectReader()); } /** From bb48901ddff79f0d81000b7e383fba9a8be6d23c Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Fri, 10 Apr 2015 02:37:04 +0200 Subject: [PATCH 04/29] Silence false potential null pointer access warnings Change-Id: I30c074a1b3436e47316b2eb2f083708161182d32 --- .../src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java index e03488b3c..75b0646ed 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java @@ -533,6 +533,7 @@ private ByteBuffer newCopyBuffer(PackOutputStream out, ReadableChannel rc) { return ByteBuffer.wrap(copyBuf, 0, bs); } + @SuppressWarnings("null") void copyAsIs(PackOutputStream out, DfsObjectToPack src, boolean validate, DfsReader ctx) throws IOException, StoredObjectRepresentationNotAvailableException { @@ -836,6 +837,7 @@ private static int read(ReadableChannel rc, ByteBuffer buf) return buf.position(); } + @SuppressWarnings("null") ObjectLoader load(DfsReader ctx, long pos) throws IOException { try { From 11a0dffd16e998959e3145de9c48dbdaf8f9757b Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Fri, 10 Apr 2015 23:53:08 +0200 Subject: [PATCH 05/29] Silence resource leak warnings where caller is responsible to close Change-Id: I63a74651689c10426d5f150ab2e027c6b63cab95 Signed-off-by: Matthias Sohn --- .../src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java | 6 ++++-- .../src/org/eclipse/jgit/lib/RepositoryCache.java | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java index eecbc224b..45dd7ee1a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java @@ -565,14 +565,16 @@ public B setup() throws IllegalArgumentException, IOException { * based on other options. If insufficient information is available, an * exception is thrown to the caller. * - * @return a repository matching this configuration. + * @return a repository matching this configuration. The caller is + * responsible to close the repository instance when it is no longer + * needed. * @throws IllegalArgumentException * insufficient parameters were set. * @throws IOException * the repository could not be accessed to configure the rest of * the builder's parameters. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "resource" }) public R build() throws IOException { R repo = (R) new FileRepository(setup()); if (isMustExist() && !repo.getObjectDatabase().exists()) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java index c7d957c4f..0c58a0bea 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java @@ -159,6 +159,7 @@ private RepositoryCache() { openLocks[i] = new Lock(); } + @SuppressWarnings("resource") private Repository openRepository(final Key location, final boolean mustExist) throws IOException { Reference ref = cacheMap.get(location); From eea43de7a4b8c012f8bb0089da0da44da2e8bafa Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Sun, 12 Apr 2015 00:43:07 +0200 Subject: [PATCH 06/29] Silence unused object warning in MyersDiff Change-Id: I7b6d7be4bb283c1f451bc58f29c71a8082580989 Signed-off-by: Matthias Sohn --- org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java | 1 + 1 file changed, 1 insertion(+) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java index 6216fdedb..9810a6ab2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java @@ -114,6 +114,7 @@ public class MyersDiff { /** Singleton instance of MyersDiff. */ public static final DiffAlgorithm INSTANCE = new LowLevelDiffAlgorithm() { + @SuppressWarnings("unused") @Override public void diffNonCommon(EditList edits, HashedSequenceComparator cmp, HashedSequence a, From 744c370c1be8044d1ccaaf84cd164324961fea1a Mon Sep 17 00:00:00 2001 From: Yuxuan 'fishy' Wang Date: Mon, 25 May 2015 11:41:24 -0700 Subject: [PATCH 07/29] Add getters to RepoProject. Change-Id: I74ded6c2c3f5985568cd77bd8799b45017fb1d09 Signed-off-by: Yuxuan 'fishy' Wang --- .../jgit/gitrepo/ManifestParserTest.java | 12 +-- .../eclipse/jgit/gitrepo/ManifestParser.java | 10 +- .../org/eclipse/jgit/gitrepo/RepoCommand.java | 22 ++--- .../org/eclipse/jgit/gitrepo/RepoProject.java | 97 ++++++++++++++++--- 4 files changed, 108 insertions(+), 33 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java index 1005b39ec..5ed4268eb 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java @@ -87,9 +87,9 @@ public void testManifestParser() throws Exception { for (RepoProject proj : parser.getProjects()) { String msg = String.format( "project \"%s\" should be included in unfiltered projects", - proj.path); - assertTrue(msg, results.contains(proj.path)); - results.remove(proj.path); + proj.getPath()); + assertTrue(msg, results.contains(proj.getPath())); + results.remove(proj.getPath()); } assertTrue( "Unfiltered projects shouldn't contain any unexpected results", @@ -101,9 +101,9 @@ public void testManifestParser() throws Exception { for (RepoProject proj : parser.getFilteredProjects()) { String msg = String.format( "project \"%s\" should be included in filtered projects", - proj.path); - assertTrue(msg, results.contains(proj.path)); - results.remove(proj.path); + proj.getPath()); + assertTrue(msg, results.contains(proj.getPath())); + results.remove(proj.getPath()); } assertTrue( "Filtered projects shouldn't contain any unexpected results", diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java index ec9fdfa4e..fa27948a6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java @@ -205,7 +205,7 @@ public void startElement( throw new SAXException(RepoText.get().invalidManifest); currentProject.addCopyFile(new CopyFile( rootRepo, - currentProject.path, + currentProject.getPath(), attributes.getValue("src"), //$NON-NLS-1$ attributes.getValue("dest"))); //$NON-NLS-1$ } else if ("include".equals(qName)) { //$NON-NLS-1$ @@ -266,7 +266,7 @@ public void endDocument() throws SAXException { throw new SAXException(e); } for (RepoProject proj : projects) { - String remote = proj.remote; + String remote = proj.getRemote(); if (remote == null) { if (defaultRemote == null) { if (filename != null) @@ -286,7 +286,7 @@ public void endDocument() throws SAXException { remoteUrl = remoteUrl + "/"; //$NON-NLS-1$ remoteUrls.put(remote, remoteUrl); } - proj.setUrl(remoteUrl + proj.name) + proj.setUrl(remoteUrl + proj.getName()) .setDefaultRevision(defaultRevision); } @@ -339,7 +339,7 @@ void removeOverlaps() { boolean inGroups(RepoProject proj) { for (String group : minusGroups) { - if (proj.groups.contains(group)) { + if (proj.inGroup(group)) { // minus groups have highest priority. return false; } @@ -349,7 +349,7 @@ boolean inGroups(RepoProject proj) { return true; } for (String group : plusGroups) { - if (proj.groups.contains(group)) + if (proj.inGroup(group)) return true; } return false; 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 d258250fe..b39dd8a1f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -379,10 +379,10 @@ public RevCommit call() throws GitAPIException { try { parser.read(inputStream); for (RepoProject proj : parser.getFilteredProjects()) { - addSubmodule(proj.url, - proj.path, + addSubmodule(proj.getUrl(), + proj.getPath(), proj.getRevision(), - proj.copyfiles); + proj.getCopyFiles()); } } catch (GitAPIException | IOException e) { throw new ManifestErrorException(e); @@ -403,17 +403,17 @@ public RevCommit call() throws GitAPIException { try (RevWalk rw = new RevWalk(repo)) { Config cfg = new Config(); for (RepoProject proj : bareProjects) { - String name = proj.path; - String nameUri = proj.name; + String name = proj.getPath(); + String nameUri = proj.getName(); cfg.setString("submodule", name, "path", name); //$NON-NLS-1$ //$NON-NLS-2$ cfg.setString("submodule", name, "url", nameUri); //$NON-NLS-1$ //$NON-NLS-2$ // create gitlink DirCacheEntry dcEntry = new DirCacheEntry(name); ObjectId objectId; - if (ObjectId.isId(proj.revision)) - objectId = ObjectId.fromString(proj.revision); + if (ObjectId.isId(proj.getRevision())) + objectId = ObjectId.fromString(proj.getRevision()); else { - objectId = callback.sha1(nameUri, proj.revision); + objectId = callback.sha1(nameUri, proj.getRevision()); } if (objectId == null) throw new RemoteUnavailableException(nameUri); @@ -421,9 +421,9 @@ public RevCommit call() throws GitAPIException { dcEntry.setFileMode(FileMode.GITLINK); builder.add(dcEntry); - for (CopyFile copyfile : proj.copyfiles) { + for (CopyFile copyfile : proj.getCopyFiles()) { byte[] src = callback.readFile( - nameUri, proj.revision, copyfile.src); + nameUri, proj.getRevision(), copyfile.src); objectId = inserter.insert(Constants.OBJ_BLOB, src); dcEntry = new DirCacheEntry(copyfile.dest); dcEntry.setObjectId(objectId); @@ -495,7 +495,7 @@ private void addSubmodule(String url, String name, String revision, List copyfiles) throws GitAPIException, IOException { if (repo.isBare()) { RepoProject proj = new RepoProject(url, name, revision, null, null); - proj.copyfiles.addAll(copyfiles); + proj.addCopyFiles(copyfiles); bareProjects.add(proj); } else { SubmoduleAddCommand add = git diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java index dfd4f1bba..1fff1c353 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java @@ -49,6 +49,8 @@ import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -62,14 +64,14 @@ * @since 4.0 */ public class RepoProject implements Comparable { - final String name; - final String path; - final String revision; - final String remote; - final Set groups; - final List copyfiles; - String url; - String defaultRevision; + private final String name; + private final String path; + private final String revision; + private final String remote; + private final Set groups; + private final List copyfiles; + private String url; + private String defaultRevision; /** * The representation of a copy file configuration. @@ -82,10 +84,13 @@ public static class CopyFile { /** * @param repo + * the super project. * @param path * the path of the project containing this copyfile config. * @param src + * the source path relative to the sub repo. * @param dest + * the destination path relative to the super project. */ public CopyFile(Repository repo, String path, String src, String dest) { this.repo = repo; @@ -108,7 +113,8 @@ public void copy() throws IOException { FileOutputStream output = new FileOutputStream(destFile); try { FileChannel channel = input.getChannel(); - output.getChannel().transferFrom(channel, 0, channel.size()); + output.getChannel().transferFrom( + channel, 0, channel.size()); } finally { output.close(); } @@ -120,10 +126,15 @@ public void copy() throws IOException { /** * @param name + * the relative path to the {@code remote} * @param path + * the relative path to the super project * @param revision + * a SHA-1 or branch name or tag name * @param remote + * name of the remote definition * @param groups + * comma separated group list */ public RepoProject(String name, String path, String revision, String remote, String groups) { @@ -162,15 +173,70 @@ public RepoProject setDefaultRevision(String defaultRevision) { return this; } + /** + * Get the name (relative path to the {@code remote}) of this sub repo. + * + * @return {@code name} + */ + public String getName() { + return name; + } + + /** + * Get the path (relative path to the super project) of this sub repo. + * + * @return {@code path} + */ + public String getPath() { + return path; + } + /** * Get the revision of the sub repo. * - * @return revision if set, or default revision. + * @return {@code revision} if set, or {@code defaultRevision}. */ public String getRevision() { return revision == null ? defaultRevision : revision; } + /** + * Getter for the copyfile configurations. + * + * @return Immutable copy of {@code copyfiles} + */ + public List getCopyFiles() { + return Collections.unmodifiableList(copyfiles); + } + + /** + * Get the url of the sub repo. + * + * @return {@code url} + */ + public String getUrl() { + return url; + } + + /** + * Get the name of the remote definition of the sub repo. + * + * @return {@remote} + */ + public String getRemote() { + return remote; + } + + /** + * Test whether this sub repo belongs to a specified group. + * + * @param group + * @return true if {@code group} is present. + */ + public boolean inGroup(String group) { + return groups.contains(group); + } + /** * Add a copy file configuration. * @@ -180,7 +246,16 @@ public void addCopyFile(CopyFile copyfile) { copyfiles.add(copyfile); } - String getPathWithSlash() { + /** + * Add a bunch of copyfile configurations. + * + * @param copyfiles + */ + public void addCopyFiles(Collection copyfiles) { + this.copyfiles.addAll(copyfiles); + } + + private String getPathWithSlash() { if (path.endsWith("/")) //$NON-NLS-1$ return path; else From 5e57cc95854dbf84bfafe3e61791a99b4d86746e Mon Sep 17 00:00:00 2001 From: David Pletcher Date: Mon, 25 May 2015 14:49:58 -0700 Subject: [PATCH 08/29] Enable public access to SimilarityIndex scoring function The SimilarityIndex class implements the useful capability of scoring the similarity between two files. That capability is required for a feature that's being developed in another package, to detect files derived from a set of potential sources. This CL adds a public factory method to create a SimilarityIndex from an ObjectLoader. It grants public access to the SimilarityIndex class, the score method, an inner exception class and a special marker instance of that exception class. Change-Id: I3f72670da643be3bb8e261c5af5e9664bcd0401b Signed-off-by: David Pletcher --- .../eclipse/jgit/diff/SimilarityIndex.java | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java index f376b8e36..1c40d7fcb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java @@ -63,10 +63,13 @@ * will not exceed 1 MiB per instance. The index starts out at a smaller size * (closer to 2 KiB), but may grow as more distinct blocks within the scanned * file are discovered. + * + * @since 4.0 */ -class SimilarityIndex { +public class SimilarityIndex { /** A special {@link TableFullException} used in place of OutOfMemoryError. */ - private static final TableFullException TABLE_FULL_OUT_OF_MEMORY = new TableFullException(); + public static final TableFullException + TABLE_FULL_OUT_OF_MEMORY = new TableFullException(); /** * Shift to apply before storing a key. @@ -105,6 +108,26 @@ class SimilarityIndex { /** {@code idHash.length == 1 << idHashBits}. */ private int idHashBits; + /** + * Create a new similarity index for the given object + * + * @param obj + * the object to hash + * @return similarity index for this object + * @throws IOException + * file contents cannot be read from the repository. + * @throws TableFullException + * object hashing overflowed the storage capacity of the + * SimilarityIndex. + */ + public static SimilarityIndex create(ObjectLoader obj) throws IOException, + TableFullException { + SimilarityIndex idx = new SimilarityIndex(); + idx.hash(obj); + idx.sort(); + return idx; + } + SimilarityIndex() { idHashBits = 8; idHash = new long[1 << idHashBits]; @@ -212,7 +235,27 @@ void sort() { Arrays.sort(idHash); } - int score(SimilarityIndex dst, int maxScore) { + /** + * Compute the similarity score between this index and another. + *

+ * A region of a file is defined as a line in a text file or a fixed-size + * block in a binary file. To prepare an index, each region in the file is + * hashed; the values and counts of hashes are retained in a sorted table. + * Define the similarity fraction F as the the count of matching regions + * between the two files divided between the maximum count of regions in + * either file. The similarity score is F multiplied by the maxScore + * constant, yielding a range [0, maxScore]. It is defined as maxScore for + * the degenerate case of two empty files. + *

+ * The similarity score is symmetrical; i.e. a.score(b) == b.score(a). + * + * @param dst + * the other index + * @param maxScore + * the score representing a 100% match + * @return the similarity score + */ + public int score(SimilarityIndex dst, int maxScore) { long max = Math.max(hashedCnt, dst.hashedCnt); if (max == 0) return maxScore; @@ -381,7 +424,8 @@ private static long countOf(long v) { return v & MAX_COUNT; } - static class TableFullException extends Exception { + /** Thrown by {@code create()} when file is too large. */ + public static class TableFullException extends Exception { private static final long serialVersionUID = 1L; } } From 0e8ac496cd9bbfa3fa306ac45706f501fc24ac38 Mon Sep 17 00:00:00 2001 From: Terry Parker Date: Mon, 11 May 2015 17:37:02 -0700 Subject: [PATCH 09/29] Add bitmap index misses to PackWriter.Statistics RevWalks to find commits that are not in bitmap indices are expensive. Track the count of commits that are enumerated via RevWalks as "bitmap index misses" in the PackWriter.Statistics class. Change-Id: Ie0135a0a0aeba2dfb6df78839d545006629f16cb Signed-off-by: Terry Parker --- .../internal/storage/pack/PackWriter.java | 13 +++++++++++ .../storage/pack/PackWriterBitmapWalker.java | 22 ++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java index 8fac90727..adc6bf11a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java @@ -1591,6 +1591,7 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor, findObjectsToPackUsingBitmaps(bitmapWalker, want, have); endPhase(countingMonitor); stats.timeCounting = System.currentTimeMillis() - countingStart; + stats.bitmapIndexMisses = bitmapWalker.getCountOfBitmapIndexMisses(); return; } } @@ -2084,6 +2085,8 @@ public long getDeltaBytes() { long totalObjects; + long bitmapIndexMisses; + long totalDeltas; long reusedObjects; @@ -2165,6 +2168,16 @@ public long getTotalObjects() { return totalObjects; } + /** + * @return the count of objects that needed to be discovered through an + * object walk because they were not found in bitmap indices. + * + * @since 4.0 + */ + public long getBitmapIndexMisses() { + return bitmapIndexMisses; + } + /** * @return total number of deltas output. This may be lower than the * actual number of deltas if a cached pack was reused. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java index 63a91cd82..debb2f2ab 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java @@ -71,6 +71,8 @@ final class PackWriterBitmapWalker { private final ProgressMonitor pm; + private long countOfBitmapIndexMisses; + PackWriterBitmapWalker( ObjectWalk walker, BitmapIndex bitmapIndex, ProgressMonitor pm) { this.walker = walker; @@ -78,6 +80,10 @@ final class PackWriterBitmapWalker { this.pm = (pm == null) ? NullProgressMonitor.INSTANCE : pm; } + long getCountOfBitmapIndexMisses() { + return countOfBitmapIndexMisses; + } + BitmapBuilder findObjects(Set start, BitmapBuilder seen, boolean ignoreMissingStart) throws MissingObjectException, IncorrectObjectTypeException, IOException { @@ -104,7 +110,8 @@ BitmapBuilder findObjects(Set start, BitmapBuilder seen, boo } if (marked) { - walker.setRevFilter(newRevFilter(seen, bitmapResult)); + BitmapRevFilter filter = newRevFilter(seen, bitmapResult); + walker.setRevFilter(filter); while (walker.next() != null) { // Iterate through all of the commits. The BitmapRevFilter does @@ -117,6 +124,7 @@ BitmapBuilder findObjects(Set start, BitmapBuilder seen, boo bitmapResult.add(ro, ro.getType()); pm.update(1); } + countOfBitmapIndexMisses += filter.getCountOfLoadedCommits(); } return bitmapResult; @@ -126,7 +134,7 @@ void reset() { walker.reset(); } - static RevFilter newRevFilter( + static BitmapRevFilter newRevFilter( final BitmapBuilder seen, final BitmapBuilder bitmapResult) { if (seen != null) { return new BitmapRevFilter() { @@ -146,12 +154,16 @@ protected boolean load(RevCommit cmit) { } static abstract class BitmapRevFilter extends RevFilter { + private long countOfLoadedCommits; + protected abstract boolean load(RevCommit cmit); @Override public final boolean include(RevWalk walker, RevCommit cmit) { - if (load(cmit)) + if (load(cmit)) { + countOfLoadedCommits++; return true; + } for (RevCommit p : cmit.getParents()) p.add(RevFlag.SEEN); return false; @@ -166,5 +178,9 @@ public final RevFilter clone() { public final boolean requiresCommitBody() { return false; } + + long getCountOfLoadedCommits() { + return countOfLoadedCommits; + } } } From b8c8008115e0c48d3d844af1dc858c700a9428e4 Mon Sep 17 00:00:00 2001 From: Dave Borowitz Date: Wed, 27 May 2015 09:40:32 -0700 Subject: [PATCH 10/29] FS: Extract GobblerThread into a private static class The primary goal is to improve exception readability. Since this is a standalone thread, just logging the stack trace of the caught exception is not very useful: java.io.IOException: Stream closed at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:162) at java.io.BufferedInputStream.read(BufferedInputStream.java:258) at org.eclipse.jgit.util.FS$2.run(FS.java:451) Providing a named class eliminates the "FS$2", and including the command name provides a little more context in the error message. A future improvement might include the stack trace that created the GobblerThread as well. Change-Id: Ibf16d15b47a85b6f41844a177e398c2fc94f27b0 --- .../eclipse/jgit/internal/JGitText.properties | 1 + .../org/eclipse/jgit/internal/JGitText.java | 1 + .../src/org/eclipse/jgit/util/FS.java | 90 ++++++++++++------- 3 files changed, 59 insertions(+), 33 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 f591eddfa..a2f06b1a2 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -257,6 +257,7 @@ exceptionCaughtDuringExecutionOfResetCommand=Exception caught during execution o exceptionCaughtDuringExecutionOfRevertCommand=Exception caught during execution of revert command. {0} exceptionCaughtDuringExecutionOfRmCommand=Exception caught during execution of rm command exceptionCaughtDuringExecutionOfTagCommand=Exception caught during execution of tag command +exceptionCaughtDuringExcecutionOfCommand=Exception caught during execution of command {0} in {1} exceptionHookExecutionInterrupted=Execution of "{0}" hook interrupted. exceptionOccurredDuringAddingOfOptionToALogCommand=Exception occurred during adding of {0} as option to a Log command exceptionOccurredDuringReadingOfGIT_DIR=Exception occurred during reading of $GIT_DIR/{0}. {1} 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 b53c7c95f..9f6efef57 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -316,6 +316,7 @@ public static JGitText get() { /***/ public String exceptionCaughtDuringExecutionOfRevertCommand; /***/ public String exceptionCaughtDuringExecutionOfRmCommand; /***/ public String exceptionCaughtDuringExecutionOfTagCommand; + /***/ public String exceptionCaughtDuringExcecutionOfCommand; /***/ public String exceptionHookExecutionInterrupted; /***/ public String exceptionOccurredDuringAddingOfOptionToALogCommand; /***/ public String exceptionOccurredDuringReadingOfGIT_DIR; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index fa0292e79..12dfe96b0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -440,40 +440,11 @@ protected static String readPipe(File dir, String[] command, String encoding, Ma if (env != null) { pb.environment().putAll(env); } - final Process p = pb.start(); - final BufferedReader lineRead = new BufferedReader( + Process p = pb.start(); + BufferedReader lineRead = new BufferedReader( new InputStreamReader(p.getInputStream(), encoding)); p.getOutputStream().close(); - final AtomicBoolean gooblerFail = new AtomicBoolean(false); - Thread gobbler = new Thread() { - public void run() { - InputStream is = p.getErrorStream(); - try { - int ch; - if (debug) - while ((ch = is.read()) != -1) - System.err.print((char) ch); - else - while (is.read() != -1) { - // ignore - } - } catch (IOException e) { - // Just print on stderr for debugging - if (debug) - e.printStackTrace(System.err); - gooblerFail.set(true); - } - try { - is.close(); - } catch (IOException e) { - // Just print on stderr for debugging - if (debug) { - LOG.debug("Caught exception in gobbler thread", e); //$NON-NLS-1$ - } - gooblerFail.set(true); - } - } - }; + GobblerThread gobbler = new GobblerThread(p, command, dir); gobbler.start(); String r = null; try { @@ -498,7 +469,7 @@ public void run() { int rc = p.waitFor(); gobbler.join(); if (rc == 0 && r != null && r.length() > 0 - && !gooblerFail.get()) + && !gobbler.fail.get()) return r; if (debug) { LOG.debug("readpipe rc=" + rc); //$NON-NLS-1$ @@ -517,6 +488,59 @@ public void run() { return null; } + private static class GobblerThread extends Thread { + private final Process p; + private final String desc; + private final String dir; + private final boolean debug = LOG.isDebugEnabled(); + private final AtomicBoolean fail = new AtomicBoolean(); + + private GobblerThread(Process p, String[] command, File dir) { + this.p = p; + if (debug) { + this.desc = Arrays.asList(command).toString(); + this.dir = dir.toString(); + } else { + this.desc = null; + this.dir = null; + } + } + + public void run() { + InputStream is = p.getErrorStream(); + try { + int ch; + if (debug) { + while ((ch = is.read()) != -1) { + System.err.print((char) ch); + } + } else { + while (is.read() != -1) { + // ignore + } + } + } catch (IOException e) { + logError(e); + fail.set(true); + } + try { + is.close(); + } catch (IOException e) { + logError(e); + fail.set(true); + } + } + + private void logError(Throwable t) { + if (!debug) { + return; + } + String msg = MessageFormat.format( + JGitText.get().exceptionCaughtDuringExcecutionOfCommand, desc, dir); + LOG.debug(msg, t); + } + } + /** * @return the path to the Git executable or {@code null} if it cannot be * determined. From 261b514ceb4271275d7ea68b20eee109442e0af4 Mon Sep 17 00:00:00 2001 From: Christian Halstrick Date: Thu, 23 Apr 2015 15:24:25 +0200 Subject: [PATCH 11/29] Better report too large pack-files from PushCommand JGits PushCommand and BasePackPushConnection were throwing generic TransportExceptions when the pushed pack-file was rejected by the server since it was too big. Let JGit better interprete the server's response to detect this situation and throw a more specific exception. This detection works by parsing the status line sent by the server. This change only recognizes the response sent by a JGit based server. All other servers which report such problems in a different way still lead to a generic TransportExceptions. Change-Id: Ic075764ea152939ce72c446252464620dd54edea Signed-off-by: Matthias Sohn --- .../src/org/eclipse/jgit/api/PushCommand.java | 4 ++ .../api/errors/TooLargePackException.java | 65 +++++++++++++++++++ .../jgit/errors/TooLargePackException.java | 17 ++++- .../transport/BasePackPushConnection.java | 4 ++ 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 org.eclipse.jgit/src/org/eclipse/jgit/api/errors/TooLargePackException.java diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java index c719f0a54..0e1ce5831 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java @@ -55,6 +55,7 @@ import org.eclipse.jgit.api.errors.InvalidRemoteException; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.errors.NotSupportedException; +import org.eclipse.jgit.errors.TooLargePackException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; @@ -156,6 +157,9 @@ public Iterable call() throws GitAPIException, PushResult result = transport.push(monitor, toPush, out); pushResults.add(result); + } catch (TooLargePackException e) { + throw new org.eclipse.jgit.api.errors.TooLargePackException( + e.getMessage(), e); } catch (TransportException e) { throw new org.eclipse.jgit.api.errors.TransportException( e.getMessage(), e); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/TooLargePackException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/TooLargePackException.java new file mode 100644 index 000000000..3833054da --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/TooLargePackException.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015, Christian Halstrick and + * other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v1.0 which accompanies this + * distribution, is reproduced below, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.api.errors; + +/** + * Exception thrown when the server rejected a too large pack + * + * @since 4.0 + */ +public class TooLargePackException extends TransportException { + private static final long serialVersionUID = 1L; + + /** + * @param msg + * message describing the transport failure. + */ + public TooLargePackException(String msg) { + super(msg); + } + + /** + * @param msg + * message describing the transport exception. + * @param cause + * why the transport failed. + */ + public TooLargePackException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargePackException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargePackException.java index 5cf0f802c..d54798541 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargePackException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargePackException.java @@ -43,17 +43,17 @@ package org.eclipse.jgit.errors; -import java.io.IOException; import java.text.MessageFormat; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.transport.URIish; /** * Thrown when a pack exceeds a given size limit * * @since 3.3 */ -public class TooLargePackException extends IOException { +public class TooLargePackException extends TransportException { private static final long serialVersionUID = 1L; /** @@ -66,4 +66,17 @@ public TooLargePackException(long packSizeLimit) { super(MessageFormat.format(JGitText.get().receivePackTooLarge, Long.valueOf(packSizeLimit))); } + + /** + * Construct a too large pack exception. + * + * @param uri + * URI used for transport + * @param s + * message + * @since 4.0 + */ + public TooLargePackException(URIish uri, String s) { + super(uri.setPass(null) + ": " + s); //$NON-NLS-1$ + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java index 1e5b8e8ad..24fb3be64 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java @@ -55,6 +55,7 @@ import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.PackProtocolException; +import org.eclipse.jgit.errors.TooLargePackException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.pack.PackWriter; @@ -314,6 +315,9 @@ private void readStatusReport(final Map refUpdates) if (!unpackLine.startsWith("unpack ")) //$NON-NLS-1$ throw new PackProtocolException(uri, MessageFormat.format(JGitText.get().unexpectedReportLine, unpackLine)); final String unpackStatus = unpackLine.substring("unpack ".length()); //$NON-NLS-1$ + if (unpackStatus.startsWith("error Pack exceeds the limit of")) //$NON-NLS-1$ + throw new TooLargePackException(uri, + unpackStatus.substring("error ".length())); //$NON-NLS-1$ if (!unpackStatus.equals("ok")) //$NON-NLS-1$ throw new TransportException(uri, MessageFormat.format( JGitText.get().errorOccurredDuringUnpackingOnTheRemoteEnd, unpackStatus)); From ebfd62433a58d23af221adfdffed56d9274f4268 Mon Sep 17 00:00:00 2001 From: Christian Halstrick Date: Tue, 19 May 2015 00:45:42 +0200 Subject: [PATCH 12/29] Fix that exceptions in ReceivePack cause Invalid Channel 101 exceptions When during a PushOperation the server hits an exception different from UnpackException the JGit server behaved wrong. That kind of exceptions are handled so late that the connection is already released and the information whether to talk sideband to the client is lost. In detail: ReceivePack.receive() will call release() and that will reset the capabilities. But later on the stack in ReceivePackServlet.doPost() it is tried to send a response to client now with reset capabilities (no sideband!). Change-Id: I0a609acc6152ab43b47a93d712deb65bb1105f75 Signed-off-by: Matthias Sohn --- .../http/test/GitServletResponseTests.java | 295 ++++++++++++++++++ .../jgit/transport/BaseReceivePack.java | 4 +- .../eclipse/jgit/transport/ReceivePack.java | 12 +- 3 files changed, 307 insertions(+), 4 deletions(-) create mode 100644 org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java new file mode 100644 index 000000000..fba1a5264 --- /dev/null +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2015, christian.Halstrick + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.http.test; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Collection; +import java.util.Collections; + +import javax.servlet.http.HttpServletRequest; + +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jgit.errors.CorruptObjectException; +import org.eclipse.jgit.errors.RepositoryNotFoundException; +import org.eclipse.jgit.errors.TooLargePackException; +import org.eclipse.jgit.errors.TransportException; +import org.eclipse.jgit.http.server.GitServlet; +import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.junit.http.HttpTestCase; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectChecker; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.revwalk.RevBlob; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.transport.PostReceiveHook; +import org.eclipse.jgit.transport.PreReceiveHook; +import org.eclipse.jgit.transport.ReceiveCommand; +import org.eclipse.jgit.transport.ReceivePack; +import org.eclipse.jgit.transport.RemoteRefUpdate; +import org.eclipse.jgit.transport.Transport; +import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for correct responses of {@link GitServlet}. Especially error + * situations where the {@link GitServlet} faces exceptions during request + * processing are tested + */ +public class GitServletResponseTests extends HttpTestCase { + private Repository srvRepo; + + private URIish srvURI; + + private GitServlet gs; + + private long maxPackSize = 0; // the maximum pack file size used by + // the server + + private PostReceiveHook postHook = null; + + private PreReceiveHook preHook = null; + + private ObjectChecker oc = null; + + /** + * Setup a http server using {@link GitServlet}. Tests should be able to + * configure the maximum pack file size, the object checker and custom hooks + * just before they talk to the server. + */ + @Before + public void setUp() throws Exception { + super.setUp(); + + final TestRepository srv = createTestRepository(); + final String repoName = srv.getRepository().getDirectory().getName(); + + ServletContextHandler app = server.addContext("/git"); + gs = new GitServlet(); + gs.setRepositoryResolver(new RepositoryResolver() { + public Repository open(HttpServletRequest req, String name) + throws RepositoryNotFoundException, + ServiceNotEnabledException { + if (!name.equals(repoName)) + throw new RepositoryNotFoundException(name); + + final Repository db = srv.getRepository(); + db.incrementOpen(); + return db; + } + }); + gs.setReceivePackFactory(new DefaultReceivePackFactory() { + public ReceivePack create(HttpServletRequest req, Repository db) + throws ServiceNotEnabledException, + ServiceNotAuthorizedException { + ReceivePack recv = super.create(req, db); + if (maxPackSize > 0) + recv.setMaxPackSizeLimit(maxPackSize); + if (postHook != null) + recv.setPostReceiveHook(postHook); + if (preHook != null) + recv.setPreReceiveHook(preHook); + if (oc != null) + recv.setObjectChecker(oc); + return recv; + } + + }); + app.addServlet(new ServletHolder(gs), "/*"); + + server.setUp(); + + srvRepo = srv.getRepository(); + srvURI = toURIish(app, repoName); + + StoredConfig cfg = srvRepo.getConfig(); + cfg.setBoolean("http", null, "receivepack", true); + cfg.save(); + } + + /** + * Configure a {@link GitServlet} that faces a {@link IllegalStateException} + * during executing preReceiveHooks. This used to lead to exceptions with a + * description of "invalid channel 101" on the client side. Make sure + * clients receive the correct response on the correct sideband. + * + * @throws Exception + */ + @Test + public void testRuntimeExceptionInPreReceiveHook() throws Exception { + final TestRepository client = createTestRepository(); + final RevBlob Q_txt = client + .blob("some blob content to measure pack size"); + final RevCommit Q = client.commit().add("Q", Q_txt).create(); + final Repository clientRepo = client.getRepository(); + final String srvBranchName = Constants.R_HEADS + "new.branch"; + Transport t; + + maxPackSize = 0; + postHook = null; + preHook = new PreReceiveHook() { + @Override + public void onPreReceive(ReceivePack rp, + Collection commands) { + throw new IllegalStateException(); + } + }; + + t = Transport.open(clientRepo, srvURI); + try { + RemoteRefUpdate update = new RemoteRefUpdate(clientRepo, Q.name(), + srvBranchName, false, null, null); + try { + t.push(NullProgressMonitor.INSTANCE, + Collections.singleton(update)); + fail("should not reach this line"); + } catch (Exception e) { + assertTrue(e instanceof TransportException); + } + } finally { + t.close(); + } + } + + /** + * Configure a {@link GitServlet} that faces a {@link IllegalStateException} + * during executing objectChecking. + * + * @throws Exception + */ + @Test + public void testObjectCheckerException() throws Exception { + final TestRepository client = createTestRepository(); + final RevBlob Q_txt = client + .blob("some blob content to measure pack size"); + final RevCommit Q = client.commit().add("Q", Q_txt).create(); + final Repository clientRepo = client.getRepository(); + final String srvBranchName = Constants.R_HEADS + "new.branch"; + Transport t; + + maxPackSize = 0; + postHook = null; + preHook = null; + oc = new ObjectChecker() { + @Override + public void checkCommit(byte[] raw) throws CorruptObjectException { + throw new IllegalStateException(); + } + }; + + t = Transport.open(clientRepo, srvURI); + try { + RemoteRefUpdate update = new RemoteRefUpdate(clientRepo, Q.name(), + srvBranchName, false, null, null); + try { + t.push(NullProgressMonitor.INSTANCE, + Collections.singleton(update)); + fail("should not reach this line"); + } catch (Exception e) { + assertTrue(e instanceof TransportException); + } + } finally { + t.close(); + } + } + + /** + * Configure a {@link GitServlet} that faces a {@link TooLargePackException} + * during persisting the pack and a {@link IllegalStateException} during + * executing postReceiveHooks. This used to lead to exceptions with a + * description of "invalid channel 101" on the client side. Make sure + * clients receive the correct response about the too large pack on the + * correct sideband. + * + * @throws Exception + */ + @Test + public void testUnpackErrorWithSubsequentExceptionInPostReceiveHook() + throws Exception { + final TestRepository client = createTestRepository(); + final RevBlob Q_txt = client + .blob("some blob content to measure pack size"); + final RevCommit Q = client.commit().add("Q", Q_txt).create(); + final Repository clientRepo = client.getRepository(); + final String srvBranchName = Constants.R_HEADS + "new.branch"; + Transport t; + + // this maxPackSize leads to an unPackError + maxPackSize = 400; + // this PostReceiveHook when called after an unsuccesfull unpack will + // lead to an IllegalStateException + postHook = new PostReceiveHook() { + public void onPostReceive(ReceivePack rp, + Collection commands) { + // the maxPackSize setting caused that the packfile couldn't be + // saved to disk. Calling getPackSize() now will lead to a + // IllegalStateException. + rp.getPackSize(); + } + }; + + t = Transport.open(clientRepo, srvURI); + try { + RemoteRefUpdate update = new RemoteRefUpdate(clientRepo, Q.name(), + srvBranchName, false, null, null); + try { + t.push(NullProgressMonitor.INSTANCE, + Collections.singleton(update)); + fail("should not reach this line"); + } catch (Exception e) { + assertTrue(e instanceof TooLargePackException); + } + } finally { + t.close(); + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java index eb770125c..9112ecbe3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java @@ -1583,7 +1583,9 @@ protected void release() throws IOException { pckIn = null; pckOut = null; refs = null; - enabledCapabilities = null; + // Keep the capabilities. If responses are sent after this release + // we need to remember at least whether sideband communication has to be + // used commands = null; if (timer != null) { try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java index e5eb82241..44b8778ee 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java @@ -240,10 +240,16 @@ void sendString(final String s) throws IOException { }); } - postReceive.onPostReceive(this, filterCommands(Result.OK)); - - if (unpackError != null) + if (unpackError != null) { + // we already know which exception to throw. Ignore + // potential additional exceptions raised in postReceiveHooks + try { + postReceive.onPostReceive(this, filterCommands(Result.OK)); + } catch (Throwable e) { + } throw new UnpackException(unpackError); + } + postReceive.onPostReceive(this, filterCommands(Result.OK)); } } From 1287cdaf338c4f1b782985597de9358de534bbef Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Wed, 27 May 2015 16:25:32 -0700 Subject: [PATCH 13/29] Close 'out' consistently in ArchiveCommand.call Whether the output stream specified with setOutputStream() is closed by ArchiveCommand.call() is murky and inconsistent: - on success, it is closed - if an exception is encountered when writing the archive, it is closed - if an exception is encountered when calling createArchiveStream to open the archive, we forget to close it Close the output stream consistently to avoid leaks. Now that the inner try-with-resources doesn't have its own finally block, this allows us to merge the two try blocks. It would be even better to never close the output stream. That will involve more API changes to avoid silently breaking callers, so it is deferred to a later change. Change-Id: I0185bdaa60ecee4a541eab5d8ff6c9c4dbe40bf1 Signed-off-by: Jonathan Nieder --- .../src/org/eclipse/jgit/api/ArchiveCommand.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java index 713866dc5..5f31be69f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java @@ -364,10 +364,11 @@ public ArchiveCommand(Repository repo) { } private OutputStream writeArchive(Format fmt) { - final String pfx = prefix == null ? "" : prefix; //$NON-NLS-1$ - try (final TreeWalk walk = new TreeWalk(repo)) { - final T outa = fmt.createArchiveOutputStream(out, formatOptions); - try (final RevWalk rw = new RevWalk(walk.getObjectReader())) { + try { + try (TreeWalk walk = new TreeWalk(repo); + RevWalk rw = new RevWalk(walk.getObjectReader())) { + final String pfx = prefix == null ? "" : prefix; //$NON-NLS-1$ + final T outa = fmt.createArchiveOutputStream(out, formatOptions); final MutableObjectId idBuf = new MutableObjectId(); final ObjectReader reader = walk.getObjectReader(); @@ -376,7 +377,7 @@ private OutputStream writeArchive(Format fmt) { walk.setFilter(PathFilterGroup.createFromStrings(paths)); while (walk.next()) { - final String name = pfx + walk.getPathString(); + String name = pfx + walk.getPathString(); FileMode mode = walk.getFileMode(0); if (walk.isSubtree()) @@ -395,10 +396,10 @@ private OutputStream writeArchive(Format fmt) { fmt.putEntry(outa, name, mode, reader.open(idBuf)); } outa.close(); + return out; } finally { out.close(); } - return out; } catch (IOException e) { // TODO(jrn): Throw finer-grained errors. throw new JGitInternalException( From a5778b6f41c113b06687d47e606595ce8e2725a4 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Wed, 27 May 2015 16:25:49 -0700 Subject: [PATCH 14/29] archive: Drop unnecessary empty comments and 'final' qualifiers on locals Early JGit code used comments to inform the Eclipse formatter about where to break lines and used final in the hope of making code faster. The ArchiveCommand command implementation imitated that style. Nowadays the project relies less on the Eclipse formatter and relies more on Java having sane performance with local variables that are not explicitly marked 'final'. Removing the unnecessary empty comments and 'final' qualifiers makes this code more readable and more consistent with recent JGit code. Change-Id: I7a181432eda7e18bd32cf110d89c0efbe490c4f1 Signed-off-by: Jonathan Nieder --- .../tst/org/eclipse/jgit/pgm/ArchiveTest.java | 150 +++++++++--------- .../org/eclipse/jgit/api/ArchiveCommand.java | 10 +- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java index 6ce092d3c..4222a2dcc 100644 --- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java @@ -92,22 +92,22 @@ public void setUp() throws Exception { @Ignore("Some versions of java.util.zip refuse to write an empty ZIP") @Test public void testEmptyArchive() throws Exception { - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=zip " + emptyTree, db); assertArrayEquals(new String[0], listZipEntries(result)); } @Test public void testEmptyTar() throws Exception { - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=tar " + emptyTree, db); assertArrayEquals(new String[0], listTarEntries(result)); } @Test public void testUnrecognizedFormat() throws Exception { - final String[] expect = new String[] { "fatal: Unknown archive format 'nonsense'" }; - final String[] actual = execute("git archive --format=nonsense " + emptyTree); + String[] expect = new String[] { "fatal: Unknown archive format 'nonsense'" }; + String[] actual = execute("git archive --format=nonsense " + emptyTree); assertArrayEquals(expect, actual); } @@ -120,9 +120,9 @@ public void testArchiveWithFiles() throws Exception { git.add().addFilepattern("c").call(); git.commit().setMessage("populate toplevel").call(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=zip HEAD", db); - assertArrayEquals(new String[] { "a", "c" }, // + assertArrayEquals(new String[] { "a", "c" }, listZipEntries(result)); } @@ -135,9 +135,9 @@ private void commitGreeting() throws Exception { @Test public void testDefaultFormatIsTar() throws Exception { commitGreeting(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive HEAD", db); - assertArrayEquals(new String[] { "greeting" }, // + assertArrayEquals(new String[] { "greeting" }, listTarEntries(result)); } @@ -147,8 +147,8 @@ private static String shellQuote(String s) { @Test public void testFormatOverridesFilename() throws Exception { - final File archive = new File(db.getWorkTree(), "format-overrides-name.tar"); - final String path = archive.getAbsolutePath(); + File archive = new File(db.getWorkTree(), "format-overrides-name.tar"); + String path = archive.getAbsolutePath(); commitGreeting(); assertArrayEquals(new String[] { "" }, @@ -162,8 +162,8 @@ public void testFormatOverridesFilename() throws Exception { @Test public void testUnrecognizedExtensionMeansTar() throws Exception { - final File archive = new File(db.getWorkTree(), "example.txt"); - final String path = archive.getAbsolutePath(); + File archive = new File(db.getWorkTree(), "example.txt"); + String path = archive.getAbsolutePath(); commitGreeting(); assertArrayEquals(new String[] { "" }, @@ -176,8 +176,8 @@ public void testUnrecognizedExtensionMeansTar() throws Exception { @Test public void testNoExtensionMeansTar() throws Exception { - final File archive = new File(db.getWorkTree(), "example"); - final String path = archive.getAbsolutePath(); + File archive = new File(db.getWorkTree(), "example"); + String path = archive.getAbsolutePath(); commitGreeting(); assertArrayEquals(new String[] { "" }, @@ -189,8 +189,8 @@ public void testNoExtensionMeansTar() throws Exception { @Test public void testExtensionMatchIsAnchored() throws Exception { - final File archive = new File(db.getWorkTree(), "two-extensions.zip.bak"); - final String path = archive.getAbsolutePath(); + File archive = new File(db.getWorkTree(), "two-extensions.zip.bak"); + String path = archive.getAbsolutePath(); commitGreeting(); assertArrayEquals(new String[] { "" }, @@ -202,8 +202,8 @@ public void testExtensionMatchIsAnchored() throws Exception { @Test public void testZipExtension() throws Exception { - final File archiveWithDot = new File(db.getWorkTree(), "greeting.zip"); - final File archiveNoDot = new File(db.getWorkTree(), "greetingzip"); + File archiveWithDot = new File(db.getWorkTree(), "greeting.zip"); + File archiveNoDot = new File(db.getWorkTree(), "greetingzip"); commitGreeting(); execute("git archive " + @@ -218,8 +218,8 @@ public void testZipExtension() throws Exception { @Test public void testTarExtension() throws Exception { - final File archive = new File(db.getWorkTree(), "tarball.tar"); - final String path = archive.getAbsolutePath(); + File archive = new File(db.getWorkTree(), "tarball.tar"); + String path = archive.getAbsolutePath(); commitGreeting(); assertArrayEquals(new String[] { "" }, @@ -234,8 +234,8 @@ public void testTgzExtensions() throws Exception { commitGreeting(); for (String ext : Arrays.asList("tar.gz", "tgz")) { - final File archiveWithDot = new File(db.getWorkTree(), "tarball." + ext); - final File archiveNoDot = new File(db.getWorkTree(), "tarball" + ext); + File archiveWithDot = new File(db.getWorkTree(), "tarball." + ext); + File archiveNoDot = new File(db.getWorkTree(), "tarball" + ext); execute("git archive " + shellQuote("--output=" + archiveWithDot.getAbsolutePath()) + " " + @@ -253,8 +253,8 @@ public void testTbz2Extension() throws Exception { commitGreeting(); for (String ext : Arrays.asList("tar.bz2", "tbz", "tbz2")) { - final File archiveWithDot = new File(db.getWorkTree(), "tarball." + ext); - final File archiveNoDot = new File(db.getWorkTree(), "tarball" + ext); + File archiveWithDot = new File(db.getWorkTree(), "tarball." + ext); + File archiveNoDot = new File(db.getWorkTree(), "tarball" + ext); execute("git archive " + shellQuote("--output=" + archiveWithDot.getAbsolutePath()) + " " + @@ -272,8 +272,8 @@ public void testTxzExtension() throws Exception { commitGreeting(); for (String ext : Arrays.asList("tar.xz", "txz")) { - final File archiveWithDot = new File(db.getWorkTree(), "tarball." + ext); - final File archiveNoDot = new File(db.getWorkTree(), "tarball" + ext); + File archiveWithDot = new File(db.getWorkTree(), "tarball." + ext); + File archiveNoDot = new File(db.getWorkTree(), "tarball" + ext); execute("git archive " + shellQuote("--output=" + archiveWithDot.getAbsolutePath()) + " " + @@ -302,7 +302,7 @@ public void testArchiveWithSubdir() throws Exception { git.add().addFilepattern("b").call(); git.commit().setMessage("add subdir").call(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=zip master", db); String[] expect = { "a", "b.c", "b0c", "b/", "b/a", "b/b", "c" }; String[] actual = listZipEntries(result); @@ -328,7 +328,7 @@ public void testTarWithSubdir() throws Exception { git.add().addFilepattern("b").call(); git.commit().setMessage("add subdir").call(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=tar master", db); String[] expect = { "a", "b.c", "b0c", "b/", "b/a", "b/b", "c" }; String[] actual = listTarEntries(result); @@ -390,7 +390,7 @@ public void testPrefixDoesNotNormalizeDoubleSlash() throws Exception { @Test public void testPrefixDoesNotNormalizeDoubleSlashInTar() throws Exception { commitFoo(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --prefix=x// --format=tar master", db); String[] expect = { "x//foo" }; assertArrayEquals(expect, listTarEntries(result)); @@ -421,7 +421,7 @@ public void testPrefixWithoutTrailingSlash() throws Exception { @Test public void testTarPrefixWithoutTrailingSlash() throws Exception { commitBazAndFooSlashBar(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --prefix=my- --format=tar master", db); String[] expect = { "my-baz", "my-foo/", "my-foo/bar" }; String[] actual = listTarEntries(result); @@ -441,7 +441,7 @@ public void testArchiveIncludesSubmoduleDirectory() throws Exception { git.submoduleAdd().setURI("./.").setPath("b").call().close(); git.commit().setMessage("add submodule").call(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=zip master", db); String[] expect = { ".gitmodules", "a", "b/", "c" }; String[] actual = listZipEntries(result); @@ -461,7 +461,7 @@ public void testTarIncludesSubmoduleDirectory() throws Exception { git.submoduleAdd().setURI("./.").setPath("b").call().close(); git.commit().setMessage("add submodule").call(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=tar master", db); String[] expect = { ".gitmodules", "a", "b/", "c" }; String[] actual = listTarEntries(result); @@ -491,7 +491,7 @@ public void testArchivePreservesMode() throws Exception { git.commit().setMessage("three files with different modes").call(); - final byte[] zipData = CLIGitCommand.rawExecute( // + byte[] zipData = CLIGitCommand.rawExecute( "git archive --format=zip master", db); writeRaw("zip-with-modes.zip", zipData); assertContainsEntryWithMode("zip-with-modes.zip", "-rw-", "plain"); @@ -520,7 +520,7 @@ public void testTarPreservesMode() throws Exception { git.commit().setMessage("three files with different modes").call(); - final byte[] archive = CLIGitCommand.rawExecute( // + byte[] archive = CLIGitCommand.rawExecute( "git archive --format=tar master", db); writeRaw("with-modes.tar", archive); assertTarContainsEntry("with-modes.tar", "-rw-r--r--", "plain"); @@ -532,7 +532,7 @@ public void testTarPreservesMode() throws Exception { @Test public void testArchiveWithLongFilename() throws Exception { String filename = ""; - final List l = new ArrayList(); + List l = new ArrayList(); for (int i = 0; i < 20; i++) { filename = filename + "1234567890/"; l.add(filename); @@ -543,7 +543,7 @@ public void testArchiveWithLongFilename() throws Exception { git.add().addFilepattern("1234567890").call(); git.commit().setMessage("file with long name").call(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=zip HEAD", db); assertArrayEquals(l.toArray(new String[l.size()]), listZipEntries(result)); @@ -552,7 +552,7 @@ public void testArchiveWithLongFilename() throws Exception { @Test public void testTarWithLongFilename() throws Exception { String filename = ""; - final List l = new ArrayList(); + List l = new ArrayList(); for (int i = 0; i < 20; i++) { filename = filename + "1234567890/"; l.add(filename); @@ -563,7 +563,7 @@ public void testTarWithLongFilename() throws Exception { git.add().addFilepattern("1234567890").call(); git.commit().setMessage("file with long name").call(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=tar HEAD", db); assertArrayEquals(l.toArray(new String[l.size()]), listTarEntries(result)); @@ -571,34 +571,34 @@ public void testTarWithLongFilename() throws Exception { @Test public void testArchivePreservesContent() throws Exception { - final String payload = "“The quick brown fox jumps over the lazy dog!”"; + String payload = "“The quick brown fox jumps over the lazy dog!”"; writeTrashFile("xyzzy", payload); git.add().addFilepattern("xyzzy").call(); git.commit().setMessage("add file with content").call(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=zip HEAD", db); - assertArrayEquals(new String[] { payload }, // + assertArrayEquals(new String[] { payload }, zipEntryContent(result, "xyzzy")); } @Test public void testTarPreservesContent() throws Exception { - final String payload = "“The quick brown fox jumps over the lazy dog!”"; + String payload = "“The quick brown fox jumps over the lazy dog!”"; writeTrashFile("xyzzy", payload); git.add().addFilepattern("xyzzy").call(); git.commit().setMessage("add file with content").call(); - final byte[] result = CLIGitCommand.rawExecute( // + byte[] result = CLIGitCommand.rawExecute( "git archive --format=tar HEAD", db); - assertArrayEquals(new String[] { payload }, // + assertArrayEquals(new String[] { payload }, tarEntryContent(result, "xyzzy")); } private Process spawnAssumingCommandPresent(String... cmdline) { - final File cwd = db.getWorkTree(); - final ProcessBuilder procBuilder = new ProcessBuilder(cmdline) // - .directory(cwd) // + File cwd = db.getWorkTree(); + ProcessBuilder procBuilder = new ProcessBuilder(cmdline) + .directory(cwd) .redirectErrorStream(true); Process proc = null; try { @@ -612,15 +612,15 @@ private Process spawnAssumingCommandPresent(String... cmdline) { } private BufferedReader readFromProcess(Process proc) throws Exception { - return new BufferedReader( // + return new BufferedReader( new InputStreamReader(proc.getInputStream(), "UTF-8")); } - private void grepForEntry(String name, String mode, String... cmdline) // + private void grepForEntry(String name, String mode, String... cmdline) throws Exception { - final Process proc = spawnAssumingCommandPresent(cmdline); + Process proc = spawnAssumingCommandPresent(cmdline); proc.getOutputStream().close(); - final BufferedReader reader = readFromProcess(proc); + BufferedReader reader = readFromProcess(proc); try { String line; while ((line = reader.readLine()) != null) @@ -672,20 +672,20 @@ private void assertIsXz(File file) throws Exception { assertMagic(new byte[] { (byte) 0xfd, '7', 'z', 'X', 'Z', 0 }, file); } - private void assertContainsEntryWithMode(String zipFilename, String mode, String name) // + private void assertContainsEntryWithMode(String zipFilename, String mode, String name) throws Exception { grepForEntry(name, mode, "zipinfo", zipFilename); } - private void assertTarContainsEntry(String tarfile, String mode, String name) // + private void assertTarContainsEntry(String tarfile, String mode, String name) throws Exception { grepForEntry(name, mode, "tar", "tvf", tarfile); } - private void writeRaw(String filename, byte[] data) // + private void writeRaw(String filename, byte[] data) throws IOException { - final File path = new File(db.getWorkTree(), filename); - final OutputStream out = new FileOutputStream(path); + File path = new File(db.getWorkTree(), filename); + OutputStream out = new FileOutputStream(path); try { out.write(data); } finally { @@ -694,8 +694,8 @@ private void writeRaw(String filename, byte[] data) // } private static String[] listZipEntries(byte[] zipData) throws IOException { - final List l = new ArrayList(); - final ZipInputStream in = new ZipInputStream( // + List l = new ArrayList(); + ZipInputStream in = new ZipInputStream( new ByteArrayInputStream(zipData)); ZipEntry e; @@ -706,9 +706,9 @@ private static String[] listZipEntries(byte[] zipData) throws IOException { } private static Future writeAsync(final OutputStream stream, final byte[] data) { - final ExecutorService executor = Executors.newSingleThreadExecutor(); + ExecutorService executor = Executors.newSingleThreadExecutor(); - return executor.submit(new Callable() { // + return executor.submit(new Callable() { public Object call() throws IOException { try { stream.write(data); @@ -721,13 +721,13 @@ public Object call() throws IOException { } private String[] listTarEntries(byte[] tarData) throws Exception { - final List l = new ArrayList(); - final Process proc = spawnAssumingCommandPresent("tar", "tf", "-"); - final BufferedReader reader = readFromProcess(proc); - final OutputStream out = proc.getOutputStream(); + List l = new ArrayList(); + Process proc = spawnAssumingCommandPresent("tar", "tf", "-"); + BufferedReader reader = readFromProcess(proc); + OutputStream out = proc.getOutputStream(); // Dump tarball to tar stdin in background - final Future writing = writeAsync(out, tarData); + Future writing = writeAsync(out, tarData); try { String line; @@ -742,9 +742,9 @@ private String[] listTarEntries(byte[] tarData) throws Exception { } } - private static String[] zipEntryContent(byte[] zipData, String path) // + private static String[] zipEntryContent(byte[] zipData, String path) throws IOException { - final ZipInputStream in = new ZipInputStream( // + ZipInputStream in = new ZipInputStream( new ByteArrayInputStream(zipData)); ZipEntry e; while ((e = in.getNextEntry()) != null) { @@ -752,8 +752,8 @@ private static String[] zipEntryContent(byte[] zipData, String path) // continue; // found! - final List l = new ArrayList(); - final BufferedReader reader = new BufferedReader( // + List l = new ArrayList(); + BufferedReader reader = new BufferedReader( new InputStreamReader(in, "UTF-8")); String line; while ((line = reader.readLine()) != null) @@ -765,13 +765,13 @@ private static String[] zipEntryContent(byte[] zipData, String path) // return null; } - private String[] tarEntryContent(byte[] tarData, String path) // + private String[] tarEntryContent(byte[] tarData, String path) throws Exception { - final List l = new ArrayList(); - final Process proc = spawnAssumingCommandPresent("tar", "Oxf", "-", path); - final BufferedReader reader = readFromProcess(proc); - final OutputStream out = proc.getOutputStream(); - final Future writing = writeAsync(out, tarData); + List l = new ArrayList(); + Process proc = spawnAssumingCommandPresent("tar", "Oxf", "-", path); + BufferedReader reader = readFromProcess(proc); + OutputStream out = proc.getOutputStream(); + Future writing = writeAsync(out, tarData); try { String line; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java index 5f31be69f..8543bd5f6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java @@ -367,10 +367,10 @@ private OutputStream writeArchive(Format fmt) { try { try (TreeWalk walk = new TreeWalk(repo); RevWalk rw = new RevWalk(walk.getObjectReader())) { - final String pfx = prefix == null ? "" : prefix; //$NON-NLS-1$ - final T outa = fmt.createArchiveOutputStream(out, formatOptions); - final MutableObjectId idBuf = new MutableObjectId(); - final ObjectReader reader = walk.getObjectReader(); + String pfx = prefix == null ? "" : prefix; //$NON-NLS-1$ + T outa = fmt.createArchiveOutputStream(out, formatOptions); + MutableObjectId idBuf = new MutableObjectId(); + ObjectReader reader = walk.getObjectReader(); walk.reset(rw.parseTree(tree)); if (!paths.isEmpty()) @@ -414,7 +414,7 @@ private OutputStream writeArchive(Format fmt) { public OutputStream call() throws GitAPIException { checkCallable(); - final Format fmt; + Format fmt; if (format == null) fmt = formatBySuffix(suffix); else From 27128b3e01a9c97f1d2549ded0d381f469f0aee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Ar=C3=A8s?= Date: Thu, 28 May 2015 14:21:03 -0400 Subject: [PATCH 15/29] Fix WindowCursor memory leak. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ObjectReader release method was replaced by close method but WindowCursor was still implementing release method. To prevent the same mistake again, make ObjectReader close method abstract to force sub classes to implement it. Change-Id: I50d0d1d19a26e306fd0dba77b246a95a44fd6584 Signed-off-by: Hugo Arès --- .../org/eclipse/jgit/internal/storage/file/PackFileTest.java | 2 +- .../jgit/internal/storage/file/UnpackedObjectTest.java | 2 +- .../eclipse/jgit/internal/storage/file/PackInputStream.java | 2 +- .../eclipse/jgit/internal/storage/file/UnpackedObject.java | 2 +- .../org/eclipse/jgit/internal/storage/file/WindowCursor.java | 3 ++- org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java | 4 +--- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java index 05055644e..cb80768e5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java @@ -123,7 +123,7 @@ public void setUp() throws Exception { @After public void tearDown() throws Exception { if (wc != null) - wc.release(); + wc.close(); new WindowCacheConfig().install(); super.tearDown(); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/UnpackedObjectTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/UnpackedObjectTest.java index 10d2b6b52..8c8c6c6d0 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/UnpackedObjectTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/UnpackedObjectTest.java @@ -108,7 +108,7 @@ public void setUp() throws Exception { @After public void tearDown() throws Exception { if (wc != null) - wc.release(); + wc.close(); new WindowCacheConfig().install(); super.tearDown(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInputStream.java index 9cb834957..154809bad 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInputStream.java @@ -80,6 +80,6 @@ public int read() throws IOException { @Override public void close() { - wc.release(); + wc.close(); } } \ No newline at end of file diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java index cb95a7656..cb7d91259 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java @@ -95,7 +95,7 @@ public static ObjectLoader parse(byte[] raw, AnyObjectId id) try { return open(new ByteArrayInputStream(raw), null, id, wc); } finally { - wc.release(); + wc.close(); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java index 3e6cb5835..a555e10d4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java @@ -330,7 +330,8 @@ int getStreamFileThreshold() { } /** Release the current window cursor. */ - public void release() { + @Override + public void close() { window = null; baseCache = null; try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java index 4c9af85fa..77cfb038c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java @@ -430,7 +430,5 @@ public BitmapIndex getBitmapIndex() throws IOException { * @since 4.0 */ @Override - public void close() { - // Do nothing. - } + public abstract void close(); } From 663ccd76f04017dab216825e9b72a962759ba2e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Ar=C3=A8s?= Date: Thu, 28 May 2015 15:59:48 -0400 Subject: [PATCH 16/29] Close WindowCursor using try-with-resources in UnpackedObject MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I187403ed432f7d6b1e84223918bd72d895e6bdfe Signed-off-by: Hugo Arès --- .../eclipse/jgit/internal/storage/file/UnpackedObject.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java index cb7d91259..e4cc69796 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java @@ -91,11 +91,8 @@ public class UnpackedObject { */ public static ObjectLoader parse(byte[] raw, AnyObjectId id) throws IOException { - WindowCursor wc = new WindowCursor(null); - try { + try (WindowCursor wc = new WindowCursor(null)) { return open(new ByteArrayInputStream(raw), null, id, wc); - } finally { - wc.close(); } } From faae5cdb5be65547f7d681108f9a194e8da748f5 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Sun, 12 Apr 2015 00:51:37 +0200 Subject: [PATCH 17/29] Fix hidden field warnings in bundle org.eclipse.jgit Change-Id: I4e79cefe15037df0e1c520956bf2482240e31a7d Signed-off-by: Matthias Sohn --- .../storage/file/ObjectDirectoryPackParser.java | 11 +++++------ .../src/org/eclipse/jgit/transport/UploadPack.java | 8 ++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java index a186b8147..1c076ee09 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java @@ -366,11 +366,10 @@ protected boolean onAppendBase(final int typeCode, final byte[] data, @Override protected void onEndThinPack() throws IOException { - final byte[] tailHash = this.tailDigest.digest(); final byte[] buf = buffer(); final MessageDigest origDigest = Constants.newMessageDigest(); - final MessageDigest tailDigest = Constants.newMessageDigest(); + final MessageDigest tailDigest2 = Constants.newMessageDigest(); final MessageDigest packDigest = Constants.newMessageDigest(); long origRemaining = origEnd; @@ -393,15 +392,15 @@ protected void onEndThinPack() throws IOException { origDigest.update(buf, 0, origCnt); origRemaining -= origCnt; if (origRemaining == 0) - tailDigest.update(buf, origCnt, n - origCnt); + tailDigest2.update(buf, origCnt, n - origCnt); } else - tailDigest.update(buf, 0, n); + tailDigest2.update(buf, 0, n); packDigest.update(buf, 0, n); } - if (!Arrays.equals(origDigest.digest(), origHash) - || !Arrays.equals(tailDigest.digest(), tailHash)) + if (!Arrays.equals(origDigest.digest(), origHash) || !Arrays + .equals(tailDigest2.digest(), this.tailDigest.digest())) throw new IOException( JGitText.get().packCorruptedWhileWritingToFilesystem); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java index c60590dda..753277dd3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -810,9 +810,9 @@ public void sendAdvertisedRefs(final RefAdvertiser adv) throws IOException, adv.advertiseCapability(OPTION_ALLOW_TIP_SHA1_IN_WANT); adv.advertiseCapability(OPTION_AGENT, UserAgent.get()); adv.setDerefTags(true); - Map refs = getAdvertisedOrDefaultRefs(); - findSymrefs(adv, refs); - advertised = adv.send(refs); + Map advertisedOrDefaultRefs = getAdvertisedOrDefaultRefs(); + findSymrefs(adv, advertisedOrDefaultRefs); + advertised = adv.send(advertisedOrDefaultRefs); if (adv.isEmpty()) adv.advertiseId(ObjectId.zeroId(), "capabilities^{}"); //$NON-NLS-1$ adv.end(); @@ -1467,7 +1467,7 @@ else if (ref.getName().startsWith(Constants.R_HEADS)) pckOut.end(); } - private void findSymrefs( + private static void findSymrefs( final RefAdvertiser adv, final Map refs) { Ref head = refs.get(Constants.HEAD); if (head != null && head.isSymbolic()) { From 6d4ebd168da236c5753f237e77b2dfcbb4e42065 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Sun, 12 Apr 2015 01:26:50 +0200 Subject: [PATCH 18/29] Fix unchecked conversion warning in MergeFormatter Change-Id: Id57ef8b2e80736652e4c5062364efa3ccd39c4c7 Signed-off-by: Matthias Sohn --- org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java index 977f95341..a9a8231ee 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java @@ -102,7 +102,7 @@ public void formatMerge(OutputStream out, MergeResult res, * metadata * @throws IOException */ - public void formatMerge(OutputStream out, MergeResult res, String baseName, + public void formatMerge(OutputStream out, MergeResult res, String baseName, String oursName, String theirsName, String charsetName) throws IOException { List names = new ArrayList(3); names.add(baseName); From 17307df3af722b9fcb5a90ebea03505a7a82faf0 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Sun, 12 Apr 2015 01:01:14 +0200 Subject: [PATCH 19/29] Silence deprecation warning in DirCacheCheckout Change-Id: I9e021ba2e0d1317bd98e86f832d55787ed6b0a63 Signed-off-by: Matthias Sohn --- .../src/org/eclipse/jgit/dircache/DirCacheCheckout.java | 1 + 1 file changed, 1 insertion(+) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java index f316ea99a..00252547d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -1192,6 +1192,7 @@ public static void checkoutEntry(Repository repo, DirCacheEntry entry, entry.setLastModified(f.lastModified()); } + @SuppressWarnings("deprecation") private static void checkValidPath(CanonicalTreeParser t) throws InvalidPathException { ObjectChecker chk = new ObjectChecker() From e013bcdcc638be71a7639c52dfcfa33445d49fd5 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Sun, 12 Apr 2015 01:08:48 +0200 Subject: [PATCH 20/29] Silence deprecation warning in WindowCacheConfig Change-Id: I923b65efeaacc5e9cc8aecc754ab8d8e63ccd2e5 Signed-off-by: Matthias Sohn --- .../src/org/eclipse/jgit/storage/file/WindowCacheConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java index 69abd0d97..4205fc4e8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java @@ -221,6 +221,7 @@ public WindowCacheConfig fromConfig(final Config rc) { * * @since 3.0 */ + @SuppressWarnings("deprecation") public void install() { WindowCache.reconfigure(this); } From 8787176ef1cd4c7b7fc6e312bdf680f384c38467 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Sun, 12 Apr 2015 01:27:12 +0200 Subject: [PATCH 21/29] Silence unchecked conversion warning in TransportSftp Change-Id: I3dc8e0b483072bdf193ae4190a60d1867ebefd12 Signed-off-by: Matthias Sohn --- .../src/org/eclipse/jgit/transport/TransportSftp.java | 1 + 1 file changed, 1 insertion(+) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java index c47645cd7..fa073ae2a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java @@ -227,6 +227,7 @@ WalkRemoteObjectDatabase openAlternate(final String location) Collection getPackNames() throws IOException { final List packs = new ArrayList(); try { + @SuppressWarnings("unchecked") final Collection list = ftp.ls("pack"); //$NON-NLS-1$ final HashMap files; final HashMap mtimes; From efacad0fc8e98505be6f007230ab2b1cdc1684f3 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Wed, 15 Apr 2015 08:40:05 +0200 Subject: [PATCH 22/29] Improve exception thrown when pull can't find advertised ref - throw an API exception instead of an internal exception to allow applications to handle this problem - improve error message to give hints about possible root causes Bug: 464660 Change-Id: Ib7d18bb2eeeac0fc218daea375b290ea5034bda1 Signed-off-by: Matthias Sohn --- .../eclipse/jgit/internal/JGitText.properties | 2 +- .../src/org/eclipse/jgit/api/PullCommand.java | 14 +++-- .../api/errors/RefNotAdvertisedException.java | 54 +++++++++++++++++++ 3 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefNotAdvertisedException.java 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 a2f06b1a2..db9a68458 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -181,7 +181,7 @@ corruptObjectTruncatedInObjectId=truncated in object id couldNotCheckOutBecauseOfConflicts=Could not check out because of conflicts couldNotDeleteLockFileShouldNotHappen=Could not delete lock file. Should not happen couldNotDeleteTemporaryIndexFileShouldNotHappen=Could not delete temporary index file. Should not happen -couldNotGetAdvertisedRef=Could not get advertised Ref for branch {0} +couldNotGetAdvertisedRef=Remote {0} did not advertise Ref for branch {1}. This Ref may not exist in the remote or may be hidden by permission settings. couldNotGetRepoStatistics=Could not get repository statistics couldNotLockHEAD=Could not lock HEAD couldNotReadIndexInOneGo=Could not read index in one go, only {0} out of {1} read diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java index ac050dd33..63de85c50 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java @@ -54,6 +54,7 @@ import org.eclipse.jgit.api.errors.InvalidRemoteException; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.api.errors.NoHeadException; +import org.eclipse.jgit.api.errors.RefNotAdvertisedException; import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.api.errors.WrongRepositoryStateException; import org.eclipse.jgit.internal.JGitText; @@ -171,6 +172,7 @@ public PullCommand setRebase(boolean useRebase) { * @throws InvalidRemoteException * @throws CanceledException * @throws RefNotFoundException + * @throws RefNotAdvertisedException * @throws NoHeadException * @throws org.eclipse.jgit.api.errors.TransportException * @throws GitAPIException @@ -178,7 +180,7 @@ public PullCommand setRebase(boolean useRebase) { public PullResult call() throws GitAPIException, WrongRepositoryStateException, InvalidConfigurationException, DetachedHeadException, InvalidRemoteException, CanceledException, - RefNotFoundException, NoHeadException, + RefNotFoundException, RefNotAdvertisedException, NoHeadException, org.eclipse.jgit.api.errors.TransportException { checkCallable(); @@ -284,11 +286,13 @@ public PullResult call() throws GitAPIException, r = fetchRes.getAdvertisedRef(Constants.R_HEADS + remoteBranchName); } - if (r == null) - throw new JGitInternalException(MessageFormat.format(JGitText - .get().couldNotGetAdvertisedRef, remoteBranchName)); - else + if (r == null) { + throw new RefNotAdvertisedException(MessageFormat.format( + JGitText.get().couldNotGetAdvertisedRef, remote, + remoteBranchName)); + } else { commitToMerge = r.getObjectId(); + } } else { try { commitToMerge = repo.resolve(remoteBranchName); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefNotAdvertisedException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefNotAdvertisedException.java new file mode 100644 index 000000000..2bd847765 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefNotAdvertisedException.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015,Matthias Sohn and + * other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v1.0 which accompanies this + * distribution, is reproduced below, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.api.errors; + +/** + * Thrown when a ref is not found in advertised refs + * + * @since 4.0 + */ +public class RefNotAdvertisedException extends GitAPIException { + private static final long serialVersionUID = 1L; + + /** + * @param message + */ + public RefNotAdvertisedException(String message) { + super(message); + } +} From 5059e3e4089545b43a9725bc79929cc0c3f59f50 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Fri, 29 May 2015 10:17:15 +0200 Subject: [PATCH 23/29] Add "src" folder to source folders of org.eclipse.jgit.test Otherwise MergeCommandTest using Sets doesn't compile in Eclipse since adbcbc79 moved Sets from the "tst" to the "src" folder. Change-Id: I661b987513365a8af0b568ec95b0898e5758f59f Signed-off-by: Matthias Sohn --- org.eclipse.jgit.test/.classpath | 1 + 1 file changed, 1 insertion(+) diff --git a/org.eclipse.jgit.test/.classpath b/org.eclipse.jgit.test/.classpath index e97de8fe8..8b81bf5b0 100644 --- a/org.eclipse.jgit.test/.classpath +++ b/org.eclipse.jgit.test/.classpath @@ -1,6 +1,7 @@ + From 6d09c486ed833484d9413e3c8f955d2afe27d397 Mon Sep 17 00:00:00 2001 From: Christian Halstrick Date: Mon, 18 May 2015 12:48:08 +0200 Subject: [PATCH 24/29] Fix CommitCommand.setOnly() When CommitCommand.setOnly(path) is used a temporary index has to be created containing only modifications for the specified pathes. The process to fill this temporary index was broken because filling the index was stopped when we reached the first untracked file. Instead the process to fill the temporary index should continue until we processed all pathes. Bug: 451465 Change-Id: I22af50d70bd3b81e7c056358724956122b0d158d Signed-off-by: Matthias Sohn --- .../tst/org/eclipse/jgit/api/CommitCommandTest.java | 11 +++++++++++ .../src/org/eclipse/jgit/api/CommitCommand.java | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java index 54fbc6671..060a5b65c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java @@ -514,6 +514,17 @@ public void commitOnlyShouldCommitUnmergedPathAndNotAffectOthers() } } + @Test + public void commitOnlyShouldHandleIgnored() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("subdir/foo", "Hello World"); + writeTrashFile("subdir/bar", "Hello World"); + writeTrashFile(".gitignore", "bar"); + git.add().addFilepattern("subdir").call(); + git.commit().setOnly("subdir").setMessage("first commit").call(); + } + } + private static void addUnmergedEntry(String file, DirCacheBuilder builder) { DirCacheEntry stage1 = new DirCacheEntry(file, DirCacheEntry.STAGE_1); DirCacheEntry stage2 = new DirCacheEntry(file, DirCacheEntry.STAGE_2); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java index 87efd7983..6174d48d3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java @@ -358,7 +358,7 @@ private DirCache createTemporaryIndex(ObjectId headId, DirCache index, // check if entry refers to a tracked file boolean tracked = dcTree != null || hTree != null; if (!tracked) - break; + continue; // for an unmerged path, DirCacheBuildIterator will yield 3 // entries, we only want to add one From c5f7ab34829e56de3b56a717eaa38b02e2810cda Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Fri, 29 May 2015 14:31:31 +0200 Subject: [PATCH 25/29] Compare API changes in clirr report against 3.7.0 Change-Id: Id819fd700ed44cdc3cdbe33a4bb9ee52a6fbbd41 Signed-off-by: Matthias Sohn --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ce4cc67a5..f8a0ce51e 100644 --- a/pom.xml +++ b/pom.xml @@ -176,7 +176,7 @@ yyyyMMddHHmm ${project.build.directory}/META-INF/MANIFEST.MF - 3.6.0.201412230720-r + 3.7.0.201502260915-r 0.1.50 0.7.9 4.11 From 174c8c5d398e2af1a612c49ea470f31fcb5247bc Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Mon, 1 Jun 2015 16:00:06 +0200 Subject: [PATCH 26/29] Update 4.5 target platform to use final Mars Orbit repository Change-Id: Ie8ff09e6b054e5fae0786557b8fe831eb9e82dd2 Signed-off-by: Matthias Sohn --- .../org.eclipse.jgit.target/jgit-4.5.target | 4 ++-- .../org.eclipse.jgit.target/jgit-4.5.tpd | 2 +- ...{S20150519210750-Mars-RC2.tpd => R20150519210750-Mars.tpd} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/{S20150519210750-Mars-RC2.tpd => R20150519210750-Mars.tpd} (96%) diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target index 05c6324ed..e7e0cb921 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target @@ -1,7 +1,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd index 0b8012034..b58d8f4eb 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd @@ -1,7 +1,7 @@ target "jgit-4.5" with source configurePhase include "projects/jetty-9.2.10.tpd" -include "orbit/S20150519210750-Mars-RC2.tpd" +include "orbit/R20150519210750-Mars.tpd" location "http://download.eclipse.org/releases/mars/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20150519210750-Mars-RC2.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150519210750-Mars.tpd similarity index 96% rename from org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20150519210750-Mars-RC2.tpd rename to org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150519210750-Mars.tpd index b4ca87a9a..7bdafd81e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20150519210750-Mars-RC2.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150519210750-Mars.tpd @@ -1,7 +1,7 @@ -target "S20141023165154-Mars-M3" with source configurePhase +target "R20150519210750-Mars" with source configurePhase // see http://download.eclipse.org/tools/orbit/downloads/ -location "http://download.eclipse.org/tools/orbit/downloads/drops/S20150519210750/repository/" { +location "http://download.eclipse.org/tools/orbit/downloads/drops/R20150519210750/repository/" { org.apache.ant [1.9.4.v201504302020,1.9.4.v201504302020] org.apache.ant.source [1.9.4.v201504302020,1.9.4.v201504302020] org.apache.commons.compress [1.6.0.v201310281400,1.6.0.v201310281400] From ce8baa37154b806b2dbb0e04e681f365c4dbd3ec Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Mon, 1 Jun 2015 11:37:38 +0200 Subject: [PATCH 27/29] Update dependencies to the versions used in target platform - update com.jcraft.jsch to 0.1.51 - update javax.servlet to 3.1.0 Change-Id: Ie536182d1efc6dcc3abd03f8a9acd013adcbf2a8 Signed-off-by: Matthias Sohn --- org.eclipse.jgit.http.server/pom.xml | 2 +- pom.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml index 38aa64c9d..e0b759a9e 100644 --- a/org.eclipse.jgit.http.server/pom.xml +++ b/org.eclipse.jgit.http.server/pom.xml @@ -75,7 +75,7 @@ javax.servlet - servlet-api + javax.servlet-api provided diff --git a/pom.xml b/pom.xml index f8a0ce51e..2bedc8798 100644 --- a/pom.xml +++ b/pom.xml @@ -177,14 +177,14 @@ ${project.build.directory}/META-INF/MANIFEST.MF 3.7.0.201502260915-r - 0.1.50 + 0.1.51 0.7.9 4.11 1C 2.0.15 1.6 4.3.1 - 2.5 + 3.1.0 9.2.10.v20150310 2.6.1 4.1.3 @@ -521,7 +521,7 @@ javax.servlet - servlet-api + javax.servlet-api ${servlet-api-version} From 6fc5af47d102c37adfa5fb6c325616214d297085 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Fri, 29 May 2015 14:39:33 +0200 Subject: [PATCH 28/29] Update project meta-data in pom.xml used for site generation - Update list of committers - Update scm information - Expose jgit hudson for Maven site - Name our project's organization - Scm URL should point to a web-enabled view on the repository - Extract tycho-extras version used during signing to a property Change-Id: If32bed323ec283b5e83d28ffe8775220f7c4cecd Signed-off-by: Matthias Sohn --- pom.xml | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 2bedc8798..5771d5ab5 100644 --- a/pom.xml +++ b/pom.xml @@ -56,15 +56,25 @@ JGit - Parent ${jgit-url} + + Eclipse JGit Project + http://www.eclipse.org/jgit + + Pure Java implementation of Git - http://egit.eclipse.org/w/?p=jgit.git - scm:git:git://egit.eclipse.org/jgit.git + http://git.eclipse.org/c/jgit/jgit.git/ + scm:git:https://git.eclipse.org/r/jgit/jgit + + hudson + https://hudson.eclipse.org/jgit/ + + Chris Aniszczyk @@ -81,6 +91,9 @@ Gunnar Wagenknecht + + Jonathan Nieder + Kevin Sawicki @@ -93,6 +106,9 @@ Robin Rosenberg + + Robin Stocker + Sasa Zivkov @@ -191,6 +207,7 @@ 1.7.2 1.2.15 2.10.1 + 0.22.0 jacoco @@ -355,12 +372,12 @@ org.eclipse.tycho.extras tycho-pack200a-plugin - 0.22.0 + ${tycho-extras-version} org.eclipse.tycho.extras tycho-pack200b-plugin - 0.22.0 + ${tycho-extras-version} org.jacoco From 1e7262ae170ca0f1cfb5573ccbc150c84a40c9f2 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Fri, 29 May 2015 16:37:20 +0200 Subject: [PATCH 29/29] Add more reports to maven site Add the following additional reports: - cross-reference report - API changes report using clirr - findbugs report - surefire-report Run $ mvn test install site:site site:stage to generate and stage the site Also see https://wiki.eclipse.org/EGit/Contributor_Guide#JGit_3 Change-Id: Ibb6a2e13e128d7728b3c632cc16bf79716dc75f5 Signed-off-by: Matthias Sohn --- pom.xml | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/pom.xml b/pom.xml index 5771d5ab5..2ed818b71 100644 --- a/pom.xml +++ b/pom.xml @@ -396,6 +396,21 @@ + + org.apache.maven.plugins + maven-surefire-report-plugin + 2.18.1 + + + org.apache.maven.plugins + maven-jxr-plugin + 2.5 + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.8 + @@ -495,6 +510,10 @@ + + org.apache.maven.plugins + maven-surefire-report-plugin + @@ -507,6 +526,29 @@ + + org.apache.maven.plugins + maven-jxr-plugin + + + org.codehaus.mojo + clirr-maven-plugin + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.apache.maven.plugins + maven-surefire-report-plugin + + true + false + + ${project.build.directory}/surefire-reports + + +