aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/BUCK1
-rw-r--r--org.eclipse.jgit/BUILD33
-rw-r--r--org.eclipse.jgit/META-INF/MANIFEST.MF87
-rw-r--r--org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF4
-rw-r--r--org.eclipse.jgit/pom.xml7
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java24
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java32
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java10
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java62
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java5
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/IMatcher.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedListener.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java4
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java50
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java26
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java14
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java21
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java12
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderOptions.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java165
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java20
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java49
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java10
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java44
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java4
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java4
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java75
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java4
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java6
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRC.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java9
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java6
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java7
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java14
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java27
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java4
56 files changed, 702 insertions, 191 deletions
diff --git a/org.eclipse.jgit/BUCK b/org.eclipse.jgit/BUCK
index 2bae6dcf25..73e2080576 100644
--- a/org.eclipse.jgit/BUCK
+++ b/org.eclipse.jgit/BUCK
@@ -9,7 +9,6 @@ java_library(
'//lib:javaewah',
'//lib:jsch',
'//lib:httpcomponents',
- '//lib:servlet-api',
'//lib:slf4j-api',
],
visibility = ['PUBLIC'],
diff --git a/org.eclipse.jgit/BUILD b/org.eclipse.jgit/BUILD
new file mode 100644
index 0000000000..a9b01e9ea6
--- /dev/null
+++ b/org.eclipse.jgit/BUILD
@@ -0,0 +1,33 @@
+package(default_visibility = ["//visibility:public"])
+
+INSECURE_CIPHER_FACTORY = [
+ "src/org/eclipse/jgit/transport/InsecureCipherFactory.java",
+]
+
+SRCS = glob(
+ ["src/**"],
+ exclude = INSECURE_CIPHER_FACTORY,
+)
+
+RESOURCES = glob(["resources/**"])
+
+java_library(
+ name = "jgit",
+ srcs = SRCS,
+ resource_strip_prefix = "org.eclipse.jgit/resources",
+ resources = RESOURCES,
+ deps = [
+ ":insecure_cipher_factory",
+ "@httpclient//jar",
+ "@javaewah//jar",
+ "@jsch//jar",
+ "@log_api//jar",
+ "@servlet_api_3_1//jar",
+ ],
+)
+
+java_library(
+ name = "insecure_cipher_factory",
+ srcs = INSECURE_CIPHER_FACTORY,
+ javacopts = ["-Xep:InsecureCipherMode:OFF"],
+)
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index 22d42751b4..8b78628209 100644
--- a/org.eclipse.jgit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -2,12 +2,12 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %plugin_name
Bundle-SymbolicName: org.eclipse.jgit
-Bundle-Version: 4.6.1.qualifier
+Bundle-Version: 4.7.0.qualifier
Bundle-Localization: plugin
Bundle-Vendor: %provider_name
Bundle-ActivationPolicy: lazy
-Export-Package: org.eclipse.jgit.annotations;version="4.6.1",
- org.eclipse.jgit.api;version="4.6.1";
+Export-Package: org.eclipse.jgit.annotations;version="4.7.0",
+ org.eclipse.jgit.api;version="4.7.0";
uses:="org.eclipse.jgit.revwalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.diff,
@@ -21,47 +21,51 @@ Export-Package: org.eclipse.jgit.annotations;version="4.6.1",
org.eclipse.jgit.submodule,
org.eclipse.jgit.transport,
org.eclipse.jgit.merge",
- org.eclipse.jgit.api.errors;version="4.6.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors",
- org.eclipse.jgit.attributes;version="4.6.1",
- org.eclipse.jgit.blame;version="4.6.1";
+ org.eclipse.jgit.api.errors;version="4.7.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors",
+ org.eclipse.jgit.attributes;version="4.7.0",
+ org.eclipse.jgit.blame;version="4.7.0";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.diff",
- org.eclipse.jgit.diff;version="4.6.1";
+ org.eclipse.jgit.diff;version="4.7.0";
uses:="org.eclipse.jgit.patch,
org.eclipse.jgit.lib,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.util",
- org.eclipse.jgit.dircache;version="4.6.1";
+ org.eclipse.jgit.dircache;version="4.7.0";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.util,
org.eclipse.jgit.events,
org.eclipse.jgit.attributes",
- org.eclipse.jgit.errors;version="4.6.1";
+ org.eclipse.jgit.errors;version="4.7.0";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.internal.storage.pack,
org.eclipse.jgit.transport,
org.eclipse.jgit.dircache",
- org.eclipse.jgit.events;version="4.6.1";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.fnmatch;version="4.6.1",
- org.eclipse.jgit.gitrepo;version="4.6.1";
+ org.eclipse.jgit.events;version="4.7.0";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.fnmatch;version="4.7.0",
+ org.eclipse.jgit.gitrepo;version="4.7.0";
uses:="org.eclipse.jgit.api,
org.eclipse.jgit.lib,
org.eclipse.jgit.revwalk,
org.xml.sax.helpers,
org.xml.sax",
- org.eclipse.jgit.gitrepo.internal;version="4.6.1";x-internal:=true,
- org.eclipse.jgit.hooks;version="4.6.1";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.ignore;version="4.6.1",
- org.eclipse.jgit.ignore.internal;version="4.6.1";x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal;version="4.6.1";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test",
- org.eclipse.jgit.internal.ketch;version="4.6.1";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.dfs;version="4.6.1";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.server,org.eclipse.jgit.http.test",
- org.eclipse.jgit.internal.storage.file;version="4.6.1";
+ org.eclipse.jgit.gitrepo.internal;version="4.7.0";x-internal:=true,
+ org.eclipse.jgit.hooks;version="4.7.0";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.ignore;version="4.7.0",
+ org.eclipse.jgit.ignore.internal;version="4.7.0";x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.internal;version="4.7.0";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test",
+ org.eclipse.jgit.internal.ketch;version="4.7.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.storage.dfs;version="4.7.0";
+ x-friends:="org.eclipse.jgit.test,
+ org.eclipse.jgit.http.server,
+ org.eclipse.jgit.http.test,
+ org.eclipse.jgit.lfs.test",
+ org.eclipse.jgit.internal.storage.file;version="4.7.0";
x-friends:="org.eclipse.jgit.test,
org.eclipse.jgit.junit,
org.eclipse.jgit.junit.http,
@@ -69,9 +73,9 @@ Export-Package: org.eclipse.jgit.annotations;version="4.6.1",
org.eclipse.jgit.lfs,
org.eclipse.jgit.pgm,
org.eclipse.jgit.pgm.test",
- org.eclipse.jgit.internal.storage.pack;version="4.6.1";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftree;version="4.6.1";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.lib;version="4.6.1";
+ org.eclipse.jgit.internal.storage.pack;version="4.7.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.storage.reftree;version="4.7.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.lib;version="4.7.0";
uses:="org.eclipse.jgit.revwalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.util,
@@ -81,32 +85,32 @@ Export-Package: org.eclipse.jgit.annotations;version="4.6.1",
org.eclipse.jgit.treewalk,
org.eclipse.jgit.transport,
org.eclipse.jgit.submodule",
- org.eclipse.jgit.merge;version="4.6.1";
+ org.eclipse.jgit.merge;version="4.7.0";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.diff,
org.eclipse.jgit.dircache,
org.eclipse.jgit.api",
- org.eclipse.jgit.nls;version="4.6.1",
- org.eclipse.jgit.notes;version="4.6.1";
+ org.eclipse.jgit.nls;version="4.7.0",
+ org.eclipse.jgit.notes;version="4.7.0";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.merge",
- org.eclipse.jgit.patch;version="4.6.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff",
- org.eclipse.jgit.revplot;version="4.6.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk",
- org.eclipse.jgit.revwalk;version="4.6.1";
+ org.eclipse.jgit.patch;version="4.7.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff",
+ org.eclipse.jgit.revplot;version="4.7.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk",
+ org.eclipse.jgit.revwalk;version="4.7.0";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.diff,
org.eclipse.jgit.revwalk.filter",
- org.eclipse.jgit.revwalk.filter;version="4.6.1";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util",
- org.eclipse.jgit.storage.file;version="4.6.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util",
- org.eclipse.jgit.storage.pack;version="4.6.1";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.submodule;version="4.6.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk",
- org.eclipse.jgit.transport;version="4.6.1";
+ org.eclipse.jgit.revwalk.filter;version="4.7.0";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util",
+ org.eclipse.jgit.storage.file;version="4.7.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util",
+ org.eclipse.jgit.storage.pack;version="4.7.0";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.submodule;version="4.7.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk",
+ org.eclipse.jgit.transport;version="4.7.0";
uses:="org.eclipse.jgit.transport.resolver,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.internal.storage.pack,
@@ -118,29 +122,28 @@ Export-Package: org.eclipse.jgit.annotations;version="4.6.1",
org.eclipse.jgit.transport.http,
org.eclipse.jgit.errors,
org.eclipse.jgit.storage.pack",
- org.eclipse.jgit.transport.http;version="4.6.1";uses:="javax.net.ssl",
- org.eclipse.jgit.transport.resolver;version="4.6.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport",
- org.eclipse.jgit.treewalk;version="4.6.1";
+ org.eclipse.jgit.transport.http;version="4.7.0";uses:="javax.net.ssl",
+ org.eclipse.jgit.transport.resolver;version="4.7.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport",
+ org.eclipse.jgit.treewalk;version="4.7.0";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.attributes,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.util,
org.eclipse.jgit.dircache",
- org.eclipse.jgit.treewalk.filter;version="4.6.1";uses:="org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util;version="4.6.1";
+ org.eclipse.jgit.treewalk.filter;version="4.7.0";uses:="org.eclipse.jgit.treewalk",
+ org.eclipse.jgit.util;version="4.7.0";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.transport.http,
org.eclipse.jgit.storage.file,
org.ietf.jgss",
- org.eclipse.jgit.util.io;version="4.6.1",
- org.eclipse.jgit.util.time;version="4.6.1"
+ org.eclipse.jgit.util.io;version="4.7.0",
+ org.eclipse.jgit.util.time;version="4.7.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
com.jcraft.jsch;version="[0.1.37,0.2.0)",
javax.crypto,
javax.net.ssl,
- javax.servlet.http;version="[2.5.0,3.2.0)",
org.slf4j;version="[1.7.0,2.0.0)",
org.xml.sax,
org.xml.sax.helpers
diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
index e310d9b280..9287b6f2e9 100644
--- a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@ Bundle-ManifestVersion: 2
Bundle-Name: org.eclipse.jgit - Sources
Bundle-SymbolicName: org.eclipse.jgit.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 4.6.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit;version="4.6.1.qualifier";roots="."
+Bundle-Version: 4.7.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit;version="4.7.0.qualifier";roots="."
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml
index 1aee726dd3..6465a00b69 100644
--- a/org.eclipse.jgit/pom.xml
+++ b/org.eclipse.jgit/pom.xml
@@ -53,7 +53,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>4.6.1-SNAPSHOT</version>
+ <version>4.7.0-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit</artifactId>
@@ -89,11 +89,6 @@
<artifactId>slf4j-api</artifactId>
</dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <scope>provided</scope>
- </dependency>
</dependencies>
<build>
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 b9b74bfc21..8bf2155d93 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -31,6 +31,7 @@ badGroupHeader=Bad group header
badObjectType=Bad object type: {0}
badRef=Bad ref: {0}: {1}
badSectionEntry=Bad section entry: {0}
+badShallowLine=Bad shallow line: {0}
bareRepositoryNoWorkdirAndIndex=Bare Repository has neither a working tree, nor an index
base64InputNotProperlyPadded=Base64 input not properly padded.
baseLengthIncorrect=base length incorrect
@@ -187,7 +188,7 @@ corruptObjectTruncatedInMode=truncated in mode
corruptObjectTruncatedInName=truncated in name
corruptObjectTruncatedInObjectId=truncated in object id
corruptObjectZeroId=entry points to null SHA-1
-corruptUseCnt=close() called when useCnt is already zero
+corruptUseCnt=close() called when useCnt is already zero for {0}
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
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
index dd5da1582f..b065b9484b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
@@ -151,23 +151,35 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
}
}
+ private static boolean isNonEmptyDirectory(File dir) {
+ if (dir != null && dir.exists()) {
+ File[] files = dir.listFiles();
+ return files != null && files.length != 0;
+ }
+ return false;
+ }
+
private Repository init(URIish u) throws GitAPIException {
InitCommand command = Git.init();
command.setBare(bare);
- if (directory == null && gitDir == null)
+ if (directory == null && gitDir == null) {
directory = new File(u.getHumanishName(), Constants.DOT_GIT);
+ }
validateDirs(directory, gitDir, bare);
- if (directory != null && directory.exists()
- && directory.listFiles().length != 0)
+ if (isNonEmptyDirectory(directory)) {
throw new JGitInternalException(MessageFormat.format(
JGitText.get().cloneNonEmptyDirectory, directory.getName()));
- if (gitDir != null && gitDir.exists() && gitDir.listFiles().length != 0)
+ }
+ if (isNonEmptyDirectory(gitDir)) {
throw new JGitInternalException(MessageFormat.format(
JGitText.get().cloneNonEmptyDirectory, gitDir.getName()));
- if (directory != null)
+ }
+ if (directory != null) {
command.setDirectory(directory);
- if (gitDir != null)
+ }
+ if (gitDir != null) {
command.setGitDir(gitDir);
+ }
return command.call().getRepository();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
index d0f729cc62..0f38db53ba 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
@@ -159,6 +159,38 @@ public class GarbageCollectCommand extends GitCommand<Properties> {
return this;
}
+ /**
+ * Whether to preserve old pack files instead of deleting them.
+ *
+ * @since 4.7
+ * @param preserveOldPacks
+ * whether to preserve old pack files
+ * @return this instance
+ */
+ public GarbageCollectCommand setPreserveOldPacks(boolean preserveOldPacks) {
+ if (pconfig == null)
+ pconfig = new PackConfig(repo);
+
+ pconfig.setPreserveOldPacks(preserveOldPacks);
+ return this;
+ }
+
+ /**
+ * Whether to prune preserved pack files in the preserved directory.
+ *
+ * @since 4.7
+ * @param prunePreserved
+ * whether to prune preserved pack files
+ * @return this instance
+ */
+ public GarbageCollectCommand setPrunePreserved(boolean prunePreserved) {
+ if (pconfig == null)
+ pconfig = new PackConfig(repo);
+
+ pconfig.setPrunePreserved(prunePreserved);
+ return this;
+ }
+
@Override
public Properties call() throws GitAPIException {
checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
index ced1863719..2daa0d1a3b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
@@ -50,6 +50,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import org.eclipse.jgit.api.MergeResult.MergeStatus;
@@ -134,7 +135,7 @@ public class MergeCommand extends GitCommand<MergeResult> {
FF_ONLY;
public String toConfigValue() {
- return "--" + name().toLowerCase().replace('_', '-'); //$NON-NLS-1$
+ return "--" + name().toLowerCase(Locale.ROOT).replace('_', '-'); //$NON-NLS-1$
}
public boolean matchConfigValue(String in) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
index b8ee1ec0b3..fc8bb874fb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
@@ -232,19 +232,19 @@ public class StashApplyCommand extends GitCommand<ObjectId> {
untrackedMerger.setBase(null);
boolean ok = untrackedMerger.merge(headCommit,
untrackedCommit);
- if (ok)
+ if (ok) {
try {
RevTree untrackedTree = revWalk
- .parseTree(untrackedMerger
- .getResultTreeId());
+ .parseTree(untrackedCommit);
resetUntracked(untrackedTree);
} catch (CheckoutConflictException e) {
throw new StashApplyFailureException(
- JGitText.get().stashApplyConflict);
+ JGitText.get().stashApplyConflict, e);
}
- else
+ } else {
throw new StashApplyFailureException(
JGitText.get().stashApplyConflict);
+ }
}
} else {
throw new StashApplyFailureException(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
index 819442cbea..fa7cc0df87 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
@@ -682,7 +682,7 @@ public class DiffFormatter implements AutoCloseable {
}
private static byte[] writeGitLinkText(AbbreviatedObjectId id) {
- if (id.toObjectId().equals(ObjectId.zeroId())) {
+ if (ObjectId.zeroId().equals(id.toObjectId())) {
return EMPTY;
}
return encodeASCII("Subproject commit " + id.name() //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java
new file mode 100644
index 0000000000..c2833a1614
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 Ericsson
+ * 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.errors;
+
+import java.io.IOException;
+
+/**
+ * Thrown when an operation was canceled
+ *
+ * @since 4.7
+ */
+public class CancelledException extends IOException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @param message
+ */
+ public CancelledException(String message) {
+ super(message);
+ }
+}
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 8a35d35fea..55ded92a17 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
@@ -57,6 +57,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.gitrepo.RepoProject.CopyFile;
import org.eclipse.jgit.gitrepo.internal.RepoText;
@@ -324,7 +325,7 @@ public class ManifestParser extends DefaultHandler {
*
* @return filtered projects list reference, never null
*/
- public List<RepoProject> getFilteredProjects() {
+ public @NonNull List<RepoProject> getFilteredProjects() {
return filteredProjects;
}
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 86dbabca0b..d18cd97489 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -181,9 +181,8 @@ public class RepoCommand extends GitCommand<RevCommit> {
throws GitAPIException, IOException {
File dir = FileUtils.createTempDir("jgit_", ".git", null); //$NON-NLS-1$ //$NON-NLS-2$
try (Git git = Git.cloneRepository().setBare(true).setDirectory(dir)
- .setURI(uri).call();
- Repository repo = git.getRepository()) {
- return readFileFromRepo(repo, ref, path);
+ .setURI(uri).call()) {
+ return readFileFromRepo(git.getRepository(), ref, path);
} finally {
FileUtils.delete(dir, FileUtils.RECURSIVE);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java
index 4e90d8c3cb..64c2a74554 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java
@@ -46,8 +46,6 @@ package org.eclipse.jgit.ignore.internal;
* Base class for default methods as {@link #toString()} and such.
* <p>
* This class is immutable and thread safe.
- *
- * @since 3.6
*/
public abstract class AbstractMatcher implements IMatcher {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/IMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/IMatcher.java
index 8bb4dfb564..4c13e2ff6a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/IMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/IMatcher.java
@@ -44,8 +44,6 @@ package org.eclipse.jgit.ignore.internal;
/**
* Generic string matcher
- *
- * @since 3.6
*/
public interface IMatcher {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java
index 3d0ad09124..3ebc6afb2c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java
@@ -44,8 +44,6 @@ package org.eclipse.jgit.ignore.internal;
/**
* Matcher for simple regex patterns starting with an asterisk, e.g. "*.tmp"
- *
- * @since 3.6
*/
public class LeadingAsteriskMatcher extends NameMatcher {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java
index 8beae8379e..888b989b62 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java
@@ -47,8 +47,6 @@ import static org.eclipse.jgit.ignore.internal.Strings.getPathSeparator;
/**
* Matcher built from patterns for file names (single path segments). This class
* is immutable and thread safe.
- *
- * @since 3.6
*/
public class NameMatcher extends AbstractMatcher {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java
index c3f6694a7a..adf13292bf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java
@@ -59,8 +59,6 @@ import org.eclipse.jgit.ignore.internal.Strings.PatternState;
* Matcher built by patterns consists of multiple path segments.
* <p>
* This class is immutable and thread safe.
- *
- * @since 3.6
*/
public class PathMatcher extends AbstractMatcher {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java
index 70c5199030..1c467fe71b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java
@@ -58,8 +58,6 @@ import org.eclipse.jgit.internal.JGitText;
/**
* Various {@link String} related utility methods, written mostly to avoid
* generation of new String objects (e.g. via splitting Strings etc).
- *
- * @since 3.6
*/
public class Strings {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java
index b927d27dbe..c7064ac851 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java
@@ -44,8 +44,6 @@ package org.eclipse.jgit.ignore.internal;
/**
* Matcher for simple patterns ending with an asterisk, e.g. "Makefile.*"
- *
- * @since 3.6
*/
public class TrailingAsteriskMatcher extends NameMatcher {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java
index 8f9815283d..f64050f83c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java
@@ -53,8 +53,6 @@ import org.eclipse.jgit.errors.InvalidPatternException;
* glob wildcards to Java {@link Pattern}'s.
* <p>
* This class is immutable and thread safe.
- *
- * @since 3.6
*/
public class WildCardMatcher extends NameMatcher {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java
index d578654375..2f24e02410 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java
@@ -47,8 +47,6 @@ package org.eclipse.jgit.ignore.internal;
* matcher matches any path.
* <p>
* This class is immutable and thread safe.
- *
- * @since 3.6
*/
public final class WildMatcher extends AbstractMatcher {
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 ada5bf7116..244356c13b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -90,6 +90,7 @@ public class JGitText extends TranslationBundle {
/***/ public String badObjectType;
/***/ public String badRef;
/***/ public String badSectionEntry;
+ /***/ public String badShallowLine;
/***/ public String bareRepositoryNoWorkdirAndIndex;
/***/ public String base64InputNotProperlyPadded;
/***/ public String baseLengthIncorrect;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedListener.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedListener.java
index 047c86f289..9f7f350833 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedListener.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedListener.java
@@ -47,8 +47,6 @@ import org.eclipse.jgit.events.RepositoryListener;
/**
* Receives {@link BeforeDfsPackIndexLoadedEvent}s.
- *
- * @since 2.2
*/
public interface BeforeDfsPackIndexLoadedListener extends RepositoryListener {
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java
index 089bfa471d..feadedbc88 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java
@@ -122,7 +122,6 @@ public class DfsBlockCacheConfig {
/**
* @return the estimated number of threads concurrently accessing the cache.
* <b>Default is 32.</b>
- * @since 4.6
*/
public int getConcurrencyLevel() {
return concurrencyLevel;
@@ -133,7 +132,6 @@ public class DfsBlockCacheConfig {
* the estimated number of threads concurrently accessing the
* cache.
* @return {@code this}
- * @since 4.6
*/
public DfsBlockCacheConfig setConcurrencyLevel(
final int newConcurrencyLevel) {
@@ -145,7 +143,6 @@ public class DfsBlockCacheConfig {
* @return highest percentage of {@link #getBlockLimit()} a single pack can
* occupy while being copied by the pack reuse strategy. <b>Default
* is 0.30, or 30%</b>.
- * @since 4.0
*/
public double getStreamRatio() {
return streamRatio;
@@ -155,7 +152,6 @@ public class DfsBlockCacheConfig {
* @param ratio
* percentage of cache to occupy with a copied pack.
* @return {@code this}
- * @since 4.0
*/
public DfsBlockCacheConfig setStreamRatio(double ratio) {
streamRatio = Math.max(0, Math.min(ratio, 1.0));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
index 6f760caea1..56ff1b5c2e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
@@ -43,9 +43,12 @@
package org.eclipse.jgit.internal.storage.dfs;
+import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_REST;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_TXN;
+import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT;
+import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.RECEIVE;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE;
import static org.eclipse.jgit.internal.storage.pack.PackExt.BITMAP_INDEX;
import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX;
@@ -55,6 +58,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -63,6 +67,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
import org.eclipse.jgit.internal.storage.file.PackIndex;
+import org.eclipse.jgit.internal.storage.file.PackReverseIndex;
import org.eclipse.jgit.internal.storage.pack.PackExt;
import org.eclipse.jgit.internal.storage.pack.PackWriter;
import org.eclipse.jgit.internal.storage.reftree.RefTreeNames;
@@ -253,7 +258,7 @@ public class DfsGarbageCollector {
for (Ref ref : refsBefore) {
if (ref.isSymbolic() || ref.getObjectId() == null)
continue;
- if (isHead(ref))
+ if (isHead(ref) || isTag(ref))
allHeads.add(ref.getObjectId());
else if (RefTreeNames.isRefTree(refdb, ref.getName()))
txnHeads.add(ref.getObjectId());
@@ -390,7 +395,8 @@ public class DfsGarbageCollector {
pw.setTagTargets(tagTargets);
pw.preparePack(pm, allHeads, PackWriter.NONE);
if (0 < pw.getObjectCount())
- writePack(GC, pw, pm);
+ writePack(GC, pw, pm,
+ estimateGcPackSize(INSERT, RECEIVE, COMPACT, GC));
}
}
@@ -403,7 +409,8 @@ public class DfsGarbageCollector {
pw.excludeObjects(packedObjs);
pw.preparePack(pm, nonHeads, allHeads);
if (0 < pw.getObjectCount())
- writePack(GC_REST, pw, pm);
+ writePack(GC_REST, pw, pm,
+ estimateGcPackSize(INSERT, RECEIVE, COMPACT, GC_REST));
}
}
@@ -416,7 +423,7 @@ public class DfsGarbageCollector {
pw.excludeObjects(packedObjs);
pw.preparePack(pm, txnHeads, PackWriter.NONE);
if (0 < pw.getObjectCount())
- writePack(GC_TXN, pw, pm);
+ writePack(GC_TXN, pw, pm, 0 /* unknown pack size */);
}
}
@@ -432,21 +439,29 @@ public class DfsGarbageCollector {
pw.setDeltaBaseAsOffset(true);
pw.setReuseDeltaCommits(true);
pm.beginTask(JGitText.get().findingGarbage, objectsBefore());
+ long estimatedPackSize = 12 + 20; // header and trailer sizes.
for (DfsPackFile oldPack : packsBefore) {
PackIndex oldIdx = oldPack.getPackIndex(ctx);
+ PackReverseIndex oldRevIdx = oldPack.getReverseIdx(ctx);
+ long maxOffset = oldPack.getPackDescription().getFileSize(PACK)
+ - 20; // pack size - trailer size.
for (PackIndex.MutableEntry ent : oldIdx) {
pm.update(1);
ObjectId id = ent.toObjectId();
if (pool.lookupOrNull(id) != null || anyPackHas(id))
continue;
- int type = oldPack.getObjectType(ctx, ent.getOffset());
+ long offset = ent.getOffset();
+ int type = oldPack.getObjectType(ctx, offset);
pw.addObject(pool.lookupAny(id, type));
+ long objSize = oldRevIdx.findNextOffset(offset, maxOffset)
+ - offset;
+ estimatedPackSize += objSize;
}
}
pm.endTask();
if (0 < pw.getObjectCount())
- writePack(UNREACHABLE_GARBAGE, pw, pm);
+ writePack(UNREACHABLE_GARBAGE, pw, pm, estimatedPackSize);
}
}
@@ -461,6 +476,10 @@ public class DfsGarbageCollector {
return ref.getName().startsWith(Constants.R_HEADS);
}
+ private static boolean isTag(Ref ref) {
+ return ref.getName().startsWith(Constants.R_TAGS);
+ }
+
private int objectsBefore() {
int cnt = 0;
for (DfsPackFile p : packsBefore)
@@ -475,9 +494,24 @@ public class DfsGarbageCollector {
return pw;
}
+ private long estimateGcPackSize(PackSource first, PackSource... rest) {
+ EnumSet<PackSource> sourceSet = EnumSet.of(first, rest);
+ // Every pack file contains 12 bytes of header and 20 bytes of trailer.
+ // Include the final pack file header and trailer size here and ignore
+ // the same from individual pack files.
+ long size = 32;
+ for (DfsPackDescription pack : getSourcePacks()) {
+ if (sourceSet.contains(pack.getPackSource())) {
+ size += pack.getFileSize(PACK) - 32;
+ }
+ }
+ return size;
+ }
+
private DfsPackDescription writePack(PackSource source, PackWriter pw,
- ProgressMonitor pm) throws IOException {
- DfsPackDescription pack = repo.getObjectDatabase().newPack(source);
+ ProgressMonitor pm, long estimatedPackSize) throws IOException {
+ DfsPackDescription pack = repo.getObjectDatabase().newPack(source,
+ estimatedPackSize);
newPackDesc.add(pack);
try (DfsOutputStream out = objdb.writeFile(pack, PACK)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
index b1d6c0dd19..b68527544a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
@@ -266,6 +266,32 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
throws IOException;
/**
+ * Generate a new unique name for a pack file.
+ *
+ * <p>
+ * Default implementation of this method would be equivalent to
+ * {@code newPack(source).setEstimatedPackSize(estimatedPackSize)}. But the
+ * clients can override this method to use the given
+ * {@code estomatedPackSize} value more efficiently in the process of
+ * creating a new {@link DfsPackDescription} object.
+ *
+ * @param source
+ * where the pack stream is created.
+ * @param estimatedPackSize
+ * the estimated size of the pack.
+ * @return a unique name for the pack file. Must not collide with any other
+ * pack file name in the same DFS.
+ * @throws IOException
+ * a new unique pack description cannot be generated.
+ */
+ protected DfsPackDescription newPack(PackSource source,
+ long estimatedPackSize) throws IOException {
+ DfsPackDescription pack = newPack(source);
+ pack.setEstimatedPackSize(estimatedPackSize);
+ return pack;
+ }
+
+ /**
* Commit a pack and index pair that was written to the DFS.
* <p>
* Committing the pack/index pair makes them visible to readers. The JGit
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
index 11aef7feaf..ba3b39360b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
@@ -224,7 +224,8 @@ public class DfsPackCompactor {
}
boolean rollback = true;
- DfsPackDescription pack = objdb.newPack(COMPACT);
+ DfsPackDescription pack = objdb.newPack(COMPACT,
+ estimatePackSize());
try {
writePack(objdb, pack, pw, pm);
writeIndex(objdb, pack, pw);
@@ -251,6 +252,17 @@ public class DfsPackCompactor {
}
}
+ private long estimatePackSize() {
+ // Every pack file contains 12 bytes of header and 20 bytes of trailer.
+ // Include the final pack file header and trailer size here and ignore
+ // the same from individual pack files.
+ long size = 32;
+ for (DfsPackFile pack : srcPacks) {
+ size += pack.getPackDescription().getFileSize(PACK) - 32;
+ }
+ return size;
+ }
+
/** @return all of the source packs that fed into this compaction. */
public List<DfsPackDescription> getSourcePacks() {
return toPrune();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java
index 2b9d0e55c7..0411bbe5e4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java
@@ -81,6 +81,8 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> {
private int indexVersion;
+ private long estimatedPackSize;
+
/**
* Initialize a description by pack name and repository.
* <p>
@@ -189,6 +191,25 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> {
return size == null ? 0 : size.longValue();
}
+ /**
+ * @param estimatedPackSize
+ * estimated size of the .pack file in bytes. If 0 the pack file
+ * size is unknown.
+ * @return {@code this}
+ */
+ public DfsPackDescription setEstimatedPackSize(long estimatedPackSize) {
+ this.estimatedPackSize = Math.max(0, estimatedPackSize);
+ return this;
+ }
+
+ /**
+ * @return estimated size of the .pack file in bytes. If 0 the pack file
+ * size is unknown.
+ */
+ public long getEstimatedPackSize() {
+ return estimatedPackSize;
+ }
+
/** @return number of objects in the pack. */
public long getObjectCount() {
return objectCount;
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 4eabb03163..f15d427f8d 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
@@ -187,7 +187,6 @@ public final class DfsPackFile {
/**
* @return whether the pack index file is loaded and cached in memory.
- * @since 2.2
*/
public boolean isIndexLoaded() {
DfsBlockCache.Ref<PackIndex> idxref = index;
@@ -499,6 +498,7 @@ public final class DfsPackFile {
rc.setReadAheadBytes(ctx.getOptions().getStreamPackBufferSize());
long position = 12;
long remaining = length - (12 + 20);
+ boolean packHeadSkipped = false;
while (0 < remaining) {
DfsBlock b = cache.get(key, alignToBlock(position));
if (b != null) {
@@ -508,6 +508,7 @@ public final class DfsPackFile {
position += n;
remaining -= n;
rc.position(position);
+ packHeadSkipped = true;
continue;
}
@@ -517,7 +518,14 @@ public final class DfsPackFile {
throw packfileIsTruncated();
else if (n > remaining)
n = (int) remaining;
- out.write(buf.array(), 0, n);
+
+ if (!packHeadSkipped) {
+ // Need skip the 'PACK' header for the first read
+ out.write(buf.array(), 12, n - 12);
+ packHeadSkipped = true;
+ } else {
+ out.write(buf.array(), 0, n);
+ }
position += n;
remaining -= n;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderOptions.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderOptions.java
index 84198077eb..d07c13d0b0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderOptions.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderOptions.java
@@ -109,7 +109,6 @@ public class DfsReaderOptions {
/**
* @return number of bytes to use for buffering when streaming a pack file
* during copying. If 0 the block size of the pack is used.
- * @since 4.0
*/
public int getStreamPackBufferSize() {
return streamPackBufferSize;
@@ -120,7 +119,6 @@ public class DfsReaderOptions {
* new buffer size in bytes for buffers used when streaming pack
* files during copying.
* @return {@code this}
- * @since 4.0
*/
public DfsReaderOptions setStreamPackBufferSize(int bufsz) {
streamPackBufferSize = Math.max(0, bufsz);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
index fd213977a8..bdcf9f9a14 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
@@ -63,7 +63,6 @@ public class InMemoryRepository extends DfsRepository {
*
* @param repoDesc
* description of the repository.
- * @since 2.0
*/
public InMemoryRepository(DfsRepositoryDescription repoDesc) {
this(new Builder().setRepositoryDescription(repoDesc));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
index 0388acbbaf..16315a5b55 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
@@ -55,6 +55,7 @@ import java.io.IOException;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.HashSet;
+import java.util.Locale;
import java.util.Objects;
import java.util.Set;
@@ -342,7 +343,7 @@ public class FileRepository extends Repository {
if (symLinks != null)
cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_SYMLINKS, symLinks.name()
- .toLowerCase());
+ .toLowerCase(Locale.ROOT));
cfg.setInt(ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 0);
cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
index e3e73e25f7..87a5ee5ae4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
@@ -79,11 +79,14 @@ import java.util.stream.Stream;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.errors.CancelledException;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.file.ObjectDirectory;
+import org.eclipse.jgit.internal.storage.file.ObjectDirectoryInserter;
import org.eclipse.jgit.internal.storage.pack.PackExt;
import org.eclipse.jgit.internal.storage.pack.PackWriter;
import org.eclipse.jgit.internal.storage.reftree.RefTreeNames;
@@ -93,6 +96,8 @@ import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdSet;
+import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Ref.Storage;
@@ -219,11 +224,41 @@ public class GC {
}
/**
+ * Loosen objects in a pack file which are not also in the newly-created
+ * pack files.
+ *
+ * @param inserter
+ * @param reader
+ * @param pack
+ * @param existing
+ * @throws IOException
+ */
+ private void loosen(ObjectDirectoryInserter inserter, ObjectReader reader, PackFile pack, HashSet<ObjectId> existing)
+ throws IOException {
+ for (PackIndex.MutableEntry entry : pack) {
+ ObjectId oid = entry.toObjectId();
+ if (existing.contains(oid)) {
+ continue;
+ }
+ existing.add(oid);
+ ObjectLoader loader = reader.open(oid);
+ inserter.insert(loader.getType(),
+ loader.getSize(),
+ loader.openStream(),
+ true /* create this object even though it's a duplicate */);
+ }
+ }
+
+ /**
* Delete old pack files. What is 'old' is defined by specifying a set of
* old pack files and a set of new pack files. Each pack file contained in
- * old pack files but not contained in new pack files will be deleted. If an
- * expirationDate is set then pack files which are younger than the
- * expirationDate will not be deleted.
+ * old pack files but not contained in new pack files will be deleted. If
+ * preserveOldPacks is set, keep a copy of the pack file in the preserve
+ * directory. If an expirationDate is set then pack files which are younger
+ * than the expirationDate will not be deleted nor preserved.
+ * <p>
+ * If we're not immediately expiring loose objects, loosen any objects
+ * in the old pack files which aren't in the new pack files.
*
* @param oldPacks
* @param newPacks
@@ -232,8 +267,21 @@ public class GC {
*/
private void deleteOldPacks(Collection<PackFile> oldPacks,
Collection<PackFile> newPacks) throws ParseException, IOException {
+ HashSet<ObjectId> ids = new HashSet<>();
+ for (PackFile pack : newPacks) {
+ for (PackIndex.MutableEntry entry : pack) {
+ ids.add(entry.toObjectId());
+ }
+ }
+ ObjectReader reader = repo.newObjectReader();
+ ObjectDirectory dir = repo.getObjectDatabase();
+ ObjectDirectoryInserter inserter = dir.newInserter();
+ boolean shouldLoosen = getExpireDate() < Long.MAX_VALUE;
+
+ prunePreserved();
long packExpireDate = getPackExpireDate();
oldPackLoop: for (PackFile oldPack : oldPacks) {
+ checkCancelled();
String oldName = oldPack.getPackName();
// check whether an old pack file is also among the list of new
// pack files. Then we must not delete it.
@@ -245,15 +293,56 @@ public class GC {
&& repo.getFS().lastModified(
oldPack.getPackFile()) < packExpireDate) {
oldPack.close();
+ if (shouldLoosen) {
+ loosen(inserter, reader, oldPack, ids);
+ }
prunePack(oldName);
}
}
- // close the complete object database. Thats my only chance to force
+ // close the complete object database. That's my only chance to force
// rescanning and to detect that certain pack files are now deleted.
repo.getObjectDatabase().close();
}
/**
+ * Deletes old pack file, unless 'preserve-oldpacks' is set, in which case it
+ * moves the pack file to the preserved directory
+ *
+ * @param packFile
+ * @param packName
+ * @param ext
+ * @param deleteOptions
+ * @throws IOException
+ */
+ private void removeOldPack(File packFile, String packName, PackExt ext,
+ int deleteOptions) throws IOException {
+ if (pconfig != null && pconfig.isPreserveOldPacks()) {
+ File oldPackDir = repo.getObjectDatabase().getPreservedDirectory();
+ FileUtils.mkdir(oldPackDir, true);
+
+ String oldPackName = "pack-" + packName + ".old-" + ext.getExtension(); //$NON-NLS-1$ //$NON-NLS-2$
+ File oldPackFile = new File(oldPackDir, oldPackName);
+ FileUtils.rename(packFile, oldPackFile);
+ } else {
+ FileUtils.delete(packFile, deleteOptions);
+ }
+ }
+
+ /**
+ * Delete the preserved directory including all pack files within
+ */
+ private void prunePreserved() {
+ if (pconfig != null && pconfig.isPrunePreserved()) {
+ try {
+ FileUtils.delete(repo.getObjectDatabase().getPreservedDirectory(),
+ FileUtils.RECURSIVE | FileUtils.RETRY | FileUtils.SKIP_MISSING);
+ } catch (IOException e) {
+ // Deletion of the preserved pack files failed. Silently return.
+ }
+ }
+ }
+
+ /**
* Delete files associated with a single pack file. First try to delete the
* ".pack" file because on some platforms the ".pack" file may be locked and
* can't be deleted. In such a case it is better to detect this early and
@@ -272,7 +361,7 @@ public class GC {
for (PackExt ext : extensions)
if (PackExt.PACK.equals(ext)) {
File f = nameFor(packName, "." + ext.getExtension()); //$NON-NLS-1$
- FileUtils.delete(f, deleteOptions);
+ removeOldPack(f, packName, ext, deleteOptions);
break;
}
// The .pack file has been deleted. Delete as many as the other
@@ -281,7 +370,7 @@ public class GC {
for (PackExt ext : extensions) {
if (!PackExt.PACK.equals(ext)) {
File f = nameFor(packName, "." + ext.getExtension()); //$NON-NLS-1$
- FileUtils.delete(f, deleteOptions);
+ removeOldPack(f, packName, ext, deleteOptions);
}
}
} catch (IOException e) {
@@ -306,6 +395,7 @@ public class GC {
pm.beginTask(JGitText.get().pruneLoosePackedObjects, fanout.length);
try {
for (String d : fanout) {
+ checkCancelled();
pm.update(1);
if (d.length() != 2)
continue;
@@ -313,6 +403,7 @@ public class GC {
if (entries == null)
continue;
for (String e : entries) {
+ checkCancelled();
if (e.length() != Constants.OBJECT_ID_STRING_LENGTH - 2)
continue;
ObjectId id;
@@ -324,11 +415,13 @@ public class GC {
continue;
}
boolean found = false;
- for (PackFile p : packs)
+ for (PackFile p : packs) {
+ checkCancelled();
if (p.hasObject(id)) {
found = true;
break;
}
+ }
if (found)
FileUtils.delete(objdb.fileFor(id), FileUtils.RETRY
| FileUtils.SKIP_MISSING
@@ -369,6 +462,7 @@ public class GC {
fanout.length);
try {
for (String d : fanout) {
+ checkCancelled();
pm.update(1);
if (d.length() != 2)
continue;
@@ -376,6 +470,7 @@ public class GC {
if (entries == null)
continue;
for (File f : entries) {
+ checkCancelled();
String fName = f.getName();
if (fName.length() != Constants.OBJECT_ID_STRING_LENGTH - 2)
continue;
@@ -404,6 +499,8 @@ public class GC {
if (deletionCandidates.isEmpty())
return;
+ checkCancelled();
+
// From the set of current refs remove all those which have been handled
// during last repack(). Only those refs will survive which have been
// added or modified since the last repack. Only these can save existing
@@ -433,11 +530,14 @@ public class GC {
// leave this method.
ObjectWalk w = new ObjectWalk(repo);
try {
- for (Ref cr : newRefs)
+ for (Ref cr : newRefs) {
+ checkCancelled();
w.markStart(w.parseAny(cr.getObjectId()));
+ }
if (lastPackedRefs != null)
- for (Ref lpr : lastPackedRefs)
+ for (Ref lpr : lastPackedRefs) {
w.markUninteresting(w.parseAny(lpr.getObjectId()));
+ }
removeReferenced(deletionCandidates, w);
} finally {
w.dispose();
@@ -455,11 +555,15 @@ public class GC {
ObjectWalk w = new ObjectWalk(repo);
try {
for (Ref ar : getAllRefs())
- for (ObjectId id : listRefLogObjects(ar, lastRepackTime))
+ for (ObjectId id : listRefLogObjects(ar, lastRepackTime)) {
+ checkCancelled();
w.markStart(w.parseAny(id));
+ }
if (lastPackedRefs != null)
- for (Ref lpr : lastPackedRefs)
+ for (Ref lpr : lastPackedRefs) {
+ checkCancelled();
w.markUninteresting(w.parseAny(lpr.getObjectId()));
+ }
removeReferenced(deletionCandidates, w);
} finally {
w.dispose();
@@ -468,6 +572,8 @@ public class GC {
if (deletionCandidates.isEmpty())
return;
+ checkCancelled();
+
// delete all candidates which have survived: these are unreferenced
// loose objects. Make a last check, though, to avoid deleting objects
// that could have been referenced while the candidates list was being
@@ -536,6 +642,7 @@ public class GC {
IncorrectObjectTypeException, IOException {
RevObject ro = w.next();
while (ro != null) {
+ checkCancelled();
if (id2File.remove(ro.getId()) != null)
if (id2File.isEmpty())
return;
@@ -543,6 +650,7 @@ public class GC {
}
ro = w.nextObject();
while (ro != null) {
+ checkCancelled();
if (id2File.remove(ro.getId()) != null)
if (id2File.isEmpty())
return;
@@ -576,6 +684,7 @@ public class GC {
pm.beginTask(JGitText.get().packRefs, refs.size());
try {
for (Ref ref : refs) {
+ checkCancelled();
if (!ref.isSymbolic() && ref.getStorage().isLoose())
refsToBePacked.add(ref.getName());
pm.update(1);
@@ -614,10 +723,11 @@ public class GC {
RefDatabase refdb = repo.getRefDatabase();
for (Ref ref : refsBefore) {
+ checkCancelled();
nonHeads.addAll(listRefLogObjects(ref, 0));
if (ref.isSymbolic() || ref.getObjectId() == null)
continue;
- if (ref.getName().startsWith(Constants.R_HEADS))
+ if (isHead(ref) || isTag(ref))
allHeads.add(ref.getObjectId());
else if (RefTreeNames.isRefTree(refdb, ref.getName()))
txnHeads.add(ref.getObjectId());
@@ -628,9 +738,11 @@ public class GC {
}
List<ObjectIdSet> excluded = new LinkedList<ObjectIdSet>();
- for (final PackFile f : repo.getObjectDatabase().getPacks())
+ for (final PackFile f : repo.getObjectDatabase().getPacks()) {
+ checkCancelled();
if (f.shouldBeKept())
excluded.add(f.getIndex());
+ }
tagTargets.addAll(allHeads);
nonHeads.addAll(indexObjects);
@@ -671,6 +783,14 @@ public class GC {
return ret;
}
+ private static boolean isHead(Ref ref) {
+ return ref.getName().startsWith(Constants.R_HEADS);
+ }
+
+ private static boolean isTag(Ref ref) {
+ return ref.getName().startsWith(Constants.R_TAGS);
+ }
+
/**
* Deletes orphans
* <p>
@@ -763,6 +883,7 @@ public class GC {
all.addAll(refs);
// add additional refs which start with refs/
for (Ref r : addl) {
+ checkCancelled();
if (r.getName().startsWith(Constants.R_REFS)) {
all.add(r);
}
@@ -800,6 +921,7 @@ public class GC {
Set<ObjectId> ret = new HashSet<ObjectId>();
while (treeWalk.next()) {
+ checkCancelled();
ObjectId objectId = treeWalk.getObjectId(0);
switch (treeWalk.getRawMode(0) & FileMode.TYPE_MASK) {
case FileMode.TYPE_MISSING:
@@ -827,6 +949,7 @@ public class GC {
private PackFile writePack(@NonNull Set<? extends ObjectId> want,
@NonNull Set<? extends ObjectId> have, Set<ObjectId> tagTargets,
List<ObjectIdSet> excludeObjects) throws IOException {
+ checkCancelled();
File tmpPack = null;
Map<PackExt, File> tmpExts = new TreeMap<PackExt, File>(
new Comparator<PackExt>() {
@@ -858,6 +981,7 @@ public class GC {
pw.preparePack(pm, want, have);
if (pw.getObjectCount() == 0)
return null;
+ checkCancelled();
// create temporary files
String id = pw.computeName().getName();
@@ -974,6 +1098,12 @@ public class GC {
return new File(packdir, "pack-" + name + ext); //$NON-NLS-1$
}
+ private void checkCancelled() throws CancelledException {
+ if (pm.isCancelled()) {
+ throw new CancelledException(JGitText.get().operationCanceled);
+ }
+ }
+
/**
* A class holding statistical data for a FileRepository regarding how many
* objects are stored as loose or packed objects
@@ -1125,7 +1255,6 @@ public class GC {
* influence how packs are written and to implement something similar to
* "git gc --aggressive"
*
- * @since 3.6
* @param pconfig
* the {@link PackConfig} used when writing packs
*/
@@ -1198,7 +1327,6 @@ public class GC {
*
* @param auto
* defines whether gc should do automatic housekeeping
- * @since 4.5
*/
public void setAuto(boolean auto) {
this.automatic = auto;
@@ -1257,9 +1385,10 @@ public class GC {
new DirectoryStream.Filter<Path>() {
public boolean accept(Path file) throws IOException {
- return Files.isRegularFile(file) && PATTERN_LOOSE_OBJECT
- .matcher(file.getFileName().toString())
- .matches();
+ Path fileName = file.getFileName();
+ return Files.isRegularFile(file) && fileName != null
+ && PATTERN_LOOSE_OBJECT
+ .matcher(fileName.toString()).matches();
}
})) {
for (Iterator<Path> iter = stream.iterator(); iter.hasNext();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
index ce9677a62d..fcc8d7178c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
@@ -150,7 +150,6 @@ public class LockFile {
*
* @param f
* the file that will be locked.
- * @since 4.2
*/
public LockFile(final File f) {
ref = f;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
index ea80528518..eec7fb7c3a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
@@ -125,6 +125,8 @@ public class ObjectDirectory extends FileObjectDatabase {
private final File packDirectory;
+ private final File preservedDirectory;
+
private final File alternatesFile;
private final AtomicReference<PackList> packList;
@@ -165,6 +167,7 @@ public class ObjectDirectory extends FileObjectDatabase {
objects = dir;
infoDirectory = new File(objects, "info"); //$NON-NLS-1$
packDirectory = new File(objects, "pack"); //$NON-NLS-1$
+ preservedDirectory = new File(packDirectory, "preserved"); //$NON-NLS-1$
alternatesFile = new File(infoDirectory, "alternates"); //$NON-NLS-1$
packList = new AtomicReference<PackList>(NO_PACKS);
unpackedObjectCache = new UnpackedObjectCache();
@@ -189,6 +192,13 @@ public class ObjectDirectory extends FileObjectDatabase {
return objects;
}
+ /**
+ * @return the location of the <code>preserved</code> directory.
+ */
+ public final File getPreservedDirectory() {
+ return preservedDirectory;
+ }
+
@Override
public boolean exists() {
return fs.exists(objects);
@@ -690,8 +700,14 @@ public class ObjectDirectory extends FileObjectDatabase {
final BufferedReader reader = open(shallowFile);
try {
String line;
- while ((line = reader.readLine()) != null)
- shallowCommitsIds.add(ObjectId.fromString(line));
+ while ((line = reader.readLine()) != null) {
+ try {
+ shallowCommitsIds.add(ObjectId.fromString(line));
+ } catch (IllegalArgumentException ex) {
+ throw new IOException(MessageFormat
+ .format(JGitText.get().badShallowLine, line));
+ }
+ }
} finally {
reader.close();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
index 9820e0ea39..a510431f37 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
@@ -86,34 +86,71 @@ class ObjectDirectoryInserter extends ObjectInserter {
@Override
public ObjectId insert(int type, byte[] data, int off, int len)
throws IOException {
+ return insert(type, data, off, len, false);
+ }
+
+ /**
+ * Insert a loose object into the database. If createDuplicate is true,
+ * write the loose object even if we already have it in the loose or packed
+ * ODB.
+ *
+ * @param type
+ * @param data
+ * @param off
+ * @param len
+ * @param createDuplicate
+ * @return ObjectId
+ * @throws IOException
+ */
+ private ObjectId insert(
+ int type, byte[] data, int off, int len, boolean createDuplicate)
+ throws IOException {
ObjectId id = idFor(type, data, off, len);
- if (db.has(id)) {
+ if (!createDuplicate && db.has(id)) {
return id;
} else {
File tmp = toTemp(type, data, off, len);
- return insertOneObject(tmp, id);
+ return insertOneObject(tmp, id, createDuplicate);
}
}
@Override
public ObjectId insert(final int type, long len, final InputStream is)
throws IOException {
+ return insert(type, len, is, false);
+ }
+
+ /**
+ * Insert a loose object into the database. If createDuplicate is true,
+ * write the loose object even if we already have it in the loose or packed
+ * ODB.
+ *
+ * @param type
+ * @param len
+ * @param is
+ * @param createDuplicate
+ * @return ObjectId
+ * @throws IOException
+ */
+ ObjectId insert(int type, long len, InputStream is, boolean createDuplicate)
+ throws IOException {
if (len <= buffer().length) {
byte[] buf = buffer();
int actLen = IO.readFully(is, buf, 0);
- return insert(type, buf, 0, actLen);
+ return insert(type, buf, 0, actLen, createDuplicate);
} else {
MessageDigest md = digest();
File tmp = toTemp(md, type, len, is);
ObjectId id = ObjectId.fromRaw(md.digest());
- return insertOneObject(tmp, id);
+ return insertOneObject(tmp, id, createDuplicate);
}
}
- private ObjectId insertOneObject(final File tmp, final ObjectId id)
+ private ObjectId insertOneObject(
+ File tmp, ObjectId id, boolean createDuplicate)
throws IOException, ObjectWritingException {
- switch (db.insertUnpackedObject(tmp, id, false /* no duplicate */)) {
+ switch (db.insertUnpackedObject(tmp, id, createDuplicate)) {
case INSERTED:
case EXISTS_PACKED:
case EXISTS_LOOSE:
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
index b385b8ab73..edf44fb6ec 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
@@ -46,6 +46,7 @@
package org.eclipse.jgit.internal.storage.file;
import static org.eclipse.jgit.internal.storage.pack.PackExt.BITMAP_INDEX;
+import static org.eclipse.jgit.internal.storage.pack.PackExt.KEEP;
import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX;
import java.io.EOFException;
@@ -241,7 +242,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
*/
public boolean shouldBeKept() {
if (keepFile == null)
- keepFile = new File(packFile.getPath() + ".keep"); //$NON-NLS-1$
+ keepFile = extFile(KEEP);
return keepFile.exists();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java
index fc802666bc..24d2c790ee 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java
@@ -74,8 +74,6 @@ import org.eclipse.jgit.util.FileUtils;
/**
* Utility for writing reflog entries
- *
- * @since 2.0
*/
public class ReflogWriter {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
index 4ee27cc845..248692f93f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
@@ -53,6 +53,9 @@ public class PackExt {
/** A pack index file extension. */
public static final PackExt INDEX = newPackExt("idx"); //$NON-NLS-1$
+ /** A keep pack file extension. */
+ public static final PackExt KEEP = newPackExt("keep"); //$NON-NLS-1$
+
/** A pack bitmap index file extension. */
public static final PackExt BITMAP_INDEX = newPackExt("bitmap"); //$NON-NLS-1$
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 8b4d2e6d35..ffab1a7465 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
@@ -164,7 +164,7 @@ public class PackWriter implements AutoCloseable {
private static final int PACK_VERSION_GENERATED = 2;
/** Empty set of objects for {@code preparePack()}. */
- public static Set<ObjectId> NONE = Collections.emptySet();
+ public static final Set<ObjectId> NONE = Collections.emptySet();
private static final Map<WeakReference<PackWriter>, Boolean> instances =
new ConcurrentHashMap<WeakReference<PackWriter>, Boolean>();
@@ -369,7 +369,6 @@ public class PackWriter implements AutoCloseable {
* the callback to set
*
* @return this object for chaining.
- * @since 4.1
*/
public PackWriter setObjectCountCallback(ObjectCountCallback callback) {
this.callback = callback;
@@ -381,7 +380,6 @@ public class PackWriter implements AutoCloseable {
*
* @param clientShallowCommits
* the shallow commits in the client
- * @since 4.1
*/
public void setClientShallowCommits(Set<ObjectId> clientShallowCommits) {
stats.clientShallowCommits = Collections
@@ -742,8 +740,6 @@ public class PackWriter implements AutoCloseable {
* Must not be {@code null}.
* @throws IOException
* an I/O problem occured while reading objects.
- *
- * @since 4.5
*/
public void preparePack(ProgressMonitor countingMonitor,
@NonNull Set<? extends ObjectId> want,
@@ -1089,8 +1085,6 @@ public class PackWriter implements AutoCloseable {
/**
* Release all resources used by this writer.
- *
- * @since 4.0
*/
@Override
public void close() {
@@ -2258,8 +2252,6 @@ public class PackWriter implements AutoCloseable {
* @return the count of objects that needed to be discovered through an
* object walk because they were not found in bitmap indices.
* Returns -1 if no bitmap indices were found.
- *
- * @since 4.0
*/
public long getBitmapIndexMisses() {
return statistics.getBitmapIndexMisses();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
index 8fe8a96e99..ec771a24f0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
@@ -58,6 +58,7 @@ import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -895,7 +896,7 @@ public class Config {
if (value instanceof ConfigEnum)
n = ((ConfigEnum) value).toConfigValue();
else
- n = value.name().toLowerCase().replace('_', ' ');
+ n = value.name().toLowerCase(Locale.ROOT).replace('_', ' ');
setString(section, subsection, name, n);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
index c5b2ef8e5b..6be97ffda6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
@@ -4,6 +4,7 @@
* Copyright (C) 2006-2010, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2006-2012, Shawn O. Pearce <spearce@spearce.org>
* Copyright (C) 2012, Daniel Megert <daniel_megert@ch.ibm.com>
+ * Copyright (C) 2017, Wim Jongman <wim.jongman@remainsoftware.com>
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -888,11 +889,12 @@ public abstract class Repository implements AutoCloseable {
} else if (newCount == -1) {
// should not happen, only log when useCnt became negative to
// minimize number of log entries
+ String message = MessageFormat.format(JGitText.get().corruptUseCnt,
+ toString());
if (LOG.isDebugEnabled()) {
- IllegalStateException e = new IllegalStateException();
- LOG.debug(JGitText.get().corruptUseCnt, e);
+ LOG.debug(message, new IllegalStateException());
} else {
- LOG.warn(JGitText.get().corruptUseCnt);
+ LOG.warn(message);
}
if (RepositoryCache.isCached(this)) {
closedAt.set(System.currentTimeMillis());
@@ -1887,4 +1889,40 @@ public abstract class Repository implements AutoCloseable {
public void autoGC(ProgressMonitor monitor) {
// default does nothing
}
+
+ /**
+ * Normalizes the passed branch name into a possible valid branch name. The
+ * validity of the returned name should be checked by a subsequent call to
+ * {@link #isValidRefName(String)}.
+ * <p/>
+ * Future implementations of this method could be more restrictive or more
+ * lenient about the validity of specific characters in the returned name.
+ * <p/>
+ * The current implementation returns a trimmed string only containing word
+ * characters ([a-zA-Z_0-9]) and hyphens ('-'). Colons are replaced by
+ * hyphens. Repeating underscores and hyphens are replaced by a single
+ * occurrence. Underscores and hyphens at the beginning of the string are
+ * removed.
+ *
+ * @param name
+ * The name to normalize.
+ *
+ * @return The normalized String or null if null was passed.
+ * @since 4.7
+ * @see #isValidRefName(String)
+ */
+ public static String normalizeBranchName(String name) {
+ if (name == null || name.length() == 0) {
+ return name;
+ }
+ String result = name.trim();
+ return result.replaceAll("\\s+([_:-])*?\\s+", "$1") //$NON-NLS-1$//$NON-NLS-2$
+ .replaceAll(":", "-") //$NON-NLS-1$//$NON-NLS-2$
+ .replaceAll("\\s+", "_") //$NON-NLS-1$//$NON-NLS-2$
+ .replaceAll("_{2,}", "_") //$NON-NLS-1$//$NON-NLS-2$
+ .replaceAll("-{2,}", "-") //$NON-NLS-1$//$NON-NLS-2$
+ .replaceAll("[^\\w-]", "") //$NON-NLS-1$ //$NON-NLS-2$
+ .replaceAll("^_+", "") //$NON-NLS-1$//$NON-NLS-2$
+ .replaceAll("^-+", ""); //$NON-NLS-1$//$NON-NLS-2$
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java
index 245b3ee599..767cb24306 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java
@@ -43,6 +43,8 @@
package org.eclipse.jgit.patch;
+import java.util.Locale;
+
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.util.RawParseUtils;
@@ -102,7 +104,7 @@ public class FormatError {
@Override
public String toString() {
final StringBuilder r = new StringBuilder();
- r.append(getSeverity().name().toLowerCase());
+ r.append(getSeverity().name().toLowerCase(Locale.ROOT));
r.append(": at offset "); //$NON-NLS-1$
r.append(getOffset());
r.append(": "); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java
index 319b819a79..36965f4996 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java
@@ -43,6 +43,8 @@
package org.eclipse.jgit.revwalk;
+import java.util.Locale;
+
import org.eclipse.jgit.lib.Constants;
/** Case insensitive key for a {@link FooterLine}. */
@@ -68,7 +70,7 @@ public final class FooterKey {
*/
public FooterKey(final String keyName) {
name = keyName;
- raw = Constants.encode(keyName.toLowerCase());
+ raw = Constants.encode(keyName.toLowerCase(Locale.ROOT));
}
/** @return name of this footer line. */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
index d594e97671..3176cb30e1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
@@ -75,6 +75,20 @@ public class PackConfig {
public static final boolean DEFAULT_REUSE_OBJECTS = true;
/**
+ * Default value of keep old packs option: {@value}
+ * @see #setPreserveOldPacks(boolean)
+ * @since 4.7
+ */
+ public static final boolean DEFAULT_PRESERVE_OLD_PACKS = false;
+
+ /**
+ * Default value of prune old packs option: {@value}
+ * @see #setPrunePreserved(boolean)
+ * @since 4.7
+ */
+ public static final boolean DEFAULT_PRUNE_PRESERVED = false;
+
+ /**
* Default value of delta compress option: {@value}
*
* @see #setDeltaCompress(boolean)
@@ -204,6 +218,10 @@ public class PackConfig {
private boolean reuseObjects = DEFAULT_REUSE_OBJECTS;
+ private boolean preserveOldPacks = DEFAULT_PRESERVE_OLD_PACKS;
+
+ private boolean prunePreserved = DEFAULT_PRUNE_PRESERVED;
+
private boolean deltaBaseAsOffset = DEFAULT_DELTA_BASE_AS_OFFSET;
private boolean deltaCompress = DEFAULT_DELTA_COMPRESS;
@@ -281,6 +299,8 @@ public class PackConfig {
this.compressionLevel = cfg.compressionLevel;
this.reuseDeltas = cfg.reuseDeltas;
this.reuseObjects = cfg.reuseObjects;
+ this.preserveOldPacks = cfg.preserveOldPacks;
+ this.prunePreserved = cfg.prunePreserved;
this.deltaBaseAsOffset = cfg.deltaBaseAsOffset;
this.deltaCompress = cfg.deltaCompress;
this.maxDeltaDepth = cfg.maxDeltaDepth;
@@ -364,6 +384,61 @@ public class PackConfig {
}
/**
+ * Checks whether to preserve old packs in a preserved directory
+ *
+ * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS}
+ *
+ * @return true if repacking will preserve old pack files.
+ * @since 4.7
+ */
+ public boolean isPreserveOldPacks() {
+ return preserveOldPacks;
+ }
+
+ /**
+ * Set preserve old packs configuration option for repacking.
+ *
+ * If enabled, old pack files are moved into a preserved subdirectory instead
+ * of being deleted
+ *
+ * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS}
+ *
+ * @param preserveOldPacks
+ * boolean indicating whether or not preserve old pack files
+ * @since 4.7
+ */
+ public void setPreserveOldPacks(boolean preserveOldPacks) {
+ this.preserveOldPacks = preserveOldPacks;
+ }
+
+ /**
+ * Checks whether to remove preserved pack files in a preserved directory
+ *
+ * Default setting: {@value #DEFAULT_PRUNE_PRESERVED}
+ *
+ * @return true if repacking will remove preserved pack files.
+ * @since 4.7
+ */
+ public boolean isPrunePreserved() {
+ return prunePreserved;
+ }
+
+ /**
+ * Set prune preserved configuration option for repacking.
+ *
+ * If enabled, preserved pack files are removed from a preserved subdirectory
+ *
+ * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS}
+ *
+ * @param prunePreserved
+ * boolean indicating whether or not preserve old pack files
+ * @since 4.7
+ */
+ public void setPrunePreserved(boolean prunePreserved) {
+ this.prunePreserved = prunePreserved;
+ }
+
+ /**
* True if writer can use offsets to point to a delta base.
*
* If true the writer may choose to use an offset to point to a delta base
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
index 5b9e8d9029..a10f3d7117 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
@@ -45,6 +45,7 @@ package org.eclipse.jgit.submodule;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
+import java.util.Locale;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheIterator;
@@ -663,7 +664,8 @@ public class SubmoduleWalk implements AutoCloseable {
ConfigConstants.CONFIG_KEY_IGNORE);
if (name == null)
return null;
- return IgnoreSubmoduleMode.valueOf(name.trim().toUpperCase());
+ return IgnoreSubmoduleMode
+ .valueOf(name.trim().toUpperCase(Locale.ROOT));
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
index 81e6904bff..4256fe47db 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
@@ -56,6 +56,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
@@ -168,7 +169,8 @@ abstract class HttpAuthMethod {
SCHEMA_NAME_SEPARATOR, 2);
try {
- Type methodType = Type.valueOf(valuePart[0].toUpperCase());
+ Type methodType = Type.valueOf(
+ valuePart[0].toUpperCase(Locale.ROOT));
if ((ignoreTypes != null)
&& (ignoreTypes.contains(methodType))) {
@@ -540,7 +542,7 @@ abstract class HttpAuthMethod {
GSSManager gssManager = GSS_MANAGER_FACTORY.newInstance(conn
.getURL());
String host = conn.getURL().getHost();
- String peerName = "HTTP@" + host.toLowerCase(); //$NON-NLS-1$
+ String peerName = "HTTP@" + host.toLowerCase(Locale.ROOT); //$NON-NLS-1$
try {
GSSName gssName = gssManager.createName(peerName,
GSSName.NT_HOSTBASED_SERVICE);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRC.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRC.java
index bacab7e21e..8855f96567 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRC.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRC.java
@@ -48,6 +48,7 @@ import java.io.FileReader;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
@@ -230,7 +231,7 @@ public class NetRC {
matcher.reset(line);
while (matcher.find()) {
- String command = matcher.group().toLowerCase();
+ String command = matcher.group().toLowerCase(Locale.ROOT);
if (command.startsWith("#")) { //$NON-NLS-1$
matcher.reset(""); //$NON-NLS-1$
continue;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java
index 81c5da3c78..87c9a50038 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java
@@ -45,8 +45,6 @@ package org.eclipse.jgit.transport;
import java.io.IOException;
-import javax.servlet.http.HttpServletResponse;
-
import org.eclipse.jgit.internal.JGitText;
/**
@@ -55,6 +53,7 @@ import org.eclipse.jgit.internal.JGitText;
* @since 2.0
*/
public class ServiceMayNotContinueException extends IOException {
+ private static final int FORBIDDEN = 403;
private static final long serialVersionUID = 1L;
private final int statusCode;
@@ -63,7 +62,7 @@ public class ServiceMayNotContinueException extends IOException {
/** Initialize with no message. */
public ServiceMayNotContinueException() {
// Do not set a message.
- statusCode = HttpServletResponse.SC_FORBIDDEN;
+ statusCode = FORBIDDEN;
}
/**
@@ -73,7 +72,7 @@ public class ServiceMayNotContinueException extends IOException {
*/
public ServiceMayNotContinueException(String msg) {
super(msg);
- statusCode = HttpServletResponse.SC_FORBIDDEN;
+ statusCode = FORBIDDEN;
}
/**
@@ -99,7 +98,7 @@ public class ServiceMayNotContinueException extends IOException {
*/
public ServiceMayNotContinueException(String msg, Throwable cause) {
super(msg, cause);
- statusCode = HttpServletResponse.SC_FORBIDDEN;
+ statusCode = FORBIDDEN;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
index da98e8c9ea..6bdf905e4f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
@@ -56,6 +56,7 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Set;
import org.eclipse.jgit.errors.NoRemoteRepositoryException;
@@ -217,11 +218,12 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
public Process exec(String command, int timeout)
throws TransportException {
String ssh = SystemReader.getInstance().getenv("GIT_SSH"); //$NON-NLS-1$
- boolean putty = ssh.toLowerCase().contains("plink"); //$NON-NLS-1$
+ boolean putty = ssh.toLowerCase(Locale.ROOT).contains("plink"); //$NON-NLS-1$
List<String> args = new ArrayList<String>();
args.add(ssh);
- if (putty && !ssh.toLowerCase().contains("tortoiseplink")) //$NON-NLS-1$
+ if (putty
+ && !ssh.toLowerCase(Locale.ROOT).contains("tortoiseplink")) //$NON-NLS-1$
args.add("-batch"); //$NON-NLS-1$
if (0 < getURI().getPort()) {
args.add(putty ? "-P" : "-p"); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
index 4c3fdd84f2..333e09d463 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
@@ -52,6 +52,7 @@ import java.security.GeneralSecurityException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import java.text.MessageFormat;
+import java.util.Locale;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -192,7 +193,7 @@ abstract class WalkEncryption {
// Standard names are not case-sensitive.
// http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
- String cryptoName = cryptoAlg.toUpperCase();
+ String cryptoName = cryptoAlg.toUpperCase(Locale.ROOT);
if (!cryptoName.startsWith("PBE")) //$NON-NLS-1$
throw new GeneralSecurityException(JGitText.get().encryptionOnlyPBE);
@@ -373,7 +374,7 @@ abstract class WalkEncryption {
SecretKey keyBase = factory.generateSecret(keySpec);
- String name = cipherAlgo.toUpperCase();
+ String name = cipherAlgo.toUpperCase(Locale.ROOT);
Matcher matcherPBE = Pattern.compile(REGEX_PBE).matcher(name);
Matcher matcherTrans = Pattern.compile(REGEX_TRANS).matcher(name);
if (matcherPBE.matches()) {
@@ -506,7 +507,7 @@ abstract class WalkEncryption {
JGitV1(String algo, String pass)
throws GeneralSecurityException {
super(wrap(algo, pass));
- String name = cipherAlgo.toUpperCase();
+ String name = cipherAlgo.toUpperCase(Locale.ROOT);
Matcher matcherPBE = Pattern.compile(REGEX_PBE).matcher(name);
if (!matcherPBE.matches())
throw new GeneralSecurityException(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java
index ed5838a20e..c05570b851 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java
@@ -7,6 +7,7 @@
package org.eclipse.jgit.util;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.Arrays;
@@ -184,11 +185,7 @@ public class Base64 {
e += 4;
}
- try {
- return new String(outBuff, 0, e, UTF_8);
- } catch (UnsupportedEncodingException uue) {
- return new String(outBuff, 0, e);
- }
+ return new String(outBuff, 0, e, StandardCharsets.UTF_8);
}
/**
@@ -304,12 +301,7 @@ public class Base64 {
* @return the decoded data
*/
public static byte[] decode(String s) {
- byte[] bytes;
- try {
- bytes = s.getBytes(UTF_8);
- } catch (UnsupportedEncodingException uee) {
- bytes = s.getBytes();
- }
+ byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
return decode(bytes, 0, bytes.length);
}
}
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 dcd7970cbc..2f570ee51c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -59,7 +59,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
-import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -1011,16 +1010,13 @@ public abstract class FS {
IOException ioException = null;
try {
process = processBuilder.start();
- final Callable<Void> errorGobbler = new StreamGobbler(
- process.getErrorStream(), errRedirect);
- final Callable<Void> outputGobbler = new StreamGobbler(
- process.getInputStream(), outRedirect);
- executor.submit(errorGobbler);
- executor.submit(outputGobbler);
+ executor.execute(
+ new StreamGobbler(process.getErrorStream(), errRedirect));
+ executor.execute(
+ new StreamGobbler(process.getInputStream(), outRedirect));
OutputStream outputStream = process.getOutputStream();
if (inRedirect != null) {
- new StreamGobbler(inRedirect, outputStream)
- .call();
+ new StreamGobbler(inRedirect, outputStream).copy();
}
try {
outputStream.close();
@@ -1336,7 +1332,7 @@ public abstract class FS {
* streams.
* </p>
*/
- private static class StreamGobbler implements Callable<Void> {
+ private static class StreamGobbler implements Runnable {
private InputStream in;
private OutputStream out;
@@ -1346,7 +1342,15 @@ public abstract class FS {
this.out = output;
}
- public Void call() throws IOException {
+ public void run() {
+ try {
+ copy();
+ } catch (IOException e) {
+ // Do nothing on read failure; leave streams open.
+ }
+ }
+
+ void copy() throws IOException {
boolean writeFailure = false;
byte buffer[] = new byte[4096];
int readBytes;
@@ -1363,7 +1367,6 @@ public abstract class FS {
}
}
}
- return null;
}
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
index aa101f73f9..c04dfa9610 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
@@ -65,6 +65,7 @@ import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.regex.Pattern;
import org.eclipse.jgit.internal.JGitText;
@@ -542,7 +543,8 @@ public class FileUtils {
public static boolean isStaleFileHandle(IOException ioe) {
String msg = ioe.getMessage();
return msg != null
- && msg.toLowerCase().matches("stale .*file .*handle"); //$NON-NLS-1$
+ && msg.toLowerCase(Locale.ROOT)
+ .matches("stale .*file .*handle"); //$NON-NLS-1$
}
/**