diff options
Diffstat (limited to 'org.eclipse.jgit/src')
332 files changed, 4966 insertions, 789 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java index 16ec1463c9..1ed79449ef 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java @@ -96,7 +96,7 @@ public class AddCommand extends GitCommand<DirCache> { */ public AddCommand(Repository repo) { super(repo); - filepatterns = new LinkedList<String>(); + filepatterns = new LinkedList<>(); } /** @@ -134,6 +134,7 @@ public class AddCommand extends GitCommand<DirCache> { * * @return the DirCache after Add */ + @Override public DirCache call() throws GitAPIException, NoFilepatternException { if (filepatterns.isEmpty()) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java index 4235e3786c..fa88fb78ee 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java @@ -81,6 +81,7 @@ public class AddNoteCommand extends GitCommand<Note> { super(repo); } + @Override public Note call() throws GitAPIException { checkCallable(); NoteMap map = NoteMap.newEmptyMap(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java index d74e991395..ba5673d977 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java @@ -109,6 +109,7 @@ public class ApplyCommand extends GitCommand<ApplyResult> { * @throws PatchFormatException * @throws PatchApplyException */ + @Override public ApplyResult call() throws GitAPIException, PatchFormatException, PatchApplyException { checkCallable(); @@ -197,10 +198,10 @@ public class ApplyCommand extends GitCommand<ApplyResult> { private void apply(File f, FileHeader fh) throws IOException, PatchApplyException { RawText rt = new RawText(f); - List<String> oldLines = new ArrayList<String>(rt.size()); + List<String> oldLines = new ArrayList<>(rt.size()); for (int i = 0; i < rt.size(); i++) oldLines.add(rt.getString(i)); - List<String> newLines = new ArrayList<String>(oldLines); + List<String> newLines = new ArrayList<>(oldLines); for (HunkHeader hh : fh.getHunks()) { byte[] b = new byte[hh.getEndOffset() - hh.getStartOffset()]; @@ -208,7 +209,7 @@ public class ApplyCommand extends GitCommand<ApplyResult> { b.length); RawText hrt = new RawText(b); - List<String> hunkLines = new ArrayList<String>(hrt.size()); + List<String> hunkLines = new ArrayList<>(hrt.size()); for (int i = 0; i < hrt.size(); i++) hunkLines.add(hrt.getString(i)); int pos = 0; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyResult.java index 558ef0f8a8..2ef6650e91 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyResult.java @@ -53,7 +53,7 @@ import java.util.List; */ public class ApplyResult { - private List<File> updatedFiles = new ArrayList<File>(); + private List<File> updatedFiles = new ArrayList<>(); /** * @param f 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 8543bd5f6a..0d18eb3d07 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java @@ -162,8 +162,8 @@ public class ArchiveCommand extends GitCommand<OutputStream> { * @param out * archive object from createArchiveOutputStream * @param path - * full filename relative to the root of the archive - * (with trailing '/' for directories) + * full filename relative to the root of the archive (with + * trailing '/' for directories) * @param mode * mode (for example FileMode.REGULAR_FILE or * FileMode.SYMLINK) @@ -171,9 +171,36 @@ public class ArchiveCommand extends GitCommand<OutputStream> { * blob object with data for this entry (null for * directories) * @throws IOException - * thrown by the underlying output stream for I/O errors + * thrown by the underlying output stream for I/O errors + * @deprecated use + * {@link #putEntry(Closeable, ObjectId, String, FileMode, ObjectLoader)} + * instead */ + @Deprecated void putEntry(T out, String path, FileMode mode, + ObjectLoader loader) throws IOException; + + /** + * Write an entry to an archive. + * + * @param out + * archive object from createArchiveOutputStream + * @param tree + * the tag, commit, or tree object to produce an archive for + * @param path + * full filename relative to the root of the archive (with + * trailing '/' for directories) + * @param mode + * mode (for example FileMode.REGULAR_FILE or + * FileMode.SYMLINK) + * @param loader + * blob object with data for this entry (null for + * directories) + * @throws IOException + * thrown by the underlying output stream for I/O errors + * @since 4.7 + */ + void putEntry(T out, ObjectId tree, String path, FileMode mode, ObjectLoader loader) throws IOException; /** @@ -232,7 +259,7 @@ public class ArchiveCommand extends GitCommand<OutputStream> { * the --format= option) */ private static final ConcurrentMap<String, FormatEntry> formats = - new ConcurrentHashMap<String, FormatEntry>(); + new ConcurrentHashMap<>(); /** * Replaces the entry for a key only if currently mapped to a given @@ -350,7 +377,7 @@ public class ArchiveCommand extends GitCommand<OutputStream> { private String prefix; private String format; private Map<String, Object> formatOptions = new HashMap<>(); - private List<String> paths = new ArrayList<String>(); + private List<String> paths = new ArrayList<>(); /** Filename suffix, for automatically choosing a format. */ private String suffix; @@ -389,11 +416,11 @@ public class ArchiveCommand extends GitCommand<OutputStream> { mode = FileMode.TREE; if (mode == FileMode.TREE) { - fmt.putEntry(outa, name + "/", mode, null); //$NON-NLS-1$ + fmt.putEntry(outa, tree, name + "/", mode, null); //$NON-NLS-1$ continue; } walk.getObjectId(idBuf, 0); - fmt.putEntry(outa, name, mode, reader.open(idBuf)); + fmt.putEntry(outa, tree, name, mode, reader.open(idBuf)); } outa.close(); return out; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java index 2a2e07ddda..b1c81ff154 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java @@ -188,7 +188,7 @@ public class BlameCommand extends GitCommand<BlameResult> { public BlameCommand reverse(AnyObjectId start, Collection<ObjectId> end) throws IOException { startCommit = start.toObjectId(); - reverseEndCommits = new ArrayList<ObjectId>(end); + reverseEndCommits = new ArrayList<>(end); return this; } @@ -198,6 +198,7 @@ public class BlameCommand extends GitCommand<BlameResult> { * * @return list of lines */ + @Override public BlameResult call() throws GitAPIException { checkCallable(); try (BlameGenerator gen = new BlameGenerator(repo, path)) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java index c17ae5c00d..21d62837e9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java @@ -180,7 +180,7 @@ public class CheckoutCommand extends GitCommand<Ref> { */ protected CheckoutCommand(Repository repo) { super(repo); - this.paths = new LinkedList<String>(); + this.paths = new LinkedList<>(); } /** @@ -196,6 +196,7 @@ public class CheckoutCommand extends GitCommand<Ref> { * if the checkout results in a conflict * @return the newly created branch */ + @Override public Ref call() throws GitAPIException, RefAlreadyExistsException, RefNotFoundException, InvalidRefNameException, CheckoutConflictException { @@ -319,10 +320,10 @@ public class CheckoutCommand extends GitCommand<Ref> { if (!dco.getToBeDeleted().isEmpty()) { status = new CheckoutResult(Status.NONDELETED, dco.getToBeDeleted(), - new ArrayList<String>(dco.getUpdated().keySet()), + new ArrayList<>(dco.getUpdated().keySet()), dco.getRemoved()); } else - status = new CheckoutResult(new ArrayList<String>(dco + status = new CheckoutResult(new ArrayList<>(dco .getUpdated().keySet()), dco.getRemoved()); return ref; @@ -455,6 +456,7 @@ public class CheckoutCommand extends GitCommand<Ref> { final String filterCommand = treeWalk .getFilterCommand(Constants.ATTR_FILTER_TYPE_SMUDGE); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { int stage = ent.getStage(); if (stage > DirCacheEntry.STAGE_0) { @@ -491,6 +493,7 @@ public class CheckoutCommand extends GitCommand<Ref> { final String filterCommand = treeWalk .getFilterCommand(Constants.ATTR_FILTER_TYPE_SMUDGE); editor.add(new PathEdit(treeWalk.getPathString()) { + @Override public void apply(DirCacheEntry ent) { ent.setObjectId(blobId); ent.setFileMode(mode); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutResult.java index 92a67f46af..2186eb4b5a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutResult.java @@ -139,11 +139,11 @@ public class CheckoutResult { if (status == Status.CONFLICTS) this.conflictList = fileList; else - this.conflictList = new ArrayList<String>(0); + this.conflictList = new ArrayList<>(0); if (status == Status.NONDELETED) this.undeletedList = fileList; else - this.undeletedList = new ArrayList<String>(0); + this.undeletedList = new ArrayList<>(0); this.modifiedList = modified; this.removedList = removed; @@ -160,8 +160,8 @@ public class CheckoutResult { CheckoutResult(List<String> modified, List<String> removed) { myStatus = Status.OK; - this.conflictList = new ArrayList<String>(0); - this.undeletedList = new ArrayList<String>(0); + this.conflictList = new ArrayList<>(0); + this.undeletedList = new ArrayList<>(0); this.modifiedList = modified; this.removedList = removed; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java index 276bf96ea2..eed7b2a254 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java @@ -85,7 +85,7 @@ import org.eclipse.jgit.treewalk.FileTreeIterator; public class CherryPickCommand extends GitCommand<CherryPickResult> { private String reflogPrefix = "cherry-pick:"; //$NON-NLS-1$ - private List<Ref> commits = new LinkedList<Ref>(); + private List<Ref> commits = new LinkedList<>(); private String ourCommitName = null; @@ -116,11 +116,12 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> { * @throws NoMessageException * @throws NoHeadException */ + @Override public CherryPickResult call() throws GitAPIException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, NoHeadException { RevCommit newHead = null; - List<Ref> cherryPickedRefs = new LinkedList<Ref>(); + List<Ref> cherryPickedRefs = new LinkedList<>(); checkCallable(); try (RevWalk revWalk = new RevWalk(repo)) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java index 7e331fd844..c58efb1478 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java @@ -94,15 +94,16 @@ public class CleanCommand extends GitCommand<Set<String>> { * @throws GitAPIException * @throws NoWorkTreeException */ + @Override public Set<String> call() throws NoWorkTreeException, GitAPIException { - Set<String> files = new TreeSet<String>(); + Set<String> files = new TreeSet<>(); try { StatusCommand command = new StatusCommand(repo); Status status = command.call(); - Set<String> untrackedAndIgnoredFiles = new TreeSet<String>( + Set<String> untrackedAndIgnoredFiles = new TreeSet<>( status.getUntracked()); - Set<String> untrackedAndIgnoredDirs = new TreeSet<String>( + Set<String> untrackedAndIgnoredDirs = new TreeSet<>( status.getUntrackedFolders()); FS fs = getRepository().getFS(); @@ -191,7 +192,7 @@ public class CleanCommand extends GitCommand<Set<String>> { private Set<String> filterIgnorePaths(Set<String> inputPaths, Set<String> ignoredNotInIndex, boolean exact) { if (ignore) { - Set<String> filtered = new TreeSet<String>(inputPaths); + Set<String> filtered = new TreeSet<>(inputPaths); for (String path : inputPaths) for (String ignored : ignoredNotInIndex) if ((exact && path.equals(ignored)) @@ -207,7 +208,7 @@ public class CleanCommand extends GitCommand<Set<String>> { private Set<String> filterFolders(Set<String> untracked, Set<String> untrackedFolders) { - Set<String> filtered = new TreeSet<String>(untracked); + Set<String> filtered = new TreeSet<>(untracked); for (String file : untracked) for (String folder : untrackedFolders) if (file.startsWith(folder)) { 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..4b815b439d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java @@ -127,6 +127,7 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> { * @throws org.eclipse.jgit.api.errors.TransportException * @throws GitAPIException */ + @Override public Git call() throws GitAPIException, InvalidRemoteException, org.eclipse.jgit.api.errors.TransportException { Repository repository = null; @@ -151,23 +152,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(); } @@ -207,7 +220,7 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> { RefSpec wcrs = new RefSpec(); wcrs = wcrs.setForceUpdate(true); wcrs = wcrs.setSourceDestination(Constants.R_HEADS + "*", dst); //$NON-NLS-1$ - List<RefSpec> specs = new ArrayList<RefSpec>(); + List<RefSpec> specs = new ArrayList<>(); if (cloneAllBranches) specs.add(wcrs); else if (branchesToClone != null 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 e1793f31af..274ece6dca 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java @@ -112,7 +112,7 @@ public class CommitCommand extends GitCommand<RevCommit> { private boolean all; - private List<String> only = new ArrayList<String>(); + private List<String> only = new ArrayList<>(); private boolean[] onlyProcessed; @@ -124,7 +124,7 @@ public class CommitCommand extends GitCommand<RevCommit> { * parents this commit should have. The current HEAD will be in this list * and also all commits mentioned in .git/MERGE_HEAD */ - private List<ObjectId> parents = new LinkedList<ObjectId>(); + private List<ObjectId> parents = new LinkedList<>(); private String reflogComment; @@ -168,6 +168,7 @@ public class CommitCommand extends GitCommand<RevCommit> { * if there are either pre-commit or commit-msg hooks present in * the repository and one of them rejects the commit. */ + @Override public RevCommit call() throws GitAPIException, NoHeadException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java index 69d82bcc67..39420d0ee8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java @@ -120,6 +120,7 @@ public class CreateBranchCommand extends GitCommand<Ref> { * invalid * @return the newly created branch */ + @Override public Ref call() throws GitAPIException, RefAlreadyExistsException, RefNotFoundException, InvalidRefNameException { checkCallable(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java index ecc1ce5a70..d7e7e5c294 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java @@ -79,7 +79,7 @@ import org.eclipse.jgit.revwalk.RevWalk; * >Git documentation about Branch</a> */ public class DeleteBranchCommand extends GitCommand<List<String>> { - private final Set<String> branchNames = new HashSet<String>(); + private final Set<String> branchNames = new HashSet<>(); private boolean force; @@ -97,10 +97,11 @@ public class DeleteBranchCommand extends GitCommand<List<String>> { * @throws CannotDeleteCurrentBranchException * @return the list with the (full) names of the deleted branches */ + @Override public List<String> call() throws GitAPIException, NotMergedException, CannotDeleteCurrentBranchException { checkCallable(); - List<String> result = new ArrayList<String>(); + List<String> result = new ArrayList<>(); if (branchNames.isEmpty()) return result; try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java index 3aeec48d9d..77e3539996 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java @@ -68,7 +68,7 @@ import org.eclipse.jgit.lib.Repository; */ public class DeleteTagCommand extends GitCommand<List<String>> { - private final Set<String> tags = new HashSet<String>(); + private final Set<String> tags = new HashSet<>(); /** * @param repo @@ -80,9 +80,10 @@ public class DeleteTagCommand extends GitCommand<List<String>> { /** * @return the list with the full names of the deleted tags */ + @Override public List<String> call() throws GitAPIException { checkCallable(); - List<String> result = new ArrayList<String>(); + List<String> result = new ArrayList<>(); if (tags.isEmpty()) return result; try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java index be456662dc..389c511e1c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java @@ -189,7 +189,7 @@ public class DescribeCommand extends GitCommand<String> { if (target == null) setTarget(Constants.HEAD); - Map<ObjectId, Ref> tags = new HashMap<ObjectId, Ref>(); + Map<ObjectId, Ref> tags = new HashMap<>(); for (Ref r : repo.getRefDatabase().getRefs(R_TAGS).values()) { ObjectId key = repo.peel(r).getPeeledObjectId(); @@ -240,7 +240,7 @@ public class DescribeCommand extends GitCommand<String> { } } - List<Candidate> candidates = new ArrayList<Candidate>(); // all the candidates we find + List<Candidate> candidates = new ArrayList<>(); // all the candidates we find // is the target already pointing to a tag? if so, we are done! Ref lucky = tags.get(target); @@ -305,6 +305,7 @@ public class DescribeCommand extends GitCommand<String> { return null; Candidate best = Collections.min(candidates, new Comparator<Candidate>() { + @Override public int compare(Candidate o1, Candidate o2) { return o1.depth - o2.depth; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java index 3e3a7a89c8..b137fc53c9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java @@ -109,6 +109,7 @@ public class DiffCommand extends GitCommand<List<DiffEntry>> { * * @return a DiffEntry for each path which is different */ + @Override public List<DiffEntry> call() throws GitAPIException { final DiffFormatter diffFmt; if (out != null && !showNameAndStatusOnly) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java index de512761a4..cc3302b486 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java @@ -42,14 +42,17 @@ */ package org.eclipse.jgit.api; +import java.io.IOException; import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.InvalidConfigurationException; import org.eclipse.jgit.api.errors.InvalidRemoteException; import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.TransportException; @@ -57,9 +60,13 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.lib.SubmoduleConfig.FetchRecurseSubmodulesMode; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.submodule.SubmoduleWalk; import org.eclipse.jgit.transport.FetchResult; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.TagOpt; @@ -74,7 +81,6 @@ import org.eclipse.jgit.transport.Transport; * >Git documentation about Fetch</a> */ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { - private String remote = Constants.DEFAULT_REMOTE_NAME; private List<RefSpec> refSpecs; @@ -91,12 +97,90 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { private TagOpt tagOption; + private FetchRecurseSubmodulesMode submoduleRecurseMode = null; + /** * @param repo */ protected FetchCommand(Repository repo) { super(repo); - refSpecs = new ArrayList<RefSpec>(3); + refSpecs = new ArrayList<>(3); + } + + private FetchRecurseSubmodulesMode getRecurseMode(String path) { + // Use the caller-specified mode, if set + if (submoduleRecurseMode != null) { + return submoduleRecurseMode; + } + + // Fall back to submodule.name.fetchRecurseSubmodules, if set + FetchRecurseSubmodulesMode mode = repo.getConfig().getEnum( + FetchRecurseSubmodulesMode.values(), + ConfigConstants.CONFIG_SUBMODULE_SECTION, path, + ConfigConstants.CONFIG_KEY_FETCH_RECURSE_SUBMODULES, null); + if (mode != null) { + return mode; + } + + // Fall back to fetch.recurseSubmodules, if set + mode = repo.getConfig().getEnum(FetchRecurseSubmodulesMode.values(), + ConfigConstants.CONFIG_FETCH_SECTION, null, + ConfigConstants.CONFIG_KEY_RECURSE_SUBMODULES, null); + if (mode != null) { + return mode; + } + + // Default to on-demand mode + return FetchRecurseSubmodulesMode.ON_DEMAND; + } + + private void fetchSubmodules(FetchResult results) + throws org.eclipse.jgit.api.errors.TransportException, + GitAPIException, InvalidConfigurationException { + try (SubmoduleWalk walk = new SubmoduleWalk(repo); + RevWalk revWalk = new RevWalk(repo)) { + // Walk over submodules in the parent repository's FETCH_HEAD. + ObjectId fetchHead = repo.resolve(Constants.FETCH_HEAD); + if (fetchHead == null) { + return; + } + walk.setTree(revWalk.parseTree(fetchHead)); + while (walk.next()) { + Repository submoduleRepo = walk.getRepository(); + + // Skip submodules that don't exist locally (have not been + // cloned), are not registered in the .gitmodules file, or + // not registered in the parent repository's config. + if (submoduleRepo == null || walk.getModulesPath() == null + || walk.getConfigUrl() == null) { + continue; + } + + FetchRecurseSubmodulesMode recurseMode = getRecurseMode( + walk.getPath()); + + // When the fetch mode is "yes" we always fetch. When the mode + // is "on demand", we only fetch if the submodule's revision was + // updated to an object that is not currently present in the + // submodule. + if ((recurseMode == FetchRecurseSubmodulesMode.ON_DEMAND + && !submoduleRepo.hasObject(walk.getObjectId())) + || recurseMode == FetchRecurseSubmodulesMode.YES) { + FetchCommand f = new FetchCommand(submoduleRepo) + .setProgressMonitor(monitor).setTagOpt(tagOption) + .setCheckFetchedObjects(checkFetchedObjects) + .setRemoveDeletedRefs(isRemoveDeletedRefs()) + .setThin(thin).setRefSpecs(refSpecs) + .setDryRun(dryRun) + .setRecurseSubmodules(recurseMode); + results.addSubmodule(walk.getPath(), f.call()); + } + } + } catch (IOException e) { + throw new JGitInternalException(e.getMessage(), e); + } catch (ConfigInvalidException e) { + throw new InvalidConfigurationException(e.getMessage(), e); + } } /** @@ -112,6 +196,7 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { * @throws org.eclipse.jgit.api.errors.TransportException * when an error occurs during transport */ + @Override public FetchResult call() throws GitAPIException, InvalidRemoteException, org.eclipse.jgit.api.errors.TransportException { checkCallable(); @@ -126,6 +211,10 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { configure(transport); FetchResult result = transport.fetch(monitor, refSpecs); + if (!repo.isBare()) { + fetchSubmodules(result); + } + return result; } catch (NoRemoteRepositoryException e) { throw new InvalidRemoteException(MessageFormat.format( @@ -145,6 +234,20 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { } /** + * Set the mode to be used for recursing into submodules. + * + * @param recurse + * @return {@code this} + * @since 4.7 + */ + public FetchCommand setRecurseSubmodules( + FetchRecurseSubmodulesMode recurse) { + checkCallable(); + submoduleRecurseMode = recurse; + return this; + } + + /** * The remote (uri or name) used for the fetch operation. If no remote is * set, the default value of <code>Constants.DEFAULT_REMOTE_NAME</code> will * be used. 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/Git.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java index 2cd5f59a71..96995693a3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java @@ -147,6 +147,7 @@ public class Git implements AutoCloseable { * * @since 3.2 */ + @Override public void close() { if (closeRepo) repo.close(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java index e9751f94a1..2a23408b53 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java @@ -126,5 +126,6 @@ public abstract class GitCommand<T> implements Callable<T> { * @throws GitAPIException * or subclass thereof when an error occurs */ + @Override public abstract T call() throws GitAPIException; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java index 37a788e85c..649484cf62 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java @@ -73,6 +73,7 @@ public class InitCommand implements Callable<Git> { * * @return the newly created {@code Git} object with associated repository */ + @Override public Git call() throws GitAPIException { try { RepositoryBuilder builder = new RepositoryBuilder(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java index efcfd16823..961eeaadd4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java @@ -101,11 +101,12 @@ public class ListBranchCommand extends GitCommand<List<Ref>> { super(repo); } + @Override public List<Ref> call() throws GitAPIException { checkCallable(); List<Ref> resultRefs; try { - Collection<Ref> refs = new ArrayList<Ref>(); + Collection<Ref> refs = new ArrayList<>(); // Also return HEAD if it's detached Ref head = repo.exactRef(Constants.HEAD); @@ -120,12 +121,13 @@ public class ListBranchCommand extends GitCommand<List<Ref>> { refs.addAll(getRefs(Constants.R_HEADS)); refs.addAll(getRefs(Constants.R_REMOTES)); } - resultRefs = new ArrayList<Ref>(filterRefs(refs)); + resultRefs = new ArrayList<>(filterRefs(refs)); } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } Collections.sort(resultRefs, new Comparator<Ref>() { + @Override public int compare(Ref o1, Ref o2) { return o1.getName().compareTo(o2.getName()); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java index ff963ede89..476c10bdbc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java @@ -77,9 +77,10 @@ public class ListNotesCommand extends GitCommand<List<Note>> { /** * @return the requested notes */ + @Override public List<Note> call() throws GitAPIException { checkCallable(); - List<Note> notes = new ArrayList<Note>(); + List<Note> notes = new ArrayList<>(); NoteMap map = NoteMap.newEmptyMap(); try (RevWalk walk = new RevWalk(repo)) { Ref ref = repo.findRef(notesRef); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java index a3b701be8e..d649a53db1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java @@ -74,10 +74,11 @@ public class ListTagCommand extends GitCommand<List<Ref>> { /** * @return the tags available */ + @Override public List<Ref> call() throws GitAPIException { checkCallable(); Map<String, Ref> refList; - List<Ref> tags = new ArrayList<Ref>(); + List<Ref> tags = new ArrayList<>(); try (RevWalk revWalk = new RevWalk(repo)) { refList = repo.getRefDatabase().getRefs(Constants.R_TAGS); for (Ref ref : refList.values()) { @@ -87,6 +88,7 @@ public class ListTagCommand extends GitCommand<List<Ref>> { throw new JGitInternalException(e.getMessage(), e); } Collections.sort(tags, new Comparator<Ref>() { + @Override public int compare(Ref o1, Ref o2) { return o1.getName().compareTo(o2.getName()); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java index bb1a738149..f8fe95a88a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java @@ -107,7 +107,7 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { private RevFilter revFilter; - private final List<PathFilter> pathFilters = new ArrayList<PathFilter>(); + private final List<PathFilter> pathFilters = new ArrayList<>(); private int maxCount = -1; @@ -132,6 +132,7 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { * @throws NoHeadException * of the references ref cannot be resolved */ + @Override public Iterable<RevCommit> call() throws GitAPIException, NoHeadException { checkCallable(); if (pathFilters.size() > 0) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java index f3527fd805..5157a411fd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java @@ -153,6 +153,7 @@ public class LsRemoteCommand extends * @throws org.eclipse.jgit.api.errors.TransportException * for errors that occurs during transport */ + @Override public Collection<Ref> call() throws GitAPIException, InvalidRemoteException, org.eclipse.jgit.api.errors.TransportException { @@ -187,14 +188,14 @@ public class LsRemoteCommand extends : Transport.open(new URIish(remote))) { transport.setOptionUploadPack(uploadPack); configure(transport); - Collection<RefSpec> refSpecs = new ArrayList<RefSpec>(1); + Collection<RefSpec> refSpecs = new ArrayList<>(1); if (tags) refSpecs.add(new RefSpec( "refs/tags/*:refs/remotes/origin/tags/*")); //$NON-NLS-1$ if (heads) refSpecs.add(new RefSpec("refs/heads/*:refs/remotes/origin/*")); //$NON-NLS-1$ Collection<Ref> refs; - Map<String, Ref> refmap = new HashMap<String, Ref>(); + Map<String, Ref> refmap = new HashMap<>(); try (FetchConnection fc = transport.openFetch()) { refs = fc.getRefs(); if (refSpecs.isEmpty()) 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..b5d9e8a6b6 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; @@ -101,7 +102,7 @@ public class MergeCommand extends GitCommand<MergeResult> { private MergeStrategy mergeStrategy = MergeStrategy.RECURSIVE; - private List<Ref> commits = new LinkedList<Ref>(); + private List<Ref> commits = new LinkedList<>(); private Boolean squash; @@ -133,10 +134,12 @@ public class MergeCommand extends GitCommand<MergeResult> { */ FF_ONLY; + @Override public String toConfigValue() { - return "--" + name().toLowerCase().replace('_', '-'); //$NON-NLS-1$ + return "--" + name().toLowerCase(Locale.ROOT).replace('_', '-'); //$NON-NLS-1$ } + @Override public boolean matchConfigValue(String in) { if (StringUtils.isEmptyOrNull(in)) return false; @@ -220,6 +223,7 @@ public class MergeCommand extends GitCommand<MergeResult> { * * @return the result of the merge */ + @Override @SuppressWarnings("boxing") public MergeResult call() throws GitAPIException, NoHeadException, ConcurrentRefUpdateException, CheckoutConflictException, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java index 6141e0c536..c487ef6509 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java @@ -185,6 +185,7 @@ public class MergeResult { * @since 3.0 **/ MERGED_NOT_COMMITTED { + @Override public String toString() { return "Merged-not-committed"; //$NON-NLS-1$ } @@ -212,6 +213,7 @@ public class MergeResult { * files (i.e. local modifications prevent checkout of files). */ CHECKOUT_CONFLICT { + @Override public String toString() { return "Checkout Conflict"; //$NON-NLS-1$ } @@ -414,7 +416,7 @@ public class MergeResult { */ public void addConflict(String path, int[][] conflictingRanges) { if (conflicts == null) - conflicts = new HashMap<String, int[][]>(); + conflicts = new HashMap<>(); conflicts.put(path, conflictingRanges); } @@ -426,7 +428,7 @@ public class MergeResult { if (!lowLevelResult.containsConflicts()) return; if (conflicts == null) - conflicts = new HashMap<String, int[][]>(); + conflicts = new HashMap<>(); int nrOfConflicts = 0; // just counting for (MergeChunk mergeChunk : lowLevelResult) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java index fd28d0ec43..2a86fabede 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java @@ -124,8 +124,8 @@ public class NameRevCommand extends GitCommand<Map<ObjectId, String>> { protected NameRevCommand(Repository repo) { super(repo); mergeCost = MERGE_COST; - prefixes = new ArrayList<String>(2); - revs = new ArrayList<ObjectId>(2); + prefixes = new ArrayList<>(2); + revs = new ArrayList<>(2); walk = new RevWalk(repo) { @Override public NameRevCommit createCommit(AnyObjectId id) { @@ -137,7 +137,7 @@ public class NameRevCommand extends GitCommand<Map<ObjectId, String>> { @Override public Map<ObjectId, String> call() throws GitAPIException { try { - Map<ObjectId, String> nonCommits = new HashMap<ObjectId, String>(); + Map<ObjectId, String> nonCommits = new HashMap<>(); FIFORevQueue pending = new FIFORevQueue(); if (refs != null) { for (Ref ref : refs) @@ -170,7 +170,7 @@ public class NameRevCommand extends GitCommand<Map<ObjectId, String>> { } Map<ObjectId, String> result = - new LinkedHashMap<ObjectId, String>(revs.size()); + new LinkedHashMap<>(revs.size()); for (ObjectId id : revs) { RevObject o = walk.parseAny(id); if (o instanceof NameRevCommit) { @@ -275,7 +275,7 @@ public class NameRevCommand extends GitCommand<Map<ObjectId, String>> { public NameRevCommand addAnnotatedTags() { checkCallable(); if (refs == null) - refs = new ArrayList<Ref>(); + refs = new ArrayList<>(); try { for (Ref ref : repo.getRefDatabase().getRefs(Constants.R_TAGS).values()) { ObjectId id = ref.getObjectId(); @@ -302,7 +302,7 @@ public class NameRevCommand extends GitCommand<Map<ObjectId, String>> { public NameRevCommand addRef(Ref ref) { checkCallable(); if (refs == null) - refs = new ArrayList<Ref>(); + refs = new ArrayList<>(); refs.add(ref); return this; } 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 a4d9ec1a07..49d1a824eb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java @@ -71,6 +71,7 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.transport.FetchResult; +import org.eclipse.jgit.transport.TagOpt; /** * The Pull command @@ -92,6 +93,8 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { private MergeStrategy strategy = MergeStrategy.RECURSIVE; + private TagOpt tagOption; + /** * @param repo */ @@ -194,6 +197,7 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { * @throws org.eclipse.jgit.api.errors.TransportException * @throws GitAPIException */ + @Override public PullResult call() throws GitAPIException, WrongRepositoryStateException, InvalidConfigurationException, DetachedHeadException, InvalidRemoteException, CanceledException, @@ -272,9 +276,8 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { JGitText.get().operationCanceled, JGitText.get().pullTaskName)); - FetchCommand fetch = new FetchCommand(repo); - fetch.setRemote(remote); - fetch.setProgressMonitor(monitor); + FetchCommand fetch = new FetchCommand(repo).setRemote(remote) + .setProgressMonitor(monitor).setTagOpt(tagOption); configure(fetch); fetchRes = fetch.call(); @@ -412,6 +415,19 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { } /** + * Sets the specification of annotated tag behavior during fetch + * + * @param tagOpt + * @return {@code this} + * @since 4.7 + */ + public PullCommand setTagOpt(TagOpt tagOpt) { + checkCallable(); + this.tagOption = tagOpt; + return this; + } + + /** * Reads the rebase mode to use for a pull command from the repository * configuration. This is the value defined for the configurations * {@code branch.[branchName].rebase}, or,if not set, {@code pull.rebase}. 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 bd4521b517..bf88842618 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java @@ -47,9 +47,12 @@ import java.io.OutputStream; import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.InvalidRemoteException; @@ -65,6 +68,7 @@ import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.PushResult; +import org.eclipse.jgit.transport.RefLeaseSpec; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.RemoteRefUpdate; @@ -85,6 +89,8 @@ public class PushCommand extends private final List<RefSpec> refSpecs; + private final Map<String, RefLeaseSpec> refLeaseSpecs; + private ProgressMonitor monitor = NullProgressMonitor.INSTANCE; private String receivePack = RemoteConfig.DEFAULT_RECEIVE_PACK; @@ -103,7 +109,8 @@ public class PushCommand extends */ protected PushCommand(Repository repo) { super(repo); - refSpecs = new ArrayList<RefSpec>(3); + refSpecs = new ArrayList<>(3); + refLeaseSpecs = new HashMap<>(); } /** @@ -119,12 +126,13 @@ public class PushCommand extends * when an error occurs with the transport * @throws GitAPIException */ + @Override public Iterable<PushResult> call() throws GitAPIException, InvalidRemoteException, org.eclipse.jgit.api.errors.TransportException { checkCallable(); - ArrayList<PushResult> pushResults = new ArrayList<PushResult>(3); + ArrayList<PushResult> pushResults = new ArrayList<>(3); try { if (refSpecs.isEmpty()) { @@ -155,7 +163,7 @@ public class PushCommand extends configure(transport); final Collection<RemoteRefUpdate> toPush = transport - .findRemoteRefUpdatesFor(refSpecs); + .findRemoteRefUpdatesFor(refSpecs, refLeaseSpecs); try { PushResult result = transport.push(monitor, toPush, out); @@ -271,6 +279,43 @@ public class PushCommand extends } /** + * @return the ref lease specs + * @since 4.7 + */ + public List<RefLeaseSpec> getRefLeaseSpecs() { + return new ArrayList<>(refLeaseSpecs.values()); + } + + /** + * The ref lease specs to be used in the push operation, + * for a force-with-lease push operation. + * + * @param specs + * @return {@code this} + * @since 4.7 + */ + public PushCommand setRefLeaseSpecs(RefLeaseSpec... specs) { + return setRefLeaseSpecs(Arrays.asList(specs)); + } + + /** + * The ref lease specs to be used in the push operation, + * for a force-with-lease push operation. + * + * @param specs + * @return {@code this} + * @since 4.7 + */ + public PushCommand setRefLeaseSpecs(List<RefLeaseSpec> specs) { + checkCallable(); + this.refLeaseSpecs.clear(); + for (RefLeaseSpec spec : specs) { + refLeaseSpecs.put(spec.getRef(), spec); + } + return this; + } + + /** * @return the ref specs */ public List<RefSpec> getRefSpecs() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java index d10cc3d715..f704492fe5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -258,6 +258,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { * @throws NoHeadException * @throws RefNotFoundException */ + @Override public RebaseResult call() throws GitAPIException, NoHeadException, RefNotFoundException, WrongRepositoryStateException { newHead = null; @@ -298,7 +299,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { org.eclipse.jgit.api.Status status = Git.wrap(repo) .status().setIgnoreSubmodules(IgnoreSubmoduleMode.ALL).call(); if (status.hasUncommittedChanges()) { - List<String> list = new ArrayList<String>(); + List<String> list = new ArrayList<>(); list.addAll(status.getUncommittedChanges()); return RebaseResult.uncommittedChanges(list); } @@ -649,7 +650,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { // Get the rewritten equivalents for the parents of the given commit private List<RevCommit> getNewParents(RevCommit commitToPick) throws IOException { - List<RevCommit> newParents = new ArrayList<RevCommit>(); + List<RevCommit> newParents = new ArrayList<>(); for (int p = 0; p < commitToPick.getParentCount(); p++) { String parentHash = commitToPick.getParent(p).getName(); if (!new File(rebaseState.getRewrittenDir(), parentHash).exists()) @@ -1055,8 +1056,8 @@ public class RebaseCommand extends GitCommand<RebaseResult> { private void popSteps(int numSteps) throws IOException { if (numSteps == 0) return; - List<RebaseTodoLine> todoLines = new LinkedList<RebaseTodoLine>(); - List<RebaseTodoLine> poppedLines = new LinkedList<RebaseTodoLine>(); + List<RebaseTodoLine> todoLines = new LinkedList<>(); + List<RebaseTodoLine> poppedLines = new LinkedList<>(); for (RebaseTodoLine line : repo.readRebaseTodo( rebaseState.getPath(GIT_REBASE_TODO), true)) { @@ -1121,7 +1122,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { } rebaseState.createFile(QUIET, ""); //$NON-NLS-1$ - ArrayList<RebaseTodoLine> toDoSteps = new ArrayList<RebaseTodoLine>(); + ArrayList<RebaseTodoLine> toDoSteps = new ArrayList<>(); toDoSteps.add(new RebaseTodoLine("# Created by EGit: rebasing " + headId.name() //$NON-NLS-1$ + " onto " + upstreamCommit.name())); //$NON-NLS-1$ // determine the commits to be applied @@ -1157,7 +1158,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { LogCommand cmd = git.log().addRange(upstreamCommit, headCommit); commitsToUse = cmd.call(); } - List<RevCommit> cherryPickList = new ArrayList<RevCommit>(); + List<RevCommit> cherryPickList = new ArrayList<>(); for (RevCommit commit : commitsToUse) { if (preserveMerges || commit.getParentCount() == 1) cherryPickList.add(commit); @@ -1604,7 +1605,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { if (raw.length == 0) return null; - Map<String, String> keyValueMap = new HashMap<String, String>(); + Map<String, String> keyValueMap = new HashMap<>(); for (int p = 0; p < raw.length;) { int end = RawParseUtils.nextLF(raw, p); if (end == p) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java index 4536af1be0..04caa0f159 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java @@ -92,6 +92,7 @@ public class ReflogCommand extends GitCommand<Collection<ReflogEntry>> { * @throws GitAPIException * @throws InvalidRefNameException */ + @Override public Collection<ReflogEntry> call() throws GitAPIException, InvalidRefNameException { checkCallable(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java index 1c4880c1e1..fd8aac75bd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java @@ -79,6 +79,7 @@ public class RemoveNoteCommand extends GitCommand<Note> { super(repo); } + @Override public Note call() throws GitAPIException { checkCallable(); try (RevWalk walk = new RevWalk(repo); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java index 044a48611b..ce3a29f36c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java @@ -96,6 +96,7 @@ public class RenameBranchCommand extends GitCommand<Ref> { * if rename is tried without specifying the old name and HEAD * is detached */ + @Override public Ref call() throws GitAPIException, RefNotFoundException, InvalidRefNameException, RefAlreadyExistsException, DetachedHeadException { checkCallable(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java index 106988d4d4..c5222c2d5f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java @@ -121,7 +121,7 @@ public class ResetCommand extends GitCommand<Ref> { private ResetType mode; - private Collection<String> filepaths = new LinkedList<String>(); + private Collection<String> filepaths = new LinkedList<>(); private boolean isReflogDisabled; @@ -141,6 +141,7 @@ public class ResetCommand extends GitCommand<Ref> { * @return the Ref after reset * @throws GitAPIException */ + @Override public Ref call() throws GitAPIException, CheckoutConflictException { checkCallable(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java index 9d79ed0299..c3152a93b4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java @@ -85,11 +85,11 @@ import org.eclipse.jgit.treewalk.FileTreeIterator; * >Git documentation about revert</a> */ public class RevertCommand extends GitCommand<RevCommit> { - private List<Ref> commits = new LinkedList<Ref>(); + private List<Ref> commits = new LinkedList<>(); private String ourCommitName = null; - private List<Ref> revertedRefs = new LinkedList<Ref>(); + private List<Ref> revertedRefs = new LinkedList<>(); private MergeResult failingResult; @@ -120,6 +120,7 @@ public class RevertCommand extends GitCommand<RevCommit> { * @throws UnmergedPathsException * @throws NoMessageException */ + @Override public RevCommit call() throws NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, GitAPIException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java index fd2cbe0129..9e2cf31100 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java @@ -99,7 +99,7 @@ public class RmCommand extends GitCommand<DirCache> { */ public RmCommand(Repository repo) { super(repo); - filepatterns = new LinkedList<String>(); + filepatterns = new LinkedList<>(); } /** @@ -136,6 +136,7 @@ public class RmCommand extends GitCommand<DirCache> { * * @return the DirCache after Rm */ + @Override public DirCache call() throws GitAPIException, NoFilepatternException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java index 168ea51e77..dbff4636e7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java @@ -74,6 +74,7 @@ public class ShowNoteCommand extends GitCommand<Note> { super(repo); } + @Override public Note call() throws GitAPIException { checkCallable(); NoteMap map = NoteMap.newEmptyMap(); 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..10ec2a6a5a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java @@ -157,6 +157,7 @@ public class StashApplyCommand extends GitCommand<ObjectId> { * @throws NoHeadException * @throws StashApplyFailureException */ + @Override public ObjectId call() throws GitAPIException, WrongRepositoryStateException, NoHeadException, StashApplyFailureException { @@ -232,19 +233,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/api/StashCreateCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java index ee9b7fcf72..681f8e65ae 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java @@ -236,6 +236,7 @@ public class StashCreateCommand extends GitCommand<RevCommit> { * @return stashed commit or null if no changes to stash * @throws GitAPIException */ + @Override public RevCommit call() throws GitAPIException { checkCallable(); @@ -261,9 +262,9 @@ public class StashCreateCommand extends GitCommand<RevCommit> { return null; MutableObjectId id = new MutableObjectId(); - List<PathEdit> wtEdits = new ArrayList<PathEdit>(); - List<String> wtDeletes = new ArrayList<String>(); - List<DirCacheEntry> untracked = new ArrayList<DirCacheEntry>(); + List<PathEdit> wtEdits = new ArrayList<>(); + List<String> wtDeletes = new ArrayList<>(); + List<DirCacheEntry> untracked = new ArrayList<>(); boolean hasChanges = false; do { AbstractTreeIterator headIter = treeWalk.getTree(0, @@ -305,6 +306,7 @@ public class StashCreateCommand extends GitCommand<RevCommit> { untracked.add(entry); else wtEdits.add(new PathEdit(entry) { + @Override public void apply(DirCacheEntry ent) { ent.copyMetaData(entry); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java index 6e1d0f2703..e215bdf7d3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java @@ -171,6 +171,7 @@ public class StashDropCommand extends GitCommand<ObjectId> { * @return commit id of stash reference or null if no more stashed changes * @throws GitAPIException */ + @Override public ObjectId call() throws GitAPIException { checkCallable(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java index aedc9a6e12..8420dd228e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java @@ -76,6 +76,7 @@ public class StashListCommand extends GitCommand<Collection<RevCommit>> { super(repo); } + @Override public Collection<RevCommit> call() throws GitAPIException, InvalidRefNameException { checkCallable(); @@ -94,7 +95,7 @@ public class StashListCommand extends GitCommand<Collection<RevCommit>> { if (stashEntries.isEmpty()) return Collections.emptyList(); - final List<RevCommit> stashCommits = new ArrayList<RevCommit>( + final List<RevCommit> stashCommits = new ArrayList<>( stashEntries.size()); try (RevWalk walk = new RevWalk(repo)) { for (ReflogEntry entry : stashEntries) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java index 48759c2d49..5b7c73b472 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java @@ -189,7 +189,7 @@ public class Status { * @since 3.2 */ public Set<String> getUncommittedChanges() { - Set<String> uncommittedChanges = new HashSet<String>(); + Set<String> uncommittedChanges = new HashSet<>(); uncommittedChanges.addAll(diff.getAdded()); uncommittedChanges.addAll(diff.getChanged()); uncommittedChanges.addAll(diff.getRemoved()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StatusCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StatusCommand.java index 9752195b95..8f7804a003 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StatusCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StatusCommand.java @@ -109,7 +109,7 @@ public class StatusCommand extends GitCommand<Status> { */ public StatusCommand addPath(String path) { if (paths == null) - paths = new LinkedList<String>(); + paths = new LinkedList<>(); paths.add(path); return this; } @@ -134,6 +134,7 @@ public class StatusCommand extends GitCommand<Status> { * @return a {@link Status} object telling about each path where working * tree, index or HEAD differ from each other. */ + @Override public Status call() throws GitAPIException, NoWorkTreeException { if (workingTreeIt == null) workingTreeIt = new FileTreeIterator(repo); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java index b0f772e0aa..0519d454ea 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java @@ -149,6 +149,7 @@ public class SubmoduleAddCommand extends * @return the newly created {@link Repository} * @throws GitAPIException */ + @Override public Repository call() throws GitAPIException { checkCallable(); if (path == null || path.length() == 0) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java index 1dbe3681bf..4c5e317cb1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java @@ -76,7 +76,7 @@ public class SubmoduleInitCommand extends GitCommand<Collection<String>> { */ public SubmoduleInitCommand(final Repository repo) { super(repo); - paths = new ArrayList<String>(); + paths = new ArrayList<>(); } /** @@ -91,6 +91,7 @@ public class SubmoduleInitCommand extends GitCommand<Collection<String>> { return this; } + @Override public Collection<String> call() throws GitAPIException { checkCallable(); @@ -98,7 +99,7 @@ public class SubmoduleInitCommand extends GitCommand<Collection<String>> { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); StoredConfig config = repo.getConfig(); - List<String> initialized = new ArrayList<String>(); + List<String> initialized = new ArrayList<>(); while (generator.next()) { // Ignore entry if URL is already present in config file if (generator.getConfigUrl() != null) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java index a1ea790d0d..8b27e4c41f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java @@ -76,7 +76,7 @@ public class SubmoduleStatusCommand extends */ public SubmoduleStatusCommand(final Repository repo) { super(repo); - paths = new ArrayList<String>(); + paths = new ArrayList<>(); } /** @@ -91,13 +91,14 @@ public class SubmoduleStatusCommand extends return this; } + @Override public Map<String, SubmoduleStatus> call() throws GitAPIException { checkCallable(); try (SubmoduleWalk generator = SubmoduleWalk.forIndex(repo)) { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); - Map<String, SubmoduleStatus> statuses = new HashMap<String, SubmoduleStatus>(); + Map<String, SubmoduleStatus> statuses = new HashMap<>(); while (generator.next()) { SubmoduleStatus status = getStatus(generator); statuses.put(status.getPath(), status); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java index 088eedc2dc..f97dce9833 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java @@ -78,7 +78,7 @@ public class SubmoduleSyncCommand extends GitCommand<Map<String, String>> { */ public SubmoduleSyncCommand(final Repository repo) { super(repo); - paths = new ArrayList<String>(); + paths = new ArrayList<>(); } /** @@ -108,13 +108,14 @@ public class SubmoduleSyncCommand extends GitCommand<Map<String, String>> { return null; } + @Override public Map<String, String> call() throws GitAPIException { checkCallable(); try (SubmoduleWalk generator = SubmoduleWalk.forIndex(repo)) { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); - Map<String, String> synced = new HashMap<String, String>(); + Map<String, String> synced = new HashMap<>(); StoredConfig config = repo.getConfig(); while (generator.next()) { String remoteUrl = generator.getRemoteUrl(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java index 342d7f42f3..29d5d49a45 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java @@ -94,7 +94,7 @@ public class SubmoduleUpdateCommand extends */ public SubmoduleUpdateCommand(final Repository repo) { super(repo); - paths = new ArrayList<String>(); + paths = new ArrayList<>(); } /** @@ -137,6 +137,7 @@ public class SubmoduleUpdateCommand extends * @throws WrongRepositoryStateException * @throws GitAPIException */ + @Override public Collection<String> call() throws InvalidConfigurationException, NoHeadException, ConcurrentRefUpdateException, CheckoutConflictException, InvalidMergeHeadsException, @@ -147,7 +148,7 @@ public class SubmoduleUpdateCommand extends try (SubmoduleWalk generator = SubmoduleWalk.forIndex(repo)) { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); - List<String> updated = new ArrayList<String>(); + List<String> updated = new ArrayList<>(); while (generator.next()) { // Skip submodules not registered in .gitmodules file if (generator.getModulesPath() == null) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java index 39dd42cc51..bdbb8620d6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java @@ -121,6 +121,7 @@ public class TagCommand extends GitCommand<Ref> { * when called on a git repo without a HEAD reference * @since 2.0 */ + @Override public Ref call() throws GitAPIException, ConcurrentRefUpdateException, InvalidTagNameException, NoHeadException { checkCallable(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java index e317507139..7df35c925c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java @@ -95,7 +95,7 @@ public class CheckoutConflictException extends GitAPIException { */ CheckoutConflictException addConflictingPath(String conflictingPath) { if (conflictingPaths == null) - conflictingPaths = new LinkedList<String>(); + conflictingPaths = new LinkedList<>(); conflictingPaths.add(conflictingPath); return this; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java index 7196502112..13aeaee7dc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java @@ -65,7 +65,7 @@ public class AttributesNode { /** Create an empty ignore node with no rules. */ public AttributesNode() { - rules = new ArrayList<AttributesRule>(); + rules = new ArrayList<>(); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java index 0532250f9c..c9c69db868 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java @@ -71,7 +71,7 @@ public class AttributesRule { private static List<Attribute> parseAttributes(String attributesLine) { // the C implementation oddly enough allows \r between attributes too. - ArrayList<Attribute> result = new ArrayList<Attribute>(); + ArrayList<Attribute> result = new ArrayList<>(); for (String attribute : attributesLine.split(ATTRIBUTES_SPLIT_REGEX)) { attribute = attribute.trim(); if (attribute.length() == 0) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java index fa6fe75e64..4ad58c3850 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java @@ -51,6 +51,7 @@ import java.io.IOException; import java.util.Collection; import java.util.Collections; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.blame.Candidate.BlobCandidate; import org.eclipse.jgit.blame.Candidate.ReverseCandidate; import org.eclipse.jgit.blame.ReverseWalk.ReverseCommit; @@ -238,11 +239,13 @@ public class BlameGenerator implements AutoCloseable { } /** - * Obtain the RenameDetector if {@code setFollowFileRenames(true)}. + * Obtain the RenameDetector, allowing the application to configure its + * settings for rename score and breaking behavior. * - * @return the rename detector, allowing the application to configure its - * settings for rename score and breaking behavior. + * @return the rename detector, or {@code null} if + * {@code setFollowFileRenames(false)}. */ + @Nullable public RenameDetector getRenameDetector() { return renameDetector; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java index 39421c6dee..bd6e5c859a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java @@ -117,7 +117,7 @@ public abstract class DiffAlgorithm { if (region.getLengthA() == 1 && region.getLengthB() == 1) return EditList.singleton(region); - SubsequenceComparator<S> cs = new SubsequenceComparator<S>(cmp); + SubsequenceComparator<S> cs = new SubsequenceComparator<>(cmp); Subsequence<S> as = Subsequence.a(a, region); Subsequence<S> bs = Subsequence.b(b, region); EditList e = Subsequence.toBase(diffNonCommon(cs, as, bs), as, bs); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java index b1cbb914d8..324b99eb58 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java @@ -55,6 +55,7 @@ import org.eclipse.jgit.util.StringUtils; public class DiffConfig { /** Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<DiffConfig> KEY = new SectionParser<DiffConfig>() { + @Override public DiffConfig parse(final Config cfg) { return new DiffConfig(cfg); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java index 24409ee592..e1dfcff6bb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java @@ -179,7 +179,7 @@ public class DiffEntry { else treeFilterMarker = null; - List<DiffEntry> r = new ArrayList<DiffEntry>(); + List<DiffEntry> r = new ArrayList<>(); MutableObjectId idBuf = new MutableObjectId(); while (walk.next()) { DiffEntry entry = new DiffEntry(); 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/diff/HashedSequencePair.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequencePair.java index 74bbca1708..bf6d967c50 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequencePair.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequencePair.java @@ -81,7 +81,7 @@ public class HashedSequencePair<S extends Sequence> { /** @return obtain a comparator that uses the cached hash codes. */ public HashedSequenceComparator<S> getComparator() { - return new HashedSequenceComparator<S>(cmp); + return new HashedSequenceComparator<>(cmp); } /** @return wrapper around A that includes cached hash codes. */ @@ -103,6 +103,6 @@ public class HashedSequencePair<S extends Sequence> { final int[] hashes = new int[end]; for (int ptr = 0; ptr < end; ptr++) hashes[ptr] = cmp.hash(base, ptr); - return new HashedSequence<S>(base, hashes); + return new HashedSequence<>(base, hashes); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java index 2f5c9ea84c..4ef58455a7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java @@ -130,17 +130,18 @@ public class HistogramDiff extends LowLevelDiffAlgorithm { maxChainLength = maxLen; } + @Override public <S extends Sequence> void diffNonCommon(EditList edits, HashedSequenceComparator<S> cmp, HashedSequence<S> a, HashedSequence<S> b, Edit region) { - new State<S>(edits, cmp, a, b).diffRegion(region); + new State<>(edits, cmp, a, b).diffRegion(region); } private class State<S extends Sequence> { private final HashedSequenceComparator<S> cmp; private final HashedSequence<S> a; private final HashedSequence<S> b; - private final List<Edit> queue = new ArrayList<Edit>(); + private final List<Edit> queue = new ArrayList<>(); /** Result edits we have determined that must be made to convert a to b. */ final EditList edits; @@ -160,7 +161,7 @@ public class HistogramDiff extends LowLevelDiffAlgorithm { } private void diffReplace(Edit r) { - Edit lcs = new HistogramDiffIndex<S>(maxChainLength, cmp, a, b, r) + Edit lcs = new HistogramDiffIndex<>(maxChainLength, cmp, a, b, r) .findLongestCommonSequence(); if (lcs != null) { // If we were given an edit, we can prove a result here. @@ -213,7 +214,7 @@ public class HistogramDiff extends LowLevelDiffAlgorithm { } private SubsequenceComparator<HashedSequence<S>> subcmp() { - return new SubsequenceComparator<HashedSequence<S>>(cmp); + return new SubsequenceComparator<>(cmp); } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java index e3861cd65e..55ceec8012 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java @@ -48,7 +48,7 @@ public abstract class LowLevelDiffAlgorithm extends DiffAlgorithm { @Override public <S extends Sequence> EditList diffNonCommon( SequenceComparator<? super S> cmp, S a, S b) { - HashedSequencePair<S> p = new HashedSequencePair<S>(cmp, a, b); + HashedSequencePair<S> p = new HashedSequencePair<>(cmp, a, b); HashedSequenceComparator<S> hc = p.getComparator(); HashedSequence<S> ha = p.getA(); HashedSequence<S> hb = p.getB(); 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 9810a6ab2f..e1bda116bf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java @@ -460,6 +460,7 @@ if (k < beginK || k > endK) } class ForwardEditPaths extends EditPaths { + @Override final int snake(int k, int x) { for (; x < endA && k + x < endB; x++) if (!cmp.equals(a, x, b, k + x)) @@ -467,18 +468,22 @@ if (k < beginK || k > endK) return x; } + @Override final int getLeft(final int x) { return x; } + @Override final int getRight(final int x) { return x + 1; } + @Override final boolean isBetter(final int left, final int right) { return left > right; } + @Override final void adjustMinMaxK(final int k, final int x) { if (x >= endA || k + x >= endB) { if (k > backward.middleK) @@ -488,6 +493,7 @@ if (k < beginK || k > endK) } } + @Override final boolean meets(int d, int k, int x, long snake) { if (k < backward.beginK || k > backward.endK) return false; @@ -502,6 +508,7 @@ if (k < beginK || k > endK) } class BackwardEditPaths extends EditPaths { + @Override final int snake(int k, int x) { for (; x > beginA && k + x > beginB; x--) if (!cmp.equals(a, x - 1, b, k + x - 1)) @@ -509,18 +516,22 @@ if (k < beginK || k > endK) return x; } + @Override final int getLeft(final int x) { return x - 1; } + @Override final int getRight(final int x) { return x; } + @Override final boolean isBetter(final int left, final int right) { return left < right; } + @Override final void adjustMinMaxK(final int k, final int x) { if (x <= beginA || k + x <= beginB) { if (k > forward.middleK) @@ -530,6 +541,7 @@ if (k < beginK || k > endK) } } + @Override final boolean meets(int d, int k, int x, long snake) { if (k < forward.beginK || k > forward.endK) return false; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java index b26e1bc429..5bfee753a6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java @@ -107,6 +107,7 @@ public class RawText extends Sequence { } /** @return total number of items in the sequence. */ + @Override public int size() { // The line map is always 2 entries larger than the number of lines in // the file. Index 0 is padded out/unused. The last index is the total diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java index 8865b62c24..bc52473d93 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java @@ -70,6 +70,7 @@ public class RenameDetector { private static final int EXACT_RENAME_SCORE = 100; private static final Comparator<DiffEntry> DIFF_COMPARATOR = new Comparator<DiffEntry>() { + @Override public int compare(DiffEntry a, DiffEntry b) { int cmp = nameOf(a).compareTo(nameOf(b)); if (cmp == 0) @@ -392,15 +393,15 @@ public class RenameDetector { /** Reset this rename detector for another rename detection pass. */ public void reset() { - entries = new ArrayList<DiffEntry>(); - deleted = new ArrayList<DiffEntry>(); - added = new ArrayList<DiffEntry>(); + entries = new ArrayList<>(); + deleted = new ArrayList<>(); + added = new ArrayList<>(); done = false; } private void breakModifies(ContentSource.Pair reader, ProgressMonitor pm) throws IOException { - ArrayList<DiffEntry> newEntries = new ArrayList<DiffEntry>(entries.size()); + ArrayList<DiffEntry> newEntries = new ArrayList<>(entries.size()); pm.beginTask(JGitText.get().renamesBreakingModifies, entries.size()); @@ -427,8 +428,8 @@ public class RenameDetector { } private void rejoinModifies(ProgressMonitor pm) { - HashMap<String, DiffEntry> nameMap = new HashMap<String, DiffEntry>(); - ArrayList<DiffEntry> newAdded = new ArrayList<DiffEntry>(added.size()); + HashMap<String, DiffEntry> nameMap = new HashMap<>(); + ArrayList<DiffEntry> newAdded = new ArrayList<>(added.size()); pm.beginTask(JGitText.get().renamesRejoiningModifies, added.size() + deleted.size()); @@ -455,7 +456,7 @@ public class RenameDetector { } added = newAdded; - deleted = new ArrayList<DiffEntry>(nameMap.values()); + deleted = new ArrayList<>(nameMap.values()); } private int calculateModifyScore(ContentSource.Pair reader, DiffEntry d) @@ -507,8 +508,8 @@ public class RenameDetector { HashMap<AbbreviatedObjectId, Object> deletedMap = populateMap(deleted, pm); HashMap<AbbreviatedObjectId, Object> addedMap = populateMap(added, pm); - ArrayList<DiffEntry> uniqueAdds = new ArrayList<DiffEntry>(added.size()); - ArrayList<List<DiffEntry>> nonUniqueAdds = new ArrayList<List<DiffEntry>>(); + ArrayList<DiffEntry> uniqueAdds = new ArrayList<>(added.size()); + ArrayList<List<DiffEntry>> nonUniqueAdds = new ArrayList<>(); for (Object o : addedMap.values()) { if (o instanceof DiffEntry) @@ -517,7 +518,7 @@ public class RenameDetector { nonUniqueAdds.add((List<DiffEntry>) o); } - ArrayList<DiffEntry> left = new ArrayList<DiffEntry>(added.size()); + ArrayList<DiffEntry> left = new ArrayList<>(added.size()); for (DiffEntry a : uniqueAdds) { Object del = deletedMap.get(a.newId); @@ -626,7 +627,7 @@ public class RenameDetector { } added = left; - deleted = new ArrayList<DiffEntry>(deletedMap.size()); + deleted = new ArrayList<>(deletedMap.size()); for (Object o : deletedMap.values()) { if (o instanceof DiffEntry) { DiffEntry e = (DiffEntry) o; @@ -676,11 +677,11 @@ public class RenameDetector { @SuppressWarnings("unchecked") private HashMap<AbbreviatedObjectId, Object> populateMap( List<DiffEntry> diffEntries, ProgressMonitor pm) { - HashMap<AbbreviatedObjectId, Object> map = new HashMap<AbbreviatedObjectId, Object>(); + HashMap<AbbreviatedObjectId, Object> map = new HashMap<>(); for (DiffEntry de : diffEntries) { Object old = map.put(id(de), de); if (old instanceof DiffEntry) { - ArrayList<DiffEntry> list = new ArrayList<DiffEntry>(2); + ArrayList<DiffEntry> list = new ArrayList<>(2); list.add((DiffEntry) old); list.add(de); map.put(id(de), list); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java index 6088d72f3b..653658be3c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java @@ -136,7 +136,7 @@ class SimilarityRenameDetector { 2 * srcs.size() * dsts.size()); int mNext = buildMatrix(pm); - out = new ArrayList<DiffEntry>(Math.min(mNext, dsts.size())); + out = new ArrayList<>(Math.min(mNext, dsts.size())); // Match rename pairs on a first come, first serve basis until // we have looked at everything that is above our minimum score. @@ -192,7 +192,7 @@ class SimilarityRenameDetector { } private static List<DiffEntry> compactSrcList(List<DiffEntry> in) { - ArrayList<DiffEntry> r = new ArrayList<DiffEntry>(in.size()); + ArrayList<DiffEntry> r = new ArrayList<>(in.size()); for (DiffEntry e : in) { if (e.changeType == ChangeType.DELETE) r.add(e); @@ -201,7 +201,7 @@ class SimilarityRenameDetector { } private static List<DiffEntry> compactDstList(List<DiffEntry> in) { - ArrayList<DiffEntry> r = new ArrayList<DiffEntry>(in.size()); + ArrayList<DiffEntry> r = new ArrayList<>(in.size()); for (DiffEntry e : in) { if (e != null) r.add(e); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java index 017fe69973..50ca613cca 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java @@ -66,7 +66,7 @@ public final class Subsequence<S extends Sequence> extends Sequence { * @return subsequence of {@code base} as described by A in {@code region}. */ public static <S extends Sequence> Subsequence<S> a(S a, Edit region) { - return new Subsequence<S>(a, region.beginA, region.endA); + return new Subsequence<>(a, region.beginA, region.endA); } /** @@ -81,7 +81,7 @@ public final class Subsequence<S extends Sequence> extends Sequence { * @return subsequence of {@code base} as described by B in {@code region}. */ public static <S extends Sequence> Subsequence<S> b(S b, Edit region) { - return new Subsequence<S>(b, region.beginB, region.endB); + return new Subsequence<>(b, region.beginB, region.endB); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java index b0cf8be076..ce52fedcb3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java @@ -111,6 +111,7 @@ public class DirCache { private static final byte[] NO_CHECKSUM = {}; static final Comparator<DirCacheEntry> ENT_CMP = new Comparator<DirCacheEntry>() { + @Override public int compare(final DirCacheEntry o1, final DirCacheEntry o2) { final int cr = cmp(o1, o2); if (cr != 0) @@ -992,7 +993,7 @@ public class DirCache { * @throws IOException */ private void updateSmudgedEntries() throws IOException { - List<String> paths = new ArrayList<String>(128); + List<String> paths = new ArrayList<>(128); try (TreeWalk walk = new TreeWalk(repository)) { walk.setOperationType(OperationType.CHECKIN_OP); for (int i = 0; i < entryCnt; i++) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java index cfebe2d073..676a6ab9c4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java @@ -218,6 +218,7 @@ public class DirCacheBuilder extends BaseDirCacheEditor { return e; } + @Override public void finish() { if (!sorted) resort(); 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 c3184437b4..84f0da9e88 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -127,11 +127,11 @@ public class DirCacheCheckout { private Repository repo; - private HashMap<String, CheckoutMetadata> updated = new HashMap<String, CheckoutMetadata>(); + private HashMap<String, CheckoutMetadata> updated = new HashMap<>(); - private ArrayList<String> conflicts = new ArrayList<String>(); + private ArrayList<String> conflicts = new ArrayList<>(); - private ArrayList<String> removed = new ArrayList<String>(); + private ArrayList<String> removed = new ArrayList<>(); private ObjectId mergeCommitTree; @@ -147,7 +147,7 @@ public class DirCacheCheckout { private boolean failOnConflict = true; - private ArrayList<String> toBeDeleted = new ArrayList<String>(); + private ArrayList<String> toBeDeleted = new ArrayList<>(); private boolean emptyDirCache; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java index c987c964c4..22bedcf91b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java @@ -74,6 +74,7 @@ import org.eclipse.jgit.util.Paths; */ public class DirCacheEditor extends BaseDirCacheEditor { private static final Comparator<PathEdit> EDIT_CMP = new Comparator<PathEdit>() { + @Override public int compare(final PathEdit o1, final PathEdit o2) { final byte[] a = o1.path; final byte[] b = o2.path; @@ -95,7 +96,7 @@ public class DirCacheEditor extends BaseDirCacheEditor { */ protected DirCacheEditor(final DirCache dc, final int ecnt) { super(dc, ecnt); - edits = new ArrayList<PathEdit>(); + edits = new ArrayList<>(); } /** @@ -123,6 +124,7 @@ public class DirCacheEditor extends BaseDirCacheEditor { return super.commit(); } + @Override public void finish() { if (!edits.isEmpty()) { applyEdits(); @@ -383,6 +385,7 @@ public class DirCacheEditor extends BaseDirCacheEditor { super(ent); } + @Override public void apply(final DirCacheEntry ent) { throw new UnsupportedOperationException(JGitText.get().noApplyInDelete); } @@ -432,6 +435,7 @@ public class DirCacheEditor extends BaseDirCacheEditor { return path; } + @Override public void apply(final DirCacheEntry ent) { throw new UnsupportedOperationException(JGitText.get().noApplyInDelete); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java index 8bcf4bf3e0..a06f9d3f4f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java @@ -80,6 +80,7 @@ public class DirCacheTree { private static final DirCacheTree[] NO_CHILDREN = {}; private static final Comparator<DirCacheTree> TREE_CMP = new Comparator<DirCacheTree>() { + @Override public int compare(final DirCacheTree o1, final DirCacheTree o2) { final byte[] a = o1.encodedName; final byte[] b = o2.encodedName; 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/errors/CompoundException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CompoundException.java index 55b64eeb90..3a7b2c66d1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/CompoundException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CompoundException.java @@ -75,7 +75,7 @@ public class CompoundException extends Exception { */ public CompoundException(final Collection<Throwable> why) { super(format(why)); - causeList = Collections.unmodifiableList(new ArrayList<Throwable>(why)); + causeList = Collections.unmodifiableList(new ArrayList<>(why)); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java b/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java index 6ac4b0f8ba..12ef533add 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java @@ -50,7 +50,7 @@ import java.util.concurrent.CopyOnWriteArrayList; /** Manages a thread-safe list of {@link RepositoryListener}s. */ public class ListenerList { - private final ConcurrentMap<Class<? extends RepositoryListener>, CopyOnWriteArrayList<ListenerHandle>> lists = new ConcurrentHashMap<Class<? extends RepositoryListener>, CopyOnWriteArrayList<ListenerHandle>>(); + private final ConcurrentMap<Class<? extends RepositoryListener>, CopyOnWriteArrayList<ListenerHandle>> lists = new ConcurrentHashMap<>(); /** * Register an IndexChangedListener. @@ -126,7 +126,7 @@ public class ListenerList { if (list == null) { CopyOnWriteArrayList<ListenerHandle> newList; - newList = new CopyOnWriteArrayList<ListenerHandle>(); + newList = new CopyOnWriteArrayList<>(); list = lists.putIfAbsent(handle.type, newList); if (list == null) list = newList; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java index 0aa0075ee4..10c84c4ecc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java @@ -70,6 +70,7 @@ abstract class AbstractHead implements Head { this.newHeads = newHeads; } + @Override public List<Head> getNextHeads(char c) { if (matches(c)) return newHeads; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java index f9c239431a..856d74e997 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java @@ -120,9 +120,9 @@ public class FileNameMatcher { private FileNameMatcher(final List<Head> headsStartValue, final List<Head> heads) { this.headsStartValue = headsStartValue; - this.heads = new ArrayList<Head>(heads.size()); + this.heads = new ArrayList<>(heads.size()); this.heads.addAll(heads); - this.listForLocalUseage = new ArrayList<Head>(heads.size()); + this.listForLocalUseage = new ArrayList<>(heads.size()); } /** @@ -158,7 +158,7 @@ public class FileNameMatcher { final List<AbstractHead> allHeads = parseHeads(patternString, invalidWildgetCharacter); - List<Head> nextHeadsSuggestion = new ArrayList<Head>(2); + List<Head> nextHeadsSuggestion = new ArrayList<>(2); nextHeadsSuggestion.add(LastHead.INSTANCE); for (int i = allHeads.size() - 1; i >= 0; i--) { final AbstractHead head = allHeads.get(i); @@ -172,7 +172,7 @@ public class FileNameMatcher { head.setNewHeads(nextHeadsSuggestion); } else { head.setNewHeads(nextHeadsSuggestion); - nextHeadsSuggestion = new ArrayList<Head>(2); + nextHeadsSuggestion = new ArrayList<>(2); nextHeadsSuggestion.add(head); } } @@ -236,7 +236,7 @@ public class FileNameMatcher { throws InvalidPatternException { int currentIndex = 0; - List<AbstractHead> heads = new ArrayList<AbstractHead>(); + List<AbstractHead> heads = new ArrayList<>(); while (currentIndex < pattern.length()) { final int groupStart = indexOfUnescaped(pattern, '[', currentIndex); if (groupStart == -1) { @@ -262,7 +262,7 @@ public class FileNameMatcher { private static List<AbstractHead> createSimpleHeads( final String patternPart, final Character invalidWildgetCharacter) { - final List<AbstractHead> heads = new ArrayList<AbstractHead>( + final List<AbstractHead> heads = new ArrayList<>( patternPart.length()); boolean escaped = false; @@ -375,7 +375,7 @@ public class FileNameMatcher { * reset and start point. */ public FileNameMatcher createMatcherForSuffix() { - final List<Head> copyOfHeads = new ArrayList<Head>(heads.size()); + final List<Head> copyOfHeads = new ArrayList<>(heads.size()); copyOfHeads.addAll(heads); return new FileNameMatcher(copyOfHeads); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java index 8af52288fc..5c18756786 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java @@ -64,7 +64,7 @@ final class GroupHead extends AbstractHead { GroupHead(String pattern, final String wholePattern) throws InvalidPatternException { super(false); - this.characterClasses = new ArrayList<CharacterPattern>(); + this.characterClasses = new ArrayList<>(); this.inverse = pattern.startsWith("!"); //$NON-NLS-1$ if (inverse) { pattern = pattern.substring(1); @@ -159,6 +159,7 @@ final class GroupHead extends AbstractHead { this.end = end; } + @Override public final boolean matches(char c) { return start <= c && c <= end; } @@ -167,6 +168,7 @@ final class GroupHead extends AbstractHead { private static final class DigitPattern implements CharacterPattern { static final GroupHead.DigitPattern INSTANCE = new DigitPattern(); + @Override public final boolean matches(char c) { return Character.isDigit(c); } @@ -175,6 +177,7 @@ final class GroupHead extends AbstractHead { private static final class LetterPattern implements CharacterPattern { static final GroupHead.LetterPattern INSTANCE = new LetterPattern(); + @Override public final boolean matches(char c) { return Character.isLetter(c); } @@ -183,6 +186,7 @@ final class GroupHead extends AbstractHead { private static final class LowerPattern implements CharacterPattern { static final GroupHead.LowerPattern INSTANCE = new LowerPattern(); + @Override public final boolean matches(char c) { return Character.isLowerCase(c); } @@ -191,6 +195,7 @@ final class GroupHead extends AbstractHead { private static final class UpperPattern implements CharacterPattern { static final GroupHead.UpperPattern INSTANCE = new UpperPattern(); + @Override public final boolean matches(char c) { return Character.isUpperCase(c); } @@ -199,6 +204,7 @@ final class GroupHead extends AbstractHead { private static final class WhitespacePattern implements CharacterPattern { static final GroupHead.WhitespacePattern INSTANCE = new WhitespacePattern(); + @Override public final boolean matches(char c) { return Character.isWhitespace(c); } @@ -211,6 +217,7 @@ final class GroupHead extends AbstractHead { this.expectedCharacter = c; } + @Override public final boolean matches(char c) { return this.expectedCharacter == c; } @@ -221,6 +228,7 @@ final class GroupHead extends AbstractHead { private static String punctCharacters = "-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; //$NON-NLS-1$ + @Override public boolean matches(char c) { return punctCharacters.indexOf(c) != -1; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java index 78a61b9c51..f9ddd9e65e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java @@ -56,6 +56,7 @@ final class LastHead implements Head { // defined because of javadoc and visibility modifier. } + @Override public List<Head> getNextHeads(char c) { return FileNameMatcher.EMPTY_HEAD_LIST; } 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..7b600ee060 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; @@ -131,8 +132,8 @@ public class ManifestParser extends DefaultHandler { lastIndex--; this.baseUrl = baseUrl.substring(0, lastIndex + 1); - plusGroups = new HashSet<String>(); - minusGroups = new HashSet<String>(); + plusGroups = new HashSet<>(); + minusGroups = new HashSet<>(); if (groups == null || groups.length() == 0 || groups.equals("default")) { //$NON-NLS-1$ // default means "all,-notdefault" @@ -146,9 +147,9 @@ public class ManifestParser extends DefaultHandler { } } - remotes = new HashMap<String, Remote>(); - projects = new ArrayList<RepoProject>(); - filteredProjects = new ArrayList<RepoProject>(); + remotes = new HashMap<>(); + projects = new ArrayList<>(); + filteredProjects = new ArrayList<>(); } /** @@ -257,7 +258,7 @@ public class ManifestParser extends DefaultHandler { return; // Only do the following after we finished reading everything. - Map<String, String> remoteUrls = new HashMap<String, String>(); + Map<String, String> remoteUrls = new HashMap<>(); URI baseUri; try { baseUri = new URI(baseUrl); @@ -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..dd68f60108 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -168,6 +168,7 @@ public class RepoCommand extends GitCommand<RevCommit> { /** A default implementation of {@link RemoteReader} callback. */ public static class DefaultRemoteReader implements RemoteReader { + @Override public ObjectId sha1(String uri, String ref) throws GitAPIException { Map<String, Ref> map = Git .lsRemoteRepository() @@ -177,13 +178,13 @@ public class RepoCommand extends GitCommand<RevCommit> { return r != null ? r.getObjectId() : null; } + @Override public byte[] readFile(String uri, String ref, String path) throws GitAPIException, IOException { File dir = FileUtils.createTempDir("jgit_", ".git", null); //$NON-NLS-1$ //$NON-NLS-2$ 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); } @@ -463,7 +464,7 @@ public class RepoCommand extends GitCommand<RevCommit> { } if (repo.isBare()) { - bareProjects = new ArrayList<RepoProject>(); + bareProjects = new ArrayList<>(); if (author == null) author = new PersonIdent(repo); if (callback == null) 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 ff4a3ed1c6..700cf11070 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java @@ -155,7 +155,7 @@ public class RepoProject implements Comparable<RepoProject> { this.remote = remote; this.groups = groups; this.recommendShallow = recommendShallow; - copyfiles = new ArrayList<CopyFile>(); + copyfiles = new ArrayList<>(); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java index ad2eeb0205..c1aca6a136 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java @@ -95,6 +95,7 @@ abstract class GitHook<T> implements Callable<T> { * If the hook has been run and a returned an exit code * different from zero. */ + @Override public abstract T call() throws IOException, AbortedByHookException; /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java index 8b1244ed1b..6314c63d2e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java @@ -83,7 +83,7 @@ public class IgnoreNode { /** Create an empty ignore node with no rules. */ public IgnoreNode() { - rules = new ArrayList<FastIgnoreRule>(); + rules = new ArrayList<>(); } /** 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..61f7b83400 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 { @@ -53,10 +51,12 @@ public interface IMatcher { * Matcher that does not match any pattern. */ public static final IMatcher NO_MATCH = new IMatcher() { + @Override public boolean matches(String path, boolean assumeDirectory) { return false; } + @Override public boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { return false; 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..cc0fe937b4 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 { @@ -57,6 +55,7 @@ public class LeadingAsteriskMatcher extends NameMatcher { "Pattern must have leading asterisk: " + pattern); //$NON-NLS-1$ } + @Override public boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { // faster local access, same as in string.indexOf() 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..00651237db 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 { @@ -72,6 +70,7 @@ public class NameMatcher extends AbstractMatcher { this.subPattern = pattern.substring(1); } + @Override public boolean matches(String path, boolean assumeDirectory) { int end = 0; int firstChar = 0; @@ -88,6 +87,7 @@ public class NameMatcher extends AbstractMatcher { return false; } + @Override public boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { // faster local access, same as in string.indexOf() 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..65224eab91 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 { @@ -92,7 +90,7 @@ public class PathMatcher extends AbstractMatcher { static private List<IMatcher> createMatchers(List<String> segments, Character pathSeparator, boolean dirOnly) throws InvalidPatternException { - List<IMatcher> matchers = new ArrayList<IMatcher>(segments.size()); + List<IMatcher> matchers = new ArrayList<>(segments.size()); for (int i = 0; i < segments.size(); i++) { String segment = segments.get(i); IMatcher matcher = createNameMatcher0(segment, pathSeparator, @@ -172,6 +170,7 @@ public class PathMatcher extends AbstractMatcher { } } + @Override public boolean matches(String path, boolean assumeDirectory) { if (matchers == null) return simpleMatch(path, assumeDirectory); @@ -211,6 +210,7 @@ public class PathMatcher extends AbstractMatcher { return false; } + @Override public boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { throw new UnsupportedOperationException( 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..da482fa50a 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 { @@ -150,7 +148,7 @@ public class Strings { if (count < 1) throw new IllegalStateException( "Pattern must have at least two segments: " + pattern); //$NON-NLS-1$ - List<String> segments = new ArrayList<String>(count); + List<String> segments = new ArrayList<>(count); int right = 0; while (true) { int left = right; 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..2e148f4a6f 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 { @@ -57,6 +55,7 @@ public class TrailingAsteriskMatcher extends NameMatcher { "Pattern must have trailing asterisk: " + pattern); //$NON-NLS-1$ } + @Override public boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { // faster local access, same as in string.indexOf() 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..93ea13c726 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 { @@ -63,10 +61,12 @@ public final class WildMatcher extends AbstractMatcher { super(WILDMATCH, false); } + @Override public final boolean matches(String path, boolean assumeDirectory) { return true; } + @Override public final boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { return true; 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..a81c93a013 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; @@ -622,6 +623,7 @@ public class JGitText extends TranslationBundle { /***/ public String sequenceTooLargeForDiffAlgorithm; /***/ public String serviceNotEnabledNoName; /***/ public String serviceNotPermitted; + /***/ public String sha1CollisionDetected1; /***/ public String shallowCommitsAlreadyInitialized; /***/ public String shallowPacksRequireDepthWalk; /***/ public String shortCompressedStreamAt; @@ -668,6 +670,7 @@ public class JGitText extends TranslationBundle { /***/ public String theFactoryMustNotBeNull; /***/ public String timeIsUncertain; /***/ public String timerAlreadyTerminated; + /***/ public String tooManyCommands; /***/ public String tooManyIncludeRecursions; /***/ public String topologicalSortRequired; /***/ public String transportExceptionBadRef; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java index 35327ea0b3..757c19ac94 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java @@ -86,6 +86,7 @@ class LagCheck implements AutoCloseable { rw.setRetainBody(false); } + @Override public void close() { if (rw != null) { rw.close(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ProposalRound.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ProposalRound.java index ddd7059fc2..1eaa33d2f2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ProposalRound.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ProposalRound.java @@ -122,6 +122,7 @@ class ProposalRound extends Round { return a == null && b == null; } + @Override void start() throws IOException { for (Proposal p : todo) { p.notifyState(RUNNING); @@ -268,6 +269,7 @@ class ProposalRound extends Round { } } + @Override void success() { for (Proposal p : todo) { p.success(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java index 396fbdd722..a0ac60809c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java @@ -240,6 +240,7 @@ public class RemoteGitReplica extends KetchReplica { ReceiveCommand.abort(tmp); } + @Override protected void blockingFetch(Repository repo, ReplicaFetchRequest req) throws NotSupportedException, TransportException { try (Transport transport = Transport.open(repo, uri)) { 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/DfsBlockCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java index f7decf1324..ef0b80c11f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java @@ -183,7 +183,7 @@ public final class DfsBlockCache { if (tableSize < 1) throw new IllegalArgumentException(JGitText.get().tSizeMustBeGreaterOrEqual1); - table = new AtomicReferenceArray<HashEntry>(tableSize); + table = new AtomicReferenceArray<>(tableSize); loadLocks = new ReentrantLock[cfg.getConcurrencyLevel()]; for (int i = 0; i < loadLocks.length; i++) loadLocks[i] = new ReentrantLock(true /* fair */); @@ -194,10 +194,10 @@ public final class DfsBlockCache { blockSizeShift = Integer.numberOfTrailingZeros(blockSize); clockLock = new ReentrantLock(true /* fair */); - clockHand = new Ref<Object>(new DfsPackKey(), -1, 0, null); + clockHand = new Ref<>(new DfsPackKey(), -1, 0, null); clockHand.next = clockHand; - packCache = new ConcurrentHashMap<DfsPackDescription, DfsPackFile>( + packCache = new ConcurrentHashMap<>( 16, 0.75f, 1); packFiles = Collections.unmodifiableCollection(packCache.values()); @@ -357,7 +357,7 @@ public final class DfsBlockCache { } key.cachedSize.addAndGet(v.size()); - Ref<DfsBlock> ref = new Ref<DfsBlock>(key, position, v.size(), v); + Ref<DfsBlock> ref = new Ref<>(key, position, v.size(), v); ref.hot = true; for (;;) { HashEntry n = new HashEntry(clean(e2), ref); @@ -461,7 +461,7 @@ public final class DfsBlockCache { } key.cachedSize.addAndGet(size); - ref = new Ref<T>(key, pos, size, v); + ref = new Ref<>(key, pos, size, v); ref.hot = true; for (;;) { HashEntry n = new HashEntry(clean(e2), ref); 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..d3803024a5 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; @@ -53,8 +56,11 @@ import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import java.io.IOException; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collection; import java.util.Collections; +import java.util.EnumSet; +import java.util.GregorianCalendar; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -63,6 +69,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; @@ -77,6 +84,7 @@ import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.pack.PackConfig; import org.eclipse.jgit.storage.pack.PackStatistics; +import org.eclipse.jgit.util.SystemReader; import org.eclipse.jgit.util.io.CountingOutputStream; /** Repack and garbage collect a repository. */ @@ -95,7 +103,8 @@ public class DfsGarbageCollector { private PackConfig packConfig; - // See pack(), below, for how these two variables interact. + // See packIsCoalesceableGarbage(), below, for how these two variables + // interact. private long coalesceGarbageLimit = 50 << 20; private long garbageTtlMillis = TimeUnit.DAYS.toMillis(1); @@ -118,9 +127,9 @@ public class DfsGarbageCollector { repo = repository; refdb = repo.getRefDatabase(); objdb = repo.getObjectDatabase(); - newPackDesc = new ArrayList<DfsPackDescription>(4); - newPackStats = new ArrayList<PackStatistics>(4); - newPackObj = new ArrayList<ObjectIdSet>(4); + newPackDesc = new ArrayList<>(4); + newPackStats = new ArrayList<>(4); + newPackObj = new ArrayList<>(4); packConfig = new PackConfig(repo); packConfig.setIndexVersion(2); @@ -223,14 +232,8 @@ public class DfsGarbageCollector { if (packConfig.getIndexVersion() != 2) throw new IllegalStateException( JGitText.get().supportOnlyPackIndexVersion2); - if (garbageTtlMillis > 0) { - // We disable coalescing because the coalescing step will keep - // refreshing the UNREACHABLE_GARBAGE pack and we wouldn't - // actually prune anything. - coalesceGarbageLimit = 0; - } - startTimeMillis = System.currentTimeMillis(); + startTimeMillis = SystemReader.getInstance().getCurrentTime(); ctx = (DfsReader) objdb.newReader(); try { refdb.refresh(); @@ -246,14 +249,14 @@ public class DfsGarbageCollector { return true; } - allHeads = new HashSet<ObjectId>(); - nonHeads = new HashSet<ObjectId>(); - txnHeads = new HashSet<ObjectId>(); - tagTargets = new HashSet<ObjectId>(); + allHeads = new HashSet<>(); + nonHeads = new HashSet<>(); + txnHeads = new HashSet<>(); + tagTargets = new HashSet<>(); 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()); @@ -301,18 +304,18 @@ public class DfsGarbageCollector { private void readPacksBefore() throws IOException { DfsPackFile[] packs = objdb.getPacks(); - packsBefore = new ArrayList<DfsPackFile>(packs.length); - expiredGarbagePacks = new ArrayList<DfsPackFile>(packs.length); + packsBefore = new ArrayList<>(packs.length); + expiredGarbagePacks = new ArrayList<>(packs.length); long mostRecentGC = mostRecentGC(packs); - long now = System.currentTimeMillis(); + long now = SystemReader.getInstance().getCurrentTime(); for (DfsPackFile p : packs) { DfsPackDescription d = p.getPackDescription(); if (d.getPackSource() != UNREACHABLE_GARBAGE) { packsBefore.add(p); } else if (packIsExpiredGarbage(d, mostRecentGC, now)) { expiredGarbagePacks.add(p); - } else if (d.getFileSize(PackExt.PACK) < coalesceGarbageLimit) { + } else if (packIsCoalesceableGarbage(d, now)) { packsBefore.add(p); } } @@ -355,6 +358,68 @@ public class DfsGarbageCollector { && now - d.getLastModified() >= garbageTtlMillis; } + private boolean packIsCoalesceableGarbage(DfsPackDescription d, long now) { + // An UNREACHABLE_GARBAGE pack can be coalesced if its size is less than + // the coalesceGarbageLimit and either garbageTtl is zero or if the pack + // is created in a close time interval (on a single calendar day when + // the garbageTtl is more than one day or one third of the garbageTtl). + // + // When the garbageTtl is more than 24 hours, garbage packs that are + // created within a single calendar day are coalesced together. This + // would make the effective ttl of the garbage pack as garbageTtl+23:59 + // and limit the number of garbage to a maximum number of + // garbageTtl_in_days + 1 (assuming all of them are less than the size + // of coalesceGarbageLimit). + // + // When the garbageTtl is less than or equal to 24 hours, garbage packs + // that are created within a one third of garbageTtl are coalesced + // together. This would make the effective ttl of the garbage packs as + // garbageTtl + (garbageTtl / 3) and would limit the number of garbage + // packs to a maximum number of 4 (assuming all of them are less than + // the size of coalesceGarbageLimit). + + if (d.getPackSource() != UNREACHABLE_GARBAGE + || d.getFileSize(PackExt.PACK) >= coalesceGarbageLimit) { + return false; + } + + if (garbageTtlMillis == 0) { + return true; + } + + long lastModified = d.getLastModified(); + long dayStartLastModified = dayStartInMillis(lastModified); + long dayStartToday = dayStartInMillis(now); + + if (dayStartLastModified != dayStartToday) { + return false; // this pack is not created today. + } + + if (garbageTtlMillis > TimeUnit.DAYS.toMillis(1)) { + return true; // ttl is more than one day and pack is created today. + } + + long timeInterval = garbageTtlMillis / 3; + if (timeInterval == 0) { + return false; // ttl is too small, don't try to coalesce. + } + + long modifiedTimeSlot = (lastModified - dayStartLastModified) / timeInterval; + long presentTimeSlot = (now - dayStartToday) / timeInterval; + return modifiedTimeSlot == presentTimeSlot; + } + + private static long dayStartInMillis(long timeInMillis) { + Calendar cal = new GregorianCalendar( + SystemReader.getInstance().getTimeZone()); + cal.setTimeInMillis(timeInMillis); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTimeInMillis(); + } + /** @return all of the source packs that fed into this compaction. */ public List<DfsPackDescription> getSourcePacks() { return toPrune(); @@ -372,7 +437,7 @@ public class DfsGarbageCollector { private List<DfsPackDescription> toPrune() { int cnt = packsBefore.size(); - List<DfsPackDescription> all = new ArrayList<DfsPackDescription>(cnt); + List<DfsPackDescription> all = new ArrayList<>(cnt); for (DfsPackFile pack : packsBefore) { all.add(pack.getPackDescription()); } @@ -390,7 +455,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 +469,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 +483,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 +499,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 +536,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 +554,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/DfsInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java index c179e77786..fd72756e39 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java @@ -90,6 +90,7 @@ import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.NB; import org.eclipse.jgit.util.TemporaryBuffer; import org.eclipse.jgit.util.io.CountingOutputStream; +import org.eclipse.jgit.util.sha1.SHA1; /** Inserts objects into the DFS. */ public class DfsInserter extends ObjectInserter { @@ -168,7 +169,7 @@ public class DfsInserter extends ObjectInserter { } long offset = beginObject(type, len); - MessageDigest md = digest(); + SHA1 md = digest(); md.update(Constants.encodedTypeString(type)); md.update((byte) ' '); md.update(Constants.encodeASCII(len)); @@ -183,7 +184,7 @@ public class DfsInserter extends ObjectInserter { len -= n; } packOut.compress.finish(); - return endObject(ObjectId.fromRaw(md.digest()), offset); + return endObject(md.toObjectId(), offset); } private byte[] insertBuffer(long len) { @@ -274,8 +275,8 @@ public class DfsInserter extends ObjectInserter { } private void beginPack() throws IOException { - objectList = new BlockList<PackedObjectInfo>(); - objectMap = new ObjectIdOwnerMap<PackedObjectInfo>(); + objectList = new BlockList<>(); + objectMap = new ObjectIdOwnerMap<>(); cache = DfsBlockCache.getInstance(); rollback = true; @@ -543,7 +544,7 @@ public class DfsInserter extends ObjectInserter { if (objectList == null) return stored; - Set<ObjectId> r = new HashSet<ObjectId>(stored.size() + 2); + Set<ObjectId> r = new HashSet<>(stored.size() + 2); r.addAll(stored); for (PackedObjectInfo obj : objectList) { if (id.prefixCompare(obj) == 0) 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..b1cb72dec9 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 @@ -160,7 +160,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { protected DfsObjDatabase(DfsRepository repository, DfsReaderOptions options) { this.repository = repository; - this.packList = new AtomicReference<PackList>(NO_PACKS); + this.packList = new AtomicReference<>(NO_PACKS); this.readerOptions = options; } @@ -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 @@ -432,7 +458,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { List<DfsPackDescription> scanned = listPacks(); Collections.sort(scanned); - List<DfsPackFile> list = new ArrayList<DfsPackFile>(scanned.size()); + List<DfsPackFile> list = new ArrayList<>(scanned.size()); boolean foundNew = false; for (DfsPackDescription dsc : scanned) { DfsPackFile oldPack = forReuse.remove(dsc); @@ -457,7 +483,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { private static Map<DfsPackDescription, DfsPackFile> reuseMap(PackList old) { Map<DfsPackDescription, DfsPackFile> forReuse - = new HashMap<DfsPackDescription, DfsPackFile>(); + = new HashMap<>(); for (DfsPackFile p : old.packs) { if (p.invalid()) { // The pack instance is corrupted, and cannot be safely used diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java index 7edae88110..ddcfff6082 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java @@ -43,8 +43,6 @@ package org.eclipse.jgit.internal.storage.dfs; -import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; - import org.eclipse.jgit.internal.storage.pack.StoredObjectRepresentation; import org.eclipse.jgit.lib.ObjectId; @@ -76,6 +74,13 @@ class DfsObjectRepresentation extends StoredObjectRepresentation { @Override public boolean wasDeltaAttempted() { - return pack.getPackDescription().getPackSource() == GC; + switch (pack.getPackDescription().getPackSource()) { + case GC: + case GC_REST: + case GC_TXN: + return true; + default: + return false; + } } } 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..0a29ac515f 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 @@ -113,10 +113,10 @@ public class DfsPackCompactor { public DfsPackCompactor(DfsRepository repository) { repo = repository; autoAddSize = 5 * 1024 * 1024; // 5 MiB - srcPacks = new ArrayList<DfsPackFile>(); - exclude = new ArrayList<ObjectIdSet>(4); - newPacks = new ArrayList<DfsPackDescription>(1); - newStats = new ArrayList<PackStatistics>(1); + srcPacks = new ArrayList<>(); + exclude = new ArrayList<>(4); + newPacks = new ArrayList<>(1); + newStats = new ArrayList<>(1); } /** @@ -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(); @@ -268,7 +280,7 @@ public class DfsPackCompactor { private List<DfsPackDescription> toPrune() { int cnt = srcPacks.size(); - List<DfsPackDescription> all = new ArrayList<DfsPackDescription>(cnt); + List<DfsPackDescription> all = new ArrayList<>(cnt); for (DfsPackFile pack : srcPacks) all.add(pack.getPackDescription()); return all; @@ -281,6 +293,7 @@ public class DfsPackCompactor { // older packs, allowing the PackWriter to be handed newer objects // first and older objects last. Collections.sort(srcPacks, new Comparator<DfsPackFile>() { + @Override public int compare(DfsPackFile a, DfsPackFile b) { return a.getPackDescription().compareTo(b.getPackDescription()); } @@ -289,7 +302,7 @@ public class DfsPackCompactor { rw = new RevWalk(ctx); added = rw.newFlag("ADDED"); //$NON-NLS-1$ isBase = rw.newFlag("IS_BASE"); //$NON-NLS-1$ - List<RevObject> baseObjects = new BlockList<RevObject>(); + List<RevObject> baseObjects = new BlockList<>(); pm.beginTask(JGitText.get().countingObjects, ProgressMonitor.UNKNOWN); for (DfsPackFile src : srcPacks) { @@ -333,7 +346,7 @@ public class DfsPackCompactor { private List<ObjectIdWithOffset> toInclude(DfsPackFile src, DfsReader ctx) throws IOException { PackIndex srcIdx = src.getPackIndex(ctx); - List<ObjectIdWithOffset> want = new BlockList<ObjectIdWithOffset>( + List<ObjectIdWithOffset> want = new BlockList<>( (int) srcIdx.getObjectCount()); SCAN: for (PackIndex.MutableEntry ent : srcIdx) { ObjectId id = ent.toObjectId(); @@ -346,6 +359,7 @@ public class DfsPackCompactor { want.add(new ObjectIdWithOffset(id, ent.getOffset())); } Collections.sort(want, new Comparator<ObjectIdWithOffset>() { + @Override public int compare(ObjectIdWithOffset a, ObjectIdWithOffset b) { return Long.signum(a.offset - b.offset); } 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..e825f1a8be 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> @@ -100,7 +102,7 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { this.repoDesc = repoDesc; int dot = name.lastIndexOf('.'); this.packName = (dot < 0) ? name : name.substring(0, dot); - this.sizeMap = new HashMap<PackExt, Long>(PackExt.values().length * 2); + this.sizeMap = new HashMap<>(PackExt.values().length * 2); } /** @return description of the repository. */ @@ -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; @@ -288,6 +309,7 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { * @param b * the other pack. */ + @Override public int compareTo(DfsPackDescription b) { // Cluster by PackSource, pushing UNREACHABLE_GARBAGE to the end. PackSource as = getPackSource(); @@ -298,6 +320,17 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { return cmp; } + // Tie break GC type packs by smallest first. There should be at most + // one of each source, but when multiple exist concurrent GCs may have + // run. Preferring the smaller file selects higher quality delta + // compression, placing less demand on the DfsBlockCache. + if (as != null && as == bs && isGC(as)) { + int cmp = Long.signum(getFileSize(PACK) - b.getFileSize(PACK)); + if (cmp != 0) { + return cmp; + } + } + // Newer packs should sort first. int cmp = Long.signum(b.getLastModified() - getLastModified()); if (cmp != 0) @@ -309,6 +342,17 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { return Long.signum(getObjectCount() - b.getObjectCount()); } + static boolean isGC(PackSource s) { + switch (s) { + case GC: + case GC_REST: + case GC_TXN: + return true; + default: + return false; + } + } + @Override public String toString() { return getFileName(PackExt.PACK); 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/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java index 8c9329503f..755b163127 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java @@ -44,10 +44,12 @@ package org.eclipse.jgit.internal.storage.dfs; +import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -64,6 +66,7 @@ import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackList; +import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.file.BitmapIndexImpl; import org.eclipse.jgit.internal.storage.file.PackBitmapIndex; import org.eclipse.jgit.internal.storage.file.PackIndex; @@ -146,6 +149,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { return null; } + @Override public Collection<CachedPack> getCachedPacksAndUpdate( BitmapBuilder needBitmap) throws IOException { for (DfsPackFile pack : db.getPacks()) { @@ -162,20 +166,19 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { throws IOException { if (id.isComplete()) return Collections.singleton(id.toObjectId()); - boolean noGarbage = avoidUnreachable; - HashSet<ObjectId> matches = new HashSet<ObjectId>(4); + HashSet<ObjectId> matches = new HashSet<>(4); PackList packList = db.getPackList(); - resolveImpl(packList, id, noGarbage, matches); + resolveImpl(packList, id, matches); if (matches.size() < MAX_RESOLVE_MATCHES && packList.dirty()) { - resolveImpl(db.scanPacks(packList), id, noGarbage, matches); + resolveImpl(db.scanPacks(packList), id, matches); } return matches; } private void resolveImpl(PackList packList, AbbreviatedObjectId id, - boolean noGarbage, HashSet<ObjectId> matches) throws IOException { + HashSet<ObjectId> matches) throws IOException { for (DfsPackFile pack : packList.packs) { - if (noGarbage && pack.isGarbage()) { + if (skipGarbagePack(pack)) { continue; } pack.resolve(this, matches, id, MAX_RESOLVE_MATCHES); @@ -187,22 +190,23 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { @Override public boolean has(AnyObjectId objectId) throws IOException { - if (last != null && last.hasObject(this, objectId)) + if (last != null + && !skipGarbagePack(last) + && last.hasObject(this, objectId)) return true; - boolean noGarbage = avoidUnreachable; PackList packList = db.getPackList(); - if (hasImpl(packList, objectId, noGarbage)) { + if (hasImpl(packList, objectId)) { return true; } else if (packList.dirty()) { - return hasImpl(db.scanPacks(packList), objectId, noGarbage); + return hasImpl(db.scanPacks(packList), objectId); } return false; } - private boolean hasImpl(PackList packList, AnyObjectId objectId, - boolean noGarbage) throws IOException { + private boolean hasImpl(PackList packList, AnyObjectId objectId) + throws IOException { for (DfsPackFile pack : packList.packs) { - if (pack == last || (noGarbage && pack.isGarbage())) + if (pack == last || skipGarbagePack(pack)) continue; if (pack.hasObject(this, objectId)) { last = pack; @@ -217,7 +221,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { throws MissingObjectException, IncorrectObjectTypeException, IOException { ObjectLoader ldr; - if (last != null) { + if (last != null && !skipGarbagePack(last)) { ldr = last.get(this, objectId); if (ldr != null) { return checkType(ldr, objectId, typeHint); @@ -225,13 +229,12 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { } PackList packList = db.getPackList(); - boolean noGarbage = avoidUnreachable; - ldr = openImpl(packList, objectId, noGarbage); + ldr = openImpl(packList, objectId); if (ldr != null) { return checkType(ldr, objectId, typeHint); } if (packList.dirty()) { - ldr = openImpl(db.scanPacks(packList), objectId, noGarbage); + ldr = openImpl(db.scanPacks(packList), objectId); if (ldr != null) { return checkType(ldr, objectId, typeHint); } @@ -251,10 +254,10 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { return ldr; } - private ObjectLoader openImpl(PackList packList, AnyObjectId objectId, - boolean noGarbage) throws IOException { + private ObjectLoader openImpl(PackList packList, AnyObjectId objectId) + throws IOException { for (DfsPackFile pack : packList.packs) { - if (pack == last || (noGarbage && pack.isGarbage())) { + if (pack == last || skipGarbagePack(pack)) { continue; } ObjectLoader ldr = pack.get(this, objectId); @@ -272,6 +275,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { } private static final Comparator<FoundObject<?>> FOUND_OBJECT_SORT = new Comparator<FoundObject<?>>() { + @Override public int compare(FoundObject<?> a, FoundObject<?> b) { int cmp = a.packIndex - b.packIndex; if (cmp == 0) @@ -315,7 +319,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { findAllImpl(db.scanPacks(packList), pending, r); } for (T t : pending) { - r.add(new FoundObject<T>(t)); + r.add(new FoundObject<>(t)); } Collections.sort(r, FOUND_OBJECT_SORT); return r; @@ -329,31 +333,32 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { } int lastIdx = 0; DfsPackFile lastPack = packs[lastIdx]; - boolean noGarbage = avoidUnreachable; OBJECT_SCAN: for (Iterator<T> it = pending.iterator(); it.hasNext();) { T t = it.next(); - try { - long p = lastPack.findOffset(this, t); - if (0 < p) { - r.add(new FoundObject<T>(t, lastIdx, lastPack, p)); - it.remove(); - continue; + if (!skipGarbagePack(lastPack)) { + try { + long p = lastPack.findOffset(this, t); + if (0 < p) { + r.add(new FoundObject<>(t, lastIdx, lastPack, p)); + it.remove(); + continue; + } + } catch (IOException e) { + // Fall though and try to examine other packs. } - } catch (IOException e) { - // Fall though and try to examine other packs. } for (int i = 0; i < packs.length; i++) { if (i == lastIdx) continue; DfsPackFile pack = packs[i]; - if (noGarbage && pack.isGarbage()) + if (skipGarbagePack(pack)) continue; try { long p = pack.findOffset(this, t); if (0 < p) { - r.add(new FoundObject<T>(t, i, pack, p)); + r.add(new FoundObject<>(t, i, pack, p)); it.remove(); lastIdx = i; lastPack = pack; @@ -368,6 +373,10 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { last = lastPack; } + private boolean skipGarbagePack(DfsPackFile pack) { + return avoidUnreachable && pack.isGarbage(); + } + @Override public <T extends ObjectId> AsyncObjectLoaderQueue<T> open( Iterable<T> objectIds, final boolean reportMissing) { @@ -385,6 +394,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { return new AsyncObjectLoaderQueue<T>() { private FoundObject<T> cur; + @Override public boolean next() throws MissingObjectException, IOException { if (idItr.hasNext()) { cur = idItr.next(); @@ -396,14 +406,17 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { } } + @Override public T getCurrent() { return cur.id; } + @Override public ObjectId getObjectId() { return cur.id; } + @Override public ObjectLoader open() throws IOException { if (cur.pack == null) throw new MissingObjectException(cur.id, @@ -411,10 +424,12 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { return cur.pack.load(DfsReader.this, cur.offset); } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return true; } + @Override public void release() { // Nothing to clean up. } @@ -440,6 +455,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { private long sz; + @Override public boolean next() throws MissingObjectException, IOException { if (idItr.hasNext()) { cur = idItr.next(); @@ -455,22 +471,27 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { } } + @Override public T getCurrent() { return cur.id; } + @Override public ObjectId getObjectId() { return cur.id; } + @Override public long getSize() { return sz; } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return true; } + @Override public void release() { // Nothing to clean up. } @@ -481,7 +502,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { public long getObjectSize(AnyObjectId objectId, int typeHint) throws MissingObjectException, IncorrectObjectTypeException, IOException { - if (last != null) { + if (last != null && !skipGarbagePack(last)) { long sz = last.getObjectSize(this, objectId); if (0 <= sz) { return sz; @@ -510,7 +531,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { private long getObjectSizeImpl(PackList packList, AnyObjectId objectId) throws IOException { for (DfsPackFile pack : packList.packs) { - if (pack == last) { + if (pack == last || skipGarbagePack(pack)) { continue; } long sz = pack.getObjectSize(this, objectId); @@ -522,22 +543,25 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { return -1; } + @Override public DfsObjectToPack newObjectToPack(AnyObjectId objectId, int type) { return new DfsObjectToPack(objectId, type); } private static final Comparator<DfsObjectToPack> OFFSET_SORT = new Comparator<DfsObjectToPack>() { + @Override public int compare(DfsObjectToPack a, DfsObjectToPack b) { return Long.signum(a.getOffset() - b.getOffset()); } }; + @Override public void selectObjectRepresentation(PackWriter packer, ProgressMonitor monitor, Iterable<ObjectToPack> objects) throws IOException, MissingObjectException { // Don't check dirty bit on PackList; assume ObjectToPacks all came from the // current list. - for (DfsPackFile pack : db.getPacks()) { + for (DfsPackFile pack : sortPacksForSelectRepresentation()) { List<DfsObjectToPack> tmp = findAllFromPack(pack, objects); if (tmp.isEmpty()) continue; @@ -556,9 +580,39 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { } } + private static final Comparator<DfsPackFile> PACK_SORT_FOR_REUSE = new Comparator<DfsPackFile>() { + @Override + public int compare(DfsPackFile af, DfsPackFile bf) { + DfsPackDescription ad = af.getPackDescription(); + DfsPackDescription bd = bf.getPackDescription(); + PackSource as = ad.getPackSource(); + PackSource bs = bd.getPackSource(); + + if (as != null && as == bs && DfsPackDescription.isGC(as)) { + // Push smaller GC files last; these likely have higher quality + // delta compression and the contained representation should be + // favored over other files. + return Long.signum(bd.getFileSize(PACK) - ad.getFileSize(PACK)); + } + + // DfsPackDescription.compareTo already did a reasonable sort. + // Rely on Arrays.sort being stable, leaving equal elements. + return 0; + } + }; + + private DfsPackFile[] sortPacksForSelectRepresentation() + throws IOException { + DfsPackFile[] packs = db.getPacks(); + DfsPackFile[] sorted = new DfsPackFile[packs.length]; + System.arraycopy(packs, 0, sorted, 0, packs.length); + Arrays.sort(sorted, PACK_SORT_FOR_REUSE); + return sorted; + } + private List<DfsObjectToPack> findAllFromPack(DfsPackFile pack, Iterable<ObjectToPack> objects) throws IOException { - List<DfsObjectToPack> tmp = new BlockList<DfsObjectToPack>(); + List<DfsObjectToPack> tmp = new BlockList<>(); PackIndex idx = pack.getPackIndex(this); for (ObjectToPack otp : objects) { long p = idx.findOffset(otp); @@ -570,6 +624,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { return tmp; } + @Override public void copyObjectAsIs(PackOutputStream out, ObjectToPack otp, boolean validate) throws IOException, StoredObjectRepresentationNotAvailableException { @@ -577,12 +632,14 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { src.pack.copyAsIs(out, src, validate, this); } + @Override public void writeObjects(PackOutputStream out, List<ObjectToPack> list) throws IOException { for (ObjectToPack otp : list) out.writeObject(otp); } + @Override public void copyPackAsIs(PackOutputStream out, CachedPack pack) throws IOException { ((DfsCachedPack) pack).copyAsIs(out, this); 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/DfsRefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java index 4ddcec1673..b41c18b6c2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java @@ -78,7 +78,7 @@ public abstract class DfsRefDatabase extends RefDatabase { */ protected DfsRefDatabase(DfsRepository repository) { this.repository = repository; - this.cache = new AtomicReference<RefCache>(); + this.cache = new AtomicReference<>(); } /** @return the repository the database holds the references of. */ @@ -120,7 +120,7 @@ public abstract class DfsRefDatabase extends RefDatabase { RefCache curr = read(); RefList<Ref> packed = RefList.emptyList(); RefList<Ref> loose = curr.ids; - RefList.Builder<Ref> sym = new RefList.Builder<Ref>(curr.sym.size()); + RefList.Builder<Ref> sym = new RefList.Builder<>(curr.sym.size()); for (int idx = 0; idx < curr.sym.size(); idx++) { Ref ref = curr.sym.get(idx); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java index ef8845084b..a5dd514709 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java @@ -143,10 +143,12 @@ public abstract class DfsRepository extends Repository { AttributesNodeProvider { private EmptyAttributesNode emptyAttributesNode = new EmptyAttributesNode(); + @Override public AttributesNode getInfoAttributesNode() throws IOException { return emptyAttributesNode; } + @Override public AttributesNode getGlobalAttributesNode() throws IOException { return emptyAttributesNode; } 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..527e46b733 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)); @@ -108,7 +107,7 @@ public class InMemoryRepository extends DfsRepository { } private class MemObjDatabase extends DfsObjDatabase { - private List<DfsPackDescription> packs = new ArrayList<DfsPackDescription>(); + private List<DfsPackDescription> packs = new ArrayList<>(); MemObjDatabase(DfsRepository repo) { super(repo, new DfsReaderOptions()); @@ -133,7 +132,7 @@ public class InMemoryRepository extends DfsRepository { Collection<DfsPackDescription> desc, Collection<DfsPackDescription> replace) { List<DfsPackDescription> n; - n = new ArrayList<DfsPackDescription>(desc.size() + packs.size()); + n = new ArrayList<>(desc.size() + packs.size()); n.addAll(desc); n.addAll(packs); if (replace != null) @@ -171,7 +170,7 @@ public class InMemoryRepository extends DfsRepository { private static class MemPack extends DfsPackDescription { final Map<PackExt, byte[]> - fileMap = new HashMap<PackExt, byte[]>(); + fileMap = new HashMap<>(); MemPack(String name, DfsRepositoryDescription repoDesc) { super(repoDesc, name); @@ -226,6 +225,7 @@ public class InMemoryRepository extends DfsRepository { data = buf; } + @Override public int read(ByteBuffer dst) { int n = Math.min(dst.remaining(), data.length - position); if (n == 0) @@ -235,30 +235,37 @@ public class InMemoryRepository extends DfsRepository { return n; } + @Override public void close() { open = false; } + @Override public boolean isOpen() { return open; } + @Override public long position() { return position; } + @Override public void position(long newPosition) { position = (int) newPosition; } + @Override public long size() { return data.length; } + @Override public int blockSize() { return 0; } + @Override public void setReadAheadBytes(int b) { // Unnecessary on a byte array. } @@ -271,7 +278,7 @@ public class InMemoryRepository extends DfsRepository { * subclasses of InMemoryRepository. */ protected class MemRefDatabase extends DfsRefDatabase { - private final ConcurrentMap<String, Ref> refs = new ConcurrentHashMap<String, Ref>(); + private final ConcurrentMap<String, Ref> refs = new ConcurrentHashMap<>(); private final ReadWriteLock lock = new ReentrantReadWriteLock(true /* fair */); /** @@ -308,8 +315,8 @@ public class InMemoryRepository extends DfsRepository { @Override protected RefCache scanAllRefs() throws IOException { - RefList.Builder<Ref> ids = new RefList.Builder<Ref>(); - RefList.Builder<Ref> sym = new RefList.Builder<Ref>(); + RefList.Builder<Ref> ids = new RefList.Builder<>(); + RefList.Builder<Ref> sym = new RefList.Builder<>(); try { lock.readLock().lock(); for (Ref ref : refs.values()) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java index 30e973ecf4..b78ff2abf9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java @@ -58,6 +58,7 @@ abstract class BasePackBitmapIndex extends PackBitmapIndex { this.bitmaps = bitmaps; } + @Override public EWAHCompressedBitmap getBitmap(AnyObjectId objectId) { StoredBitmap sb = bitmaps.get(objectId); return sb != null ? sb.getBitmap() : null; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java index b18a06f9c9..88eef4ce86 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java @@ -370,6 +370,7 @@ public class BitmapIndexImpl implements BitmapIndex { private int type; private IntIterator cached = dynamic; + @Override public boolean hasNext() { if (!cached.hasNext()) { if (commits.hasNext()) { @@ -391,6 +392,7 @@ public class BitmapIndexImpl implements BitmapIndex { return true; } + @Override public BitmapObject next() { if (!hasNext()) throw new NoSuchElementException(); @@ -408,6 +410,7 @@ public class BitmapIndexImpl implements BitmapIndex { return out; } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -439,10 +442,10 @@ public class BitmapIndexImpl implements BitmapIndex { private static final class MutableBitmapIndex { private final ObjectIdOwnerMap<MutableEntry> - revMap = new ObjectIdOwnerMap<MutableEntry>(); + revMap = new ObjectIdOwnerMap<>(); private final BlockList<MutableEntry> - revList = new BlockList<MutableEntry>(); + revList = new BlockList<>(); int findPosition(AnyObjectId objectId) { MutableEntry entry = revMap.get(objectId); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java index a81d8ec0e9..d47b304688 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java @@ -90,7 +90,7 @@ class CachedObjectDirectory extends FileObjectDatabase { } private ObjectIdOwnerMap<UnpackedObjectId> scanLoose() { - ObjectIdOwnerMap<UnpackedObjectId> m = new ObjectIdOwnerMap<UnpackedObjectId>(); + ObjectIdOwnerMap<UnpackedObjectId> m = new ObjectIdOwnerMap<>(); File objects = wrapped.getDirectory(); String[] fanout = objects.list(); if (fanout == null) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java index e968119ad9..4b4337d1ed 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java @@ -65,10 +65,12 @@ public class CheckoutEntryImpl implements CheckoutEntry { to = comment.substring(p2 + " to ".length(), p3); //$NON-NLS-1$ } + @Override public String getFromBranch() { return from; } + @Override public String getToBranch() { return to; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/DeltaBaseCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/DeltaBaseCache.java index a95dea74b6..b3979894e4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/DeltaBaseCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/DeltaBaseCache.java @@ -69,7 +69,7 @@ class DeltaBaseCache { private int openByteCount; static { - DEAD = new SoftReference<Entry>(null); + DEAD = new SoftReference<>(null); reconfigure(new WindowCacheConfig()); } @@ -115,7 +115,7 @@ class DeltaBaseCache { e.provider = pack; e.position = position; e.sz = data.length; - e.data = new SoftReference<Entry>(new Entry(data, objectType)); + e.data = new SoftReference<>(new Entry(data, objectType)); moveToHead(e); } 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..ba52251a4c 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, @@ -489,7 +490,7 @@ public class FileRepository extends Repository { */ @Override public Set<ObjectId> getAdditionalHaves() { - HashSet<ObjectId> r = new HashSet<ObjectId>(); + HashSet<ObjectId> r = new HashSet<>(); for (AlternateHandle d : objectDatabase.myAlternates()) { if (d instanceof AlternateRepository) { Repository repo; 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 b608416868..c68e5f7f3d 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,6 +79,7 @@ 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; @@ -93,6 +94,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 +222,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 +265,22 @@ 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 = !"now".equals(getPruneExpireStr()) && //$NON-NLS-1$ + 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 +292,57 @@ 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 @@ -360,7 +453,7 @@ public class GC { // Collect all loose objects which are old enough, not referenced from // the index and not in objectsToKeep - Map<ObjectId, File> deletionCandidates = new HashMap<ObjectId, File>(); + Map<ObjectId, File> deletionCandidates = new HashMap<>(); Set<ObjectId> indexObjects = null; File objects = repo.getObjectsDirectory(); String[] fanout = objects.list(); @@ -371,6 +464,7 @@ public class GC { fanout.length); try { for (String d : fanout) { + checkCancelled(); pm.update(1); if (d.length() != 2) continue; @@ -378,6 +472,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; @@ -407,6 +502,8 @@ public class GC { 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 @@ -436,11 +533,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(); @@ -458,11 +558,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(); @@ -471,6 +575,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 @@ -495,9 +601,7 @@ public class GC { long expireDate = Long.MAX_VALUE; if (expire == null && expireAgeMillis == -1) { - String pruneExpireStr = repo.getConfig().getString( - ConfigConstants.CONFIG_GC_SECTION, null, - ConfigConstants.CONFIG_KEY_PRUNEEXPIRE); + String pruneExpireStr = getPruneExpireStr(); if (pruneExpireStr == null) pruneExpireStr = PRUNE_EXPIRE_DEFAULT; expire = GitDateParser.parse(pruneExpireStr, null, SystemReader @@ -511,6 +615,12 @@ public class GC { return expireDate; } + private String getPruneExpireStr() { + return repo.getConfig().getString( + ConfigConstants.CONFIG_GC_SECTION, null, + ConfigConstants.CONFIG_KEY_PRUNEEXPIRE); + } + private long getPackExpireDate() throws ParseException { long packExpireDate = Long.MAX_VALUE; @@ -546,6 +656,7 @@ public class GC { IncorrectObjectTypeException, IOException { RevObject ro = w.next(); while (ro != null) { + checkCancelled(); if (id2File.remove(ro.getId()) != null) if (id2File.isEmpty()) return; @@ -553,6 +664,7 @@ public class GC { } ro = w.nextObject(); while (ro != null) { + checkCancelled(); if (id2File.remove(ro.getId()) != null) if (id2File.isEmpty()) return; @@ -582,10 +694,11 @@ public class GC { */ public void packRefs() throws IOException { Collection<Ref> refs = repo.getRefDatabase().getRefs(Constants.R_REFS).values(); - List<String> refsToBePacked = new ArrayList<String>(refs.size()); + List<String> refsToBePacked = new ArrayList<>(refs.size()); 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); @@ -616,18 +729,19 @@ public class GC { long time = System.currentTimeMillis(); Collection<Ref> refsBefore = getAllRefs(); - Set<ObjectId> allHeads = new HashSet<ObjectId>(); - Set<ObjectId> nonHeads = new HashSet<ObjectId>(); - Set<ObjectId> txnHeads = new HashSet<ObjectId>(); - Set<ObjectId> tagTargets = new HashSet<ObjectId>(); + Set<ObjectId> allHeads = new HashSet<>(); + Set<ObjectId> nonHeads = new HashSet<>(); + Set<ObjectId> txnHeads = new HashSet<>(); + Set<ObjectId> tagTargets = new HashSet<>(); Set<ObjectId> indexObjects = listNonHEADIndexObjects(); 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()); @@ -637,15 +751,17 @@ public class GC { tagTargets.add(ref.getPeeledObjectId()); } - List<ObjectIdSet> excluded = new LinkedList<ObjectIdSet>(); - for (final PackFile f : repo.getObjectDatabase().getPacks()) + List<ObjectIdSet> excluded = new LinkedList<>(); + for (final PackFile f : repo.getObjectDatabase().getPacks()) { + checkCancelled(); if (f.shouldBeKept()) excluded.add(f.getIndex()); + } tagTargets.addAll(allHeads); nonHeads.addAll(indexObjects); - List<PackFile> ret = new ArrayList<PackFile>(2); + List<PackFile> ret = new ArrayList<>(2); PackFile heads = null; if (!allHeads.isEmpty()) { heads = writePack(allHeads, Collections.<ObjectId> emptySet(), @@ -681,6 +797,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> @@ -739,7 +863,7 @@ public class GC { .getReverseEntries(); if (rlEntries == null || rlEntries.isEmpty()) return Collections.<ObjectId> emptySet(); - Set<ObjectId> ret = new HashSet<ObjectId>(); + Set<ObjectId> ret = new HashSet<>(); for (ReflogEntry e : rlEntries) { if (e.getWho().getWhen().getTime() < minTime) break; @@ -773,6 +897,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); } @@ -807,9 +932,10 @@ public class GC { treeWalk.setFilter(TreeFilter.ANY_DIFF); treeWalk.setRecursive(true); - Set<ObjectId> ret = new HashSet<ObjectId>(); + Set<ObjectId> ret = new HashSet<>(); while (treeWalk.next()) { + checkCancelled(); ObjectId objectId = treeWalk.getObjectId(0); switch (treeWalk.getRawMode(0) & FileMode.TYPE_MASK) { case FileMode.TYPE_MISSING: @@ -837,9 +963,11 @@ 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>( + Map<PackExt, File> tmpExts = new TreeMap<>( new Comparator<PackExt>() { + @Override public int compare(PackExt o1, PackExt o2) { // INDEX entries must be returned last, so the pack // scanner does pick up the new pack until all the @@ -868,6 +996,7 @@ public class GC { pw.preparePack(pm, want, have); if (pw.getObjectCount() == 0) return null; + checkCancelled(); // create temporary files String id = pw.computeName().getName(); @@ -984,6 +1113,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 @@ -1031,6 +1166,7 @@ public class GC { */ public long numberOfBitmaps; + @Override public String toString() { final StringBuilder b = new StringBuilder(); b.append("numberOfPackedObjects=").append(numberOfPackedObjects); //$NON-NLS-1$ @@ -1135,7 +1271,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 */ @@ -1208,7 +1343,6 @@ public class GC { * * @param auto * defines whether gc should do automatic housekeeping - * @since 4.5 */ public void setAuto(boolean auto) { this.automatic = auto; @@ -1266,10 +1400,12 @@ public class GC { try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, new DirectoryStream.Filter<Path>() { + @Override 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..d2fcacf3ea 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 @@ -110,6 +110,7 @@ public class LockFile { /** Filter to skip over active lock files when listing a directory. */ static final FilenameFilter FILTER = new FilenameFilter() { + @Override public boolean accept(File dir, String name) { return !name.endsWith(SUFFIX); } @@ -150,7 +151,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 6489415ebb..00e39533b1 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,13 +167,14 @@ 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); + packList = new AtomicReference<>(NO_PACKS); unpackedObjectCache = new UnpackedObjectCache(); this.fs = fs; this.shallowFile = shallowFile; - alternates = new AtomicReference<AlternateHandle[]>(); + alternates = new AtomicReference<>(); if (alternatePaths != null) { AlternateHandle[] alt; @@ -185,10 +188,18 @@ public class ObjectDirectory extends FileObjectDatabase { /** * @return the location of the <code>objects</code> directory. */ + @Override public final File getDirectory() { 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); @@ -250,6 +261,7 @@ public class ObjectDirectory extends FileObjectDatabase { * index file could not be opened, read, or is not recognized as * a Git pack file index. */ + @Override public PackFile openPack(final File pack) throws IOException { final String p = pack.getName(); @@ -436,6 +448,7 @@ public class ObjectDirectory extends FileObjectDatabase { return null; } + @Override ObjectLoader openLooseObject(WindowCursor curs, AnyObjectId id) throws IOException { File path = fileFor(id); @@ -451,6 +464,7 @@ public class ObjectDirectory extends FileObjectDatabase { } } + @Override long getObjectSize(WindowCursor curs, AnyObjectId id) throws IOException { if (unpackedObjectCache.isUnpacked(id)) { @@ -574,7 +588,7 @@ public class ObjectDirectory extends FileObjectDatabase { warnTmpl = JGitText.get().packWasDeleted; removePack(p); } - } else if (FileUtils.isStaleFileHandle(e)) { + } else if (FileUtils.isStaleFileHandleInCausalChain(e)) { warnTmpl = JGitText.get().packHandleIsStale; removePack(p); } else { @@ -689,6 +703,7 @@ public class ObjectDirectory extends FileObjectDatabase { && old != scanPacks(old); } + @Override Config getConfig() { return config; } @@ -705,13 +720,19 @@ public class ObjectDirectory extends FileObjectDatabase { if (shallowFileSnapshot == null || shallowFileSnapshot.isModified(shallowFile)) { - shallowCommitsIds = new HashSet<ObjectId>(); + shallowCommitsIds = new HashSet<>(); 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(); } @@ -796,7 +817,7 @@ public class ObjectDirectory extends FileObjectDatabase { final Map<String, PackFile> forReuse = reuseMap(old); final FileSnapshot snapshot = FileSnapshot.save(packDirectory); final Set<String> names = listPackDirectory(); - final List<PackFile> list = new ArrayList<PackFile>(names.size() >> 2); + final List<PackFile> list = new ArrayList<>(names.size() >> 2); boolean foundNew = false; for (final String indexName : names) { // Must match "pack-[0-9a-f]{40}.idx" to be an index. @@ -854,7 +875,7 @@ public class ObjectDirectory extends FileObjectDatabase { } private static Map<String, PackFile> reuseMap(final PackList old) { - final Map<String, PackFile> forReuse = new HashMap<String, PackFile>(); + final Map<String, PackFile> forReuse = new HashMap<>(); for (final PackFile p : old.packs) { if (p.invalid()) { // The pack instance is corrupted, and cannot be safely used @@ -883,7 +904,7 @@ public class ObjectDirectory extends FileObjectDatabase { final String[] nameList = packDirectory.list(); if (nameList == null) return Collections.emptySet(); - final Set<String> nameSet = new HashSet<String>(nameList.length << 1); + final Set<String> nameSet = new HashSet<>(nameList.length << 1); for (final String name : nameList) { if (name.startsWith("pack-")) //$NON-NLS-1$ nameSet.add(name); @@ -910,7 +931,7 @@ public class ObjectDirectory extends FileObjectDatabase { } private AlternateHandle[] loadAlternates() throws IOException { - final List<AlternateHandle> l = new ArrayList<AlternateHandle>(4); + final List<AlternateHandle> l = new ArrayList<>(4); final BufferedReader br = open(alternatesFile); try { String line; @@ -953,6 +974,7 @@ public class ObjectDirectory extends FileObjectDatabase { * identity of the loose object to map to the directory. * @return location of the object, if it were to exist as a loose object. */ + @Override public File fileFor(AnyObjectId objectId) { String n = objectId.name(); String d = n.substring(0, 2); @@ -993,6 +1015,7 @@ public class ObjectDirectory extends FileObjectDatabase { repository = r; } + @Override void close() { repository.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..aa435bf67c 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 @@ -49,12 +49,11 @@ import java.io.EOFException; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.Channels; -import java.security.DigestOutputStream; -import java.security.MessageDigest; import java.text.MessageFormat; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; @@ -69,6 +68,7 @@ import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.transport.PackParser; import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.IO; +import org.eclipse.jgit.util.sha1.SHA1; /** Creates loose objects in a {@link ObjectDirectory}. */ class ObjectDirectoryInserter extends ObjectInserter { @@ -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(); + SHA1 md = digest(); File tmp = toTemp(md, type, len, is); - ObjectId id = ObjectId.fromRaw(md.digest()); - return insertOneObject(tmp, id); + ObjectId id = md.toObjectId(); + 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: @@ -156,7 +193,7 @@ class ObjectDirectoryInserter extends ObjectInserter { } @SuppressWarnings("resource" /* java 7 */) - private File toTemp(final MessageDigest md, final int type, long len, + private File toTemp(final SHA1 md, final int type, long len, final InputStream is) throws IOException, FileNotFoundException, Error { boolean delete = true; @@ -168,7 +205,7 @@ class ObjectDirectoryInserter extends ObjectInserter { if (config.getFSyncObjectFiles()) out = Channels.newOutputStream(fOut.getChannel()); DeflaterOutputStream cOut = compress(out); - DigestOutputStream dOut = new DigestOutputStream(cOut, md); + SHA1OutputStream dOut = new SHA1OutputStream(cOut, md); writeHeader(dOut, type, len); final byte[] buf = buffer(); @@ -248,4 +285,25 @@ class ObjectDirectoryInserter extends ObjectInserter { return new EOFException(MessageFormat.format( JGitText.get().inputDidntMatchLength, Long.valueOf(missing))); } + + private static class SHA1OutputStream extends FilterOutputStream { + private final SHA1 md; + + SHA1OutputStream(OutputStream out, SHA1 md) { + super(out); + this.md = md; + } + + @Override + public void write(int b) throws IOException { + md.update((byte) b); + out.write(b); + } + + @Override + public void write(byte[] in, int p, int n) throws IOException { + md.update(in, p, n); + out.write(in, p, n); + } + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java index 956e8de0a7..bfd60fc535 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java @@ -75,9 +75,9 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex { private final EWAHCompressedBitmap tags; private final BlockList<PositionEntry> byOffset; final BlockList<StoredBitmap> - byAddOrder = new BlockList<StoredBitmap>(); + byAddOrder = new BlockList<>(); final ObjectIdOwnerMap<PositionEntry> - positionEntries = new ObjectIdOwnerMap<PositionEntry>(); + positionEntries = new ObjectIdOwnerMap<>(); /** * Creates a PackBitmapIndex used for building the contents of an index @@ -133,6 +133,7 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex { positionEntries.add(new PositionEntry(entries.get(i), i)); } Collections.sort(entries, new Comparator<ObjectToPack>() { + @Override public int compare(ObjectToPack a, ObjectToPack b) { return Long.signum(a.getOffset() - b.getOffset()); } @@ -274,14 +275,17 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex { // Add order is from oldest to newest. The reverse add order is the // output order. return new Iterable<StoredEntry>() { + @Override public Iterator<StoredEntry> iterator() { return new Iterator<StoredEntry>() { private int index = byAddOrder.size() - 1; + @Override public boolean hasNext() { return index >= 0; } + @Override public StoredEntry next() { if (!hasNext()) throw new NoSuchElementException(); @@ -315,6 +319,7 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex { bestXorOffset, item.getFlags()); } + @Override public void remove() { throw new UnsupportedOperationException(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java index 2c462a78b7..9a8c2752dd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java @@ -107,7 +107,7 @@ public class PackBitmapIndexRemapper extends PackBitmapIndex BasePackBitmapIndex oldPackIndex, PackBitmapIndex newPackIndex) { this.oldPackIndex = oldPackIndex; this.newPackIndex = newPackIndex; - convertedBitmaps = new ObjectIdOwnerMap<StoredBitmap>(); + convertedBitmaps = new ObjectIdOwnerMap<>(); inflated = new BitSet(newPackIndex.getObjectCount()); prevToNewMapping = new int[oldPackIndex.getObjectCount()]; @@ -137,6 +137,7 @@ public class PackBitmapIndexRemapper extends PackBitmapIndex return newPackIndex.ofObjectType(bitmap, type); } + @Override public Iterator<Entry> iterator() { if (oldPackIndex == null) return Collections.<Entry> emptyList().iterator(); @@ -145,6 +146,7 @@ public class PackBitmapIndexRemapper extends PackBitmapIndex return new Iterator<Entry>() { private Entry entry; + @Override public boolean hasNext() { while (entry == null && it.hasNext()) { StoredBitmap sb = it.next(); @@ -154,6 +156,7 @@ public class PackBitmapIndexRemapper extends PackBitmapIndex return entry != null; } + @Override public Entry next() { if (!hasNext()) throw new NoSuchElementException(); @@ -163,6 +166,7 @@ public class PackBitmapIndexRemapper extends PackBitmapIndex return res; } + @Override public void remove() { throw new UnsupportedOperationException(); } 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 e004f90902..f4a77d2a2a 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 @@ -47,6 +47,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.INDEX; +import static org.eclipse.jgit.internal.storage.pack.PackExt.KEEP; import java.io.EOFException; import java.io.File; @@ -94,6 +95,7 @@ import org.eclipse.jgit.util.RawParseUtils; public class PackFile implements Iterable<PackIndex.MutableEntry> { /** Sorts PackFiles to be most recently created to least recently created. */ public static final Comparator<PackFile> SORT = new Comparator<PackFile>() { + @Override public int compare(final PackFile a, final PackFile b) { return b.packLastModified - a.packLastModified; } @@ -244,7 +246,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(); } @@ -294,6 +296,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { * * @see PackIndex#iterator() */ + @Override public Iterator<PackIndex.MutableEntry> iterator() { try { return idx().iterator(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java index f36bd4d70c..ac1b7a367d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java @@ -184,6 +184,7 @@ public abstract class PackIndex * * @return iterator over pack index entries */ + @Override public abstract Iterator<MutableEntry> iterator(); /** @@ -366,6 +367,7 @@ public abstract class PackIndex protected abstract MutableEntry initEntry(); + @Override public boolean hasNext() { return returnedNumber < getObjectCount(); } @@ -374,8 +376,10 @@ public abstract class PackIndex * Implementation must update {@link #returnedNumber} before returning * element. */ + @Override public abstract MutableEntry next(); + @Override public void remove() { throw new UnsupportedOperationException(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java index e5a729dbf3..8a08456246 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java @@ -240,6 +240,7 @@ class PackIndexV1 extends PackIndex { @Override protected MutableEntry initEntry() { return new MutableEntry() { + @Override protected void ensureId() { idBuffer.fromRaw(idxdata[levelOne], levelTwo - Constants.OBJECT_ID_LENGTH); @@ -247,6 +248,7 @@ class PackIndexV1 extends PackIndex { }; } + @Override public MutableEntry next() { for (; levelOne < idxdata.length; levelOne++) { if (idxdata[levelOne] == null) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java index d87336f99c..5c2986a04e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java @@ -311,6 +311,7 @@ class PackIndexV2 extends PackIndex { @Override protected MutableEntry initEntry() { return new MutableEntry() { + @Override protected void ensureId() { idBuffer.fromRaw(names[levelOne], levelTwo - Constants.OBJECT_ID_LENGTH / 4); @@ -318,6 +319,7 @@ class PackIndexV2 extends PackIndex { }; } + @Override public MutableEntry next() { for (; levelOne < names.length; levelOne++) { if (levelTwo < names[levelOne].length) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java index e3d0d6162c..24d51a5ea6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java @@ -153,10 +153,10 @@ public class RefDirectory extends RefDatabase { * converted into resolved references during a get operation, ensuring the * live value is always returned. */ - private final AtomicReference<RefList<LooseRef>> looseRefs = new AtomicReference<RefList<LooseRef>>(); + private final AtomicReference<RefList<LooseRef>> looseRefs = new AtomicReference<>(); /** Immutable sorted list of packed references. */ - final AtomicReference<PackedRefList> packedRefs = new AtomicReference<PackedRefList>(); + final AtomicReference<PackedRefList> packedRefs = new AtomicReference<>(); /** * Number of modifications made to this database. @@ -194,6 +194,7 @@ public class RefDirectory extends RefDatabase { return logWriter; } + @Override public void create() throws IOException { FileUtils.mkdir(refsDir); FileUtils.mkdir(new File(refsDir, R_HEADS.substring(R_REFS.length()))); @@ -351,7 +352,7 @@ public class RefDirectory extends RefDatabase { @Override public List<Ref> getAdditionalRefs() throws IOException { - List<Ref> ret = new LinkedList<Ref>(); + List<Ref> ret = new LinkedList<>(); for (String name : additionalRefsNames) { Ref r = getRef(name); if (r != null) @@ -370,7 +371,7 @@ public class RefDirectory extends RefDatabase { private int curIdx; - final RefList.Builder<Ref> symbolic = new RefList.Builder<Ref>(4); + final RefList.Builder<Ref> symbolic = new RefList.Builder<>(4); RefList.Builder<LooseRef> newLoose; @@ -534,6 +535,7 @@ public class RefDirectory extends RefDatabase { fireRefsChanged(); } + @Override public RefDirectoryUpdate newUpdate(String name, boolean detach) throws IOException { boolean detachingSymbolicRef = false; @@ -798,7 +800,8 @@ public class RefDirectory extends RefDatabase { return new PackedRefList(parsePackedRefs(br), snapshot, ObjectId.fromRaw(digest.digest())); } catch (IOException e) { - if (FileUtils.isStaleFileHandle(e) && retries < maxStaleRetries) { + if (FileUtils.isStaleFileHandleInCausalChain(e) + && retries < maxStaleRetries) { if (LOG.isDebugEnabled()) { LOG.debug(MessageFormat.format( JGitText.get().packedRefsHandleIsStale, @@ -816,7 +819,7 @@ public class RefDirectory extends RefDatabase { private RefList<Ref> parsePackedRefs(final BufferedReader br) throws IOException { - RefList.Builder<Ref> all = new RefList.Builder<Ref>(); + RefList.Builder<Ref> all = new RefList.Builder<>(); Ref last = null; boolean peeled = false; boolean needSort = false; @@ -1125,10 +1128,12 @@ public class RefDirectory extends RefDatabase { this.snapShot = snapshot; } + @Override public FileSnapshot getSnapShot() { return snapShot; } + @Override public LooseRef peel(ObjectIdRef newLeaf) { return this; } @@ -1144,10 +1149,12 @@ public class RefDirectory extends RefDatabase { this.snapShot = snapshot; } + @Override public FileSnapshot getSnapShot() { return snapShot; } + @Override public LooseRef peel(ObjectIdRef newLeaf) { return this; } @@ -1163,6 +1170,7 @@ public class RefDirectory extends RefDatabase { this.snapShot = snapShot; } + @Override public FileSnapshot getSnapShot() { return snapShot; } @@ -1175,6 +1183,7 @@ public class RefDirectory extends RefDatabase { return id; } + @Override public LooseRef peel(ObjectIdRef newLeaf) { ObjectId peeledObjectId = newLeaf.getPeeledObjectId(); ObjectId objectId = getObjectId(); @@ -1198,10 +1207,12 @@ public class RefDirectory extends RefDatabase { this.snapShot = snapshot; } + @Override public FileSnapshot getSnapShot() { return snapShot; } + @Override public LooseRef peel(ObjectIdRef newLeaf) { // We should never try to peel the symbolic references. throw new UnsupportedOperationException(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java index 60f04b8d1f..16b2a460e1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java @@ -93,6 +93,7 @@ public class ReflogEntryImpl implements Serializable, ReflogEntry { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getOldId() */ + @Override public ObjectId getOldId() { return oldId; } @@ -100,6 +101,7 @@ public class ReflogEntryImpl implements Serializable, ReflogEntry { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getNewId() */ + @Override public ObjectId getNewId() { return newId; } @@ -107,6 +109,7 @@ public class ReflogEntryImpl implements Serializable, ReflogEntry { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getWho() */ + @Override public PersonIdent getWho() { return who; } @@ -114,6 +117,7 @@ public class ReflogEntryImpl implements Serializable, ReflogEntry { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getComment() */ + @Override public String getComment() { return comment; } @@ -128,6 +132,7 @@ public class ReflogEntryImpl implements Serializable, ReflogEntry { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#parseCheckout() */ + @Override public CheckoutEntry parseCheckout() { if (getComment().startsWith(CheckoutEntryImpl.CHECKOUT_MOVING_FROM)) return new CheckoutEntryImpl(this); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java index 2f583b275a..c3702fecab 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java @@ -74,6 +74,7 @@ class ReflogReaderImpl implements ReflogReader { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getLastEntry() */ + @Override public ReflogEntry getLastEntry() throws IOException { return getReverseEntry(0); } @@ -81,6 +82,7 @@ class ReflogReaderImpl implements ReflogReader { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getReverseEntries() */ + @Override public List<ReflogEntry> getReverseEntries() throws IOException { return getReverseEntries(Integer.MAX_VALUE); } @@ -88,6 +90,7 @@ class ReflogReaderImpl implements ReflogReader { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getReverseEntry(int) */ + @Override public ReflogEntry getReverseEntry(int number) throws IOException { if (number < 0) throw new IllegalArgumentException(); @@ -116,6 +119,7 @@ class ReflogReaderImpl implements ReflogReader { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getReverseEntries(int) */ + @Override public List<ReflogEntry> getReverseEntries(int max) throws IOException { final byte[] log; try { @@ -128,7 +132,7 @@ class ReflogReaderImpl implements ReflogReader { } int rs = RawParseUtils.prevLF(log, log.length); - List<ReflogEntry> ret = new ArrayList<ReflogEntry>(); + List<ReflogEntry> ret = new ArrayList<>(); while (rs >= 0 && max-- > 0) { rs = RawParseUtils.prevLF(log, rs); ReflogEntry entry = new ReflogEntryImpl(log, rs < 0 ? 0 : rs + 2); 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/file/SimpleDataInput.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java index a7330681fb..452636dcab 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java @@ -64,11 +64,13 @@ class SimpleDataInput implements DataInput { this.fd = fd; } + @Override public int readInt() throws IOException { readFully(buf, 0, 4); return NB.decodeInt32(buf, 0); } + @Override public long readLong() throws IOException { readFully(buf, 0, 8); return NB.decodeInt64(buf, 0); @@ -79,54 +81,67 @@ class SimpleDataInput implements DataInput { return NB.decodeUInt32(buf, 0); } + @Override public void readFully(byte[] b) throws IOException { readFully(b, 0, b.length); } + @Override public void readFully(byte[] b, int off, int len) throws IOException { IO.readFully(fd, b, off, len); } + @Override public int skipBytes(int n) throws IOException { throw new UnsupportedOperationException(); } + @Override public boolean readBoolean() throws IOException { throw new UnsupportedOperationException(); } + @Override public byte readByte() throws IOException { throw new UnsupportedOperationException(); } + @Override public int readUnsignedByte() throws IOException { throw new UnsupportedOperationException(); } + @Override public short readShort() throws IOException { throw new UnsupportedOperationException(); } + @Override public int readUnsignedShort() throws IOException { throw new UnsupportedOperationException(); } + @Override public char readChar() throws IOException { throw new UnsupportedOperationException(); } + @Override public float readFloat() throws IOException { throw new UnsupportedOperationException(); } + @Override public double readDouble() throws IOException { throw new UnsupportedOperationException(); } + @Override public String readLine() throws IOException { throw new UnsupportedOperationException(); } + @Override public String readUTF() throws IOException { throw new UnsupportedOperationException(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java index d9c899ae59..373a49465b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java @@ -64,61 +64,75 @@ class SimpleDataOutput implements DataOutput { this.fd = fd; } + @Override public void writeShort(int v) throws IOException { NB.encodeInt16(buf, 0, v); fd.write(buf, 0, 2); } + @Override public void writeInt(int v) throws IOException { NB.encodeInt32(buf, 0, v); fd.write(buf, 0, 4); } + @Override public void writeLong(long v) throws IOException { NB.encodeInt64(buf, 0, v); fd.write(buf, 0, 8); } + @Override public void write(int b) throws IOException { throw new UnsupportedOperationException(); } + @Override public void write(byte[] b) throws IOException { throw new UnsupportedOperationException(); } + @Override public void write(byte[] b, int off, int len) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeBoolean(boolean v) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeByte(int v) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeChar(int v) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeFloat(float v) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeDouble(double v) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeBytes(String s) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeChars(String s) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeUTF(String s) throws IOException { throw new UnsupportedOperationException(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java index ce67ae07ad..967754a627 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java @@ -100,7 +100,7 @@ class UnpackedObjectCache { final int bits; Table(int bits) { - this.ids = new AtomicReferenceArray<ObjectId>(1 << bits); + this.ids = new AtomicReferenceArray<>(1 << bits); this.shift = 32 - bits; this.bits = bits; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java index e1b7606df2..a525c85116 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java @@ -235,9 +235,9 @@ public class WindowCache { if (lockCount < 1) throw new IllegalArgumentException(JGitText.get().lockCountMustBeGreaterOrEqual1); - queue = new ReferenceQueue<ByteWindow>(); + queue = new ReferenceQueue<>(); clock = new AtomicLong(1); - table = new AtomicReferenceArray<Entry>(tableSize); + table = new AtomicReferenceArray<>(tableSize); locks = new Lock[lockCount]; for (int i = 0; i < locks.length; i++) locks[i] = new Lock(); 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 a742d1747e..83b236ed96 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 @@ -125,6 +125,7 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { return null; } + @Override public Collection<CachedPack> getCachedPacksAndUpdate( BitmapBuilder needBitmap) throws IOException { for (PackFile pack : db.getPacks()) { @@ -141,15 +142,17 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { throws IOException { if (id.isComplete()) return Collections.singleton(id.toObjectId()); - HashSet<ObjectId> matches = new HashSet<ObjectId>(4); + HashSet<ObjectId> matches = new HashSet<>(4); db.resolve(matches, id); return matches; } + @Override public boolean has(AnyObjectId objectId) throws IOException { return db.has(objectId); } + @Override public ObjectLoader open(AnyObjectId objectId, int typeHint) throws MissingObjectException, IncorrectObjectTypeException, IOException { @@ -170,6 +173,7 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { return db.getShallowCommits(); } + @Override public long getObjectSize(AnyObjectId objectId, int typeHint) throws MissingObjectException, IncorrectObjectTypeException, IOException { @@ -183,10 +187,12 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { return sz; } + @Override public LocalObjectToPack newObjectToPack(AnyObjectId objectId, int type) { return new LocalObjectToPack(objectId, type); } + @Override public void selectObjectRepresentation(PackWriter packer, ProgressMonitor monitor, Iterable<ObjectToPack> objects) throws IOException, MissingObjectException { @@ -196,6 +202,7 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { } } + @Override public void copyObjectAsIs(PackOutputStream out, ObjectToPack otp, boolean validate) throws IOException, StoredObjectRepresentationNotAvailableException { @@ -203,6 +210,7 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { src.pack.copyAsIs(out, src, validate, this); } + @Override public void writeObjects(PackOutputStream out, List<ObjectToPack> list) throws IOException { for (ObjectToPack otp : list) @@ -245,6 +253,7 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { return cnt - need; } + @Override public void copyPackAsIs(PackOutputStream out, CachedPack pack) throws IOException { ((LocalCachedPack) pack).copyAsIs(out, this); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WriteConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WriteConfig.java index 4f79ea9723..1e2b239324 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WriteConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WriteConfig.java @@ -50,6 +50,7 @@ import org.eclipse.jgit.lib.CoreConfig; class WriteConfig { /** Key for {@link Config#get(SectionParser)}. */ static final Config.SectionParser<WriteConfig> KEY = new SectionParser<WriteConfig>() { + @Override public WriteConfig parse(final Config cfg) { return new WriteConfig(cfg); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java index b6af0b03f5..d231ccb997 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java @@ -96,7 +96,7 @@ class BaseSearch { edgeObjects = edges; alreadyProcessed = new IntSet(); - treeCache = new ObjectIdOwnerMap<TreeWithData>(); + treeCache = new ObjectIdOwnerMap<>(); parser = new CanonicalTreeParser(); idBuf = new MutableObjectId(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaCache.java index 91917b2812..973dd1de37 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaCache.java @@ -60,7 +60,7 @@ class DeltaCache { DeltaCache(PackConfig pc) { size = pc.getDeltaCacheSize(); entryLimit = pc.getDeltaCacheLimit(); - queue = new ReferenceQueue<byte[]>(); + queue = new ReferenceQueue<>(); } boolean canCache(int length, ObjectToPack src, ObjectToPack res) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java index 2a2a463b80..0f22de08e0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java @@ -421,6 +421,7 @@ public class DeltaIndex { return start - resPtr; } + @Override @SuppressWarnings("nls") public String toString() { String[] units = { "bytes", "KiB", "MiB", "GiB" }; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java index 42927426b9..0c4e4448d8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java @@ -78,7 +78,7 @@ final class DeltaTask implements Callable<Object> { Block(int threads, PackConfig config, ObjectReader reader, DeltaCache dc, ThreadSafeProgressMonitor pm, ObjectToPack[] list, int begin, int end) { - this.tasks = new ArrayList<DeltaTask>(threads); + this.tasks = new ArrayList<>(threads); this.threads = threads; this.config = config; this.templateReader = reader; @@ -176,7 +176,7 @@ final class DeltaTask implements Callable<Object> { } private ArrayList<WeightedPath> computeTopPaths() { - ArrayList<WeightedPath> topPaths = new ArrayList<WeightedPath>( + ArrayList<WeightedPath> topPaths = new ArrayList<>( threads); int cp = beginIndex; int ch = list[cp].getPathHash(); @@ -213,6 +213,7 @@ final class DeltaTask implements Callable<Object> { // Sort by starting index to identify gaps later. Collections.sort(topPaths, new Comparator<WeightedPath>() { + @Override public int compare(WeightedPath a, WeightedPath b) { return a.slice.beginIndex - b.slice.beginIndex; } @@ -244,6 +245,7 @@ final class DeltaTask implements Callable<Object> { this.slice = s; } + @Override public int compareTo(WeightedPath o) { int cmp = Long.signum(weight - o.weight); if (cmp != 0) { @@ -275,7 +277,7 @@ final class DeltaTask implements Callable<Object> { DeltaTask(Block b) { this.block = b; - this.slices = new LinkedList<Slice>(); + this.slices = new LinkedList<>(); } void add(Slice s) { @@ -290,6 +292,7 @@ final class DeltaTask implements Callable<Object> { slices.add(s); } + @Override public Object call() throws Exception { or = block.templateReader.newReader(); try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java index 19d06a23f8..73b285afc1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java @@ -160,6 +160,7 @@ final class DeltaWindow { clear(n); } res.set(next); + clearWindowOnTypeSwitch(); if (res.object.isEdge() || res.object.doNotAttemptDelta()) { // We don't actually want to make a delta for @@ -194,6 +195,15 @@ final class DeltaWindow { return DeltaIndex.estimateIndexSize(len) - len; } + private void clearWindowOnTypeSwitch() { + DeltaWindowEntry p = res.prev; + if (!p.empty() && res.type() != p.type()) { + for (; p != res; p = p.prev) { + clear(p); + } + } + } + private void clear(DeltaWindowEntry ent) { if (ent.index != null) loaded -= ent.index.getIndexSize(); @@ -258,12 +268,6 @@ final class DeltaWindow { private boolean delta(final DeltaWindowEntry src) throws IOException { - // Objects must use only the same type as their delta base. - if (src.type() != res.type()) { - keepInWindow(); - return NEXT_RES; - } - // If the sizes are radically different, this is a bad pairing. if (res.size() < src.size() >>> 4) return NEXT_SRC; 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..93dbee3e79 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,18 +164,20 @@ 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>(); + new ConcurrentHashMap<>(); private static final Iterable<PackWriter> instancesIterable = new Iterable<PackWriter>() { + @Override public Iterator<PackWriter> iterator() { return new Iterator<PackWriter>() { private final Iterator<WeakReference<PackWriter>> it = instances.keySet().iterator(); private PackWriter next; + @Override public boolean hasNext() { if (next != null) return true; @@ -189,6 +191,7 @@ public class PackWriter implements AutoCloseable { return false; } + @Override public PackWriter next() { if (hasNext()) { PackWriter result = next; @@ -198,6 +201,7 @@ public class PackWriter implements AutoCloseable { throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -213,21 +217,21 @@ public class PackWriter implements AutoCloseable { @SuppressWarnings("unchecked") BlockList<ObjectToPack> objectsLists[] = new BlockList[OBJ_TAG + 1]; { - objectsLists[OBJ_COMMIT] = new BlockList<ObjectToPack>(); - objectsLists[OBJ_TREE] = new BlockList<ObjectToPack>(); - objectsLists[OBJ_BLOB] = new BlockList<ObjectToPack>(); - objectsLists[OBJ_TAG] = new BlockList<ObjectToPack>(); + objectsLists[OBJ_COMMIT] = new BlockList<>(); + objectsLists[OBJ_TREE] = new BlockList<>(); + objectsLists[OBJ_BLOB] = new BlockList<>(); + objectsLists[OBJ_TAG] = new BlockList<>(); } - private ObjectIdOwnerMap<ObjectToPack> objectsMap = new ObjectIdOwnerMap<ObjectToPack>(); + private ObjectIdOwnerMap<ObjectToPack> objectsMap = new ObjectIdOwnerMap<>(); // edge objects for thin packs - private List<ObjectToPack> edgeObjects = new BlockList<ObjectToPack>(); + private List<ObjectToPack> edgeObjects = new BlockList<>(); // Objects the client is known to have already. private BitmapBuilder haveObjects; - private List<CachedPack> cachedPacks = new ArrayList<CachedPack>(2); + private List<CachedPack> cachedPacks = new ArrayList<>(2); private Set<ObjectId> tagTargets = Collections.emptySet(); @@ -355,7 +359,7 @@ public class PackWriter implements AutoCloseable { reuseValidate = true; // be paranoid by default stats = new PackStatistics.Accumulator(); state = new MutableState(); - selfRef = new WeakReference<PackWriter>(this); + selfRef = new WeakReference<>(this); instances.put(selfRef, Boolean.TRUE); } @@ -369,7 +373,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,11 +384,10 @@ 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 - .unmodifiableSet(new HashSet<ObjectId>(clientShallowCommits)); + .unmodifiableSet(new HashSet<>(clientShallowCommits)); } /** @@ -742,21 +744,20 @@ 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, @NonNull Set<? extends ObjectId> have, @NonNull Set<? extends ObjectId> shallow) throws IOException { - ObjectWalk ow; - if (shallowPack) { - ow = new DepthWalk.ObjectWalk(reader, depth - 1); - } else { - ow = new ObjectWalk(reader); + try (ObjectWalk ow = getObjectWalk()) { + ow.assumeShallow(shallow); + preparePack(countingMonitor, ow, want, have); } - ow.assumeShallow(shallow); - preparePack(countingMonitor, ow, want, have); + } + + private ObjectWalk getObjectWalk() { + return shallowPack ? new DepthWalk.ObjectWalk(reader, depth - 1) + : new ObjectWalk(reader); } /** @@ -917,7 +918,7 @@ public class PackWriter implements AutoCloseable { cnt += objectsLists[OBJ_BLOB].size(); cnt += objectsLists[OBJ_TAG].size(); - sortedByName = new BlockList<ObjectToPack>(cnt); + sortedByName = new BlockList<>(cnt); sortedByName.addAll(objectsLists[OBJ_COMMIT]); sortedByName.addAll(objectsLists[OBJ_TREE]); sortedByName.addAll(objectsLists[OBJ_BLOB]); @@ -1089,8 +1090,6 @@ public class PackWriter implements AutoCloseable { /** * Release all resources used by this writer. - * - * @since 4.0 */ @Override public void close() { @@ -1113,7 +1112,7 @@ public class PackWriter implements AutoCloseable { beginPhase(PackingPhase.FINDING_SOURCES, monitor, cnt); if (cnt <= 4096) { // For small object counts, do everything as one list. - BlockList<ObjectToPack> tmp = new BlockList<ObjectToPack>((int) cnt); + BlockList<ObjectToPack> tmp = new BlockList<>((int) cnt); tmp.addAll(objectsLists[OBJ_TAG]); tmp.addAll(objectsLists[OBJ_COMMIT]); tmp.addAll(objectsLists[OBJ_TREE]); @@ -1259,6 +1258,7 @@ public class PackWriter implements AutoCloseable { // bigger ones, because source files grow and hardly ever shrink. // Arrays.sort(list, 0, cnt, new Comparator<ObjectToPack>() { + @Override public int compare(ObjectToPack a, ObjectToPack b) { int cmp = (a.isDoNotDelta() ? 1 : 0) - (b.isDoNotDelta() ? 1 : 0); @@ -1404,6 +1404,7 @@ public class PackWriter implements AutoCloseable { // can schedule these for us. for (final DeltaTask task : taskBlock.tasks) { executor.execute(new Runnable() { + @Override public void run() { try { task.call(); @@ -1446,7 +1447,7 @@ public class PackWriter implements AutoCloseable { private static void runTasks(ExecutorService pool, ThreadSafeProgressMonitor pm, DeltaTask.Block tb, List<Throwable> errors) throws IOException { - List<Future<?>> futures = new ArrayList<Future<?>>(tb.tasks.size()); + List<Future<?>> futures = new ArrayList<>(tb.tasks.size()); for (DeltaTask task : tb.tasks) futures.add(pool.submit(task)); @@ -1675,7 +1676,7 @@ public class PackWriter implements AutoCloseable { } } - List<ObjectId> all = new ArrayList<ObjectId>(want.size() + have.size()); + List<ObjectId> all = new ArrayList<>(want.size() + have.size()); all.addAll(want); all.addAll(have); @@ -1693,9 +1694,9 @@ public class PackWriter implements AutoCloseable { walker.sort(RevSort.BOUNDARY, true); } - List<RevObject> wantObjs = new ArrayList<RevObject>(want.size()); - List<RevObject> haveObjs = new ArrayList<RevObject>(haveEst); - List<RevTag> wantTags = new ArrayList<RevTag>(want.size()); + List<RevObject> wantObjs = new ArrayList<>(want.size()); + List<RevObject> haveObjs = new ArrayList<>(haveEst); + List<RevTag> wantTags = new ArrayList<>(want.size()); // Retrieve the RevWalk's versions of "want" and "have" objects to // maintain any state previously set in the RevWalk. @@ -1726,7 +1727,7 @@ public class PackWriter implements AutoCloseable { } if (!wantTags.isEmpty()) { - all = new ArrayList<ObjectId>(wantTags.size()); + all = new ArrayList<>(wantTags.size()); for (RevTag tag : wantTags) all.add(tag.getObject()); q = walker.parseAny(all, true); @@ -1769,8 +1770,8 @@ public class PackWriter implements AutoCloseable { walker.markUninteresting(obj); final int maxBases = config.getDeltaSearchWindowSize(); - Set<RevTree> baseTrees = new HashSet<RevTree>(); - BlockList<RevCommit> commits = new BlockList<RevCommit>(); + Set<RevTree> baseTrees = new HashSet<>(); + BlockList<RevCommit> commits = new BlockList<>(); Set<ObjectId> roots = new HashSet<>(); RevCommit c; while ((c = walker.next()) != null) { @@ -2258,8 +2259,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/internal/storage/pack/PackWriterBitmapPreparer.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java index 77311abaa5..07a03b4040 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java @@ -91,6 +91,7 @@ class PackWriterBitmapPreparer { private static final int DAY_IN_SECONDS = 24 * 60 * 60; private static final Comparator<BitmapBuilderEntry> ORDER_BY_CARDINALITY = new Comparator<BitmapBuilderEntry>() { + @Override public int compare(BitmapBuilderEntry a, BitmapBuilderEntry b) { return Integer.signum(a.getBuilder().cardinality() - b.getBuilder().cardinality()); @@ -167,7 +168,7 @@ class PackWriterBitmapPreparer { pm.endTask(); int totCommits = selectionHelper.getCommitCount(); - BlockList<BitmapCommit> selections = new BlockList<BitmapCommit>( + BlockList<BitmapCommit> selections = new BlockList<>( totCommits / recentCommitSpan + 1); for (BitmapCommit reuse : selectionHelper.reusedCommits) { selections.add(reuse); @@ -194,7 +195,7 @@ class PackWriterBitmapPreparer { // better compression/on the run-length encoding of the XORs between // them. List<List<BitmapCommit>> chains = - new ArrayList<List<BitmapCommit>>(); + new ArrayList<>(); // Mark the current branch as inactive if its tip commit isn't // recent and there are an excessive number of branches, to @@ -286,7 +287,7 @@ class PackWriterBitmapPreparer { } if (longestAncestorChain == null) { - longestAncestorChain = new ArrayList<BitmapCommit>(); + longestAncestorChain = new ArrayList<>(); chains.add(longestAncestorChain); } longestAncestorChain.add(new BitmapCommit( @@ -375,7 +376,7 @@ class PackWriterBitmapPreparer { int expectedCommitCount) throws IncorrectObjectTypeException, IOException, MissingObjectException { BitmapBuilder reuse = commitBitmapIndex.newBitmapBuilder(); - List<BitmapCommit> reuseCommits = new ArrayList<BitmapCommit>(); + List<BitmapCommit> reuseCommits = new ArrayList<>(); for (PackBitmapIndexRemapper.Entry entry : bitmapRemapper) { // More recent commits did not have the reuse flag set, so skip them if ((entry.getFlags() & FLAG_REUSE) != FLAG_REUSE) { @@ -397,9 +398,9 @@ class PackWriterBitmapPreparer { // Add branch tips that are not represented in old bitmap indices. Set // up the RevWalk to walk the new commits not in the old packs. - List<BitmapBuilderEntry> tipCommitBitmaps = new ArrayList<BitmapBuilderEntry>( + List<BitmapBuilderEntry> tipCommitBitmaps = new ArrayList<>( want.size()); - Set<RevCommit> peeledWant = new HashSet<RevCommit>(want.size()); + Set<RevCommit> peeledWant = new HashSet<>(want.size()); for (AnyObjectId objectId : want) { RevObject ro = rw.peel(rw.parseAny(objectId)); if (!(ro instanceof RevCommit) || reuse.contains(ro)) { @@ -579,20 +580,24 @@ class PackWriterBitmapPreparer { this.reusedCommits = reuse; } + @Override public Iterator<RevCommit> iterator() { // Member variables referenced by this iterator will have synthetic // accessors generated for them if they are made private. return new Iterator<RevCommit>() { int pos = commitStartPos; + @Override public boolean hasNext() { return pos < commitsByOldest.length; } + @Override public RevCommit next() { return commitsByOldest[pos++]; } + @Override public void remove() { throw new UnsupportedOperationException(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java index 11081d59ee..f964bf2b4f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java @@ -159,6 +159,7 @@ public abstract class AnyObjectId implements Comparable<AnyObjectId> { * @return < 0 if this id comes before other; 0 if this id is equal to * other; > 0 if this id comes after other. */ + @Override public final int compareTo(final AnyObjectId other) { if (this == other) return 0; @@ -261,6 +262,7 @@ public abstract class AnyObjectId implements Comparable<AnyObjectId> { return abbr.prefixCompare(this) == 0; } + @Override public final int hashCode() { return w2; } @@ -276,6 +278,7 @@ public abstract class AnyObjectId implements Comparable<AnyObjectId> { return other != null ? equals(this, other) : false; } + @Override public final boolean equals(final Object o) { if (o instanceof AnyObjectId) return equals((AnyObjectId) o); 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 670f9a9e14..de1003bdde 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java @@ -218,7 +218,7 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re public B addAlternateObjectDirectory(File other) { if (other != null) { if (alternateObjectDirectories == null) - alternateObjectDirectories = new LinkedList<File>(); + alternateObjectDirectories = new LinkedList<>(); alternateObjectDirectories.add(other); } return self(); @@ -429,7 +429,7 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re public B addCeilingDirectory(File root) { if (root != null) { if (ceilingDirectories == null) - ceilingDirectories = new LinkedList<File>(); + ceilingDirectories = new LinkedList<>(); ceilingDirectories.add(root); } return self(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java index 653c9f66b6..3f6995de83 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java @@ -120,7 +120,7 @@ public class BatchRefUpdate { */ protected BatchRefUpdate(RefDatabase refdb) { this.refdb = refdb; - this.commands = new ArrayList<ReceiveCommand>(); + this.commands = new ArrayList<>(); this.atomic = refdb.performsAtomicTransactions(); } @@ -400,7 +400,7 @@ public class BatchRefUpdate { } monitor.beginTask(JGitText.get().updatingReferences, commands.size()); - List<ReceiveCommand> commands2 = new ArrayList<ReceiveCommand>( + List<ReceiveCommand> commands2 = new ArrayList<>( commands.size()); // First delete refs. This may free the name space for some of the // updates. @@ -431,7 +431,7 @@ public class BatchRefUpdate { } if (!commands2.isEmpty()) { // What part of the name space is already taken - Collection<String> takenNames = new HashSet<String>(refdb.getRefs( + Collection<String> takenNames = new HashSet<>(refdb.getRefs( RefDatabase.ALL).keySet()); Collection<String> takenPrefixes = getTakenPrefixes(takenNames); @@ -525,7 +525,7 @@ public class BatchRefUpdate { private static Collection<String> getTakenPrefixes( final Collection<String> names) { - Collection<String> ref = new HashSet<String>(); + Collection<String> ref = new HashSet<>(); for (String name : names) ref.addAll(getPrefixes(name)); return ref; @@ -539,7 +539,7 @@ public class BatchRefUpdate { } static Collection<String> getPrefixes(String s) { - Collection<String> ret = new HashSet<String>(); + Collection<String> ret = new HashSet<>(); int p1 = s.indexOf('/'); while (p1 > 0) { ret.add(s.substring(0, p1)); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java index a3859abb23..54c80522b8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java @@ -68,10 +68,12 @@ public abstract class BatchingProgressMonitor implements ProgressMonitor { delayStartUnit = unit; } + @Override public void start(int totalTasks) { // Ignore the number of tasks. } + @Override public void beginTask(String title, int work) { endTask(); task = new Task(title, work); @@ -79,11 +81,13 @@ public abstract class BatchingProgressMonitor implements ProgressMonitor { task.delay(delayStartTime, delayStartUnit); } + @Override public void update(int completed) { if (task != null) task.update(this, completed); } + @Override public void endTask() { if (task != null) { task.end(this); @@ -91,6 +95,7 @@ public abstract class BatchingProgressMonitor implements ProgressMonitor { } } + @Override public boolean isCancelled() { return false; } @@ -178,6 +183,7 @@ public abstract class BatchingProgressMonitor implements ProgressMonitor { timerFuture = WorkQueue.getExecutor().schedule(this, time, unit); } + @Override public void run() { display = true; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java index 9ddff25480..00f42a49a5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java @@ -108,6 +108,7 @@ public interface BitmapIndex { * * @return an Iterator. */ + @Override Iterator<BitmapObject> iterator(); } @@ -166,6 +167,7 @@ public interface BitmapIndex { * the other bitmap * @return the current builder. */ + @Override BitmapBuilder or(Bitmap other); /** @@ -176,6 +178,7 @@ public interface BitmapIndex { * the other bitmap * @return the current builder. */ + @Override BitmapBuilder andNot(Bitmap other); /** @@ -185,6 +188,7 @@ public interface BitmapIndex { * the other bitmap * @return the current builder. */ + @Override BitmapBuilder xor(Bitmap other); /** @return the fully built immutable bitmap */ 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..f45c71cf95 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; @@ -121,7 +122,7 @@ public class Config { */ public Config(Config defaultConfig) { baseConfig = defaultConfig; - state = new AtomicReference<ConfigSnapshot>(newState()); + state = new AtomicReference<>(newState()); } /** @@ -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); } @@ -959,7 +960,7 @@ public class Config { final String section, final String subsection) { final int max = srcState.entryList.size(); - final ArrayList<ConfigLine> r = new ArrayList<ConfigLine>(max); + final ArrayList<ConfigLine> r = new ArrayList<>(max); boolean lastWasMatch = false; for (ConfigLine e : srcState.entryList) { @@ -1074,7 +1075,7 @@ public class Config { // for a new section header. Assume that and allocate the space. // final int max = src.entryList.size() + values.size() + 1; - final ArrayList<ConfigLine> r = new ArrayList<ConfigLine>(max); + final ArrayList<ConfigLine> r = new ArrayList<>(max); r.addAll(src.entryList); return r; } @@ -1162,7 +1163,7 @@ public class Config { throw new ConfigInvalidException( JGitText.get().tooManyIncludeRecursions); } - final List<ConfigLine> newEntries = new ArrayList<ConfigLine>(); + final List<ConfigLine> newEntries = new ArrayList<>(); final StringReader in = new StringReader(text); ConfigLine last = null; ConfigLine e = new ConfigLine(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java index cde41c2124..74fc7067a1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java @@ -374,4 +374,16 @@ public class ConfigConstants { * @since 4.6 */ public static final String CONFIG_KEY_USEJGITBUILTIN = "useJGitBuiltin"; + + /** + * The "fetchRecurseSubmodules" key + * @since 4.7 + */ + public static final String CONFIG_KEY_FETCH_RECURSE_SUBMODULES = "fetchRecurseSubmodules"; + + /** + * The "recurseSubmodules" key + * @since 4.7 + */ + public static final String CONFIG_KEY_RECURSE_SUBMODULES = "recurseSubmodules"; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigSnapshot.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigSnapshot.java index 5ed129ed02..f5ada13a38 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigSnapshot.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigSnapshot.java @@ -78,7 +78,7 @@ class ConfigSnapshot { ConfigSnapshot(List<ConfigLine> entries, ConfigSnapshot base) { entryList = entries; - cache = new ConcurrentHashMap<Object, Object>(16, 0.75f, 1); + cache = new ConcurrentHashMap<>(16, 0.75f, 1); baseState = base; } @@ -112,7 +112,7 @@ class ConfigSnapshot { if (idx < 0) idx = -(idx + 1); - Map<String, String> m = new LinkedHashMap<String, String>(); + Map<String, String> m = new LinkedHashMap<>(); while (idx < s.size()) { ConfigLine e = s.get(idx++); if (!e.match(section, subsection)) @@ -187,7 +187,7 @@ class ConfigSnapshot { } private static List<ConfigLine> sort(List<ConfigLine> in) { - List<ConfigLine> sorted = new ArrayList<ConfigLine>(in.size()); + List<ConfigLine> sorted = new ArrayList<>(in.size()); for (ConfigLine line : in) { if (line.section != null && line.name != null) sorted.add(line); @@ -217,6 +217,7 @@ class ConfigSnapshot { } private static class LineComparator implements Comparator<ConfigLine> { + @Override public int compare(ConfigLine a, ConfigLine b) { return compare2( a.section, a.subsection, a.name, @@ -236,8 +237,8 @@ class ConfigSnapshot { final Map<String, Set<String>> subsections; SectionNames(ConfigSnapshot cfg) { - Map<String, String> sec = new LinkedHashMap<String, String>(); - Map<String, Set<String>> sub = new HashMap<String, Set<String>>(); + Map<String, String> sec = new LinkedHashMap<>(); + Map<String, Set<String>> sub = new HashMap<>(); while (cfg != null) { for (ConfigLine e : cfg.entryList) { if (e.section == null) @@ -252,7 +253,7 @@ class ConfigSnapshot { Set<String> m = sub.get(l1); if (m == null) { - m = new LinkedHashSet<String>(); + m = new LinkedHashSet<>(); sub.put(l1, m); } m.add(e.subsection); @@ -286,14 +287,17 @@ class ConfigSnapshot { public Iterator<String> iterator() { final Iterator<String> i = names.values().iterator(); return new Iterator<String>() { + @Override public boolean hasNext() { return i.hasNext(); } + @Override public String next() { return i.next(); } + @Override public void remove() { throw new UnsupportedOperationException(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java index 83efd43aa0..40aba636d1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java @@ -58,6 +58,7 @@ import org.eclipse.jgit.lib.Config.SectionParser; public class CoreConfig { /** Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<CoreConfig> KEY = new SectionParser<CoreConfig>() { + @Override public CoreConfig parse(final Config cfg) { return new CoreConfig(cfg); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java index eabcbbf632..c236c35f3c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java @@ -51,22 +51,27 @@ package org.eclipse.jgit.lib; */ public abstract class EmptyProgressMonitor implements ProgressMonitor { + @Override public void start(int totalTasks) { // empty } + @Override public void beginTask(String title, int totalWork) { // empty } + @Override public void update(int completed) { // empty } + @Override public void endTask() { // empty } + @Override public boolean isCancelled() { return false; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java index f295f5b72f..a489461f84 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java @@ -86,6 +86,7 @@ public abstract class FileMode { @SuppressWarnings("synthetic-access") public static final FileMode TREE = new FileMode(TYPE_TREE, Constants.OBJ_TREE) { + @Override public boolean equals(final int modeBits) { return (modeBits & TYPE_MASK) == TYPE_TREE; } @@ -95,6 +96,7 @@ public abstract class FileMode { @SuppressWarnings("synthetic-access") public static final FileMode SYMLINK = new FileMode(TYPE_SYMLINK, Constants.OBJ_BLOB) { + @Override public boolean equals(final int modeBits) { return (modeBits & TYPE_MASK) == TYPE_SYMLINK; } @@ -104,6 +106,7 @@ public abstract class FileMode { @SuppressWarnings("synthetic-access") public static final FileMode REGULAR_FILE = new FileMode(0100644, Constants.OBJ_BLOB) { + @Override public boolean equals(final int modeBits) { return (modeBits & TYPE_MASK) == TYPE_FILE && (modeBits & 0111) == 0; } @@ -113,6 +116,7 @@ public abstract class FileMode { @SuppressWarnings("synthetic-access") public static final FileMode EXECUTABLE_FILE = new FileMode(0100755, Constants.OBJ_BLOB) { + @Override public boolean equals(final int modeBits) { return (modeBits & TYPE_MASK) == TYPE_FILE && (modeBits & 0111) != 0; } @@ -122,6 +126,7 @@ public abstract class FileMode { @SuppressWarnings("synthetic-access") public static final FileMode GITLINK = new FileMode(TYPE_GITLINK, Constants.OBJ_COMMIT) { + @Override public boolean equals(final int modeBits) { return (modeBits & TYPE_MASK) == TYPE_GITLINK; } @@ -131,6 +136,7 @@ public abstract class FileMode { @SuppressWarnings("synthetic-access") public static final FileMode MISSING = new FileMode(TYPE_MISSING, Constants.OBJ_BAD) { + @Override public boolean equals(final int modeBits) { return modeBits == 0; } @@ -258,6 +264,7 @@ public abstract class FileMode { } /** Format this mode as an octal string (for debugging only). */ + @Override public String toString() { return Integer.toOctalString(modeBits); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java index af6a4fb919..e544b72a85 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java @@ -253,19 +253,19 @@ public class IndexDiff { private final WorkingTreeIterator initialWorkingTreeIterator; - private Set<String> added = new HashSet<String>(); + private Set<String> added = new HashSet<>(); - private Set<String> changed = new HashSet<String>(); + private Set<String> changed = new HashSet<>(); - private Set<String> removed = new HashSet<String>(); + private Set<String> removed = new HashSet<>(); - private Set<String> missing = new HashSet<String>(); + private Set<String> missing = new HashSet<>(); - private Set<String> modified = new HashSet<String>(); + private Set<String> modified = new HashSet<>(); - private Set<String> untracked = new HashSet<String>(); + private Set<String> untracked = new HashSet<>(); - private Map<String, StageState> conflicts = new HashMap<String, StageState>(); + private Map<String, StageState> conflicts = new HashMap<>(); private Set<String> ignored; @@ -275,11 +275,11 @@ public class IndexDiff { private IndexDiffFilter indexDiffFilter; - private Map<String, IndexDiff> submoduleIndexDiffs = new HashMap<String, IndexDiff>(); + private Map<String, IndexDiff> submoduleIndexDiffs = new HashMap<>(); private IgnoreSubmoduleMode ignoreSubmoduleMode = null; - private Map<FileMode, Set<String>> fileModes = new HashMap<FileMode, Set<String>>(); + private Map<FileMode, Set<String>> fileModes = new HashMap<>(); /** * Construct an IndexDiff @@ -342,6 +342,7 @@ public class IndexDiff { } private WorkingTreeIteratorFactory wTreeIt = new WorkingTreeIteratorFactory() { + @Override public WorkingTreeIterator getWorkingTreeIterator(Repository repo) { return new FileTreeIterator(repo); } @@ -416,7 +417,7 @@ public class IndexDiff { treeWalk.addTree(new DirCacheIterator(dirCache)); treeWalk.addTree(initialWorkingTreeIterator); initialWorkingTreeIterator.setDirCacheIterator(treeWalk, 1); - Collection<TreeFilter> filters = new ArrayList<TreeFilter>(4); + Collection<TreeFilter> filters = new ArrayList<>(4); if (monitor != null) { // Get the maximum size of the work tree and index @@ -517,7 +518,7 @@ public class IndexDiff { String path = treeWalk.getPathString(); if (path != null) { if (values == null) - values = new HashSet<String>(); + values = new HashSet<>(); values.add(path); fileModes.put(treeWalk.getFileMode(i), values); } @@ -686,7 +687,7 @@ public class IndexDiff { */ public Set<String> getAssumeUnchanged() { if (assumeUnchanged == null) { - HashSet<String> unchanged = new HashSet<String>(); + HashSet<String> unchanged = new HashSet<>(); for (int i = 0; i < dirCache.getEntryCount(); i++) if (dirCache.getEntry(i).isAssumeValid()) unchanged.add(dirCache.getEntry(i).getPathString()); @@ -700,7 +701,7 @@ public class IndexDiff { */ public Set<String> getUntrackedFolders() { return ((indexDiffFilter == null) ? Collections.<String> emptySet() - : new HashSet<String>(indexDiffFilter.getUntrackedFolders())); + : new HashSet<>(indexDiffFilter.getUntrackedFolders())); } /** @@ -726,7 +727,7 @@ public class IndexDiff { public Set<String> getPathsWithIndexMode(final FileMode mode) { Set<String> paths = fileModes.get(mode); if (paths == null) - paths = new HashSet<String>(); + paths = new HashSet<>(); return paths; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java index 1a49ae9d78..4b14d121e0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java @@ -209,6 +209,24 @@ public class MutableObjectId extends AnyObjectId { } /** + * Convert an ObjectId from binary representation expressed in integers. + * + * @param a + * @param b + * @param c + * @param d + * @param e + * @since 4.7 + */ + public void set(int a, int b, int c, int d, int e) { + w1 = a; + w2 = b; + w3 = c; + w4 = d; + w5 = e; + } + + /** * Convert an ObjectId from hex characters (US-ASCII). * * @param buf diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java index d05c8c6b01..497beb033a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java @@ -56,22 +56,27 @@ public class NullProgressMonitor implements ProgressMonitor { // Do not let others instantiate } + @Override public void start(int totalTasks) { // Do not report. } + @Override public void beginTask(String title, int totalWork) { // Do not report. } + @Override public void update(int completed) { // Do not report. } + @Override public boolean isCancelled() { return false; } + @Override public void endTask() { // Do not report. } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java index feecbd81c0..9d3aee1508 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java @@ -611,7 +611,7 @@ public class ObjectChecker { int ptr = 0; int lastNameB = 0, lastNameE = 0, lastMode = 0; Set<String> normalized = windows || macosx - ? new HashSet<String>() + ? new HashSet<>() : null; while (ptr < sz) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java index 2a2d67d25a..991f03f82e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java @@ -248,8 +248,17 @@ public class ObjectId extends AnyObjectId implements Serializable { } } - ObjectId(final int new_1, final int new_2, final int new_3, - final int new_4, final int new_5) { + /** + * Construct an ObjectId from 160 bits provided in 5 words. + * + * @param new_1 + * @param new_2 + * @param new_3 + * @param new_4 + * @param new_5 + * @since 4.7 + */ + public ObjectId(int new_1, int new_2, int new_3, int new_4, int new_5) { w1 = new_1; w2 = new_2; w3 = new_3; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java index c286f5e463..636716bcb3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java @@ -67,11 +67,13 @@ public abstract class ObjectIdRef implements Ref { super(st, name, id); } + @Override @Nullable public ObjectId getPeeledObjectId() { return null; } + @Override public boolean isPeeled() { return false; } @@ -99,11 +101,13 @@ public abstract class ObjectIdRef implements Ref { peeledObjectId = p; } + @Override @NonNull public ObjectId getPeeledObjectId() { return peeledObjectId; } + @Override public boolean isPeeled() { return true; } @@ -127,11 +131,13 @@ public abstract class ObjectIdRef implements Ref { super(st, name, id); } + @Override @Nullable public ObjectId getPeeledObjectId() { return null; } + @Override public boolean isPeeled() { return true; } @@ -161,30 +167,36 @@ public abstract class ObjectIdRef implements Ref { this.objectId = id; } + @Override @NonNull public String getName() { return name; } + @Override public boolean isSymbolic() { return false; } + @Override @NonNull public Ref getLeaf() { return this; } + @Override @NonNull public Ref getTarget() { return this; } + @Override @Nullable public ObjectId getObjectId() { return objectId; } + @Override @NonNull public Storage getStorage() { return storage; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java index faed64bfe7..43fc7bfb97 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java @@ -111,6 +111,7 @@ public class ObjectIdSubclassMap<V extends ObjectId> * object to find. * @return true if the mapping exists for this object; false otherwise. */ + @Override public boolean contains(final AnyObjectId toFind) { return get(toFind) != null; } @@ -187,16 +188,19 @@ public class ObjectIdSubclassMap<V extends ObjectId> return size == 0; } + @Override public Iterator<V> iterator() { return new Iterator<V>() { private int found; private int i; + @Override public boolean hasNext() { return found < size; } + @Override public V next() { while (i < table.length) { final V v = table[i++]; @@ -208,6 +212,7 @@ public class ObjectIdSubclassMap<V extends ObjectId> throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java index 4c51279d05..857ec9b2df 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java @@ -50,10 +50,10 @@ import java.io.ByteArrayInputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; -import java.security.MessageDigest; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.transport.PackParser; +import org.eclipse.jgit.util.sha1.SHA1; /** * Inserts objects into an existing {@code ObjectDatabase}. @@ -107,41 +107,50 @@ public abstract class ObjectInserter implements AutoCloseable { return delegate().buffer(); } + @Override public ObjectId idFor(int type, byte[] data) { return delegate().idFor(type, data); } + @Override public ObjectId idFor(int type, byte[] data, int off, int len) { return delegate().idFor(type, data, off, len); } + @Override public ObjectId idFor(int objectType, long length, InputStream in) throws IOException { return delegate().idFor(objectType, length, in); } + @Override public ObjectId idFor(TreeFormatter formatter) { return delegate().idFor(formatter); } + @Override public ObjectId insert(int type, byte[] data) throws IOException { return delegate().insert(type, data); } + @Override public ObjectId insert(int type, byte[] data, int off, int len) throws IOException { return delegate().insert(type, data, off, len); } + @Override public ObjectId insert(int objectType, long length, InputStream in) throws IOException { return delegate().insert(objectType, length, in); } + @Override public PackParser newPackParser(InputStream in) throws IOException { return delegate().newPackParser(in); } + @Override public ObjectReader newReader() { final ObjectReader dr = delegate().newReader(); return new ObjectReader.Filter() { @@ -157,24 +166,24 @@ public abstract class ObjectInserter implements AutoCloseable { }; } + @Override public void flush() throws IOException { delegate().flush(); } + @Override public void close() { delegate().close(); } } - /** Digest to compute the name of an object. */ - private final MessageDigest digest; + private final SHA1 hasher = SHA1.newInstance(); /** Temporary working buffer for streaming data through. */ private byte[] tempBuffer; /** Create a new inserter for a database. */ protected ObjectInserter() { - digest = Constants.newMessageDigest(); } /** @@ -208,10 +217,12 @@ public abstract class ObjectInserter implements AutoCloseable { return b; } - /** @return digest to help compute an ObjectId */ - protected MessageDigest digest() { - digest.reset(); - return digest; + /** + * @return digest to help compute an ObjectId + * @since 4.7 + */ + protected SHA1 digest() { + return hasher.reset(); } /** @@ -241,13 +252,13 @@ public abstract class ObjectInserter implements AutoCloseable { * @return the name of the object. */ public ObjectId idFor(int type, byte[] data, int off, int len) { - MessageDigest md = digest(); + SHA1 md = SHA1.newInstance(); md.update(Constants.encodedTypeString(type)); md.update((byte) ' '); md.update(Constants.encodeASCII(len)); md.update((byte) 0); md.update(data, off, len); - return ObjectId.fromRaw(md.digest()); + return md.toObjectId(); } /** @@ -266,7 +277,7 @@ public abstract class ObjectInserter implements AutoCloseable { */ public ObjectId idFor(int objectType, long length, InputStream in) throws IOException { - MessageDigest md = digest(); + SHA1 md = SHA1.newInstance(); md.update(Constants.encodedTypeString(objectType)); md.update((byte) ' '); md.update(Constants.encodeASCII(length)); @@ -279,7 +290,7 @@ public abstract class ObjectInserter implements AutoCloseable { md.update(buf, 0, n); length -= n; } - return ObjectId.fromRaw(md.digest()); + return md.toObjectId(); } /** 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 372da98939..f39f291899 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java @@ -134,7 +134,7 @@ public abstract class ObjectReader implements AutoCloseable { Collection<ObjectId> matches = resolve(abbrev); while (1 < matches.size() && len < Constants.OBJECT_ID_STRING_LENGTH) { abbrev = objectId.abbreviate(++len); - List<ObjectId> n = new ArrayList<ObjectId>(8); + List<ObjectId> n = new ArrayList<>(8); for (ObjectId candidate : matches) { if (abbrev.prefixCompare(candidate) == 0) n.add(candidate); @@ -286,6 +286,7 @@ public abstract class ObjectReader implements AutoCloseable { return new AsyncObjectLoaderQueue<T>() { private T cur; + @Override public boolean next() throws MissingObjectException, IOException { if (idItr.hasNext()) { cur = idItr.next(); @@ -295,22 +296,27 @@ public abstract class ObjectReader implements AutoCloseable { } } + @Override public T getCurrent() { return cur; } + @Override public ObjectId getObjectId() { return cur; } + @Override public ObjectLoader open() throws IOException { return ObjectReader.this.open(cur, OBJ_ANY); } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return true; } + @Override public void release() { // Since we are sequential by default, we don't // have any state to clean up if we terminate early. @@ -370,6 +376,7 @@ public abstract class ObjectReader implements AutoCloseable { private long sz; + @Override public boolean next() throws MissingObjectException, IOException { if (idItr.hasNext()) { cur = idItr.next(); @@ -380,22 +387,27 @@ public abstract class ObjectReader implements AutoCloseable { } } + @Override public T getCurrent() { return cur; } + @Override public ObjectId getObjectId() { return cur; } + @Override public long getSize() { return sz; } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return true; } + @Override public void release() { // Since we are sequential by default, we don't // have any state to clean up if we terminate early. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java index 627ccaa206..45757e42f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java @@ -336,6 +336,7 @@ public class PersonIdent implements Serializable { /** * Hashcode is based only on the email address and timestamp. */ + @Override public int hashCode() { int hc = getEmailAddress().hashCode(); hc *= 31; @@ -343,6 +344,7 @@ public class PersonIdent implements Serializable { return hc; } + @Override public boolean equals(final Object o) { if (o instanceof PersonIdent) { final PersonIdent p = (PersonIdent) o; @@ -370,6 +372,7 @@ public class PersonIdent implements Serializable { return r.toString(); } + @Override @SuppressWarnings("nls") public String toString() { final StringBuilder r = new StringBuilder(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java index 75a3592213..1047a6df99 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java @@ -89,7 +89,7 @@ public class RebaseTodoFile { byte[] buf = IO.readFully(new File(repo.getDirectory(), path)); int ptr = 0; int tokenBegin = 0; - List<RebaseTodoLine> r = new LinkedList<RebaseTodoLine>(); + List<RebaseTodoLine> r = new LinkedList<>(); while (ptr < buf.length) { tokenBegin = ptr; ptr = RawParseUtils.nextLF(buf, ptr); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java index c6e10299ef..95e338685a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java @@ -60,6 +60,7 @@ public class RefComparator implements Comparator<Ref> { /** Singleton instance of RefComparator */ public static final RefComparator INSTANCE = new RefComparator(); + @Override public int compare(final Ref o1, final Ref o2) { return compareTo(o1, o2); } @@ -72,7 +73,7 @@ public class RefComparator implements Comparator<Ref> { * @return sorted collection of refs */ public static Collection<Ref> sort(final Collection<Ref> refs) { - final List<Ref> r = new ArrayList<Ref>(refs); + final List<Ref> r = new ArrayList<>(refs); Collections.sort(r, INSTANCE); return r; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java index 517c8aa538..59a104b60f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java @@ -150,7 +150,7 @@ public abstract class RefDatabase { lastSlash = name.lastIndexOf('/', lastSlash - 1); } - List<String> conflicting = new ArrayList<String>(); + List<String> conflicting = new ArrayList<>(); // Cannot be the container of an existing reference. String prefix = name + '/'; for (String existing : allRefs.keySet()) 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..ea37e79381 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 @@ -65,6 +66,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import java.util.regex.Pattern; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; @@ -110,6 +112,17 @@ public abstract class Repository implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(Repository.class); private static final ListenerList globalListeners = new ListenerList(); + /** + * Branch names containing slashes should not have a name component that is + * one of the reserved device names on Windows. + * + * @see #normalizeBranchName(String) + */ + private static final Pattern FORBIDDEN_BRANCH_NAME_COMPONENTS = Pattern + .compile( + "(^|/)(aux|com[1-9]|con|lpt[1-9]|nul|prn)(\\.[^/]*)?", //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + /** @return the global listener list observing all events in this JVM. */ public static ListenerList getGlobalListenerList() { return globalListeners; @@ -888,11 +901,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()); @@ -910,7 +924,6 @@ public abstract class Repository implements AutoCloseable { getRefDatabase().close(); } - @SuppressWarnings("nls") @Override @NonNull public String toString() { @@ -921,7 +934,7 @@ public abstract class Repository implements AutoCloseable { else desc = getClass().getSimpleName() + "-" //$NON-NLS-1$ + System.identityHashCode(this); - return "Repository[" + desc + "]"; //$NON-NLS-1$ + return "Repository[" + desc + "]"; //$NON-NLS-1$ //$NON-NLS-2$ } /** @@ -1051,7 +1064,7 @@ public abstract class Repository implements AutoCloseable { try { return getRefDatabase().getRefs(RefDatabase.ALL); } catch (IOException e) { - return new HashMap<String, Ref>(); + return new HashMap<>(); } } @@ -1065,7 +1078,7 @@ public abstract class Repository implements AutoCloseable { try { return getRefDatabase().getRefs(Constants.R_TAGS); } catch (IOException e) { - return new HashMap<String, Ref>(); + return new HashMap<>(); } } @@ -1100,7 +1113,7 @@ public abstract class Repository implements AutoCloseable { @NonNull public Map<AnyObjectId, Set<Ref>> getAllRefsByPeeledObjectId() { Map<String, Ref> allRefs = getAllRefs(); - Map<AnyObjectId, Set<Ref>> ret = new HashMap<AnyObjectId, Set<Ref>>(allRefs.size()); + Map<AnyObjectId, Set<Ref>> ret = new HashMap<>(allRefs.size()); for (Ref ref : allRefs.values()) { ref = peel(ref); AnyObjectId target = ref.getPeeledObjectId(); @@ -1112,7 +1125,7 @@ public abstract class Repository implements AutoCloseable { // that was not the case (rare) if (oset.size() == 1) { // Was a read-only singleton, we must copy to a new Set - oset = new HashSet<Ref>(oset); + oset = new HashSet<>(oset); } ret.put(target, oset); oset.add(ref); @@ -1331,12 +1344,105 @@ public abstract class Repository implements AutoCloseable { } /** + * 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 the trimmed input string if this is + * already a valid branch name. Otherwise it returns a trimmed string with + * special characters not allowed by {@link #isValidRefName(String)} + * replaced by hyphens ('-') and blanks replaced by underscores ('_'). + * Leading and trailing slashes, dots, hyphens, and underscores are removed. + * + * @param name + * to normalize + * + * @return The normalized name or an empty String if it is {@code null} or + * empty. + * @since 4.7 + * @see #isValidRefName(String) + */ + public static String normalizeBranchName(String name) { + if (name == null || name.isEmpty()) { + return ""; //$NON-NLS-1$ + } + String result = name.trim(); + String fullName = result.startsWith(Constants.R_HEADS) ? result + : Constants.R_HEADS + result; + if (isValidRefName(fullName)) { + return result; + } + + // All Unicode blanks to underscore + result = result.replaceAll("(?:\\h|\\v)+", "_"); //$NON-NLS-1$ //$NON-NLS-2$ + StringBuilder b = new StringBuilder(); + char p = '/'; + for (int i = 0, len = result.length(); i < len; i++) { + char c = result.charAt(i); + if (c < ' ' || c == 127) { + continue; + } + // Substitute a dash for problematic characters + switch (c) { + case '\\': + case '^': + case '~': + case ':': + case '?': + case '*': + case '[': + case '@': + case '<': + case '>': + case '|': + case '"': + c = '-'; + break; + default: + break; + } + // Collapse multiple slashes, dashes, dots, underscores, and omit + // dashes, dots, and underscores following a slash. + switch (c) { + case '/': + if (p == '/') { + continue; + } + p = '/'; + break; + case '.': + case '_': + case '-': + if (p == '/' || p == '-') { + continue; + } + p = '-'; + break; + default: + p = c; + break; + } + b.append(c); + } + // Strip trailing special characters, and avoid the .lock extension + result = b.toString().replaceFirst("[/_.-]+$", "") //$NON-NLS-1$ //$NON-NLS-2$ + .replaceAll("\\.lock($|/)", "_lock$1"); //$NON-NLS-1$ //$NON-NLS-2$ + return FORBIDDEN_BRANCH_NAME_COMPONENTS.matcher(result) + .replaceAll("$1+$2$3"); //$NON-NLS-1$ + } + + /** * Strip work dir and return normalized repository path. * - * @param workDir Work dir - * @param file File whose path shall be stripped of its workdir - * @return normalized repository relative path or the empty - * string if the file is not relative to the work directory. + * @param workDir + * Work dir + * @param file + * File whose path shall be stripped of its workdir + * @return normalized repository relative path or the empty string if the + * file is not relative to the work directory. */ @NonNull public static String stripWorkDir(File workDir, File file) { @@ -1574,7 +1680,7 @@ public abstract class Repository implements AutoCloseable { if (raw == null) return null; - LinkedList<ObjectId> heads = new LinkedList<ObjectId>(); + LinkedList<ObjectId> heads = new LinkedList<>(); for (int p = 0; p < raw.length;) { heads.add(ObjectId.fromString(raw, p)); p = RawParseUtils 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 2f1a9e1cda..baa5286862 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java @@ -300,7 +300,7 @@ public class RepositoryCache { } private Collection<Key> getKeys() { - return new ArrayList<Key>(cacheMap.keySet()); + return new ArrayList<>(cacheMap.keySet()); } private void clearAllExpired() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/SubmoduleConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SubmoduleConfig.java new file mode 100644 index 0000000000..3126160c33 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SubmoduleConfig.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2017, David Pursehouse <david.pursehouse@gmail.com> + * 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.lib; + +/** + * Submodule section of a Git configuration file. + * + * @since 4.7 + */ +public class SubmoduleConfig { + + /** + * Config values for submodule.[name].fetchRecurseSubmodules. + */ + public enum FetchRecurseSubmodulesMode implements Config.ConfigEnum { + /** Unconditionally recurse into all populated submodules. */ + YES("true"), //$NON-NLS-1$ + + /** + * Only recurse into a populated submodule when the superproject + * retrieves a commit that updates the submodule's reference to a commit + * that isn't already in the local submodule clone. + */ + ON_DEMAND("on-demand"), //$NON-NLS-1$ + + /** Completely disable recursion. */ + NO("false"); //$NON-NLS-1$ + + private final String configValue; + + private FetchRecurseSubmodulesMode(String configValue) { + this.configValue = configValue; + } + + @Override + public String toConfigValue() { + return configValue; + } + + @Override + public boolean matchConfigValue(String s) { + return configValue.equals(s); + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java index eeab921a7a..71d5cd7ac1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java @@ -70,15 +70,18 @@ public class SymbolicRef implements Ref { this.target = target; } + @Override @NonNull public String getName() { return name; } + @Override public boolean isSymbolic() { return true; } + @Override @NonNull public Ref getLeaf() { Ref dst = getTarget(); @@ -87,26 +90,31 @@ public class SymbolicRef implements Ref { return dst; } + @Override @NonNull public Ref getTarget() { return target; } + @Override @Nullable public ObjectId getObjectId() { return getLeaf().getObjectId(); } + @Override @NonNull public Storage getStorage() { return Storage.LOOSE; } + @Override @Nullable public ObjectId getPeeledObjectId() { return getLeaf().getPeeledObjectId(); } + @Override public boolean isPeeled() { return getLeaf().isPeeled(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java index ff85f9b8fd..5824a55ff1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java @@ -87,12 +87,14 @@ public class ThreadSafeProgressMonitor implements ProgressMonitor { this.process = new Semaphore(0); } + @Override public void start(int totalTasks) { if (!isMainThread()) throw new IllegalStateException(); pm.start(totalTasks); } + @Override public void beginTask(String title, int totalWork) { if (!isMainThread()) throw new IllegalStateException(); @@ -156,11 +158,13 @@ public class ThreadSafeProgressMonitor implements ProgressMonitor { pm.update(cnt); } + @Override public void update(int completed) { if (0 == pendingUpdates.getAndAdd(completed)) process.release(); } + @Override public boolean isCancelled() { lock.lock(); try { @@ -170,6 +174,7 @@ public class ThreadSafeProgressMonitor implements ProgressMonitor { } } + @Override public void endTask() { if (!isMainThread()) throw new IllegalStateException(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/UserConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/UserConfig.java index b8d236c1da..bd393dd2ff 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/UserConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/UserConfig.java @@ -52,6 +52,7 @@ import org.eclipse.jgit.util.SystemReader; public class UserConfig { /** Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<UserConfig> KEY = new SectionParser<UserConfig>() { + @Override public UserConfig parse(final Config cfg) { return new UserConfig(cfg); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java index 9735d19e5e..07b87f58d2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java @@ -67,6 +67,7 @@ class WorkQueue { private final ThreadFactory baseFactory = Executors .defaultThreadFactory(); + @Override public Thread newThread(Runnable taskBody) { Thread thr = baseFactory.newThread(taskBody); thr.setName("JGit-WorkQueue"); //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java index 112550a1de..04c65effb8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java @@ -98,11 +98,11 @@ public final class MergeAlgorithm { */ public <S extends Sequence> MergeResult<S> merge( SequenceComparator<S> cmp, S base, S ours, S theirs) { - List<S> sequences = new ArrayList<S>(3); + List<S> sequences = new ArrayList<>(3); sequences.add(base); sequences.add(ours); sequences.add(theirs); - MergeResult<S> result = new MergeResult<S>(sequences); + MergeResult<S> result = new MergeResult<>(sequences); if (ours.size() == 0) { if (theirs.size() != 0) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java index 83b143b90d..d059391826 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java @@ -167,6 +167,7 @@ public class MergeConfig { this.branch = branch; } + @Override public MergeConfig parse(Config cfg) { return new MergeConfig(branch, cfg); } 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 ee6095aa71..43876a6227 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java @@ -105,7 +105,7 @@ public class MergeFormatter { @SuppressWarnings("unchecked") public void formatMerge(OutputStream out, MergeResult res, String baseName, String oursName, String theirsName, String charsetName) throws IOException { - List<String> names = new ArrayList<String>(3); + List<String> names = new ArrayList<>(3); names.add(baseName); names.add(oursName); names.add(theirsName); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeMessageFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeMessageFormatter.java index 82cbf368c7..ca0e18a0ef 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeMessageFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeMessageFormatter.java @@ -71,11 +71,11 @@ public class MergeMessageFormatter { StringBuilder sb = new StringBuilder(); sb.append("Merge "); //$NON-NLS-1$ - List<String> branches = new ArrayList<String>(); - List<String> remoteBranches = new ArrayList<String>(); - List<String> tags = new ArrayList<String>(); - List<String> commits = new ArrayList<String>(); - List<String> others = new ArrayList<String>(); + List<String> branches = new ArrayList<>(); + List<String> remoteBranches = new ArrayList<>(); + List<String> tags = new ArrayList<>(); + List<String> commits = new ArrayList<>(); + List<String> others = new ArrayList<>(); for (Ref ref : refsToMerge) { if (ref.getName().startsWith(Constants.R_HEADS)) { branches.add("'" + Repository.shortenRefName(ref.getName()) //$NON-NLS-1$ @@ -95,7 +95,7 @@ public class MergeMessageFormatter { } } - List<String> listings = new ArrayList<String>(); + List<String> listings = new ArrayList<>(); if (!branches.isEmpty()) listings.add(joinNames(branches, "branch", "branches")); //$NON-NLS-1$//$NON-NLS-2$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java index 106f9c7796..ff3c8ab172 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java @@ -133,14 +133,17 @@ public class MergeResult<S extends Sequence> implements Iterable<MergeChunk> { * @return an iterator over the MergeChunks. The iterator does not support * the remove operation */ + @Override public Iterator<MergeChunk> iterator() { return new Iterator<MergeChunk>() { int idx; + @Override public boolean hasNext() { return (idx < chunks.size()); } + @Override public MergeChunk next() { ConflictState state = states[chunks.get(idx++)]; int srcIdx = chunks.get(idx++); @@ -149,6 +152,7 @@ public class MergeResult<S extends Sequence> implements Iterable<MergeChunk> { return new MergeChunk(srcIdx, begin, end, state); } + @Override public void remove() { throw new UnsupportedOperationException(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeStrategy.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeStrategy.java index c5e615ed87..656480e468 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeStrategy.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeStrategy.java @@ -80,7 +80,7 @@ public abstract class MergeStrategy { */ public static final ThreeWayMergeStrategy RECURSIVE = new StrategyRecursive(); - private static final HashMap<String, MergeStrategy> STRATEGIES = new HashMap<String, MergeStrategy>(); + private static final HashMap<String, MergeStrategy> STRATEGIES = new HashMap<>(); static { register(OURS); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java index e0556447ce..f8e1998ed7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java @@ -147,7 +147,7 @@ public class RecursiveMerger extends ResolveMerger { */ protected RevCommit getBaseCommit(RevCommit a, RevCommit b, int callDepth) throws IOException { - ArrayList<RevCommit> baseCommits = new ArrayList<RevCommit>(); + ArrayList<RevCommit> baseCommits = new ArrayList<>(); walk.reset(); walk.setRevFilter(RevFilter.MERGE_BASE); walk.markStart(a); @@ -181,7 +181,7 @@ public class RecursiveMerger extends ResolveMerger { dircache = DirCache.read(reader, currentBase.getTree()); inCore = true; - List<RevCommit> parents = new ArrayList<RevCommit>(); + List<RevCommit> parents = new ArrayList<>(); parents.add(currentBase); for (int commitIdx = 1; commitIdx < baseCommits.size(); commitIdx++) { RevCommit nextBase = baseCommits.get(commitIdx); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java index fd5e7ef7ba..f667af278a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java @@ -180,14 +180,14 @@ public class ResolveMerger extends ThreeWayMerger { * * @since 3.4 */ - protected List<String> unmergedPaths = new ArrayList<String>(); + protected List<String> unmergedPaths = new ArrayList<>(); /** * Files modified during this merge operation. * * @since 3.4 */ - protected List<String> modifiedFiles = new LinkedList<String>(); + protected List<String> modifiedFiles = new LinkedList<>(); /** * If the merger has nothing to do for a file but check it out at the end of @@ -195,7 +195,7 @@ public class ResolveMerger extends ThreeWayMerger { * * @since 3.4 */ - protected Map<String, DirCacheEntry> toBeCheckedOut = new HashMap<String, DirCacheEntry>(); + protected Map<String, DirCacheEntry> toBeCheckedOut = new HashMap<>(); /** * Paths in this list will be deleted from the local copy at the end of the @@ -203,7 +203,7 @@ public class ResolveMerger extends ThreeWayMerger { * * @since 3.4 */ - protected List<String> toBeDeleted = new ArrayList<String>(); + protected List<String> toBeDeleted = new ArrayList<>(); /** * Low-level textual merge results. Will be passed on to the callers in case @@ -211,14 +211,14 @@ public class ResolveMerger extends ThreeWayMerger { * * @since 3.4 */ - protected Map<String, MergeResult<? extends Sequence>> mergeResults = new HashMap<String, MergeResult<? extends Sequence>>(); + protected Map<String, MergeResult<? extends Sequence>> mergeResults = new HashMap<>(); /** * Paths for which the merge failed altogether. * * @since 3.4 */ - protected Map<String, MergeFailureReason> failingPaths = new HashMap<String, MergeFailureReason>(); + protected Map<String, MergeFailureReason> failingPaths = new HashMap<>(); /** * Updated as we merge entries of the tree walk. Tells us whether we should @@ -518,7 +518,7 @@ public class ResolveMerger extends ThreeWayMerger { unmergedPaths.add(tw.getPathString()); mergeResults.put( tw.getPathString(), - new MergeResult<RawText>(Collections + new MergeResult<>(Collections .<RawText> emptyList())); } return true; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java index d880d9b616..fd425abf35 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java @@ -65,7 +65,7 @@ import org.eclipse.jgit.errors.TranslationStringMissingException; */ class GlobalBundleCache { private static final Map<Locale, Map<Class, TranslationBundle>> cachedBundles - = new HashMap<Locale, Map<Class, TranslationBundle>>(); + = new HashMap<>(); /** * Looks up for a translation bundle in the global cache. If found returns @@ -87,7 +87,7 @@ class GlobalBundleCache { try { Map<Class, TranslationBundle> bundles = cachedBundles.get(locale); if (bundles == null) { - bundles = new HashMap<Class, TranslationBundle>(); + bundles = new HashMap<>(); cachedBundles.put(locale, bundles); } TranslationBundle bundle = bundles.get(type); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java index a768c25a20..5e7beed1e5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java @@ -72,6 +72,7 @@ public class NLS { public static final Locale ROOT_LOCALE = new Locale("", "", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ private static final InheritableThreadLocal<NLS> local = new InheritableThreadLocal<NLS>() { + @Override protected NLS initialValue() { return new NLS(Locale.getDefault()); } @@ -119,7 +120,7 @@ public class NLS { } final private Locale locale; - final private ConcurrentHashMap<Class, TranslationBundle> map = new ConcurrentHashMap<Class, TranslationBundle>(); + final private ConcurrentHashMap<Class, TranslationBundle> map = new ConcurrentHashMap<>(); private NLS(Locale locale) { this.locale = locale; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java index db49448515..2e7327ca32 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java @@ -67,6 +67,7 @@ import org.eclipse.jgit.util.io.UnionInputStream; */ public class DefaultNoteMerger implements NoteMerger { + @Override public Note merge(Note base, Note ours, Note theirs, ObjectReader reader, ObjectInserter inserter) throws IOException { if (ours == null) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java index 79fbb09ecc..7827a9aa05 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java @@ -140,6 +140,7 @@ class FanoutBucket extends InMemoryNoteBucket { private Iterator<Note> itr; + @Override public boolean hasNext() { if (itr != null && itr.hasNext()) return true; @@ -164,6 +165,7 @@ class FanoutBucket extends InMemoryNoteBucket { return false; } + @Override public Note next() { if (hasNext()) return itr.next(); @@ -171,6 +173,7 @@ class FanoutBucket extends InMemoryNoteBucket { throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -259,6 +262,7 @@ class FanoutBucket extends InMemoryNoteBucket { return inserter.insert(build(true, inserter)); } + @Override ObjectId getTreeId() { try (ObjectInserter.Formatter f = new ObjectInserter.Formatter()) { return f.idFor(build(false, null)); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java index 41f7501e51..1be5251622 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java @@ -122,10 +122,12 @@ class LeafBucket extends InMemoryNoteBucket { return new Iterator<Note>() { private int idx; + @Override public boolean hasNext() { return idx < cnt; } + @Override public Note next() { if (hasNext()) return notes[idx++]; @@ -133,6 +135,7 @@ class LeafBucket extends InMemoryNoteBucket { throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -144,6 +147,7 @@ class LeafBucket extends InMemoryNoteBucket { return cnt; } + @Override InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData, ObjectReader or) throws IOException { int p = search(noteOn); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java index 25b2ae89e9..44c59260e8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java @@ -201,6 +201,7 @@ public class NoteMap implements Iterable<Note> { * @return an iterator that iterates over notes of this NoteMap. Non note * entries are ignored by this iterator. */ + @Override public Iterator<Note> iterator() { try { return root.iterator(new MutableObjectId(), reader); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java index b104a49842..2c8f34e7cd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java @@ -183,7 +183,7 @@ public class CombinedFileHeader extends FileHeader { protected void parseIndexLine(int ptr, final int eol) { // "index $asha1,$bsha1..$csha1" // - final List<AbbreviatedObjectId> ids = new ArrayList<AbbreviatedObjectId>(); + final List<AbbreviatedObjectId> ids = new ArrayList<>(); while (ptr < eol) { final int comma = nextLF(buf, ptr, ','); if (eol <= comma) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java index eb2bfac1b0..ed79787291 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java @@ -266,6 +266,7 @@ public class CombinedHunkHeader extends HunkHeader { } } + @Override void extractFileLines(final StringBuilder sb, final String[] text, final int[] offsets) { final byte[] buf = file.buf; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java index 534c827314..eb28a0e2a3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java @@ -305,7 +305,7 @@ public class FileHeader extends DiffEntry { if (h.getFileHeader() != this) throw new IllegalArgumentException(JGitText.get().hunkBelongsToAnotherFile); if (hunks == null) - hunks = new ArrayList<HunkHeader>(); + hunks = new ArrayList<>(); hunks.add(h); } 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/patch/Patch.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java index 40ea77e8ec..10ac449d12 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java @@ -83,8 +83,8 @@ public class Patch { /** Create an empty patch. */ public Patch() { - files = new ArrayList<FileHeader>(); - errors = new ArrayList<FormatError>(0); + files = new ArrayList<>(); + errors = new ArrayList<>(0); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java index 6102a81482..a8eb86e232 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java @@ -74,12 +74,12 @@ public class PlotCommitList<L extends PlotLane> extends private int positionsAllocated; - private final TreeSet<Integer> freePositions = new TreeSet<Integer>(); + private final TreeSet<Integer> freePositions = new TreeSet<>(); - private final HashSet<PlotLane> activeLanes = new HashSet<PlotLane>(32); + private final HashSet<PlotLane> activeLanes = new HashSet<>(32); /** number of (child) commits on a lane */ - private final HashMap<PlotLane, Integer> laneLength = new HashMap<PlotLane, Integer>( + private final HashMap<PlotLane, Integer> laneLength = new HashMap<>( 32); @Override diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java index 55cf235cf9..be1f07a38c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java @@ -107,7 +107,7 @@ public class PlotWalk extends RevWalk { if (set == null) set = Collections.singleton(ref); else { - set = new HashSet<Ref>(set); + set = new HashSet<>(set); set.add(ref); } reverseRefMap.put(ref.getObjectId(), set); @@ -147,6 +147,7 @@ public class PlotWalk extends RevWalk { } class PlotRefComparator implements Comparator<Ref> { + @Override public int compare(Ref o1, Ref o2) { try { RevObject obj1 = parseAny(o1.getObjectId()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java index 843c2afa2f..4923d0f741 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java @@ -107,6 +107,7 @@ abstract class AbstractRevQueue extends Generator { * * @return the first commit of this queue. */ + @Override public abstract RevCommit next(); /** Remove all entries from this queue. */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java index 30d140a748..db5379e507 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java @@ -83,6 +83,7 @@ abstract class BlockRevQueue extends AbstractRevQueue { * @param q * the other queue we will steal entries from. */ + @Override public void shareFreeList(final BlockRevQueue q) { free = q.free; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java index 0802bfafde..cd7c074cce 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java @@ -82,6 +82,7 @@ public class DateRevQueue extends AbstractRevQueue { } } + @Override public void add(final RevCommit c) { sinceLastIndex++; if (++inQueue > REBUILD_INDEX_COUNT @@ -126,6 +127,7 @@ public class DateRevQueue extends AbstractRevQueue { } } + @Override public RevCommit next() { final Entry q = head; if (q == null) @@ -161,6 +163,7 @@ public class DateRevQueue extends AbstractRevQueue { return head != null ? head.commit : null; } + @Override public void clear() { head = null; free = null; @@ -170,6 +173,7 @@ public class DateRevQueue extends AbstractRevQueue { last = -1; } + @Override boolean everbodyHasFlag(final int f) { for (Entry q = head; q != null; q = q.next) { if ((q.commit.flags & f) == 0) @@ -178,6 +182,7 @@ public class DateRevQueue extends AbstractRevQueue { return true; } + @Override boolean anybodyHasFlag(final int f) { for (Entry q = head; q != null; q = q.next) { if ((q.commit.flags & f) != 0) @@ -191,6 +196,7 @@ public class DateRevQueue extends AbstractRevQueue { return outputType | SORT_COMMIT_TIME_DESC; } + @Override public String toString() { final StringBuilder s = new StringBuilder(); for (Entry q = head; q != null; q = q.next) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java index 59a360f867..f932593e82 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java @@ -138,14 +138,17 @@ public interface DepthWalk { return new Commit(id); } + @Override public int getDepth() { return depth; } + @Override public RevFlag getUnshallowFlag() { return UNSHALLOW; } + @Override public RevFlag getReinterestingFlag() { return REINTERESTING; } @@ -239,14 +242,17 @@ public interface DepthWalk { return new Commit(id); } + @Override public int getDepth() { return depth; } + @Override public RevFlag getUnshallowFlag() { return UNSHALLOW; } + @Override public RevFlag getReinterestingFlag() { return REINTERESTING; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java index b8f63aaa58..14156042c8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java @@ -64,6 +64,7 @@ public class FIFORevQueue extends BlockRevQueue { super(s); } + @Override public void add(final RevCommit c) { Block b = tail; if (b == null) { @@ -107,6 +108,7 @@ public class FIFORevQueue extends BlockRevQueue { head = b; } + @Override public RevCommit next() { final Block b = head; if (b == null) @@ -122,12 +124,14 @@ public class FIFORevQueue extends BlockRevQueue { return c; } + @Override public void clear() { head = null; tail = null; free.clear(); } + @Override boolean everbodyHasFlag(final int f) { for (Block b = head; b != null; b = b.next) { for (int i = b.headIndex; i < b.tailIndex; i++) @@ -137,6 +141,7 @@ public class FIFORevQueue extends BlockRevQueue { return true; } + @Override boolean anybodyHasFlag(final int f) { for (Block b = head; b != null; b = b.next) { for (int i = b.headIndex; i < b.tailIndex; i++) @@ -154,6 +159,7 @@ public class FIFORevQueue extends BlockRevQueue { } } + @Override public String toString() { final StringBuilder s = new StringBuilder(); for (Block q = head; q != null; q = q.next) { 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/revwalk/LIFORevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java index 9abaf8dccf..f9da5b17ba 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java @@ -63,6 +63,7 @@ public class LIFORevQueue extends BlockRevQueue { super(s); } + @Override public void add(final RevCommit c) { Block b = head; if (b == null || !b.canUnpop()) { @@ -74,6 +75,7 @@ public class LIFORevQueue extends BlockRevQueue { b.unpop(c); } + @Override public RevCommit next() { final Block b = head; if (b == null) @@ -87,11 +89,13 @@ public class LIFORevQueue extends BlockRevQueue { return c; } + @Override public void clear() { head = null; free.clear(); } + @Override boolean everbodyHasFlag(final int f) { for (Block b = head; b != null; b = b.next) { for (int i = b.headIndex; i < b.tailIndex; i++) @@ -101,6 +105,7 @@ public class LIFORevQueue extends BlockRevQueue { return true; } + @Override boolean anybodyHasFlag(final int f) { for (Block b = head; b != null; b = b.next) { for (int i = b.headIndex; i < b.tailIndex; i++) @@ -110,6 +115,7 @@ public class LIFORevQueue extends BlockRevQueue { return false; } + @Override public String toString() { final StringBuilder s = new StringBuilder(); for (Block q = head; q != null; q = q.next) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java index 3609d46e30..5d7e72dd29 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java @@ -87,7 +87,7 @@ class MergeBaseGenerator extends Generator { private int recarryMask; private int mergeBaseAncestor = -1; - private LinkedList<RevCommit> ret = new LinkedList<RevCommit>(); + private LinkedList<RevCommit> ret = new LinkedList<>(); MergeBaseGenerator(final RevWalk w) { walker = w; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java index 9c3af5a5dc..58689981b5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java @@ -133,7 +133,7 @@ public class ObjectWalk extends RevWalk { public ObjectWalk(ObjectReader or) { super(or); setRetainBody(false); - rootObjects = new ArrayList<RevObject>(); + rootObjects = new ArrayList<>(); pendingObjects = new BlockObjQueue(); objectFilter = ObjectFilter.ALL; pathBuf = new byte[256]; @@ -243,6 +243,7 @@ public class ObjectWalk extends RevWalk { addObject(o); } + @Override public void sort(RevSort s) { super.sort(s); boundary = hasRevSort(RevSort.BOUNDARY); @@ -681,7 +682,7 @@ public class ObjectWalk extends RevWalk { for (RevObject obj : rootObjects) obj.flags &= ~IN_PENDING; - rootObjects = new ArrayList<RevObject>(); + rootObjects = new ArrayList<>(); pendingObjects = new BlockObjQueue(); currVisit = null; freeVisit = null; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java index 1e91006d47..c641a13311 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java @@ -565,7 +565,7 @@ public class RevCommit extends RevObject { ptr--; final int msgB = RawParseUtils.commitMessage(raw, 0); - final ArrayList<FooterLine> r = new ArrayList<FooterLine>(4); + final ArrayList<FooterLine> r = new ArrayList<>(4); final Charset enc = guessEncoding(); for (;;) { ptr = RawParseUtils.prevLF(raw, ptr); @@ -628,7 +628,7 @@ public class RevCommit extends RevObject { final List<FooterLine> src = getFooterLines(); if (src.isEmpty()) return Collections.emptyList(); - final ArrayList<String> r = new ArrayList<String>(src.size()); + final ArrayList<String> r = new ArrayList<>(src.size()); for (final FooterLine f : src) { if (f.matches(keyName)) r.add(f.getValue()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java index 0998a3a221..dae52f85db 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java @@ -99,6 +99,7 @@ public class RevFlag { return walker; } + @Override public String toString() { return name; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlagSet.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlagSet.java index ca30fd98d1..bb699e08c4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlagSet.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlagSet.java @@ -61,7 +61,7 @@ public class RevFlagSet extends AbstractSet<RevFlag> { /** Create an empty set of flags. */ public RevFlagSet() { - active = new ArrayList<RevFlag>(); + active = new ArrayList<>(); } /** @@ -72,7 +72,7 @@ public class RevFlagSet extends AbstractSet<RevFlag> { */ public RevFlagSet(final RevFlagSet s) { mask = s.mask; - active = new ArrayList<RevFlag>(s.active); + active = new ArrayList<>(s.active); } /** @@ -132,14 +132,17 @@ public class RevFlagSet extends AbstractSet<RevFlag> { return new Iterator<RevFlag>() { private RevFlag current; + @Override public boolean hasNext() { return i.hasNext(); } + @Override public RevFlag next() { return current = i.next(); } + @Override public void remove() { mask &= ~current.mask; i.remove(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java index 5052a4dea5..95986782cd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java @@ -78,6 +78,7 @@ public class RevObjectList<E extends RevObject> extends AbstractList<E> { // Initialized above. } + @Override public void add(final int index, final E element) { if (index != size) throw new UnsupportedOperationException(MessageFormat.format( @@ -87,6 +88,7 @@ public class RevObjectList<E extends RevObject> extends AbstractList<E> { size++; } + @Override @SuppressWarnings("unchecked") public E set(int index, E element) { Block s = contents; @@ -107,6 +109,7 @@ public class RevObjectList<E extends RevObject> extends AbstractList<E> { return (E) old; } + @Override @SuppressWarnings("unchecked") public E get(int index) { Block s = contents; @@ -120,6 +123,7 @@ public class RevObjectList<E extends RevObject> extends AbstractList<E> { return s != null ? (E) s.contents[index] : null; } + @Override public int size() { return size; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java index a7f7cd4635..320f05f440 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -226,8 +226,8 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { private RevWalk(ObjectReader or, boolean closeReader) { reader = or; idBuffer = new MutableObjectId(); - objects = new ObjectIdOwnerMap<RevObject>(); - roots = new ArrayList<RevCommit>(); + objects = new ObjectIdOwnerMap<>(); + roots = new ArrayList<>(); queue = new DateRevQueue(); pending = new StartGenerator(this); sorting = EnumSet.of(RevSort.NONE); @@ -931,8 +931,8 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { */ public <T extends ObjectId> AsyncRevObjectQueue parseAny( Iterable<T> objectIds, boolean reportMissing) { - List<T> need = new ArrayList<T>(); - List<RevObject> have = new ArrayList<RevObject>(); + List<T> need = new ArrayList<>(); + List<RevObject> have = new ArrayList<>(); for (T id : objectIds) { RevObject r = objects.get(id); if (r != null && (r.flags & PARSED) != 0) @@ -944,14 +944,17 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { final Iterator<RevObject> objItr = have.iterator(); if (need.isEmpty()) { return new AsyncRevObjectQueue() { + @Override public RevObject next() { return objItr.hasNext() ? objItr.next() : null; } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return true; } + @Override public void release() { // In-memory only, no action required. } @@ -960,6 +963,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { final AsyncObjectLoaderQueue<T> lItr = reader.open(need, reportMissing); return new AsyncRevObjectQueue() { + @Override public RevObject next() throws MissingObjectException, IncorrectObjectTypeException, IOException { if (objItr.hasNext()) @@ -983,10 +987,12 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { return r; } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return lItr.cancel(mayInterruptIfRunning); } + @Override public void release() { lItr.release(); } @@ -1316,6 +1322,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { * @return an iterator over this walker's commits. * @see RevWalkException */ + @Override public Iterator<RevCommit> iterator() { final RevCommit first; try { @@ -1331,10 +1338,12 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { return new Iterator<RevCommit>() { RevCommit next = first; + @Override public boolean hasNext() { return next != null; } + @Override public RevCommit next() { try { final RevCommit r = next; @@ -1349,6 +1358,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { } } + @Override public void remove() { throw new UnsupportedOperationException(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java index 11fec31e91..e751d7714c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java @@ -121,7 +121,7 @@ public final class RevWalkUtils { if (end != null) walk.markUninteresting(end); - List<RevCommit> commits = new ArrayList<RevCommit>(); + List<RevCommit> commits = new ArrayList<>(); for (RevCommit c : walk) commits.add(c); return commits; @@ -155,7 +155,7 @@ public final class RevWalkUtils { // Make sure commit is from the same RevWalk commit = revWalk.parseCommit(commit.getId()); revWalk.reset(); - List<Ref> result = new ArrayList<Ref>(); + List<Ref> result = new ArrayList<>(); final int SKEW = 24*3600; // one day clock skew diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java index 14a98a10bf..6b90d29f1c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java @@ -286,6 +286,7 @@ public abstract class RevFilter { * * @return another copy of this filter, suitable for another thread. */ + @Override public abstract RevFilter clone(); @Override diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java index 38a0fa2aac..6cfd352ec1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java @@ -185,6 +185,7 @@ public class FileBasedConfig extends StoredConfig { * @throws IOException * the file could not be written. */ + @Override public void save() throws IOException { final byte[] out; final String text = toText(); 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..c64aa2d782 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 @@ -969,6 +1044,7 @@ public class PackConfig { getBitmapInactiveBranchAgeInDays())); } + @Override public String toString() { final StringBuilder b = new StringBuilder(); b.append("maxDeltaDepth=").append(getMaxDeltaDepth()); //$NON-NLS-1$ 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/AbstractAdvertiseRefsHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java index 2d730a10f3..6f1369458c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java @@ -57,12 +57,14 @@ import org.eclipse.jgit.revwalk.RevWalk; * @since 2.0 */ public abstract class AbstractAdvertiseRefsHook implements AdvertiseRefsHook { + @Override public void advertiseRefs(UploadPack uploadPack) throws ServiceMayNotContinueException { uploadPack.setAdvertisedRefs(getAdvertisedRefs( uploadPack.getRepository(), uploadPack.getRevWalk())); } + @Override public void advertiseRefs(BaseReceivePack receivePack) throws ServiceMayNotContinueException { Map<String, Ref> refs = getAdvertisedRefs(receivePack.getRepository(), diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java index c3af74a7c2..96d7c240c3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java @@ -56,10 +56,12 @@ public interface AdvertiseRefsHook { * {@link BaseReceivePack#setAdvertisedRefs(java.util.Map,java.util.Set)}. */ public static final AdvertiseRefsHook DEFAULT = new AdvertiseRefsHook() { + @Override public void advertiseRefs(UploadPack uploadPack) { // Do nothing. } + @Override public void advertiseRefs(BaseReceivePack receivePack) { // Do nothing. } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java index 00942aba45..22ea5cba9a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java @@ -79,12 +79,14 @@ public class AdvertiseRefsHookChain implements AdvertiseRefsHook { return new AdvertiseRefsHookChain(newHooks, i); } + @Override public void advertiseRefs(BaseReceivePack rp) throws ServiceMayNotContinueException { for (int i = 0; i < count; i++) hooks[i].advertiseRefs(rp); } + @Override public void advertiseRefs(UploadPack rp) throws ServiceMayNotContinueException { for (int i = 0; i < count; i++) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java index 1aebaddacd..64cb4ddba8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java @@ -120,7 +120,7 @@ public class AmazonS3 { private static final String X_AMZ_META = "x-amz-meta-"; //$NON-NLS-1$ static { - SIGNED_HEADERS = new HashSet<String>(); + SIGNED_HEADERS = new HashSet<>(); SIGNED_HEADERS.add("content-type"); //$NON-NLS-1$ SIGNED_HEADERS.add("content-md5"); //$NON-NLS-1$ SIGNED_HEADERS.add("date"); //$NON-NLS-1$ @@ -606,7 +606,7 @@ public class AmazonS3 { void authorize(final HttpURLConnection c) throws IOException { final Map<String, List<String>> reqHdr = c.getRequestProperties(); - final SortedMap<String, String> sigHdr = new TreeMap<String, String>(); + final SortedMap<String, String> sigHdr = new TreeMap<>(); for (final Map.Entry<String, List<String>> entry : reqHdr.entrySet()) { final String hdr = entry.getKey(); if (isSignedHeader(hdr)) @@ -664,7 +664,7 @@ public class AmazonS3 { } private final class ListParser extends DefaultHandler { - final List<String> entries = new ArrayList<String>(); + final List<String> entries = new ArrayList<>(); private final String bucket; @@ -680,7 +680,7 @@ public class AmazonS3 { } void list() throws IOException { - final Map<String, String> args = new TreeMap<String, String>(); + final Map<String, String> args = new TreeMap<>(); if (prefix.length() > 0) args.put("prefix", prefix); //$NON-NLS-1$ if (!entries.isEmpty()) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java index 59ff1bd997..69028fab31 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java @@ -71,18 +71,22 @@ public abstract class BaseConnection implements Connection { private Writer messageWriter; + @Override public Map<String, Ref> getRefsMap() { return advertisedRefs; } + @Override public final Collection<Ref> getRefs() { return advertisedRefs.values(); } + @Override public final Ref getRef(final String name) { return advertisedRefs.get(name); } + @Override public String getMessages() { return messageWriter != null ? messageWriter.toString() : ""; //$NON-NLS-1$ } @@ -94,6 +98,7 @@ public abstract class BaseConnection implements Connection { * server does not advertise this version. * @since 4.0 */ + @Override public String getPeerUserAgent() { return peerUserAgent; } @@ -109,6 +114,7 @@ public abstract class BaseConnection implements Connection { peerUserAgent = agent; } + @Override public abstract void close(); /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java index cc2770771e..41b8c2d765 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java @@ -64,12 +64,14 @@ import org.eclipse.jgit.lib.Ref; */ abstract class BaseFetchConnection extends BaseConnection implements FetchConnection { + @Override public final void fetch(final ProgressMonitor monitor, final Collection<Ref> want, final Set<ObjectId> have) throws TransportException { fetch(monitor, want, have, null); } + @Override public final void fetch(final ProgressMonitor monitor, final Collection<Ref> want, final Set<ObjectId> have, OutputStream out) throws TransportException { @@ -81,6 +83,7 @@ abstract class BaseFetchConnection extends BaseConnection implements * Default implementation of {@link FetchConnection#didFetchIncludeTags()} - * returning false. */ + @Override public boolean didFetchIncludeTags() { return false; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java index aa36aeb1be..c69544930d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java @@ -117,10 +117,10 @@ abstract class BasePackConnection extends BaseConnection { protected boolean statelessRPC; /** Capability tokens advertised by the remote side. */ - private final Set<String> remoteCapablities = new HashSet<String>(); + private final Set<String> remoteCapablities = new HashSet<>(); /** Extra objects the remote has, but which aren't offered as refs. */ - protected final Set<ObjectId> additionalHaves = new HashSet<ObjectId>(); + protected final Set<ObjectId> additionalHaves = new HashSet<>(); BasePackConnection(final PackTransport packTransport) { transport = (Transport) packTransport; @@ -191,7 +191,7 @@ abstract class BasePackConnection extends BaseConnection { } private void readAdvertisedRefsImpl() throws IOException { - final LinkedHashMap<String, Ref> avail = new LinkedHashMap<String, Ref>(); + final LinkedHashMap<String, Ref> avail = new LinkedHashMap<>(); for (;;) { String line; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java index 0dd907f97e..e8d18812f6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java @@ -260,7 +260,7 @@ public abstract class BasePackFetchConnection extends BasePackConnection if (local != null) { walk = new RevWalk(local); - reachableCommits = new RevCommitList<RevCommit>(); + reachableCommits = new RevCommitList<>(); REACHABLE = walk.newFlag("REACHABLE"); //$NON-NLS-1$ COMMON = walk.newFlag("COMMON"); //$NON-NLS-1$ STATE = walk.newFlag("STATE"); //$NON-NLS-1$ @@ -280,6 +280,7 @@ public abstract class BasePackFetchConnection extends BasePackConnection private static class FetchConfig { static final SectionParser<FetchConfig> KEY = new SectionParser<FetchConfig>() { + @Override public FetchConfig parse(final Config cfg) { return new FetchConfig(cfg); } @@ -292,6 +293,7 @@ public abstract class BasePackFetchConnection extends BasePackConnection } } + @Override public final void fetch(final ProgressMonitor monitor, final Collection<Ref> want, final Set<ObjectId> have) throws TransportException { @@ -301,6 +303,7 @@ public abstract class BasePackFetchConnection extends BasePackConnection /** * @since 3.0 */ + @Override public final void fetch(final ProgressMonitor monitor, final Collection<Ref> want, final Set<ObjectId> have, OutputStream outputStream) throws TransportException { @@ -308,18 +311,22 @@ public abstract class BasePackFetchConnection extends BasePackConnection doFetch(monitor, want, have, outputStream); } + @Override public boolean didFetchIncludeTags() { return false; } + @Override public boolean didFetchTestConnectivity() { return false; } + @Override public void setPackLockMessage(final String message) { lockMessage = message; } + @Override public Collection<PackLock> getPackLocks() { if (packLock != null) return Collections.singleton(packLock); 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 86cc484e34..679ea0c8fd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java @@ -152,6 +152,7 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen pushOptions = transport.getPushOptions(); } + @Override public void push(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates) throws TransportException { @@ -161,6 +162,7 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen /** * @since 3.0 */ + @Override public void push(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates, OutputStream outputStream) throws TransportException { @@ -326,8 +328,8 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen private void writePack(final Map<String, RemoteRefUpdate> refUpdates, final ProgressMonitor monitor) throws IOException { - Set<ObjectId> remoteObjects = new HashSet<ObjectId>(); - Set<ObjectId> newObjects = new HashSet<ObjectId>(); + Set<ObjectId> remoteObjects = new HashSet<>(); + Set<ObjectId> newObjects = new HashSet<>(); try (final PackWriter writer = new PackWriter(transport.getPackConfig(), local.newObjectReader())) { 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 4d0803a339..6f94dbbfec 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java @@ -97,6 +97,7 @@ import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.transport.PacketLineIn.InputOverLimitIOException; import org.eclipse.jgit.transport.ReceiveCommand.Result; import org.eclipse.jgit.util.io.InterruptTimer; import org.eclipse.jgit.util.io.LimitedInputStream; @@ -123,7 +124,7 @@ public abstract class BaseReceivePack { * line from the client. */ public FirstLine(String line) { - final HashSet<String> caps = new HashSet<String>(); + final HashSet<String> caps = new HashSet<>(); final int nul = line.indexOf('\0'); if (nul >= 0) { for (String c : line.substring(nul + 1).split(" ")) //$NON-NLS-1$ @@ -244,6 +245,8 @@ public abstract class BaseReceivePack { String userAgent; private Set<ObjectId> clientShallowCommits; private List<ReceiveCommand> commands; + private long maxCommandBytes; + private long maxDiscardBytes; private StringBuilder advertiseError; @@ -318,16 +321,19 @@ public abstract class BaseReceivePack { allowNonFastForwards = rc.allowNonFastForwards; allowOfsDelta = rc.allowOfsDelta; allowPushOptions = rc.allowPushOptions; + maxCommandBytes = rc.maxCommandBytes; + maxDiscardBytes = rc.maxDiscardBytes; advertiseRefsHook = AdvertiseRefsHook.DEFAULT; refFilter = RefFilter.DEFAULT; - advertisedHaves = new HashSet<ObjectId>(); - clientShallowCommits = new HashSet<ObjectId>(); + advertisedHaves = new HashSet<>(); + clientShallowCommits = new HashSet<>(); signedPushConfig = rc.signedPush; } /** Configuration for receive operations. */ protected static class ReceiveConfig { static final SectionParser<ReceiveConfig> KEY = new SectionParser<ReceiveConfig>() { + @Override public ReceiveConfig parse(final Config cfg) { return new ReceiveConfig(cfg); } @@ -338,7 +344,8 @@ public abstract class BaseReceivePack { final boolean allowNonFastForwards; final boolean allowOfsDelta; final boolean allowPushOptions; - + final long maxCommandBytes; + final long maxDiscardBytes; final SignedPushConfig signedPush; ReceiveConfig(final Config config) { @@ -350,6 +357,12 @@ public abstract class BaseReceivePack { true); allowPushOptions = config.getBoolean("receive", "pushoptions", //$NON-NLS-1$ //$NON-NLS-2$ false); + maxCommandBytes = config.getLong("receive", //$NON-NLS-1$ + "maxCommandBytes", //$NON-NLS-1$ + 3 << 20); + maxDiscardBytes = config.getLong("receive", //$NON-NLS-1$ + "maxCommandDiscardBytes", //$NON-NLS-1$ + -1); signedPush = SignedPushConfig.KEY.parse(config); } } @@ -729,6 +742,38 @@ public abstract class BaseReceivePack { } /** + * Set the maximum number of command bytes to read from the client. + * + * @param limit + * command limit in bytes; if 0 there is no limit. + * @since 4.7 + */ + public void setMaxCommandBytes(long limit) { + maxCommandBytes = limit; + } + + /** + * Set the maximum number of command bytes to discard from the client. + * <p> + * Discarding remaining bytes allows this instance to consume the rest of + * the command block and send a human readable over-limit error via the + * side-band channel. If the client sends an excessive number of bytes this + * limit kicks in and the instance disconnects, resulting in a non-specific + * 'pipe closed', 'end of stream', or similar generic error at the client. + * <p> + * When the limit is set to {@code -1} the implementation will default to + * the larger of {@code 3 * maxCommandBytes} or {@code 3 MiB}. + * + * @param limit + * discard limit in bytes; if 0 there is no limit; if -1 the + * implementation tries to set a reasonable default. + * @since 4.7 + */ + public void setMaxCommandDiscardBytes(long limit) { + maxDiscardBytes = limit; + } + + /** * Set the maximum allowed Git object size. * <p> * If an object is larger than the given size the pack-parsing will throw an @@ -741,7 +786,6 @@ public abstract class BaseReceivePack { maxObjectSizeLimit = limit; } - /** * Set the maximum allowed pack size. * <p> @@ -1014,20 +1058,12 @@ public abstract class BaseReceivePack { rawOut = o; } - if (maxPackSizeLimit >= 0) - rawIn = new LimitedInputStream(rawIn, maxPackSizeLimit) { - @Override - protected void limitExceeded() throws TooLargePackException { - throw new TooLargePackException(limit); - } - }; - pckIn = new PacketLineIn(rawIn); pckOut = new PacketLineOut(rawOut); pckOut.setFlushOnEnd(false); - enabledCapabilities = new HashSet<String>(); - commands = new ArrayList<ReceiveCommand>(); + enabledCapabilities = new HashSet<>(); + commands = new ArrayList<>(); } /** @return advertised refs, or the default if not explicitly advertised. */ @@ -1134,13 +1170,16 @@ public abstract class BaseReceivePack { * @throws IOException */ protected void recvCommands() throws IOException { + PacketLineIn pck = maxCommandBytes > 0 + ? new PacketLineIn(rawIn, maxCommandBytes) + : pckIn; PushCertificateParser certParser = getPushCertificateParser(); boolean firstPkt = true; try { for (;;) { String line; try { - line = pckIn.readString(); + line = pck.readString(); } catch (EOFException eof) { if (commands.isEmpty()) return; @@ -1163,13 +1202,13 @@ public abstract class BaseReceivePack { enableCapabilities(); if (line.equals(GitProtocolConstants.OPTION_PUSH_CERT)) { - certParser.receiveHeader(pckIn, !isBiDirectionalPipe()); + certParser.receiveHeader(pck, !isBiDirectionalPipe()); continue; } } if (line.equals(PushCertificateParser.BEGIN_SIGNATURE)) { - certParser.receiveSignature(pckIn); + certParser.receiveSignature(pck); continue; } @@ -1186,18 +1225,31 @@ public abstract class BaseReceivePack { } pushCert = certParser.build(); if (hasCommands()) { - readPostCommands(pckIn); + readPostCommands(pck); } } catch (PackProtocolException e) { - if (sideBand) { - try { - pckIn.discardUntilEnd(); - } catch (IOException e2) { - // Ignore read failures attempting to discard. - } - } + discardCommands(); fatalError(e.getMessage()); throw e; + } catch (InputOverLimitIOException e) { + String msg = JGitText.get().tooManyCommands; + discardCommands(); + fatalError(msg); + throw new PackProtocolException(msg); + } + } + + private void discardCommands() { + if (sideBand) { + long max = maxDiscardBytes; + if (max < 0) { + max = Math.max(3 * maxCommandBytes, 3L << 20); + } + try { + new PacketLineIn(rawIn, max).discardUntilEnd(); + } catch (IOException e) { + // Ignore read failures attempting to discard. + } } } @@ -1309,7 +1361,7 @@ public abstract class BaseReceivePack { if (getRefLogIdent() != null) lockMsg += " from " + getRefLogIdent().toExternalString(); //$NON-NLS-1$ - parser = ins.newPackParser(rawIn); + parser = ins.newPackParser(packInputStream()); parser.setAllowThin(true); parser.setNeedNewObjectIds(checkReferencedIsReachable); parser.setNeedBaseObjectIds(checkReferencedIsReachable); @@ -1329,6 +1381,19 @@ public abstract class BaseReceivePack { timeoutIn.setTimeout(timeout * 1000); } + private InputStream packInputStream() { + InputStream packIn = rawIn; + if (maxPackSizeLimit >= 0) { + packIn = new LimitedInputStream(packIn, maxPackSizeLimit) { + @Override + protected void limitExceeded() throws TooLargePackException { + throw new TooLargePackException(limit); + } + }; + } + return packIn; + } + private boolean needCheckConnectivity() { return isCheckReceivedObjects() || isCheckReferencedObjectsAreReachable() diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java index 8038fa4d31..f37ba01034 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java @@ -92,7 +92,7 @@ class BundleFetchConnection extends BaseFetchConnection { InputStream bin; - final Map<ObjectId, String> prereqs = new HashMap<ObjectId, String>(); + final Map<ObjectId, String> prereqs = new HashMap<>(); private String lockMessage; @@ -130,7 +130,7 @@ class BundleFetchConnection extends BaseFetchConnection { private void readBundleV2() throws IOException { final byte[] hdrbuf = new byte[1024]; - final LinkedHashMap<String, Ref> avail = new LinkedHashMap<String, Ref>(); + final LinkedHashMap<String, Ref> avail = new LinkedHashMap<>(); for (;;) { String line = readLine(hdrbuf); if (line.length() == 0) @@ -180,6 +180,7 @@ class BundleFetchConnection extends BaseFetchConnection { return line.toString(); } + @Override public boolean didFetchTestConnectivity() { return false; } @@ -207,10 +208,12 @@ class BundleFetchConnection extends BaseFetchConnection { } } + @Override public void setPackLockMessage(final String message) { lockMessage = message; } + @Override public Collection<PackLock> getPackLocks() { if (packLock != null) return Collections.singleton(packLock); @@ -225,8 +228,8 @@ class BundleFetchConnection extends BaseFetchConnection { final RevFlag PREREQ = rw.newFlag("PREREQ"); //$NON-NLS-1$ final RevFlag SEEN = rw.newFlag("SEEN"); //$NON-NLS-1$ - final Map<ObjectId, String> missing = new HashMap<ObjectId, String>(); - final List<RevObject> commits = new ArrayList<RevObject>(); + final Map<ObjectId, String> missing = new HashMap<>(); + final List<RevObject> commits = new ArrayList<>(); for (final Map.Entry<ObjectId, String> e : prereqs.entrySet()) { ObjectId p = e.getKey(); try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java index ca624c03d5..37d70e3a14 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java @@ -102,9 +102,9 @@ public class BundleWriter { */ public BundleWriter(final Repository repo) { db = repo; - include = new TreeMap<String, ObjectId>(); - assume = new HashSet<RevCommit>(); - tagTargets = new HashSet<ObjectId>(); + include = new TreeMap<>(); + assume = new HashSet<>(); + tagTargets = new HashSet<>(); } /** @@ -202,8 +202,8 @@ public class BundleWriter { try (PackWriter packWriter = new PackWriter(pc, db.newObjectReader())) { packWriter.setObjectCountCallback(callback); - final HashSet<ObjectId> inc = new HashSet<ObjectId>(); - final HashSet<ObjectId> exc = new HashSet<ObjectId>(); + final HashSet<ObjectId> inc = new HashSet<>(); + final HashSet<ObjectId> exc = new HashSet<>(); inc.addAll(include.values()); for (final RevCommit r : assume) exc.add(r.getId()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java index 739ddccc73..8cb3d604cf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java @@ -68,7 +68,7 @@ public class ChainingCredentialsProvider extends CredentialsProvider { * here */ public ChainingCredentialsProvider(CredentialsProvider... providers) { - this.credentialProviders = new ArrayList<CredentialsProvider>( + this.credentialProviders = new ArrayList<>( Arrays.asList(providers)); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Connection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Connection.java index da288ec31e..9a272a4fdd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Connection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Connection.java @@ -112,6 +112,7 @@ public interface Connection extends AutoCloseable { * Implementers shouldn't throw checked exceptions. This override narrows * the signature to prevent them from doing so. */ + @Override public void close(); /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java index 6757aaf108..83586350be 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java @@ -85,14 +85,17 @@ public class CredentialsProviderUserInfo implements UserInfo, return uri; } + @Override public String getPassword() { return password; } + @Override public String getPassphrase() { return passphrase; } + @Override public boolean promptPassphrase(String msg) { CredentialItem.StringType v = newPrompt(msg); if (provider.get(uri, v)) { @@ -104,6 +107,7 @@ public class CredentialsProviderUserInfo implements UserInfo, } } + @Override public boolean promptPassword(String msg) { CredentialItem.Password p = new CredentialItem.Password(msg); if (provider.get(uri, p)) { @@ -119,22 +123,25 @@ public class CredentialsProviderUserInfo implements UserInfo, return new CredentialItem.StringType(msg, true); } + @Override public boolean promptYesNo(String msg) { CredentialItem.YesNoType v = new CredentialItem.YesNoType(msg); return provider.get(uri, v) && v.getValue(); } + @Override public void showMessage(String msg) { provider.get(uri, new CredentialItem.InformationalMessage(msg)); } + @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { CredentialItem.StringType[] v = new CredentialItem.StringType[prompt.length]; for (int i = 0; i < prompt.length; i++) v[i] = new CredentialItem.StringType(prompt[i], !echo[i]); - List<CredentialItem> items = new ArrayList<CredentialItem>(); + List<CredentialItem> items = new ArrayList<>(); if (instruction != null && instruction.length() > 0) items.add(new CredentialItem.InformationalMessage(instruction)); items.addAll(Arrays.asList(v)); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java index 1beec906ed..40b2c47df0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java @@ -111,6 +111,7 @@ public class Daemon { repositoryResolver = (RepositoryResolver<DaemonClient>) RepositoryResolver.NONE; uploadPackFactory = new UploadPackFactory<DaemonClient>() { + @Override public UploadPack create(DaemonClient req, Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { @@ -122,6 +123,7 @@ public class Daemon { }; receivePackFactory = new ReceivePackFactory<DaemonClient>() { + @Override public ReceivePack create(DaemonClient req, Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { @@ -298,6 +300,7 @@ public class Daemon { run = true; acceptThread = new Thread(processors, "Git-Daemon-Accept") { //$NON-NLS-1$ + @Override public void run() { while (isRunning()) { try { @@ -344,6 +347,7 @@ public class Daemon { dc.setRemoteAddress(((InetSocketAddress) peer).getAddress()); new Thread(processors, "Git-Daemon-Client " + peer.toString()) { //$NON-NLS-1$ + @Override public void run() { try { dc.execute(s); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java index ec6f24273d..80b2caebc4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java @@ -65,6 +65,7 @@ public abstract class DaemonService { DaemonService(final String cmdName, final String cfgName) { command = cmdName.startsWith("git-") ? cmdName : "git-" + cmdName; //$NON-NLS-1$ //$NON-NLS-2$ configKey = new SectionParser<ServiceConfig>() { + @Override public ServiceConfig parse(final Config cfg) { return new ServiceConfig(DaemonService.this, cfg, cfgName); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java index 70128077d2..23fd7e39c5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java @@ -59,6 +59,7 @@ import com.jcraft.jsch.Session; * connection will immediately fail. */ class DefaultSshSessionFactory extends JschConfigSessionFactory { + @Override protected void configure(final OpenSshConfig.Host hc, final Session session) { // No additional configuration required. } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java index 8cb36c7918..280e6d4df7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java @@ -88,18 +88,18 @@ class FetchProcess { private final Collection<RefSpec> toFetch; /** Set of refs we will actually wind up asking to obtain. */ - private final HashMap<ObjectId, Ref> askFor = new HashMap<ObjectId, Ref>(); + private final HashMap<ObjectId, Ref> askFor = new HashMap<>(); /** Objects we know we have locally. */ - private final HashSet<ObjectId> have = new HashSet<ObjectId>(); + private final HashSet<ObjectId> have = new HashSet<>(); /** Updates to local tracking branches (if any). */ - private final ArrayList<TrackingRefUpdate> localUpdates = new ArrayList<TrackingRefUpdate>(); + private final ArrayList<TrackingRefUpdate> localUpdates = new ArrayList<>(); /** Records to be recorded into FETCH_HEAD. */ - private final ArrayList<FetchHeadRecord> fetchHeadUpdates = new ArrayList<FetchHeadRecord>(); + private final ArrayList<FetchHeadRecord> fetchHeadUpdates = new ArrayList<>(); - private final ArrayList<PackLock> packLocks = new ArrayList<PackLock>(); + private final ArrayList<PackLock> packLocks = new ArrayList<>(); private FetchConnection conn; @@ -137,7 +137,7 @@ class FetchProcess { try { result.setAdvertisedRefs(transport.getURI(), conn.getRefsMap()); result.peerUserAgent = conn.getPeerUserAgent(); - final Set<Ref> matched = new HashSet<Ref>(); + final Set<Ref> matched = new HashSet<>(); for (final RefSpec spec : toFetch) { if (spec.getSource() == null) throw new TransportException(MessageFormat.format( @@ -275,11 +275,11 @@ class FetchProcess { // We rebuild our askFor list using only the refs that the // new connection has offered to us. // - final HashMap<ObjectId, Ref> avail = new HashMap<ObjectId, Ref>(); + final HashMap<ObjectId, Ref> avail = new HashMap<>(); for (final Ref r : conn.getRefs()) avail.put(r.getObjectId(), r); - final Collection<Ref> wants = new ArrayList<Ref>(askFor.values()); + final Collection<Ref> wants = new ArrayList<>(askFor.values()); askFor.clear(); for (final Ref want : wants) { final Ref newRef = avail.get(want.getObjectId()); @@ -369,7 +369,7 @@ class FetchProcess { } private Collection<Ref> expandAutoFollowTags() throws TransportException { - final Collection<Ref> additionalTags = new ArrayList<Ref>(); + final Collection<Ref> additionalTags = new ArrayList<>(); final Map<String, Ref> haveRefs = localRefs(); for (final Ref r : conn.getRefs()) { if (!isTag(r)) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchResult.java index 3d95eddc9b..2667ec37ca 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchResult.java @@ -48,7 +48,10 @@ package org.eclipse.jgit.transport; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Final status after a successful fetch from a remote repository. @@ -58,12 +61,39 @@ import java.util.List; public class FetchResult extends OperationResult { private final List<FetchHeadRecord> forMerge; + private final Map<String, FetchResult> submodules; + FetchResult() { - forMerge = new ArrayList<FetchHeadRecord>(); + forMerge = new ArrayList<>(); + submodules = new HashMap<>(); } void add(final FetchHeadRecord r) { if (!r.notForMerge) forMerge.add(r); } + + /** + * Add fetch results for a submodule. + * + * @param path + * the submodule path + * @param result + * the fetch result + * @since 4.7 + */ + public void addSubmodule(String path, FetchResult result) { + submodules.put(path, result); + } + + /** + * Get fetch results for submodules. + * + * @return Fetch results for submodules as a map of submodule paths to fetch + * results. + * @since 4.7 + */ + public Map<String, FetchResult> submoduleResults() { + return Collections.unmodifiableMap(submodules); + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java index 319ae1edc7..d43be8974c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java @@ -82,6 +82,7 @@ public class HMACSHA1NonceGenerator implements NonceGenerator { } } + @Override public synchronized String createNonce(Repository repo, long timestamp) throws IllegalStateException { String path; 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..c97daa958f 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))) { @@ -346,7 +348,7 @@ abstract class HttpAuthMethod { @SuppressWarnings("boxing") @Override void configureRequest(final HttpConnection conn) throws IOException { - final Map<String, String> r = new LinkedHashMap<String, String>(); + final Map<String, String> r = new LinkedHashMap<>(); final String realm = params.get("realm"); //$NON-NLS-1$ final String nonce = params.get("nonce"); //$NON-NLS-1$ @@ -465,7 +467,7 @@ abstract class HttpAuthMethod { } private static Map<String, String> parse(String auth) { - Map<String, String> p = new HashMap<String, String>(); + Map<String, String> p = new HashMap<>(); int next = 0; while (next < auth.length()) { if (next < auth.length() && auth.charAt(next) == ',') { @@ -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/InternalFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java index 7fc4048115..bea8d60ecd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java @@ -87,6 +87,7 @@ class InternalFetchConnection<C> extends BasePackFetchConnection { } worker = new Thread("JGit-Upload-Pack") { //$NON-NLS-1$ + @Override public void run() { try { final UploadPack rp = uploadPackFactory.create(req, remote); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java index ab76e0f1ed..8a1884e5fc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java @@ -79,6 +79,7 @@ class InternalPushConnection<C> extends BasePackPushConnection { } worker = new Thread("JGit-Receive-Pack") { //$NON-NLS-1$ + @Override public void run() { try { final ReceivePack rp = receivePackFactory.create(req, remote); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java index d1cbd8d268..ce14183a56 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java @@ -80,7 +80,7 @@ import com.jcraft.jsch.UserInfo; * to supply appropriate {@link UserInfo} to the session. */ public abstract class JschConfigSessionFactory extends SshSessionFactory { - private final Map<String, JSch> byIdentityFile = new HashMap<String, JSch>(); + private final Map<String, JSch> byIdentityFile = new HashMap<>(); private JSch defaultJSch; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschSession.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschSession.java index fa27bfce5f..f445bcbcfb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschSession.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschSession.java @@ -87,10 +87,12 @@ public class JschSession implements RemoteSession { this.uri = uri; } + @Override public Process exec(String command, int timeout) throws IOException { return new JschProcess(command, timeout); } + @Override public void disconnect() { if (sock.isConnected()) sock.disconnect(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/LongMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/LongMap.java index 88b4b074a3..4d60202a6f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/LongMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/LongMap.java @@ -106,7 +106,7 @@ final class LongMap<V> { if (++size == growAt) grow(); - insert(new Node<V>(key, value)); + insert(new Node<>(key, value)); return null; } 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..bab5bf0354 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; @@ -124,7 +125,7 @@ public class NetRC { private long lastModified; - private Map<String, NetRCEntry> hosts = new HashMap<String, NetRCEntry>(); + private Map<String, NetRCEntry> hosts = new HashMap<>(); private static final TreeMap<String, State> STATE = new TreeMap<String, NetRC.State>() { private static final long serialVersionUID = -4285910831814853334L; @@ -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/OpenSshConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java index 38f3a2ac77..8b7b60da37 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java @@ -175,9 +175,9 @@ public class OpenSshConfig { } private Map<String, Host> parse(final InputStream in) throws IOException { - final Map<String, Host> m = new LinkedHashMap<String, Host>(); + final Map<String, Host> m = new LinkedHashMap<>(); final BufferedReader br = new BufferedReader(new InputStreamReader(in)); - final List<Host> current = new ArrayList<Host>(4); + final List<Host> current = new ArrayList<>(4); String line; while ((line = br.readLine()) != null) { @@ -311,6 +311,7 @@ public class OpenSshConfig { static String userName() { return AccessController.doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return System.getProperty("user.name"); //$NON-NLS-1$ } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/OperationResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/OperationResult.java index ad51f3e70c..42317984fe 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/OperationResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/OperationResult.java @@ -64,7 +64,7 @@ public abstract class OperationResult { URIish uri; - final SortedMap<String, TrackingRefUpdate> updates = new TreeMap<String, TrackingRefUpdate>(); + final SortedMap<String, TrackingRefUpdate> updates = new TreeMap<>(); StringBuilder messageBuffer; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java index 4bbe3f8813..c82b3891b5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java @@ -83,6 +83,7 @@ import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.util.BlockList; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.NB; +import org.eclipse.jgit.util.sha1.SHA1; /** * Parses a pack stream and imports it for an {@link ObjectInserter}. @@ -116,8 +117,7 @@ public abstract class PackParser { private byte[] hdrBuf; - private final MessageDigest objectDigest; - + private final SHA1 objectHasher = SHA1.newInstance(); private final MutableObjectId tempObjectId; private InputStream in; @@ -206,7 +206,6 @@ public abstract class PackParser { buf = new byte[BUFFER_SIZE]; tempBuffer = new byte[BUFFER_SIZE]; hdrBuf = new byte[64]; - objectDigest = Constants.newMessageDigest(); tempObjectId = new MutableObjectId(); packDigest = Constants.newMessageDigest(); checkObjectCollisions = true; @@ -275,7 +274,7 @@ public abstract class PackParser { */ public void setNeedNewObjectIds(boolean b) { if (b) - newObjectIds = new ObjectIdSubclassMap<ObjectId>(); + newObjectIds = new ObjectIdSubclassMap<>(); else newObjectIds = null; } @@ -333,14 +332,14 @@ public abstract class PackParser { public ObjectIdSubclassMap<ObjectId> getNewObjectIds() { if (newObjectIds != null) return newObjectIds; - return new ObjectIdSubclassMap<ObjectId>(); + return new ObjectIdSubclassMap<>(); } /** @return set of objects the incoming pack assumed for delta purposes */ public ObjectIdSubclassMap<ObjectId> getBaseObjectIds() { if (baseObjectIds != null) return baseObjectIds; - return new ObjectIdSubclassMap<ObjectId>(); + return new ObjectIdSubclassMap<>(); } /** @@ -527,9 +526,9 @@ public abstract class PackParser { readPackHeader(); entries = new PackedObjectInfo[(int) objectCount]; - baseById = new ObjectIdOwnerMap<DeltaChain>(); - baseByPos = new LongMap<UnresolvedDelta>(); - deferredCheckBlobs = new BlockList<PackedObjectInfo>(); + baseById = new ObjectIdOwnerMap<>(); + baseByPos = new LongMap<>(); + deferredCheckBlobs = new BlockList<>(); receiving.beginTask(JGitText.get().receivingObjects, (int) objectCount); @@ -667,12 +666,13 @@ public abstract class PackParser { JGitText.get().corruptionDetectedReReadingAt, Long.valueOf(visit.delta.position))); + SHA1 objectDigest = objectHasher.reset(); objectDigest.update(Constants.encodedTypeString(type)); objectDigest.update((byte) ' '); objectDigest.update(Constants.encodeASCII(visit.data.length)); objectDigest.update((byte) 0); objectDigest.update(visit.data); - tempObjectId.fromRaw(objectDigest.digest(), 0); + objectDigest.digest(tempObjectId); verifySafeObject(tempObjectId, type, visit.data); @@ -826,9 +826,9 @@ public abstract class PackParser { growEntries(baseById.size()); if (needBaseObjectIds) - baseObjectIds = new ObjectIdSubclassMap<ObjectId>(); + baseObjectIds = new ObjectIdSubclassMap<>(); - final List<DeltaChain> missing = new ArrayList<DeltaChain>(64); + final List<DeltaChain> missing = new ArrayList<>(64); for (final DeltaChain baseId : baseById) { if (baseId.head == null) continue; @@ -1024,6 +1024,7 @@ public abstract class PackParser { private void whole(final long pos, final int type, final long sz) throws IOException { + SHA1 objectDigest = objectHasher.reset(); objectDigest.update(Constants.encodedTypeString(type)); objectDigest.update((byte) ' '); objectDigest.update(Constants.encodeASCII(sz)); @@ -1043,7 +1044,7 @@ public abstract class PackParser { cnt += r; } inf.close(); - tempObjectId.fromRaw(objectDigest.digest(), 0); + objectDigest.digest(tempObjectId); checkContentLater = isCheckObjectCollisions() && readCurs.has(tempObjectId); data = null; @@ -1051,7 +1052,7 @@ public abstract class PackParser { } else { data = inflateAndReturn(Source.INPUT, sz); objectDigest.update(data); - tempObjectId.fromRaw(objectDigest.digest(), 0); + objectDigest.digest(tempObjectId); verifySafeObject(tempObjectId, type, data); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java index e142babd68..e70925693b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java @@ -87,19 +87,32 @@ public class PacketLineIn { ACK_READY; } + private final byte[] lineBuffer = new byte[SideBandOutputStream.SMALL_BUF]; private final InputStream in; + private long limit; - private final byte[] lineBuffer; + /** + * Create a new packet line reader. + * + * @param in + * the input stream to consume. + */ + public PacketLineIn(InputStream in) { + this(in, 0); + } /** * Create a new packet line reader. * - * @param i + * @param in * the input stream to consume. + * @param limit + * bytes to read from the input; unlimited if set to 0. + * @since 4.7 */ - public PacketLineIn(final InputStream i) { - in = i; - lineBuffer = new byte[SideBandOutputStream.SMALL_BUF]; + public PacketLineIn(InputStream in, long limit) { + this.in = in; + this.limit = limit; } AckNackResult readACK(final MutableObjectId returnedId) throws IOException { @@ -210,15 +223,48 @@ public class PacketLineIn { int readLength() throws IOException { IO.readFully(in, lineBuffer, 0, 4); + int len; try { - final int len = RawParseUtils.parseHexInt16(lineBuffer, 0); - if (len != 0 && len < 4) - throw new ArrayIndexOutOfBoundsException(); - return len; + len = RawParseUtils.parseHexInt16(lineBuffer, 0); } catch (ArrayIndexOutOfBoundsException err) { - throw new IOException(MessageFormat.format(JGitText.get().invalidPacketLineHeader, - "" + (char) lineBuffer[0] + (char) lineBuffer[1] //$NON-NLS-1$ - + (char) lineBuffer[2] + (char) lineBuffer[3])); + throw invalidHeader(); } + + if (len == 0) { + return 0; + } else if (len < 4) { + throw invalidHeader(); + } + + if (limit != 0) { + int n = len - 4; + if (limit < n) { + limit = -1; + try { + IO.skipFully(in, n); + } catch (IOException e) { + // Ignore failure discarding packet over limit. + } + throw new InputOverLimitIOException(); + } + // if set limit must not be 0 (means unlimited). + limit = n < limit ? limit - n : -1; + } + return len; + } + + private IOException invalidHeader() { + return new IOException(MessageFormat.format(JGitText.get().invalidPacketLineHeader, + "" + (char) lineBuffer[0] + (char) lineBuffer[1] //$NON-NLS-1$ + + (char) lineBuffer[2] + (char) lineBuffer[3])); + } + + /** + * IOException thrown by read when the configured input limit is exceeded. + * + * @since 4.7 + */ + public static class InputOverLimitIOException extends IOException { + private static final long serialVersionUID = 1L; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java index 1e662751bc..8e395018cd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java @@ -62,6 +62,7 @@ import java.util.Collection; public interface PostReceiveHook { /** A simple no-op hook. */ public static final PostReceiveHook NULL = new PostReceiveHook() { + @Override public void onPostReceive(final ReceivePack rp, final Collection<ReceiveCommand> commands) { // Do nothing. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java index da86525dcd..3bdcd68959 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java @@ -77,6 +77,7 @@ public class PostReceiveHookChain implements PostReceiveHook { return new PostReceiveHookChain(newHooks, i); } + @Override public void onPostReceive(ReceivePack rp, Collection<ReceiveCommand> commands) { for (int i = 0; i < count; i++) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java index 53eeab1dff..5b37bcdf0c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java @@ -58,6 +58,7 @@ import org.eclipse.jgit.storage.pack.PackStatistics; public interface PostUploadHook { /** A simple no-op hook. */ public static final PostUploadHook NULL = new PostUploadHook() { + @Override public void onPostUpload(PackStatistics stats) { // Do nothing. } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java index 4e2eaeaff1..26323badc6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java @@ -78,6 +78,7 @@ public class PostUploadHookChain implements PostUploadHook { return new PostUploadHookChain(newHooks, i); } + @Override public void onPostUpload(PackStatistics stats) { for (int i = 0; i < count; i++) hooks[i].onPostUpload(stats); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java index 9a743a515b..27b2df08ce 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java @@ -78,6 +78,7 @@ import java.util.Collection; public interface PreReceiveHook { /** A simple no-op hook. */ public static final PreReceiveHook NULL = new PreReceiveHook() { + @Override public void onPreReceive(final ReceivePack rp, final Collection<ReceiveCommand> commands) { // Do nothing. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java index bd4441fed7..7b1c8fb3f2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java @@ -76,6 +76,7 @@ public class PreReceiveHookChain implements PreReceiveHook { return new PreReceiveHookChain(newHooks, i); } + @Override public void onPreReceive(ReceivePack rp, Collection<ReceiveCommand> commands) { for (int i = 0; i < count; i++) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHook.java index 0360f120e0..7d9638cfc0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHook.java @@ -58,12 +58,14 @@ import org.eclipse.jgit.lib.ObjectId; public interface PreUploadHook { /** A simple no-op hook. */ public static final PreUploadHook NULL = new PreUploadHook() { + @Override public void onBeginNegotiateRound(UploadPack up, Collection<? extends ObjectId> wants, int cntOffered) throws ServiceMayNotContinueException { // Do nothing. } + @Override public void onEndNegotiateRound(UploadPack up, Collection<? extends ObjectId> wants, int cntCommon, int cntNotFound, boolean ready) @@ -71,6 +73,7 @@ public interface PreUploadHook { // Do nothing. } + @Override public void onSendPack(UploadPack up, Collection<? extends ObjectId> wants, Collection<? extends ObjectId> haves) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java index 7f515e038c..c9f88dd164 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java @@ -79,6 +79,7 @@ public class PreUploadHookChain implements PreUploadHook { return new PreUploadHookChain(newHooks, i); } + @Override public void onBeginNegotiateRound(UploadPack up, Collection<? extends ObjectId> wants, int cntOffered) throws ServiceMayNotContinueException { @@ -86,6 +87,7 @@ public class PreUploadHookChain implements PreUploadHook { hooks[i].onBeginNegotiateRound(up, wants, cntOffered); } + @Override public void onEndNegotiateRound(UploadPack up, Collection<? extends ObjectId> wants, int cntCommon, int cntNotFound, boolean ready) @@ -94,6 +96,7 @@ public class PreUploadHookChain implements PreUploadHook { hooks[i].onEndNegotiateRound(up, wants, cntCommon, cntNotFound, ready); } + @Override public void onSendPack(UploadPack up, Collection<? extends ObjectId> wants, Collection<? extends ObjectId> haves) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java index d436e08df1..706e727060 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java @@ -140,6 +140,7 @@ public class PushCertificateStore implements AutoCloseable { * If {@link #get(String)} was called, closes the cached object reader created * by that method. Does not close the underlying repository. */ + @Override public void close() { if (reader != null) { reader.close(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java index 5590c2d256..3201732a98 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java @@ -124,7 +124,7 @@ class PushProcess { throws TransportException { this.walker = new RevWalk(transport.local); this.transport = transport; - this.toPush = new HashMap<String, RemoteRefUpdate>(); + this.toPush = new HashMap<>(); this.out = out; this.pushOptions = transport.getPushOptions(); for (final RemoteRefUpdate rru : toPush) { @@ -190,7 +190,7 @@ class PushProcess { private Map<String, RemoteRefUpdate> prepareRemoteUpdates() throws TransportException { boolean atomic = transport.isPushAtomic(); - final Map<String, RemoteRefUpdate> result = new HashMap<String, RemoteRefUpdate>(); + final Map<String, RemoteRefUpdate> result = new HashMap<>(); for (final RemoteRefUpdate rru : toPush.values()) { final Ref advertisedRef = connection.getRef(rru.getRemoteName()); ObjectId advertisedOld = null; 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 393e25a2a8..169df3be26 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java @@ -273,6 +273,7 @@ public class ReceivePack extends BaseReceivePack { if (reportStatus) { if (echoCommandFailures && msgOut != null) { sendStatusReport(false, unpackError, new Reporter() { + @Override void sendString(final String s) throws IOException { msgOut.write(Constants.encode(s + "\n")); //$NON-NLS-1$ } @@ -285,6 +286,7 @@ public class ReceivePack extends BaseReceivePack { } } sendStatusReport(true, unpackError, new Reporter() { + @Override void sendString(final String s) throws IOException { pckOut.writeString(s + "\n"); //$NON-NLS-1$ } @@ -292,6 +294,7 @@ public class ReceivePack extends BaseReceivePack { pckOut.end(); } else if (msgOut != null) { sendStatusReport(false, unpackError, new Reporter() { + @Override void sendString(final String s) throws IOException { msgOut.write(Constants.encode(s + "\n")); //$NON-NLS-1$ } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java index 0cd720c29d..745e813c41 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java @@ -163,9 +163,9 @@ public abstract class RefAdvertiser { private final char[] tmpId = new char[Constants.OBJECT_ID_STRING_LENGTH]; - final Set<String> capablities = new LinkedHashSet<String>(); + final Set<String> capablities = new LinkedHashSet<>(); - private final Set<ObjectId> sent = new HashSet<ObjectId>(); + private final Set<ObjectId> sent = new HashSet<>(); private Repository repository; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java index e46195fc19..d4f85f2af5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java @@ -59,6 +59,7 @@ import org.eclipse.jgit.lib.Ref; public interface RefFilter { /** The default filter, allows all refs to be shown. */ public static final RefFilter DEFAULT = new RefFilter() { + @Override public Map<String, Ref> filter (final Map<String, Ref> refs) { return refs; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefLeaseSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefLeaseSpec.java new file mode 100644 index 0000000000..734f523c4c --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefLeaseSpec.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 Two Sigma Open Source + * 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.transport; + +import java.io.Serializable; + +/** + * Describes the expected value for a ref being pushed. + * @since 4.7 + */ +public class RefLeaseSpec implements Serializable { + private static final long serialVersionUID = 1L; + + /** Name of the ref whose value we want to check. */ + private final String ref; + + /** Local commitish to get expected value from. */ + private final String expected; + + /** + * + * @param ref + * ref being pushed + * @param expected + * the expected value of the ref + */ + public RefLeaseSpec(String ref, String expected) { + this.ref = ref; + this.expected = expected; + } + + /** + * Get the ref to protect. + * + * @return name of ref to check. + */ + public String getRef() { + return ref; + } + + /** + * Get the expected value of the ref, in the form + * of a local committish + * + * @return expected ref value. + */ + public String getExpected() { + return expected; + } + + @Override + public String toString() { + final StringBuilder r = new StringBuilder(); + r.append(getRef()); + r.append(':'); + r.append(getExpected()); + return r.toString(); + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java index 1440b83cf7..64f6c3fb97 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java @@ -556,6 +556,7 @@ public class RefSpec implements Serializable { return true; } + @Override public int hashCode() { int hc = 0; if (getSource() != null) @@ -565,6 +566,7 @@ public class RefSpec implements Serializable { return hc; } + @Override public boolean equals(final Object obj) { if (!(obj instanceof RefSpec)) return false; @@ -588,6 +590,7 @@ public class RefSpec implements Serializable { return a.equals(b); } + @Override public String toString() { final StringBuilder r = new StringBuilder(); if (isForceUpdate()) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java index ba0931b9ba..d91684e2f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java @@ -114,11 +114,11 @@ public class RemoteConfig implements Serializable { */ public static List<RemoteConfig> getAllRemoteConfigs(final Config rc) throws URISyntaxException { - final List<String> names = new ArrayList<String>(rc + final List<String> names = new ArrayList<>(rc .getSubsections(SECTION)); Collections.sort(names); - final List<RemoteConfig> result = new ArrayList<RemoteConfig>(names + final List<RemoteConfig> result = new ArrayList<>(names .size()); for (final String name : names) result.add(new RemoteConfig(rc, name)); @@ -169,24 +169,24 @@ public class RemoteConfig implements Serializable { vlst = rc.getStringList(SECTION, name, KEY_URL); Map<String, String> insteadOf = getReplacements(rc, KEY_INSTEADOF); - uris = new ArrayList<URIish>(vlst.length); + uris = new ArrayList<>(vlst.length); for (final String s : vlst) uris.add(new URIish(replaceUri(s, insteadOf))); Map<String, String> pushInsteadOf = getReplacements(rc, KEY_PUSHINSTEADOF); vlst = rc.getStringList(SECTION, name, KEY_PUSHURL); - pushURIs = new ArrayList<URIish>(vlst.length); + pushURIs = new ArrayList<>(vlst.length); for (final String s : vlst) pushURIs.add(new URIish(replaceUri(s, pushInsteadOf))); vlst = rc.getStringList(SECTION, name, KEY_FETCH); - fetch = new ArrayList<RefSpec>(vlst.length); + fetch = new ArrayList<>(vlst.length); for (final String s : vlst) fetch.add(new RefSpec(s)); vlst = rc.getStringList(SECTION, name, KEY_PUSH); - push = new ArrayList<RefSpec>(vlst.length); + push = new ArrayList<>(vlst.length); for (final String s : vlst) push.add(new RefSpec(s)); @@ -213,7 +213,7 @@ public class RemoteConfig implements Serializable { * the configuration file to store ourselves into. */ public void update(final Config rc) { - final List<String> vlst = new ArrayList<String>(); + final List<String> vlst = new ArrayList<>(); vlst.clear(); for (final URIish u : getURIs()) @@ -272,7 +272,7 @@ public class RemoteConfig implements Serializable { private Map<String, String> getReplacements(final Config config, final String keyName) { - final Map<String, String> replacements = new HashMap<String, String>(); + final Map<String, String> replacements = new HashMap<>(); for (String url : config.getSubsections(KEY_URL)) for (String insteadOf : config.getStringList(KEY_URL, url, keyName)) replacements.put(insteadOf, url); 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/SignedPushConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SignedPushConfig.java index 942e7d7742..83b4acaea2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SignedPushConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SignedPushConfig.java @@ -55,6 +55,7 @@ public class SignedPushConfig { /** Key for {@link Config#get(SectionParser)}. */ public static final SectionParser<SignedPushConfig> KEY = new SectionParser<SignedPushConfig>() { + @Override public SignedPushConfig parse(Config cfg) { return new SignedPushConfig(cfg); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java index 5fd2f84b7e..8a28e3a7d7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java @@ -103,7 +103,7 @@ public class TestProtocol<C> extends TransportProtocol { ReceivePackFactory<C> receivePackFactory) { this.uploadPackFactory = uploadPackFactory; this.receivePackFactory = receivePackFactory; - this.handles = new HashMap<URIish, Handle>(); + this.handles = new HashMap<>(); } @Override @@ -174,7 +174,7 @@ public class TestProtocol<C> extends TransportProtocol { public FetchConnection openFetch() throws NotSupportedException, TransportException { handle.remote.incrementOpen(); - return new InternalFetchConnection<C>( + return new InternalFetchConnection<>( this, uploadPackFactory, handle.req, handle.remote); } @@ -182,7 +182,7 @@ public class TestProtocol<C> extends TransportProtocol { public PushConnection openPush() throws NotSupportedException, TransportException { handle.remote.incrementOpen(); - return new InternalPushConnection<C>( + return new InternalPushConnection<>( this, receivePackFactory, handle.req, handle.remote); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java index 72c9c8b93e..2198b50f0d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java @@ -70,6 +70,7 @@ public class TransferConfig { /** Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<TransferConfig> KEY = new SectionParser<TransferConfig>() { + @Override public TransferConfig parse(final Config cfg) { return new TransferConfig(cfg); } @@ -207,8 +208,9 @@ public class TransferConfig { return RefFilter.DEFAULT; return new RefFilter() { + @Override public Map<String, Ref> filter(Map<String, Ref> refs) { - Map<String, Ref> result = new HashMap<String, Ref>(); + Map<String, Ref> result = new HashMap<>(); for (Map.Entry<String, Ref> e : refs.entrySet()) { boolean add = true; for (String hide : hideRefs) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java index df860695df..649e840626 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java @@ -80,6 +80,7 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectChecker; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; @@ -108,7 +109,7 @@ public abstract class Transport implements AutoCloseable { } private static final List<WeakReference<TransportProtocol>> protocols = - new CopyOnWriteArrayList<WeakReference<TransportProtocol>>(); + new CopyOnWriteArrayList<>(); static { // Registration goes backwards in order of priority. @@ -225,7 +226,7 @@ public abstract class Transport implements AutoCloseable { * the protocol definition. Must not be null. */ public static void register(TransportProtocol proto) { - protocols.add(0, new WeakReference<TransportProtocol>(proto)); + protocols.add(0, new WeakReference<>(proto)); } /** @@ -255,7 +256,7 @@ public abstract class Transport implements AutoCloseable { */ public static List<TransportProtocol> getTransportProtocols() { int cnt = protocols.size(); - List<TransportProtocol> res = new ArrayList<TransportProtocol>(cnt); + List<TransportProtocol> res = new ArrayList<>(cnt); for (WeakReference<TransportProtocol> ref : protocols) { TransportProtocol proto = ref.get(); if (proto != null) @@ -379,7 +380,7 @@ public abstract class Transport implements AutoCloseable { TransportException { final RemoteConfig cfg = new RemoteConfig(local.getConfig(), remote); if (doesNotExist(cfg)) { - final ArrayList<Transport> transports = new ArrayList<Transport>(1); + final ArrayList<Transport> transports = new ArrayList<>(1); transports.add(open(local, new URIish(remote), null)); return transports; } @@ -489,7 +490,7 @@ public abstract class Transport implements AutoCloseable { final RemoteConfig cfg, final Operation op) throws NotSupportedException, TransportException { final List<URIish> uris = getURIs(cfg, op); - final List<Transport> transports = new ArrayList<Transport>(uris.size()); + final List<Transport> transports = new ArrayList<>(uris.size()); for (final URIish uri : uris) { final Transport tn = open(local, uri, cfg.getName()); tn.applyConfig(cfg); @@ -603,14 +604,16 @@ public abstract class Transport implements AutoCloseable { * Convert push remote refs update specification from {@link RefSpec} form * to {@link RemoteRefUpdate}. Conversion expands wildcards by matching * source part to local refs. expectedOldObjectId in RemoteRefUpdate is - * always set as null. Tracking branch is configured if RefSpec destination - * matches source of any fetch ref spec for this transport remote - * configuration. + * set when specified in leases. Tracking branch is configured if RefSpec + * destination matches source of any fetch ref spec for this transport + * remote configuration. * * @param db * local database. * @param specs * collection of RefSpec to convert. + * @param leases + * map from ref to lease (containing expected old object id) * @param fetchSpecs * fetch specifications used for finding localtracking refs. May * be null or empty collection. @@ -618,13 +621,15 @@ public abstract class Transport implements AutoCloseable { * @throws IOException * when problem occurred during conversion or specification set * up: most probably, missing objects or refs. + * @since 4.7 */ public static Collection<RemoteRefUpdate> findRemoteRefUpdatesFor( final Repository db, final Collection<RefSpec> specs, + final Map<String, RefLeaseSpec> leases, Collection<RefSpec> fetchSpecs) throws IOException { if (fetchSpecs == null) fetchSpecs = Collections.emptyList(); - final List<RemoteRefUpdate> result = new LinkedList<RemoteRefUpdate>(); + final List<RemoteRefUpdate> result = new LinkedList<>(); final Collection<RefSpec> procRefs = expandPushWildcardsFor(db, specs); for (final RefSpec spec : procRefs) { @@ -652,18 +657,48 @@ public abstract class Transport implements AutoCloseable { final boolean forceUpdate = spec.isForceUpdate(); final String localName = findTrackingRefName(destSpec, fetchSpecs); + final RefLeaseSpec leaseSpec = leases.get(destSpec); + final ObjectId expected = leaseSpec == null ? null : + db.resolve(leaseSpec.getExpected()); final RemoteRefUpdate rru = new RemoteRefUpdate(db, srcSpec, - destSpec, forceUpdate, localName, null); + destSpec, forceUpdate, localName, expected); result.add(rru); } return result; } + /** + * Convert push remote refs update specification from {@link RefSpec} form + * to {@link RemoteRefUpdate}. Conversion expands wildcards by matching + * source part to local refs. expectedOldObjectId in RemoteRefUpdate is + * always set as null. Tracking branch is configured if RefSpec destination + * matches source of any fetch ref spec for this transport remote + * configuration. + * + * @param db + * local database. + * @param specs + * collection of RefSpec to convert. + * @param fetchSpecs + * fetch specifications used for finding localtracking refs. May + * be null or empty collection. + * @return collection of set up {@link RemoteRefUpdate}. + * @throws IOException + * when problem occurred during conversion or specification set + * up: most probably, missing objects or refs. + */ + public static Collection<RemoteRefUpdate> findRemoteRefUpdatesFor( + final Repository db, final Collection<RefSpec> specs, + Collection<RefSpec> fetchSpecs) throws IOException { + return findRemoteRefUpdatesFor(db, specs, Collections.emptyMap(), + fetchSpecs); + } + private static Collection<RefSpec> expandPushWildcardsFor( final Repository db, final Collection<RefSpec> specs) throws IOException { final Map<String, Ref> localRefs = db.getRefDatabase().getRefs(ALL); - final Collection<RefSpec> procRefs = new HashSet<RefSpec>(); + final Collection<RefSpec> procRefs = new HashSet<>(); for (final RefSpec spec : specs) { if (spec.isWildcard()) { @@ -1182,7 +1217,7 @@ public abstract class Transport implements AutoCloseable { // the local tracking branches without incurring additional // object transfer overheads. // - final Collection<RefSpec> tmp = new ArrayList<RefSpec>(toFetch); + final Collection<RefSpec> tmp = new ArrayList<>(toFetch); for (final RefSpec requested : toFetch) { final String reqSrc = requested.getSource(); for (final RefSpec configured : fetch) { @@ -1341,7 +1376,36 @@ public abstract class Transport implements AutoCloseable { */ public Collection<RemoteRefUpdate> findRemoteRefUpdatesFor( final Collection<RefSpec> specs) throws IOException { - return findRemoteRefUpdatesFor(local, specs, fetch); + return findRemoteRefUpdatesFor(local, specs, Collections.emptyMap(), + fetch); + } + + /** + * Convert push remote refs update specification from {@link RefSpec} form + * to {@link RemoteRefUpdate}. Conversion expands wildcards by matching + * source part to local refs. expectedOldObjectId in RemoteRefUpdate is + * set according to leases. Tracking branch is configured if RefSpec destination + * matches source of any fetch ref spec for this transport remote + * configuration. + * <p> + * Conversion is performed for context of this transport (database, fetch + * specifications). + * + * @param specs + * collection of RefSpec to convert. + * @param leases + * map from ref to lease (containing expected old object id) + * @return collection of set up {@link RemoteRefUpdate}. + * @throws IOException + * when problem occurred during conversion or specification set + * up: most probably, missing objects or refs. + * @since 4.7 + */ + public Collection<RemoteRefUpdate> findRemoteRefUpdatesFor( + final Collection<RefSpec> specs, + final Map<String, RefLeaseSpec> leases) throws IOException { + return findRemoteRefUpdatesFor(local, specs, leases, + fetch); } /** @@ -1383,5 +1447,6 @@ public abstract class Transport implements AutoCloseable { * Implementers shouldn't throw checked exceptions. This override narrows * the signature to prevent them from doing so. */ + @Override public abstract void close(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java index 23c506b128..6cd119bd2f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java @@ -101,23 +101,28 @@ public class TransportAmazonS3 extends HttpTransport implements WalkTransport { static final String S3_SCHEME = "amazon-s3"; //$NON-NLS-1$ static final TransportProtocol PROTO_S3 = new TransportProtocol() { + @Override public String getName() { return "Amazon S3"; //$NON-NLS-1$ } + @Override public Set<String> getSchemes() { return Collections.singleton(S3_SCHEME); } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.USER, URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.PASS)); } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportAmazonS3(local, uri); @@ -265,10 +270,10 @@ public class TransportAmazonS3 extends HttpTransport implements WalkTransport { @Override Collection<String> getPackNames() throws IOException { - final HashSet<String> have = new HashSet<String>(); + final HashSet<String> have = new HashSet<>(); have.addAll(s3.list(bucket, resolveKey("pack"))); //$NON-NLS-1$ - final Collection<String> packs = new ArrayList<String>(); + final Collection<String> packs = new ArrayList<>(); for (final String n : have) { if (!n.startsWith("pack-") || !n.endsWith(".pack")) //$NON-NLS-1$ //$NON-NLS-2$ continue; @@ -307,7 +312,7 @@ public class TransportAmazonS3 extends HttpTransport implements WalkTransport { } Map<String, Ref> readAdvertisedRefs() throws TransportException { - final TreeMap<String, Ref> avail = new TreeMap<String, Ref>(); + final TreeMap<String, Ref> avail = new TreeMap<>(); readPackedRefs(avail); readLooseRefs(avail); readRef(avail, Constants.HEAD); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java index 9b0834133b..f2ddc0d0d1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java @@ -66,7 +66,7 @@ class TransportBundleFile extends Transport implements TransportBundle { private final String[] schemeNames = { "bundle", "file" }; //$NON-NLS-1$ //$NON-NLS-2$ private final Set<String> schemeSet = Collections - .unmodifiableSet(new LinkedHashSet<String>(Arrays + .unmodifiableSet(new LinkedHashSet<>(Arrays .asList(schemeNames))); @Override @@ -74,6 +74,7 @@ class TransportBundleFile extends Transport implements TransportBundle { return JGitText.get().transportProtoBundleFile; } + @Override public Set<String> getSchemes() { return schemeSet; } @@ -106,6 +107,7 @@ class TransportBundleFile extends Transport implements TransportBundle { return TransportLocal.PROTO_LOCAL.open(uri, local, remoteName); } + @Override public Transport open(URIish uri) throws NotSupportedException, TransportException { if ("bundle".equals(uri.getScheme())) { //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java index c6e4c50801..7bf5b947d8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java @@ -75,27 +75,33 @@ class TransportGitAnon extends TcpTransport implements PackTransport { static final int GIT_PORT = Daemon.DEFAULT_PORT; static final TransportProtocol PROTO_GIT = new TransportProtocol() { + @Override public String getName() { return JGitText.get().transportProtoGitAnon; } + @Override public Set<String> getSchemes() { return Collections.singleton("git"); //$NON-NLS-1$ } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.PORT)); } + @Override public int getDefaultPort() { return GIT_PORT; } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportGitAnon(local, uri); 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..9a40f47cb7 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; @@ -86,27 +87,32 @@ public class TransportGitSsh extends SshTransport implements PackTransport { private final String[] schemeNames = { "ssh", "ssh+git", "git+ssh" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ private final Set<String> schemeSet = Collections - .unmodifiableSet(new LinkedHashSet<String>(Arrays + .unmodifiableSet(new LinkedHashSet<>(Arrays .asList(schemeNames))); + @Override public String getName() { return JGitText.get().transportProtoSSH; } + @Override public Set<String> getSchemes() { return schemeSet; } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.USER, URIishField.PASS, URIishField.PORT)); } + @Override public int getDefaultPort() { return 22; } @@ -123,6 +129,7 @@ public class TransportGitSsh extends SshTransport implements PackTransport { return super.canHandle(uri, local, remoteName); } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportGitSsh(local, uri); @@ -214,14 +221,16 @@ public class TransportGitSsh extends SshTransport implements PackTransport { } private class ExtSession implements RemoteSession { + @Override 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>(); + List<String> args = new ArrayList<>(); 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$ @@ -248,6 +257,7 @@ public class TransportGitSsh extends SshTransport implements PackTransport { } } + @Override public void disconnect() { // Nothing to do } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java index 96a6fe1d01..26a254d946 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java @@ -52,6 +52,7 @@ import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT; import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT_ENCODING; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_TYPE; +import static org.eclipse.jgit.util.HttpSupport.HDR_LOCATION; import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA; import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT; import static org.eclipse.jgit.util.HttpSupport.HDR_WWW_AUTHENTICATE; @@ -153,64 +154,77 @@ public class TransportHttp extends HttpTransport implements WalkTransport, private final String[] schemeNames = { "http", "https" }; //$NON-NLS-1$ //$NON-NLS-2$ private final Set<String> schemeSet = Collections - .unmodifiableSet(new LinkedHashSet<String>(Arrays + .unmodifiableSet(new LinkedHashSet<>(Arrays .asList(schemeNames))); + @Override public String getName() { return JGitText.get().transportProtoHTTP; } + @Override public Set<String> getSchemes() { return schemeSet; } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.USER, URIishField.PASS, URIishField.PORT)); } + @Override public int getDefaultPort() { return 80; } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportHttp(local, uri); } + @Override public Transport open(URIish uri) throws NotSupportedException { return new TransportHttp(uri); } }; static final TransportProtocol PROTO_FTP = new TransportProtocol() { + @Override public String getName() { return JGitText.get().transportProtoFTP; } + @Override public Set<String> getSchemes() { return Collections.singleton("ftp"); //$NON-NLS-1$ } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.USER, URIishField.PASS, URIishField.PORT)); } + @Override public int getDefaultPort() { return 21; } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportHttp(local, uri); @@ -218,6 +232,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, }; private static final Config.SectionParser<HttpConfig> HTTP_KEY = new SectionParser<HttpConfig>() { + @Override public HttpConfig parse(final Config cfg) { return new HttpConfig(cfg); } @@ -536,7 +551,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } catch (IOException e) { if (authMethod.getType() != HttpAuthMethod.Type.NONE) { if (ignoreTypes == null) { - ignoreTypes = new HashSet<Type>(); + ignoreTypes = new HashSet<>(); } ignoreTypes.add(authMethod.getType()); @@ -711,7 +726,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, @Override Collection<String> getPackNames() throws IOException { - final Collection<String> packs = new ArrayList<String>(); + final Collection<String> packs = new ArrayList<>(); try { final BufferedReader br = openReader(INFO_PACKS); try { @@ -764,7 +779,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, Map<String, Ref> readAdvertisedImpl(final BufferedReader br) throws IOException, PackProtocolException { - final TreeMap<String, Ref> avail = new TreeMap<String, Ref>(); + final TreeMap<String, Ref> avail = new TreeMap<>(); for (;;) { String line = br.readLine(); if (line == null) @@ -862,6 +877,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, readAdvertisedRefs(); } + @Override protected void doPush(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates, OutputStream outputStream) throws TransportException { @@ -898,9 +914,13 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } void openStream() throws IOException { + openStream(null); + } + + void openStream(final String redirectUrl) throws IOException { conn = httpOpen( METHOD_POST, - new URL(baseUrl, serviceName), + redirectUrl == null ? new URL(baseUrl, serviceName) : new URL(redirectUrl), AcceptEncoding.GZIP); conn.setInstanceFollowRedirects(false); conn.setDoOutput(true); @@ -909,6 +929,10 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } void sendRequest() throws IOException { + sendRequest(null); + } + + void sendRequest(final String redirectUrl) throws IOException { // Try to compress the content, but only if that is smaller. TemporaryBuffer buf = new TemporaryBuffer.Heap(http.postBuffer); try { @@ -923,7 +947,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, buf = out; } - openStream(); + openStream(redirectUrl); if (buf != out) conn.setRequestProperty(HDR_CONTENT_ENCODING, ENCODING_GZIP); conn.setFixedLengthStreamingMode((int) buf.length()); @@ -933,6 +957,12 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } finally { httpOut.close(); } + + final int status = HttpSupport.response(conn); + if (status == HttpConnection.HTTP_MOVED_PERM) { + String locationHeader = HttpSupport.responseHeader(conn, HDR_LOCATION); + sendRequest(locationHeader); + } } void openResponse() throws IOException { @@ -960,16 +990,19 @@ public class TransportHttp extends HttpTransport implements WalkTransport, abstract void execute() throws IOException; class HttpExecuteStream extends InputStream { + @Override public int read() throws IOException { execute(); return -1; } + @Override public int read(byte[] b, int off, int len) throws IOException { execute(); return -1; } + @Override public long skip(long n) throws IOException { execute(); return 0; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java index 1528c71426..f483ec7f9f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java @@ -100,6 +100,7 @@ class TransportLocal extends Transport implements PackTransport { return JGitText.get().transportProtoLocal; } + @Override public Set<String> getSchemes() { return Collections.singleton("file"); //$NON-NLS-1$ } @@ -132,6 +133,7 @@ class TransportLocal extends Transport implements PackTransport { return new TransportLocal(local, uri, gitDir); } + @Override public Transport open(URIish uri) throws NotSupportedException, TransportException { File path = FS.DETECTED.resolve(new File("."), uri.getPath()); //$NON-NLS-1$ @@ -189,7 +191,7 @@ class TransportLocal extends Transport implements PackTransport { return createUploadPack(db); } }; - return new InternalFetchConnection<Void>(this, upf, null, openRepo()); + return new InternalFetchConnection<>(this, upf, null, openRepo()); } @Override @@ -205,7 +207,7 @@ class TransportLocal extends Transport implements PackTransport { return createReceivePack(db); } }; - return new InternalPushConnection<Void>(this, rpf, null, openRepo()); + return new InternalPushConnection<>(this, rpf, null, openRepo()); } @Override 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 fa073ae2af..c46f94b7da 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java @@ -99,28 +99,34 @@ import com.jcraft.jsch.SftpException; */ public class TransportSftp extends SshTransport implements WalkTransport { static final TransportProtocol PROTO_SFTP = new TransportProtocol() { + @Override public String getName() { return JGitText.get().transportProtoSFTP; } + @Override public Set<String> getSchemes() { return Collections.singleton("sftp"); //$NON-NLS-1$ } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.USER, URIishField.PASS, URIishField.PORT)); } + @Override public int getDefaultPort() { return 22; } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportSftp(local, uri); @@ -225,15 +231,15 @@ public class TransportSftp extends SshTransport implements WalkTransport { @Override Collection<String> getPackNames() throws IOException { - final List<String> packs = new ArrayList<String>(); + final List<String> packs = new ArrayList<>(); try { @SuppressWarnings("unchecked") final Collection<ChannelSftp.LsEntry> list = ftp.ls("pack"); //$NON-NLS-1$ final HashMap<String, ChannelSftp.LsEntry> files; final HashMap<String, Integer> mtimes; - files = new HashMap<String, ChannelSftp.LsEntry>(); - mtimes = new HashMap<String, Integer>(); + files = new HashMap<>(); + mtimes = new HashMap<>(); for (final ChannelSftp.LsEntry ent : list) files.put(ent.getFilename(), ent); @@ -251,6 +257,7 @@ public class TransportSftp extends SshTransport implements WalkTransport { } Collections.sort(packs, new Comparator<String>() { + @Override public int compare(final String o1, final String o2) { return mtimes.get(o2).intValue() - mtimes.get(o1).intValue(); @@ -381,7 +388,7 @@ public class TransportSftp extends SshTransport implements WalkTransport { } Map<String, Ref> readAdvertisedRefs() throws TransportException { - final TreeMap<String, Ref> avail = new TreeMap<String, Ref>(); + final TreeMap<String, Ref> avail = new TreeMap<>(); readPackedRefs(avail); readRef(avail, ROOT_DIR + Constants.HEAD, Constants.HEAD); readLooseRefs(avail, ROOT_DIR + "refs", "refs/"); //$NON-NLS-1$ //$NON-NLS-2$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java index 3c5c8daddd..ffd4d41f2a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java @@ -560,6 +560,7 @@ public class URIish implements Serializable { return r; } + @Override public int hashCode() { int hc = 0; if (getScheme() != null) @@ -577,6 +578,7 @@ public class URIish implements Serializable { return hc; } + @Override public boolean equals(final Object obj) { if (!(obj instanceof URIish)) return false; @@ -615,6 +617,7 @@ public class URIish implements Serializable { return format(true, false); } + @Override public String toString() { return format(false, false); } 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 201fb18740..58fdd25745 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -177,7 +177,7 @@ public class UploadPack { */ public FirstLine(String line) { if (line.length() > 45) { - final HashSet<String> opts = new HashSet<String>(); + final HashSet<String> opts = new HashSet<>(); String opt = line.substring(45); if (opt.startsWith(" ")) //$NON-NLS-1$ opt = opt.substring(1); @@ -263,19 +263,19 @@ public class UploadPack { String userAgent; /** Raw ObjectIds the client has asked for, before validating them. */ - private final Set<ObjectId> wantIds = new HashSet<ObjectId>(); + private final Set<ObjectId> wantIds = new HashSet<>(); /** Objects the client wants to obtain. */ - private final Set<RevObject> wantAll = new HashSet<RevObject>(); + private final Set<RevObject> wantAll = new HashSet<>(); /** Objects on both sides, these don't have to be sent. */ - private final Set<RevObject> commonBase = new HashSet<RevObject>(); + private final Set<RevObject> commonBase = new HashSet<>(); /** Shallow commits the client already has. */ - private final Set<ObjectId> clientShallowCommits = new HashSet<ObjectId>(); + private final Set<ObjectId> clientShallowCommits = new HashSet<>(); /** Shallow commits on the client which are now becoming unshallow */ - private final List<ObjectId> unshallowCommits = new ArrayList<ObjectId>(); + private final List<ObjectId> unshallowCommits = new ArrayList<>(); /** Desired depth from the client on a shallow request. */ private int depth; @@ -776,7 +776,7 @@ public class UploadPack { } private static Set<ObjectId> refIdSet(Collection<Ref> refs) { - Set<ObjectId> ids = new HashSet<ObjectId>(refs.size()); + Set<ObjectId> ids = new HashSet<>(refs.size()); for (Ref ref : refs) { ObjectId id = ref.getObjectId(); if (id != null) { @@ -1018,7 +1018,7 @@ public class UploadPack { okToGiveUp = Boolean.FALSE; ObjectId last = ObjectId.zeroId(); - List<ObjectId> peerHas = new ArrayList<ObjectId>(64); + List<ObjectId> peerHas = new ArrayList<>(64); for (;;) { String line; try { @@ -1172,7 +1172,7 @@ public class UploadPack { for (ObjectId obj : wantIds) { if (!advertised.contains(obj)) { if (notAdvertisedWants == null) - notAdvertisedWants = new ArrayList<ObjectId>(); + notAdvertisedWants = new ArrayList<>(); notAdvertisedWants.add(obj); } } @@ -1215,6 +1215,7 @@ public class UploadPack { */ public static final class AdvertisedRequestValidator implements RequestValidator { + @Override public void checkWants(UploadPack up, List<ObjectId> wants) throws PackProtocolException, IOException { if (!up.isBiDirectionalPipe()) @@ -1231,6 +1232,7 @@ public class UploadPack { */ public static final class ReachableCommitRequestValidator implements RequestValidator { + @Override public void checkWants(UploadPack up, List<ObjectId> wants) throws PackProtocolException, IOException { checkNotAdvertisedWants(up.getRevWalk(), wants, @@ -1244,6 +1246,7 @@ public class UploadPack { * @since 3.1 */ public static final class TipRequestValidator implements RequestValidator { + @Override public void checkWants(UploadPack up, List<ObjectId> wants) throws PackProtocolException, IOException { if (!up.isBiDirectionalPipe()) @@ -1266,6 +1269,7 @@ public class UploadPack { */ public static final class ReachableCommitTipRequestValidator implements RequestValidator { + @Override public void checkWants(UploadPack up, List<ObjectId> wants) throws PackProtocolException, IOException { checkNotAdvertisedWants(up.getRevWalk(), wants, @@ -1279,6 +1283,7 @@ public class UploadPack { * @since 3.1 */ public static final class AnyRequestValidator implements RequestValidator { + @Override public void checkWants(UploadPack up, List<ObjectId> wants) throws PackProtocolException, IOException { // All requests are valid. @@ -1483,7 +1488,7 @@ public class UploadPack { pw.setReuseValidatingObjects(false); if (commonBase.isEmpty() && refs != null) { - Set<ObjectId> tagTargets = new HashSet<ObjectId>(); + Set<ObjectId> tagTargets = new HashSet<>(); for (Ref ref : refs.values()) { if (ref.getPeeledObjectId() != null) tagTargets.add(ref.getPeeledObjectId()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java index 0588634d2a..afc9965183 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java @@ -59,6 +59,7 @@ import org.eclipse.jgit.internal.storage.pack.PackWriter; public interface UploadPackLogger { // TODO remove in JGit 5.0 /** A simple no-op logger. */ public static final UploadPackLogger NULL = new UploadPackLogger() { + @Override public void onPackStatistics(PackWriter.Statistics stats) { // Do nothing. } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java index 4ea0319d9c..9a8c12c648 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java @@ -84,6 +84,7 @@ public class UploadPackLoggerChain implements UploadPackLogger { /** * @since 3.0 */ + @Override public void onPackStatistics(PackWriter.Statistics stats) { for (int i = 0; i < count; i++) loggers[i].onPackStatistics(stats); 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/transport/WalkFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java index 13d4a24b02..3d60aedcca 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java @@ -197,20 +197,20 @@ class WalkFetchConnection extends BaseFetchConnection { inserter = local.newObjectInserter(); reader = inserter.newReader(); - remotes = new ArrayList<WalkRemoteObjectDatabase>(); + remotes = new ArrayList<>(); remotes.add(w); - unfetchedPacks = new LinkedList<RemotePack>(); - packsConsidered = new HashSet<String>(); + unfetchedPacks = new LinkedList<>(); + packsConsidered = new HashSet<>(); - noPacksYet = new LinkedList<WalkRemoteObjectDatabase>(); + noPacksYet = new LinkedList<>(); noPacksYet.add(w); - noAlternatesYet = new LinkedList<WalkRemoteObjectDatabase>(); + noAlternatesYet = new LinkedList<>(); noAlternatesYet.add(w); - fetchErrors = new HashMap<ObjectId, List<Throwable>>(); - packLocks = new ArrayList<PackLock>(4); + fetchErrors = new HashMap<>(); + packLocks = new ArrayList<>(4); revWalk = new RevWalk(reader); revWalk.setRetainBody(false); @@ -220,9 +220,10 @@ class WalkFetchConnection extends BaseFetchConnection { LOCALLY_SEEN = revWalk.newFlag("LOCALLY_SEEN"); //$NON-NLS-1$ localCommitQueue = new DateRevQueue(); - workQueue = new LinkedList<ObjectId>(); + workQueue = new LinkedList<>(); } + @Override public boolean didFetchTestConnectivity() { return true; } @@ -248,10 +249,12 @@ class WalkFetchConnection extends BaseFetchConnection { } } + @Override public Collection<PackLock> getPackLocks() { return packLocks; } + @Override public void setPackLockMessage(final String message) { lockMessage = message; } @@ -270,7 +273,7 @@ class WalkFetchConnection extends BaseFetchConnection { private void queueWants(final Collection<Ref> want) throws TransportException { - final HashSet<ObjectId> inWorkQueue = new HashSet<ObjectId>(); + final HashSet<ObjectId> inWorkQueue = new HashSet<>(); for (final Ref r : want) { final ObjectId id = r.getObjectId(); if (id == null) { @@ -594,7 +597,7 @@ class WalkFetchConnection extends BaseFetchConnection { private Iterator<ObjectId> swapFetchQueue() { final Iterator<ObjectId> r = workQueue.iterator(); - workQueue = new LinkedList<ObjectId>(); + workQueue = new LinkedList<>(); return r; } @@ -791,7 +794,7 @@ class WalkFetchConnection extends BaseFetchConnection { final ObjectId objId = id.copy(); List<Throwable> errors = fetchErrors.get(objId); if (errors == null) { - errors = new ArrayList<Throwable>(2); + errors = new ArrayList<>(2); fetchErrors.put(objId, errors); } errors.add(what); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java index 7b449c752a..5c4e14ca31 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java @@ -134,25 +134,27 @@ class WalkPushConnection extends BaseConnection implements PushConnection { dest = w; } + @Override public void push(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates) throws TransportException { push(monitor, refUpdates, null); } + @Override public void push(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates, OutputStream out) throws TransportException { markStartedOperation(); packNames = null; - newRefs = new TreeMap<String, Ref>(getRefsMap()); - packedRefUpdates = new ArrayList<RemoteRefUpdate>(refUpdates.size()); + newRefs = new TreeMap<>(getRefsMap()); + packedRefUpdates = new ArrayList<>(refUpdates.size()); // Filter the commands and issue all deletes first. This way we // can correctly handle a directory being cleared out and a new // ref using the directory name being created. // - final List<RemoteRefUpdate> updates = new ArrayList<RemoteRefUpdate>(); + final List<RemoteRefUpdate> updates = new ArrayList<>(); for (final RemoteRefUpdate u : refUpdates.values()) { final String n = u.getRemoteName(); if (!n.startsWith("refs/") || !Repository.isValidRefName(n)) { //$NON-NLS-1$ @@ -223,8 +225,8 @@ class WalkPushConnection extends BaseConnection implements PushConnection { try (final PackWriter writer = new PackWriter(transport.getPackConfig(), local.newObjectReader())) { - final Set<ObjectId> need = new HashSet<ObjectId>(); - final Set<ObjectId> have = new HashSet<ObjectId>(); + final Set<ObjectId> need = new HashSet<>(); + final Set<ObjectId> have = new HashSet<>(); for (final RemoteRefUpdate r : updates) need.add(r.getNewObjectId()); for (final Ref r : getRefs()) { @@ -241,7 +243,7 @@ class WalkPushConnection extends BaseConnection implements PushConnection { if (writer.getObjectCount() == 0) return; - packNames = new LinkedHashMap<String, String>(); + packNames = new LinkedHashMap<>(); for (final String n : dest.getPackNames()) packNames.put(n, n); @@ -277,7 +279,7 @@ class WalkPushConnection extends BaseConnection implements PushConnection { // way clients are likely to consult the newest pack first, // and discover the most recent objects there. // - final ArrayList<String> infoPacks = new ArrayList<String>(); + final ArrayList<String> infoPacks = new ArrayList<>(); infoPacks.add(packName); infoPacks.addAll(packNames.keySet()); dest.writeInfoPacks(infoPacks); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java index 24f30ed206..17f8c3ec19 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java @@ -396,7 +396,7 @@ abstract class WalkRemoteObjectDatabase { throws IOException { final BufferedReader br = openReader(listPath); try { - final Collection<WalkRemoteObjectDatabase> alts = new ArrayList<WalkRemoteObjectDatabase>(); + final Collection<WalkRemoteObjectDatabase> alts = new ArrayList<>(); for (;;) { String line = br.readLine(); if (line == null) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java index 09613fd7ac..58081c1c90 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java @@ -73,6 +73,12 @@ public interface HttpConnection { public static final int HTTP_OK = java.net.HttpURLConnection.HTTP_OK; /** + * @see HttpURLConnection#HTTP_MOVED_PERM + * @since 4.7 + */ + public static final int HTTP_MOVED_PERM = java.net.HttpURLConnection.HTTP_MOVED_PERM; + + /** * @see HttpURLConnection#HTTP_NOT_FOUND */ public static final int HTTP_NOT_FOUND = java.net.HttpURLConnection.HTTP_NOT_FOUND; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java index ed37feab3f..534e3d734f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java @@ -94,95 +94,118 @@ public class JDKHttpConnection implements HttpConnection { .openConnection(proxy); } + @Override public int getResponseCode() throws IOException { return wrappedUrlConnection.getResponseCode(); } + @Override public URL getURL() { return wrappedUrlConnection.getURL(); } + @Override public String getResponseMessage() throws IOException { return wrappedUrlConnection.getResponseMessage(); } + @Override public Map<String, List<String>> getHeaderFields() { return wrappedUrlConnection.getHeaderFields(); } + @Override public void setRequestProperty(String key, String value) { wrappedUrlConnection.setRequestProperty(key, value); } + @Override public void setRequestMethod(String method) throws ProtocolException { wrappedUrlConnection.setRequestMethod(method); } + @Override public void setUseCaches(boolean usecaches) { wrappedUrlConnection.setUseCaches(usecaches); } + @Override public void setConnectTimeout(int timeout) { wrappedUrlConnection.setConnectTimeout(timeout); } + @Override public void setReadTimeout(int timeout) { wrappedUrlConnection.setReadTimeout(timeout); } + @Override public String getContentType() { return wrappedUrlConnection.getContentType(); } + @Override public InputStream getInputStream() throws IOException { return wrappedUrlConnection.getInputStream(); } + @Override public String getHeaderField(String name) { return wrappedUrlConnection.getHeaderField(name); } + @Override public int getContentLength() { return wrappedUrlConnection.getContentLength(); } + @Override public void setInstanceFollowRedirects(boolean followRedirects) { wrappedUrlConnection.setInstanceFollowRedirects(followRedirects); } + @Override public void setDoOutput(boolean dooutput) { wrappedUrlConnection.setDoOutput(dooutput); } + @Override public void setFixedLengthStreamingMode(int contentLength) { wrappedUrlConnection.setFixedLengthStreamingMode(contentLength); } + @Override public OutputStream getOutputStream() throws IOException { return wrappedUrlConnection.getOutputStream(); } + @Override public void setChunkedStreamingMode(int chunklen) { wrappedUrlConnection.setChunkedStreamingMode(chunklen); } + @Override public String getRequestMethod() { return wrappedUrlConnection.getRequestMethod(); } + @Override public boolean usingProxy() { return wrappedUrlConnection.usingProxy(); } + @Override public void connect() throws IOException { wrappedUrlConnection.connect(); } + @Override public void setHostnameVerifier(HostnameVerifier hostnameverifier) { ((HttpsURLConnection) wrappedUrlConnection) .setHostnameVerifier(hostnameverifier); } + @Override public void configure(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnectionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnectionFactory.java index d1c875d40f..b9f009f1b7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnectionFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnectionFactory.java @@ -52,10 +52,12 @@ import java.net.URL; * @since 3.3 */ public class JDKHttpConnectionFactory implements HttpConnectionFactory { + @Override public HttpConnection create(URL url) throws IOException { return new JDKHttpConnection(url); } + @Override public HttpConnection create(URL url, Proxy proxy) throws IOException { return new JDKHttpConnection(url, proxy); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java index 6964e7fa28..7654d462eb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java @@ -72,8 +72,8 @@ public class FileResolver<C> implements RepositoryResolver<C> { /** Initialize an empty file based resolver. */ public FileResolver() { - exports = new ConcurrentHashMap<String, Repository>(); - exportBase = new CopyOnWriteArrayList<File>(); + exports = new ConcurrentHashMap<>(); + exportBase = new CopyOnWriteArrayList<>(); } /** @@ -91,6 +91,7 @@ public class FileResolver<C> implements RepositoryResolver<C> { setExportAll(exportAll); } + @Override public Repository open(final C req, final String name) throws RepositoryNotFoundException, ServiceNotEnabledException { if (isUnreasonableName(name)) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java index 4cf49f5531..73c2ed80c9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java @@ -55,6 +55,7 @@ import org.eclipse.jgit.transport.ReceivePack; public interface ReceivePackFactory<C> { /** A factory disabling the ReceivePack service for all repositories */ public static final ReceivePackFactory<?> DISABLED = new ReceivePackFactory<Object>() { + @Override public ReceivePack create(Object req, Repository db) throws ServiceNotEnabledException { throw new ServiceNotEnabledException(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java index c7f0d32cb4..80211e5812 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java @@ -56,6 +56,7 @@ import org.eclipse.jgit.transport.ServiceMayNotContinueException; public interface RepositoryResolver<C> { /** Resolver configured to open nothing. */ public static final RepositoryResolver<?> NONE = new RepositoryResolver<Object>() { + @Override public Repository open(Object req, String name) throws RepositoryNotFoundException { throw new RepositoryNotFoundException(name); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java index f0d2ba865b..d7ed0f68cf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java @@ -55,6 +55,7 @@ import org.eclipse.jgit.transport.UploadPack; public interface UploadPackFactory<C> { /** A factory disabling the UploadPack service for all repositories. */ public static final UploadPackFactory<?> DISABLED = new UploadPackFactory<Object>() { + @Override public UploadPack create(Object req, Repository db) throws ServiceNotEnabledException { throw new ServiceNotEnabledException(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java index c038f07725..2d6abd1ad0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java @@ -249,6 +249,7 @@ public class CanonicalTreeParser extends AbstractTreeIterator { return p; } + @Override public CanonicalTreeParser createSubtreeIterator(final ObjectReader reader) throws IncorrectObjectTypeException, IOException { return createSubtreeIterator(reader, new MutableObjectId()); @@ -280,6 +281,7 @@ public class CanonicalTreeParser extends AbstractTreeIterator { return currPtr == 0; } + @Override public boolean eof() { return currPtr == raw.length; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java index b9293ebfb6..c0b29ef930 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java @@ -353,6 +353,7 @@ public class NameConflictTreeWalk extends TreeWalk { dfConflict = null; } + @Override void stopWalk() throws IOException { if (!needsStopWalk()) { return; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java index 5dfebe9ca7..c54e1484ca 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java @@ -128,7 +128,7 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { * The filter command as defined in gitattributes. The keys are * filterName+"."+filterCommandType. E.g. "lfs.clean" */ - private Map<String, String> filterCommandsByNameDotType = new HashMap<String, String>(); + private Map<String, String> filterCommandsByNameDotType = new HashMap<>(); /** * @param operationType @@ -559,6 +559,7 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { * @return a {@link Set} of {@link Attribute}s that match the current entry. * @since 4.2 */ + @Override public Attributes getAttributes() { if (attrs != null) return attrs; @@ -825,7 +826,7 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { } currentHead = t; - if (!filter.include(this)) { + if (filter.matchFilter(this) == 1) { skipEntriesEqual(); continue; } @@ -1061,6 +1062,60 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { /** * Test if the supplied path matches the current entry's path. * <p> + * This method detects if the supplied path is equal to, a subtree of, or + * not similar at all to the current entry. It is faster to use this + * method than to use {@link #getPathString()} to first create a String + * object, then test <code>startsWith</code> or some other type of string + * match function. + * <p> + * If the current entry is a subtree, then all paths within the subtree + * are considered to match it. + * + * @param p + * path buffer to test. Callers should ensure the path does not + * end with '/' prior to invocation. + * @param pLen + * number of bytes from <code>buf</code> to test. + * @return -1 if the current path is a parent to p; 0 if p matches the current + * path; 1 if the current path is different and will never match + * again on this tree walk. + * @since 4.7 + */ + public int isPathMatch(final byte[] p, final int pLen) { + final AbstractTreeIterator t = currentHead; + final byte[] c = t.path; + final int cLen = t.pathLen; + int ci; + + for (ci = 0; ci < cLen && ci < pLen; ci++) { + final int c_value = (c[ci] & 0xff) - (p[ci] & 0xff); + if (c_value != 0) { + // Paths do not and will never match + return 1; + } + } + + if (ci < cLen) { + // Ran out of pattern but we still had current data. + // If c[ci] == '/' then pattern matches the subtree. + // Otherwise it is a partial match == miss + return c[ci] == '/' ? 0 : 1; + } + + if (ci < pLen) { + // Ran out of current, but we still have pattern data. + // If p[ci] == '/' then this subtree is a parent in the pattern, + // otherwise it's a miss. + return p[ci] == '/' && FileMode.TREE.equals(t.mode) ? -1 : 1; + } + + // Both strings are identical. + return 0; + } + + /** + * Test if the supplied path matches the current entry's path. + * <p> * This method tests that the supplied path is exactly equal to the current * entry or is one of its parent directories. It is faster to use this * method then to use {@link #getPathString()} to first create a String diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java index 52477cb573..b1b146c854 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -56,7 +56,6 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetEncoder; -import java.security.MessageDigest; import java.text.MessageFormat; import java.util.Arrays; import java.util.Collections; @@ -99,6 +98,7 @@ import org.eclipse.jgit.util.TemporaryBuffer; import org.eclipse.jgit.util.TemporaryBuffer.LocalFile; import org.eclipse.jgit.util.io.AutoLFInputStream; import org.eclipse.jgit.util.io.EolStreamTypeUtil; +import org.eclipse.jgit.util.sha1.SHA1; /** * Walks a working directory tree as part of a {@link TreeWalk}. @@ -364,7 +364,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { if (is == null) return zeroid; try { - state.initializeDigestAndReadBuffer(); + state.initializeReadBuffer(); final long len = e.getLength(); InputStream filteredIs = possiblyFilteredInputStream(e, is, len, @@ -715,6 +715,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { } private static final Comparator<Entry> ENTRY_CMP = new Comparator<Entry>() { + @Override public int compare(Entry a, Entry b) { return Paths.compare( a.encodedName, 0, a.encodedNameLen, a.getMode().getBits(), @@ -1098,10 +1099,9 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { } private byte[] computeHash(InputStream in, long length) throws IOException { - final MessageDigest contentDigest = state.contentDigest; + SHA1 contentDigest = SHA1.newInstance(); final byte[] contentReadBuffer = state.contentReadBuffer; - contentDigest.reset(); contentDigest.update(hblob); contentDigest.update((byte) ' '); @@ -1154,6 +1154,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { b.get(encodedName = new byte[encodedNameLen]); } + @Override public String toString() { return getMode().toString() + " " + getName(); //$NON-NLS-1$ } @@ -1328,9 +1329,6 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { /** File name character encoder. */ final CharsetEncoder nameEncoder; - /** Digest computer for {@link #contentId} computations. */ - MessageDigest contentDigest; - /** Buffer used to perform {@link #contentId} computations. */ byte[] contentReadBuffer; @@ -1345,9 +1343,8 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { this.nameEncoder = Constants.CHARSET.newEncoder(); } - void initializeDigestAndReadBuffer() { - if (contentDigest == null) { - contentDigest = Constants.newMessageDigest(); + void initializeReadBuffer() { + if (contentReadBuffer == null) { contentReadBuffer = new byte[BUFFER_SIZE]; } } @@ -1366,7 +1363,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { cmd = state.walk .getFilterCommand(Constants.ATTR_FILTER_TYPE_CLEAN); } - cleanFilterCommandHolder = new Holder<String>(cmd); + cleanFilterCommandHolder = new Holder<>(cmd); } return cleanFilterCommandHolder.get(); } @@ -1413,7 +1410,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { break; } } - eolStreamTypeHolder = new Holder<EolStreamType>(type); + eolStreamTypeHolder = new Holder<>(type); } return eolStreamTypeHolder.get(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeOptions.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeOptions.java index 112ce8fb9f..7d2b33f43d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeOptions.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeOptions.java @@ -56,6 +56,7 @@ import org.eclipse.jgit.lib.CoreConfig.SymLinks; public class WorkingTreeOptions { /** Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<WorkingTreeOptions> KEY = new SectionParser<WorkingTreeOptions>() { + @Override public WorkingTreeOptions parse(final Config cfg) { return new WorkingTreeOptions(cfg); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java index d5e7464d4f..9658166a85 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java @@ -128,7 +128,25 @@ public abstract class AndTreeFilter extends TreeFilter { public boolean include(final TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { - return a.include(walker) && b.include(walker); + return matchFilter(walker) <= 0; + } + + @Override + public int matchFilter(TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + final int ra = a.matchFilter(walker); + if (ra == 1) { + return 1; + } + final int rb = b.matchFilter(walker); + if (rb == 1) { + return 1; + } + if (ra == -1 || rb == -1) { + return -1; + } + return 0; } @Override @@ -159,11 +177,24 @@ public abstract class AndTreeFilter extends TreeFilter { public boolean include(final TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { + return matchFilter(walker) <= 0; + } + + @Override + public int matchFilter(TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + int m = 0; for (final TreeFilter f : subfilters) { - if (!f.include(walker)) - return false; + int r = f.matchFilter(walker); + if (r == 1) { + return 1; + } + if (r == -1) { + m = -1; + } } - return true; + return m; } @Override 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 42725bc767..b821a16471 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 @@ -86,11 +86,11 @@ public class IndexDiffFilter extends TreeFilter { private final boolean honorIgnores; - private final Set<String> ignoredPaths = new HashSet<String>(); + private final Set<String> ignoredPaths = new HashSet<>(); - private final LinkedList<String> untrackedParentFolders = new LinkedList<String>(); + private final LinkedList<String> untrackedParentFolders = new LinkedList<>(); - private final LinkedList<String> untrackedFolders = new LinkedList<String>(); + private final LinkedList<String> untrackedFolders = new LinkedList<>(); /** * Creates a new instance of this filter. Do not use an instance of this @@ -292,7 +292,7 @@ public class IndexDiffFilter extends TreeFilter { * empty list will be returned. */ public List<String> getUntrackedFolders() { - LinkedList<String> ret = new LinkedList<String>(untrackedFolders); + LinkedList<String> ret = new LinkedList<>(untrackedFolders); if (!untrackedParentFolders.isEmpty()) { String toBeAdded = untrackedParentFolders.getLast(); while (!ret.isEmpty() && ret.getLast().startsWith(toBeAdded)) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java index 8ec04bb32d..80c0b87e1c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java @@ -78,7 +78,23 @@ public class NotTreeFilter extends TreeFilter { public boolean include(final TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { - return !a.include(walker); + return matchFilter(walker) == 0; + } + + @Override + public int matchFilter(TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + final int r = a.matchFilter(walker); + // switch 0 and 1, keep -1 as that defines a subpath that must be + // traversed before a final verdict can be made. + if (r == 0) { + return 1; + } + if (r == 1) { + return 0; + } + return -1; } @Override diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java index 270633ce63..2c1a9d4388 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java @@ -126,7 +126,25 @@ public abstract class OrTreeFilter extends TreeFilter { public boolean include(final TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { - return a.include(walker) || b.include(walker); + return matchFilter(walker) <= 0; + } + + @Override + public int matchFilter(TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + final int ra = a.matchFilter(walker); + if (ra == 0) { + return 0; + } + final int rb = b.matchFilter(walker); + if (rb == 0) { + return 0; + } + if (ra == -1 || rb == -1) { + return -1; + } + return 1; } @Override @@ -157,11 +175,24 @@ public abstract class OrTreeFilter extends TreeFilter { public boolean include(final TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { + return matchFilter(walker) <= 0; + } + + @Override + public int matchFilter(TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + int m = 1; for (final TreeFilter f : subfilters) { - if (f.include(walker)) - return true; + int r = f.matchFilter(walker); + if (r == 0) { + return 0; + } + if (r == -1) { + m = -1; + } } - return false; + return m; } @Override diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java index d85ea8cc5d..445ba157ea 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java @@ -97,7 +97,12 @@ public class PathFilter extends TreeFilter { @Override public boolean include(final TreeWalk walker) { - return walker.isPathPrefix(pathRaw, pathRaw.length) == 0; + return matchFilter(walker) <= 0; + } + + @Override + public int matchFilter(final TreeWalk walker) { + return walker.isPathMatch(pathRaw, pathRaw.length); } @Override @@ -113,6 +118,7 @@ public class PathFilter extends TreeFilter { return this; } + @Override @SuppressWarnings("nls") public String toString() { return "PATH(\"" + pathStr + "\")"; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java index 7601956c43..174a4f5b06 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java @@ -173,6 +173,7 @@ public class PathFilterGroup { return this; } + @Override public String toString() { return "FAST_" + path.toString(); //$NON-NLS-1$ } @@ -267,6 +268,7 @@ public class PathFilterGroup { return this; } + @Override public String toString() { final StringBuilder r = new StringBuilder(); r.append("FAST("); //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java index 7d99e58f38..2c2fb47463 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java @@ -199,6 +199,34 @@ public abstract class TreeFilter { IOException; /** + * Determine if the current entry is a parent, a match, or no match. + * <p> + * This method extends the result returned by {@link #include(TreeWalk)} + * with a third option (-1), splitting the value true. This gives the + * application a possibility to distinguish between an exact match + * and the case when a subtree to the current entry might be a match. + * + * @param walker + * the walker the filter needs to examine. + * @return -1 if the current entry is a parent of the filter but no + * exact match has been made; 0 if the current entry should + * be seen by the application; 1 if it should be hidden. + * @throws MissingObjectException + * as thrown by {@link #include(TreeWalk)} + * @throws IncorrectObjectTypeException + * as thrown by {@link #include(TreeWalk)} + * @throws IOException + * as thrown by {@link #include(TreeWalk)} + * @since 4.7 + */ + public int matchFilter(final TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException + { + return include(walker) ? 0 : 1; + } + + /** * Does this tree filter require a recursive walk to match everything? * <p> * If this tree filter is matching on full entry path names and its pattern @@ -220,6 +248,7 @@ public abstract class TreeFilter { * * @return another copy of this filter, suitable for another thread. */ + @Override public abstract TreeFilter clone(); @Override 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/BlockList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java index 9d0ad736fa..c86c588acd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java @@ -309,10 +309,12 @@ public class BlockList<T> extends AbstractList<T> { private T[] block = directory[0]; + @Override public boolean hasNext() { return index < size; } + @Override public T next() { if (size <= index) throw new NoSuchElementException(); @@ -329,6 +331,7 @@ public class BlockList<T> extends AbstractList<T> { return res; } + @Override public void remove() { if (index == 0) throw new IllegalStateException(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java index 6828185a8a..8677c690fb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java @@ -51,7 +51,7 @@ import java.util.concurrent.CopyOnWriteArrayList; /** Abstract authenticator which remembers prior authentications. */ public abstract class CachedAuthenticator extends Authenticator { - private static final Collection<CachedAuthentication> cached = new CopyOnWriteArrayList<CachedAuthentication>(); + private static final Collection<CachedAuthentication> cached = new CopyOnWriteArrayList<>(); /** * Add a cached authentication for future use. 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..68b71309b1 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; @@ -376,7 +375,7 @@ public abstract class FS { public File userHome() { Holder<File> p = userHome; if (p == null) { - p = new Holder<File>(userHomeImpl()); + p = new Holder<>(userHomeImpl()); userHome = p; } return p.value; @@ -391,7 +390,7 @@ public abstract class FS { * @return {@code this}. */ public FS setUserHome(File path) { - userHome = new Holder<File>(path); + userHome = new Holder<>(path); return this; } @@ -410,6 +409,7 @@ public abstract class FS { protected File userHomeImpl() { final String home = AccessController .doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return System.getProperty("user.home"); //$NON-NLS-1$ } @@ -650,7 +650,7 @@ public abstract class FS { */ public File getGitSystemConfig() { if (gitSystemConfig == null) { - gitSystemConfig = new Holder<File>(discoverGitSystemConfig()); + gitSystemConfig = new Holder<>(discoverGitSystemConfig()); } return gitSystemConfig.value; } @@ -664,7 +664,7 @@ public abstract class FS { * @since 4.0 */ public FS setGitSystemConfig(File configFile) { - gitSystemConfig = new Holder<File>(configFile); + gitSystemConfig = new Holder<>(configFile); return this; } @@ -1011,16 +1011,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 +1333,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 +1343,16 @@ public abstract class FS { this.out = output; } - public Void call() throws IOException { + @Override + 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 +1369,6 @@ public abstract class FS { } } } - return null; } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java index cb4868cc7a..0780d2b560 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java @@ -225,7 +225,7 @@ public class FS_POSIX extends FS { @Override public ProcessBuilder runInShell(String cmd, String[] args) { - List<String> argv = new ArrayList<String>(4 + args.length); + List<String> argv = new ArrayList<>(4 + args.length); argv.add("sh"); //$NON-NLS-1$ argv.add("-c"); //$NON-NLS-1$ argv.add(cmd + " \"$@\""); //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java index 0e9172e8c0..060292160e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java @@ -83,18 +83,22 @@ public class FS_Win32 extends FS { super(src); } + @Override public FS newInstance() { return new FS_Win32(this); } + @Override public boolean supportsExecute() { return false; } + @Override public boolean canExecute(final File f) { return false; } + @Override public boolean setExecute(final File f, final boolean canExec) { return false; } @@ -158,7 +162,7 @@ public class FS_Win32 extends FS { @Override public ProcessBuilder runInShell(String cmd, String[] args) { - List<String> argv = new ArrayList<String>(3 + args.length); + List<String> argv = new ArrayList<>(3 + args.length); argv.add("cmd.exe"); //$NON-NLS-1$ argv.add("/c"); //$NON-NLS-1$ argv.add(cmd); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java index f8ea5d0aa6..545cc0119e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java @@ -77,6 +77,7 @@ public class FS_Win32_Cygwin extends FS_Win32 { public static boolean isCygwin() { final String path = AccessController .doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return System.getProperty("java.library.path"); //$NON-NLS-1$ } @@ -106,10 +107,12 @@ public class FS_Win32_Cygwin extends FS_Win32 { super(src); } + @Override public FS newInstance() { return new FS_Win32_Cygwin(this); } + @Override public File resolve(final File dir, final String pn) { String useCygPath = System.getProperty("jgit.usecygpath"); //$NON-NLS-1$ if (useCygPath != null && useCygPath.equals("true")) { //$NON-NLS-1$ @@ -133,6 +136,7 @@ public class FS_Win32_Cygwin extends FS_Win32 { protected File userHomeImpl() { final String home = AccessController .doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return System.getenv("HOME"); //$NON-NLS-1$ } @@ -144,7 +148,7 @@ public class FS_Win32_Cygwin extends FS_Win32 { @Override public ProcessBuilder runInShell(String cmd, String[] args) { - List<String> argv = new ArrayList<String>(4 + args.length); + List<String> argv = new ArrayList<>(4 + args.length); argv.add("sh.exe"); //$NON-NLS-1$ argv.add("-c"); //$NON-NLS-1$ argv.add(cmd + " \"$@\""); //$NON-NLS-1$ 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..1f20e9700d 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; @@ -150,8 +151,8 @@ public class FileUtils { if ((options & RECURSIVE) != 0 && fs.isDirectory(f)) { final File[] items = f.listFiles(); if (items != null) { - List<File> files = new ArrayList<File>(); - List<File> dirs = new ArrayList<File>(); + List<File> files = new ArrayList<>(); + List<File> dirs = new ArrayList<>(); for (File c : items) if (c.isFile()) files.add(c); @@ -542,7 +543,28 @@ 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$ + } + + /** + * Determine if a throwable or a cause in its causal chain is a Stale NFS + * File Handle + * + * @param throwable + * @return a boolean true if the throwable or a cause in its causal chain is + * a Stale NFS File Handle + * @since 4.7 + */ + public static boolean isStaleFileHandleInCausalChain(Throwable throwable) { + while (throwable != null) { + if (throwable instanceof IOException + && isStaleFileHandle((IOException) throwable)) { + return true; + } + throwable = throwable.getCause(); + } + return false; } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java index 7bc3c88c5d..da78008a0b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java @@ -75,8 +75,9 @@ public class GitDateParser { private static ThreadLocal<Map<Locale, Map<ParseableSimpleDateFormat, SimpleDateFormat>>> formatCache = new ThreadLocal<Map<Locale, Map<ParseableSimpleDateFormat, SimpleDateFormat>>>() { + @Override protected Map<Locale, Map<ParseableSimpleDateFormat, SimpleDateFormat>> initialValue() { - return new HashMap<Locale, Map<ParseableSimpleDateFormat, SimpleDateFormat>>(); + return new HashMap<>(); } }; @@ -90,7 +91,7 @@ public class GitDateParser { Map<ParseableSimpleDateFormat, SimpleDateFormat> map = cache .get(locale); if (map == null) { - map = new HashMap<ParseableSimpleDateFormat, SimpleDateFormat>(); + map = new HashMap<>(); cache.put(locale, map); return getNewSimpleDateFormat(f, locale, map); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java index 251381ab33..13e61a7972 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java @@ -141,6 +141,12 @@ public class HttpSupport { /** The {@code Accept-Encoding} header. */ public static final String HDR_ACCEPT_ENCODING = "Accept-Encoding"; //$NON-NLS-1$ + /** + * The {@code Location} header. + * @since 4.7 + */ + public static final String HDR_LOCATION = "Location"; //$NON-NLS-1$ + /** The {@code gzip} encoding value for {@link #HDR_ACCEPT_ENCODING}. */ public static final String ENCODING_GZIP = "gzip"; //$NON-NLS-1$ @@ -235,6 +241,23 @@ public class HttpSupport { } /** + * Extract a HTTP header from the response. + * + * @param c + * connection the header should be obtained from. + * @param headerName + * the header name + * @return the header value + * @throws IOException + * communications error prevented obtaining the header. + * @since 4.7 + */ + public static String responseHeader(final HttpConnection c, + final String headerName) throws IOException { + return c.getHeaderField(headerName); + } + + /** * Determine the proxy server (if any) needed to obtain a URL. * * @param proxySelector @@ -280,15 +303,18 @@ public class HttpSupport { } private static class DummyX509TrustManager implements X509TrustManager { + @Override public X509Certificate[] getAcceptedIssuers() { return null; } + @Override public void checkClientTrusted(X509Certificate[] certs, String authType) { // no check } + @Override public void checkServerTrusted(X509Certificate[] certs, String authType) { // no check @@ -296,6 +322,7 @@ public class HttpSupport { } private static class DummyHostnameVerifier implements HostnameVerifier { + @Override public boolean verify(String hostname, SSLSession session) { // always accept return true; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java index 0d283fde63..6cff76cc21 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java @@ -344,7 +344,7 @@ public class IO { * @since 2.0 */ public static List<String> readLines(final String s) { - List<String> l = new ArrayList<String>(); + List<String> l = new ArrayList<>(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java index f7688e3609..658dd06d46 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java @@ -138,6 +138,7 @@ public class IntList { entries = n; } + @Override public String toString() { final StringBuilder r = new StringBuilder(); r.append('['); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java index dc4004fcef..e3639f5c65 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java @@ -159,6 +159,7 @@ public class LongList { entries = n; } + @Override public String toString() { final StringBuilder r = new StringBuilder(); r.append('['); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java index 4eeecdbf2d..e85bd659b4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java @@ -74,14 +74,17 @@ public final class RawCharSequence implements CharSequence { endPtr = end; } + @Override public char charAt(final int index) { return (char) (buffer[startPtr + index] & 0xff); } + @Override public int length() { return endPtr - startPtr; } + @Override public CharSequence subSequence(final int start, final int end) { return new RawCharSequence(buffer, startPtr + start, startPtr + end); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java index 0853e95366..159781795e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java @@ -68,7 +68,7 @@ import org.eclipse.jgit.lib.RefComparator; * the type of reference being stored in the collection. */ public class RefList<T extends Ref> implements Iterable<Ref> { - private static final RefList<Ref> EMPTY = new RefList<Ref>(new Ref[0], 0); + private static final RefList<Ref> EMPTY = new RefList<>(new Ref[0], 0); /** * @return an empty unmodifiable reference list. @@ -100,20 +100,24 @@ public class RefList<T extends Ref> implements Iterable<Ref> { this.cnt = src.cnt; } + @Override public Iterator<Ref> iterator() { return new Iterator<Ref>() { private int idx; + @Override public boolean hasNext() { return idx < cnt; } + @Override public Ref next() { if (idx < cnt) return list[idx++]; throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -209,7 +213,7 @@ public class RefList<T extends Ref> implements Iterable<Ref> { * @return a new builder with the first {@code n} elements already added. */ public final Builder<T> copy(int n) { - Builder<T> r = new Builder<T>(Math.max(16, n)); + Builder<T> r = new Builder<>(Math.max(16, n)); r.addAll(list, 0, n); return r; } @@ -230,7 +234,7 @@ public class RefList<T extends Ref> implements Iterable<Ref> { Ref[] newList = new Ref[cnt]; System.arraycopy(list, 0, newList, 0, cnt); newList[idx] = ref; - return new RefList<T>(newList, cnt); + return new RefList<>(newList, cnt); } /** @@ -257,7 +261,7 @@ public class RefList<T extends Ref> implements Iterable<Ref> { newList[idx] = ref; if (idx < cnt) System.arraycopy(list, idx, newList, idx + 1, cnt - idx); - return new RefList<T>(newList, cnt + 1); + return new RefList<>(newList, cnt + 1); } /** @@ -278,7 +282,7 @@ public class RefList<T extends Ref> implements Iterable<Ref> { System.arraycopy(list, 0, newList, 0, idx); if (idx + 1 < cnt) System.arraycopy(list, idx + 1, newList, idx, cnt - (idx + 1)); - return new RefList<T>(newList, cnt - 1); + return new RefList<>(newList, cnt - 1); } /** @@ -427,7 +431,7 @@ public class RefList<T extends Ref> implements Iterable<Ref> { /** @return an unmodifiable list using this collection's backing array. */ public RefList<T> toRefList() { - return new RefList<T>(list, size); + return new RefList<>(list, size); } @Override diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java index c72727b542..510e81821e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java @@ -304,12 +304,14 @@ public class RefMap extends AbstractMap<String, Ref> { } } + @Override public boolean hasNext() { if (next == null) next = peek(); return next != null; } + @Override public Entry<String, Ref> next() { if (hasNext()) { Entry<String, Ref> r = next; @@ -367,6 +369,7 @@ public class RefMap extends AbstractMap<String, Ref> { return null; } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -379,14 +382,17 @@ public class RefMap extends AbstractMap<String, Ref> { this.ref = ref; } + @Override public String getKey() { return toMapKey(ref); } + @Override public Ref getValue() { return ref; } + @Override public Ref setValue(Ref value) { Ref prior = put(getKey(), value); ref = value; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java index b36fc2391a..2cd8035854 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java @@ -87,22 +87,27 @@ public abstract class SystemReader { private static class Default extends SystemReader { private volatile String hostname; + @Override public String getenv(String variable) { return System.getenv(variable); } + @Override public String getProperty(String key) { return System.getProperty(key); } + @Override public FileBasedConfig openSystemConfig(Config parent, FS fs) { File configFile = fs.getGitSystemConfig(); if (configFile == null) { return new FileBasedConfig(null, fs) { + @Override public void load() { // empty, do not load } + @Override public boolean isOutdated() { // regular class would bomb here return false; @@ -112,11 +117,13 @@ public abstract class SystemReader { return new FileBasedConfig(parent, configFile, fs); } + @Override public FileBasedConfig openUserConfig(Config parent, FS fs) { final File home = fs.userHome(); return new FileBasedConfig(parent, new File(home, ".gitconfig"), fs); //$NON-NLS-1$ } + @Override public String getHostname() { if (hostname == null) { try { @@ -331,6 +338,7 @@ public abstract class SystemReader { private String getOsName() { return AccessController.doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return getProperty("os.name"); //$NON-NLS-1$ } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java index 57bcfbd5e5..e3f1916f43 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java @@ -325,7 +325,7 @@ public abstract class TemporaryBuffer extends OutputStream { if (blocks != null) blocks.clear(); else - blocks = new ArrayList<Block>(initialBlocks); + blocks = new ArrayList<>(initialBlocks); blocks.add(new Block(Math.min(inCoreLimit, Block.SZ))); } @@ -363,6 +363,7 @@ public abstract class TemporaryBuffer extends OutputStream { overflow.write(last.buffer, 0, last.count); } + @Override public void close() throws IOException { if (overflow != null) { try { @@ -441,11 +442,13 @@ public abstract class TemporaryBuffer extends OutputStream { this.directory = directory; } + @Override protected OutputStream overflow() throws IOException { onDiskFile = File.createTempFile("jgit_", ".buf", directory); //$NON-NLS-1$ //$NON-NLS-2$ return new BufferedOutputStream(new FileOutputStream(onDiskFile)); } + @Override public long length() { if (onDiskFile == null) { return super.length(); @@ -453,6 +456,7 @@ public abstract class TemporaryBuffer extends OutputStream { return onDiskFile.length(); } + @Override public byte[] toByteArray() throws IOException { if (onDiskFile == null) { return super.toByteArray(); @@ -471,6 +475,7 @@ public abstract class TemporaryBuffer extends OutputStream { return out; } + @Override public void writeTo(final OutputStream os, ProgressMonitor pm) throws IOException { if (onDiskFile == null) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/InterruptTimer.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/InterruptTimer.java index 1024380264..0c5edb0070 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/InterruptTimer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/InterruptTimer.java @@ -176,6 +176,7 @@ public final class InterruptTimer { callingThread = Thread.currentThread(); } + @Override public synchronized void run() { while (!terminated && callingThread.isAlive()) { try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java index 6adadbbb82..a7a0347401 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java @@ -115,6 +115,7 @@ public class TeeInputStream extends InputStream { return n; } + @Override public void close() throws IOException { byte[] b = skipBuffer(); for (;;) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java index c34c1fb681..5eca0d99e1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java @@ -69,6 +69,7 @@ public class ThrowingPrintWriter extends Writer { public ThrowingPrintWriter(Writer out) { this.out = out; LF = AccessController.doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return SystemReader.getInstance().getProperty("line.separator"); //$NON-NLS-1$ } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java index 0319afd5ad..1c46310ef5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java @@ -67,7 +67,7 @@ public class UnionInputStream extends InputStream { } }; - private final LinkedList<InputStream> streams = new LinkedList<InputStream>(); + private final LinkedList<InputStream> streams = new LinkedList<>(); /** Create an empty InputStream that is currently at EOF state. */ public UnionInputStream() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.compress b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.compress new file mode 100644 index 0000000000..3a80fd2aaf --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.compress @@ -0,0 +1,92 @@ +/* Template for compress method; run through cpp. */ + +#define ROUND1_STEP(a, b, c, d, e, T) e += s1(a,b,c,d,w[T]); b = rotateLeft(b, 30) +#define ROUND2_STEP(a, b, c, d, e, T) e += s2(a,b,c,d,w[T]); b = rotateLeft(b, 30) +#define ROUND3_STEP(a, b, c, d, e, T) e += s3(a,b,c,d,w[T]); b = rotateLeft(b, 30) +#define ROUND4_STEP(a, b, c, d, e, T) e += s4(a,b,c,d,w[T]); b = rotateLeft(b, 30) + + ROUND1_STEP(a, b, c, d, e, 0); + ROUND1_STEP(e, a, b, c, d, 1); + ROUND1_STEP(d, e, a, b, c, 2); + ROUND1_STEP(c, d, e, a, b, 3); + ROUND1_STEP(b, c, d, e, a, 4); + ROUND1_STEP(a, b, c, d, e, 5); + ROUND1_STEP(e, a, b, c, d, 6); + ROUND1_STEP(d, e, a, b, c, 7); + ROUND1_STEP(c, d, e, a, b, 8); + ROUND1_STEP(b, c, d, e, a, 9); + ROUND1_STEP(a, b, c, d, e, 10); + ROUND1_STEP(e, a, b, c, d, 11); + ROUND1_STEP(d, e, a, b, c, 12); + ROUND1_STEP(c, d, e, a, b, 13); + ROUND1_STEP(b, c, d, e, a, 14); + ROUND1_STEP(a, b, c, d, e, 15); + ROUND1_STEP(e, a, b, c, d, 16); + ROUND1_STEP(d, e, a, b, c, 17); + ROUND1_STEP(c, d, e, a, b, 18); + ROUND1_STEP(b, c, d, e, a, 19); + + ROUND2_STEP(a, b, c, d, e, 20); + ROUND2_STEP(e, a, b, c, d, 21); + ROUND2_STEP(d, e, a, b, c, 22); + ROUND2_STEP(c, d, e, a, b, 23); + ROUND2_STEP(b, c, d, e, a, 24); + ROUND2_STEP(a, b, c, d, e, 25); + ROUND2_STEP(e, a, b, c, d, 26); + ROUND2_STEP(d, e, a, b, c, 27); + ROUND2_STEP(c, d, e, a, b, 28); + ROUND2_STEP(b, c, d, e, a, 29); + ROUND2_STEP(a, b, c, d, e, 30); + ROUND2_STEP(e, a, b, c, d, 31); + ROUND2_STEP(d, e, a, b, c, 32); + ROUND2_STEP(c, d, e, a, b, 33); + ROUND2_STEP(b, c, d, e, a, 34); + ROUND2_STEP(a, b, c, d, e, 35); + ROUND2_STEP(e, a, b, c, d, 36); + ROUND2_STEP(d, e, a, b, c, 37); + ROUND2_STEP(c, d, e, a, b, 38); + ROUND2_STEP(b, c, d, e, a, 39); + + ROUND3_STEP(a, b, c, d, e, 40); + ROUND3_STEP(e, a, b, c, d, 41); + ROUND3_STEP(d, e, a, b, c, 42); + ROUND3_STEP(c, d, e, a, b, 43); + ROUND3_STEP(b, c, d, e, a, 44); + ROUND3_STEP(a, b, c, d, e, 45); + ROUND3_STEP(e, a, b, c, d, 46); + ROUND3_STEP(d, e, a, b, c, 47); + ROUND3_STEP(c, d, e, a, b, 48); + ROUND3_STEP(b, c, d, e, a, 49); + ROUND3_STEP(a, b, c, d, e, 50); + ROUND3_STEP(e, a, b, c, d, 51); + ROUND3_STEP(d, e, a, b, c, 52); + ROUND3_STEP(c, d, e, a, b, 53); + ROUND3_STEP(b, c, d, e, a, 54); + ROUND3_STEP(a, b, c, d, e, 55); + ROUND3_STEP(e, a, b, c, d, 56); + ROUND3_STEP(d, e, a, b, c, 57); + state58.save(a, b, c, d, e); + ROUND3_STEP(c, d, e, a, b, 58); + ROUND3_STEP(b, c, d, e, a, 59); + + ROUND4_STEP(a, b, c, d, e, 60); + ROUND4_STEP(e, a, b, c, d, 61); + ROUND4_STEP(d, e, a, b, c, 62); + ROUND4_STEP(c, d, e, a, b, 63); + ROUND4_STEP(b, c, d, e, a, 64); + state65.save(a, b, c, d, e); + ROUND4_STEP(a, b, c, d, e, 65); + ROUND4_STEP(e, a, b, c, d, 66); + ROUND4_STEP(d, e, a, b, c, 67); + ROUND4_STEP(c, d, e, a, b, 68); + ROUND4_STEP(b, c, d, e, a, 69); + ROUND4_STEP(a, b, c, d, e, 70); + ROUND4_STEP(e, a, b, c, d, 71); + ROUND4_STEP(d, e, a, b, c, 72); + ROUND4_STEP(c, d, e, a, b, 73); + ROUND4_STEP(b, c, d, e, a, 74); + ROUND4_STEP(a, b, c, d, e, 75); + ROUND4_STEP(e, a, b, c, d, 76); + ROUND4_STEP(d, e, a, b, c, 77); + ROUND4_STEP(c, d, e, a, b, 78); + ROUND4_STEP(b, c, d, e, a, 79); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java new file mode 100644 index 0000000000..544971199e --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java @@ -0,0 +1,601 @@ +/* + * Copyright (C) 2017, 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.util.sha1; + +import static java.lang.Integer.lowestOneBit; +import static java.lang.Integer.numberOfTrailingZeros; +import static java.lang.Integer.rotateLeft; +import static java.lang.Integer.rotateRight; + +import java.util.Arrays; + +import org.eclipse.jgit.lib.MutableObjectId; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.util.NB; +import org.eclipse.jgit.util.SystemReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Pure Java implementation of SHA-1 from FIPS 180-1 / RFC 3174. + * + * <p> + * See <a href="https://tools.ietf.org/html/rfc3174">RFC 3174</a>. + * <p> + * Unlike MessageDigest, this implementation includes the algorithm used by + * {@code sha1dc} to detect cryptanalytic collision attacks against SHA-1, such + * as the one used by <a href="https://shattered.it/">SHAttered</a>. See + * <a href="https://github.com/cr-marcstevens/sha1collisiondetection"> + * sha1collisiondetection</a> for more information. + * <p> + * When detectCollision is true (default), this implementation throws + * {@link Sha1CollisionException} from any digest method if a potential + * collision was detected. + * + * @since 4.7 + */ +public class SHA1 { + private static Logger LOG = LoggerFactory.getLogger(SHA1.class); + private static final boolean DETECT_COLLISIONS; + + static { + SystemReader sr = SystemReader.getInstance(); + String v = sr.getProperty("org.eclipse.jgit.util.sha1.detectCollision"); //$NON-NLS-1$ + DETECT_COLLISIONS = v != null ? Boolean.parseBoolean(v) : true; + } + + /** @return a new context to compute a SHA-1 hash of data. */ + public static SHA1 newInstance() { + return new SHA1(); + } + + private final State h = new State(); + private final int[] w = new int[80]; + + /** Buffer to accumulate partial blocks to 64 byte alignment. */ + private final byte[] buffer = new byte[64]; + + /** Total number of bytes in the message. */ + private long length; + + private boolean detectCollision = DETECT_COLLISIONS; + private boolean foundCollision; + + private final int[] w2 = new int[80]; + private final State state58 = new State(); + private final State state65 = new State(); + private final State hIn = new State(); + private final State hTmp = new State(); + + private SHA1() { + h.init(); + } + + /** + * Enable likely collision detection. + * <p> + * Default is {@code true}. + * <p> + * May also be set by system property: + * {@code -Dorg.eclipse.jgit.util.sha1.detectCollision=true}. + * + * @param detect + * @return {@code this} + */ + public SHA1 setDetectCollision(boolean detect) { + detectCollision = detect; + return this; + } + + /** + * Update the digest computation by adding a byte. + * + * @param b + */ + public void update(byte b) { + int bufferLen = (int) (length & 63); + length++; + buffer[bufferLen] = b; + if (bufferLen == 63) { + compress(buffer, 0); + } + } + + /** + * Update the digest computation by adding bytes to the message. + * + * @param in + * input array of bytes. + */ + public void update(byte[] in) { + update(in, 0, in.length); + } + + /** + * Update the digest computation by adding bytes to the message. + * + * @param in + * input array of bytes. + * @param p + * offset to start at from {@code in}. + * @param len + * number of bytes to hash. + */ + public void update(byte[] in, int p, int len) { + // SHA-1 compress can only process whole 64 byte blocks. + // Hold partial updates in buffer, whose length is the low bits. + int bufferLen = (int) (length & 63); + length += len; + + if (bufferLen > 0) { + int n = Math.min(64 - bufferLen, len); + System.arraycopy(in, p, buffer, bufferLen, n); + p += n; + len -= n; + if (bufferLen + n < 64) { + return; + } + compress(buffer, 0); + } + while (len >= 64) { + compress(in, p); + p += 64; + len -= 64; + } + if (len > 0) { + System.arraycopy(in, p, buffer, 0, len); + } + } + + private void compress(byte[] block, int p) { + initBlock(block, p); + int ubcDvMask = detectCollision ? UbcCheck.check(w) : 0; + compress(); + + while (ubcDvMask != 0) { + int b = numberOfTrailingZeros(lowestOneBit(ubcDvMask)); + UbcCheck.DvInfo dv = UbcCheck.DV[b]; + for (int i = 0; i < 80; i++) { + w2[i] = w[i] ^ dv.dm[i]; + } + recompress(dv.testt); + if (eq(hTmp, h)) { + foundCollision = true; + break; + } + ubcDvMask &= ~(1 << b); + } + } + + private void initBlock(byte[] block, int p) { + for (int t = 0; t < 16; t++) { + w[t] = NB.decodeInt32(block, p + (t << 2)); + } + + // RFC 3174 6.1.b, extend state vector to 80 words. + for (int t = 16; t < 80; t++) { + int x = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]; + w[t] = rotateLeft(x, 1); // S^1(...) + } + } + + private void compress() { + // Method 1 from RFC 3174 section 6.1. + // Method 2 (circular queue of 16 words) is slower. + int a = h.a, b = h.b, c = h.c, d = h.d, e = h.e; + + // @formatter:off + e += s1(a, b, c, d,w[ 0]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 1]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 2]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 3]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 4]); c = rotateLeft( c, 30); + e += s1(a, b, c, d,w[ 5]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 6]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 7]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 8]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 9]); c = rotateLeft( c, 30); + e += s1(a, b, c, d,w[ 10]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 11]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 12]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 13]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 14]); c = rotateLeft( c, 30); + e += s1(a, b, c, d,w[ 15]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 16]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 17]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 18]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 19]); c = rotateLeft( c, 30); + + e += s2(a, b, c, d,w[ 20]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 21]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 22]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 23]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 24]); c = rotateLeft( c, 30); + e += s2(a, b, c, d,w[ 25]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 26]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 27]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 28]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 29]); c = rotateLeft( c, 30); + e += s2(a, b, c, d,w[ 30]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 31]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 32]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 33]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 34]); c = rotateLeft( c, 30); + e += s2(a, b, c, d,w[ 35]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 36]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 37]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 38]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 39]); c = rotateLeft( c, 30); + + e += s3(a, b, c, d,w[ 40]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 41]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 42]); e = rotateLeft( e, 30); + b += s3(c, d, e, a,w[ 43]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 44]); c = rotateLeft( c, 30); + e += s3(a, b, c, d,w[ 45]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 46]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 47]); e = rotateLeft( e, 30); + b += s3(c, d, e, a,w[ 48]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 49]); c = rotateLeft( c, 30); + e += s3(a, b, c, d,w[ 50]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 51]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 52]); e = rotateLeft( e, 30); + b += s3(c, d, e, a,w[ 53]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 54]); c = rotateLeft( c, 30); + e += s3(a, b, c, d,w[ 55]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 56]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 57]); e = rotateLeft( e, 30); + state58.save(a, b, c, d, e); + b += s3(c, d, e, a,w[ 58]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 59]); c = rotateLeft( c, 30); + + e += s4(a, b, c, d,w[ 60]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 61]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 62]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 63]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 64]); c = rotateLeft( c, 30); + state65.save(a, b, c, d, e); + e += s4(a, b, c, d,w[ 65]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 66]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 67]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 68]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 69]); c = rotateLeft( c, 30); + e += s4(a, b, c, d,w[ 70]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 71]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 72]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 73]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 74]); c = rotateLeft( c, 30); + e += s4(a, b, c, d,w[ 75]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 76]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 77]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 78]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 79]); c = rotateLeft( c, 30); + + // @formatter:on + h.save(h.a + a, h.b + b, h.c + c, h.d + d, h.e + e); + } + + private void recompress(int t) { + State s; + if (t == 58) { + s = state58; + } else if (t == 65) { + s = state65; + } else { + throw new IllegalStateException(); + } + int a = s.a, b = s.b, c = s.c, d = s.d, e = s.e; + + // @formatter:off + if (t == 65) { + { c = rotateRight( c, 30); a -= s4(b, c, d, e,w2[ 64]);} + { d = rotateRight( d, 30); b -= s4(c, d, e, a,w2[ 63]);} + { e = rotateRight( e, 30); c -= s4(d, e, a, b,w2[ 62]);} + { a = rotateRight( a, 30); d -= s4(e, a, b, c,w2[ 61]);} + { b = rotateRight( b, 30); e -= s4(a, b, c, d,w2[ 60]);} + + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 59]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 58]);} + } + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 57]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 56]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 55]);} + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 54]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 53]);} + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 52]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 51]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 50]);} + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 49]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 48]);} + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 47]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 46]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 45]);} + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 44]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 43]);} + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 42]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 41]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 40]);} + + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 39]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 38]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 37]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 36]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 35]);} + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 34]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 33]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 32]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 31]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 30]);} + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 29]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 28]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 27]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 26]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 25]);} + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 24]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 23]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 22]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 21]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 20]);} + + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 19]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 18]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 17]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 16]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 15]);} + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 14]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 13]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 12]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 11]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 10]);} + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 9]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 8]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 7]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 6]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 5]);} + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 4]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 3]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 2]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 1]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 0]);} + + hIn.save(a, b, c, d, e); + a = s.a; b = s.b; c = s.c; d = s.d; e = s.e; + + if (t == 58) { + { b += s3(c, d, e, a,w2[ 58]); d = rotateLeft( d, 30);} + { a += s3(b, c, d, e,w2[ 59]); c = rotateLeft( c, 30);} + + { e += s4(a, b, c, d,w2[ 60]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 61]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 62]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 63]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 64]); c = rotateLeft( c, 30);} + } + { e += s4(a, b, c, d,w2[ 65]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 66]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 67]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 68]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 69]); c = rotateLeft( c, 30);} + { e += s4(a, b, c, d,w2[ 70]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 71]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 72]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 73]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 74]); c = rotateLeft( c, 30);} + { e += s4(a, b, c, d,w2[ 75]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 76]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 77]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 78]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 79]); c = rotateLeft( c, 30);} + + // @formatter:on + hTmp.save(hIn.a + a, hIn.b + b, hIn.c + c, hIn.d + d, hIn.e + e); + } + + private static int s1(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 0 <= t <= 19 + + ((b & c) | ((~b) & d)) + + 0x5A827999 + w_t; + } + + private static int s2(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 20 <= t <= 39 + + (b ^ c ^ d) + + 0x6ED9EBA1 + w_t; + } + + private static int s3(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 40 <= t <= 59 + + ((b & c) | (b & d) | (c & d)) + + 0x8F1BBCDC + w_t; + } + + private static int s4(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 60 <= t <= 79 + + (b ^ c ^ d) + + 0xCA62C1D6 + w_t; + } + + private static boolean eq(State q, State r) { + return q.a == r.a + && q.b == r.b + && q.c == r.c + && q.d == r.d + && q.e == r.e; + } + + private void finish() { + int bufferLen = (int) (length & 63); + if (bufferLen > 55) { + // Last block is too small; pad, compress, pad another block. + buffer[bufferLen++] = (byte) 0x80; + Arrays.fill(buffer, bufferLen, 64, (byte) 0); + compress(buffer, 0); + Arrays.fill(buffer, 0, 56, (byte) 0); + } else { + // Last block can hold padding and length. + buffer[bufferLen++] = (byte) 0x80; + Arrays.fill(buffer, bufferLen, 56, (byte) 0); + } + + // SHA-1 appends the length of the message in bits after the + // padding block (above). Here length is in bytes. Multiply by + // 8 by shifting by 3 as part of storing the 64 bit byte length + // into the two words expected in the trailer. + NB.encodeInt32(buffer, 56, (int) (length >>> (32 - 3))); + NB.encodeInt32(buffer, 60, (int) (length << 3)); + compress(buffer, 0); + + if (foundCollision) { + ObjectId id = h.toObjectId(); + LOG.warn("possible SHA-1 collision " + id.name()); //$NON-NLS-1$ + throw new Sha1CollisionException(id); + } + } + + /** + * Finish the digest and return the resulting hash. + * <p> + * Once {@code digest()} is called, this instance should be discarded. + * + * @return the bytes for the resulting hash. + * @throws Sha1CollisionException + * if a collision was detected and safeHash is false. + */ + public byte[] digest() throws Sha1CollisionException { + finish(); + + byte[] b = new byte[20]; + NB.encodeInt32(b, 0, h.a); + NB.encodeInt32(b, 4, h.b); + NB.encodeInt32(b, 8, h.c); + NB.encodeInt32(b, 12, h.d); + NB.encodeInt32(b, 16, h.e); + return b; + } + + /** + * Finish the digest and return the resulting hash. + * <p> + * Once {@code digest()} is called, this instance should be discarded. + * + * @return the ObjectId for the resulting hash. + * @throws Sha1CollisionException + * if a collision was detected and safeHash is false. + */ + public ObjectId toObjectId() throws Sha1CollisionException { + finish(); + return h.toObjectId(); + } + + /** + * Finish the digest and return the resulting hash. + * <p> + * Once {@code digest()} is called, this instance should be discarded. + * + * @param id + * destination to copy the digest to. + * @throws Sha1CollisionException + * if a collision was detected and safeHash is false. + */ + public void digest(MutableObjectId id) throws Sha1CollisionException { + finish(); + id.set(h.a, h.b, h.c, h.d, h.e); + } + + /** + * Check if a collision was detected. + * + * <p> + * This method only returns an accurate result after the digest was obtained + * through {@link #digest()}, {@link #digest(MutableObjectId)} or + * {@link #toObjectId()}, as the hashing function must finish processing to + * know the final state. + * + * @return {@code true} if a likely collision was detected. + */ + public boolean hasCollision() { + return foundCollision; + } + + /** + * Reset this instance to compute another hash. + * + * @return {@code this}. + */ + public SHA1 reset() { + h.init(); + length = 0; + foundCollision = false; + return this; + } + + private static final class State { + int a; + int b; + int c; + int d; + int e; + + final void init() { + // Magic initialization constants defined by FIPS180. + save(0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0); + } + + final void save(int a1, int b1, int c1, int d1, int e1) { + a = a1; + b = b1; + c = c1; + d = d1; + e = e1; + } + + ObjectId toObjectId() { + return new ObjectId(a, b, c, d, e); + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.recompress b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.recompress new file mode 100644 index 0000000000..44d3d6db84 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.recompress @@ -0,0 +1,192 @@ +/* Template for recompress method; run through cpp. */ + +#define ROUND1_STEP(a, b, c, d, e, T) {e += s1(a,b,c,d,w2[T]); b = rotateLeft(b, 30);} +#define ROUND2_STEP(a, b, c, d, e, T) {e += s2(a,b,c,d,w2[T]); b = rotateLeft(b, 30);} +#define ROUND3_STEP(a, b, c, d, e, T) {e += s3(a,b,c,d,w2[T]); b = rotateLeft(b, 30);} +#define ROUND4_STEP(a, b, c, d, e, T) {e += s4(a,b,c,d,w2[T]); b = rotateLeft(b, 30);} + +#define ROUND1_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s1(a,b,c,d,w2[T]);} +#define ROUND2_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s2(a,b,c,d,w2[T]);} +#define ROUND3_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s3(a,b,c,d,w2[T]);} +#define ROUND4_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s4(a,b,c,d,w2[T]);} + + /* Condition to go backwards: if (t > step) */ + /* t=80-66 have no identified DV; skip. + ROUND4_STEP_BW(b, c, d, e, a, 79) + ROUND4_STEP_BW(c, d, e, a, b, 78) + ROUND4_STEP_BW(d, e, a, b, c, 77) + ROUND4_STEP_BW(e, a, b, c, d, 76) + ROUND4_STEP_BW(a, b, c, d, e, 75) + ROUND4_STEP_BW(b, c, d, e, a, 74) + ROUND4_STEP_BW(c, d, e, a, b, 73) + ROUND4_STEP_BW(d, e, a, b, c, 72) + ROUND4_STEP_BW(e, a, b, c, d, 71) + ROUND4_STEP_BW(a, b, c, d, e, 70) + ROUND4_STEP_BW(b, c, d, e, a, 69) + ROUND4_STEP_BW(c, d, e, a, b, 68) + ROUND4_STEP_BW(d, e, a, b, c, 67) + ROUND4_STEP_BW(e, a, b, c, d, 66) + ROUND4_STEP_BW(a, b, c, d, e, 65) + */ + if (t == 65) { + ROUND4_STEP_BW(b, c, d, e, a, 64) + ROUND4_STEP_BW(c, d, e, a, b, 63) + ROUND4_STEP_BW(d, e, a, b, c, 62) + ROUND4_STEP_BW(e, a, b, c, d, 61) + ROUND4_STEP_BW(a, b, c, d, e, 60) + + ROUND3_STEP_BW(b, c, d, e, a, 59) + ROUND3_STEP_BW(c, d, e, a, b, 58) + } + ROUND3_STEP_BW(d, e, a, b, c, 57) + ROUND3_STEP_BW(e, a, b, c, d, 56) + ROUND3_STEP_BW(a, b, c, d, e, 55) + ROUND3_STEP_BW(b, c, d, e, a, 54) + ROUND3_STEP_BW(c, d, e, a, b, 53) + ROUND3_STEP_BW(d, e, a, b, c, 52) + ROUND3_STEP_BW(e, a, b, c, d, 51) + ROUND3_STEP_BW(a, b, c, d, e, 50) + ROUND3_STEP_BW(b, c, d, e, a, 49) + ROUND3_STEP_BW(c, d, e, a, b, 48) + ROUND3_STEP_BW(d, e, a, b, c, 47) + ROUND3_STEP_BW(e, a, b, c, d, 46) + ROUND3_STEP_BW(a, b, c, d, e, 45) + ROUND3_STEP_BW(b, c, d, e, a, 44) + ROUND3_STEP_BW(c, d, e, a, b, 43) + ROUND3_STEP_BW(d, e, a, b, c, 42) + ROUND3_STEP_BW(e, a, b, c, d, 41) + ROUND3_STEP_BW(a, b, c, d, e, 40) + + ROUND2_STEP_BW(b, c, d, e, a, 39) + ROUND2_STEP_BW(c, d, e, a, b, 38) + ROUND2_STEP_BW(d, e, a, b, c, 37) + ROUND2_STEP_BW(e, a, b, c, d, 36) + ROUND2_STEP_BW(a, b, c, d, e, 35) + ROUND2_STEP_BW(b, c, d, e, a, 34) + ROUND2_STEP_BW(c, d, e, a, b, 33) + ROUND2_STEP_BW(d, e, a, b, c, 32) + ROUND2_STEP_BW(e, a, b, c, d, 31) + ROUND2_STEP_BW(a, b, c, d, e, 30) + ROUND2_STEP_BW(b, c, d, e, a, 29) + ROUND2_STEP_BW(c, d, e, a, b, 28) + ROUND2_STEP_BW(d, e, a, b, c, 27) + ROUND2_STEP_BW(e, a, b, c, d, 26) + ROUND2_STEP_BW(a, b, c, d, e, 25) + ROUND2_STEP_BW(b, c, d, e, a, 24) + ROUND2_STEP_BW(c, d, e, a, b, 23) + ROUND2_STEP_BW(d, e, a, b, c, 22) + ROUND2_STEP_BW(e, a, b, c, d, 21) + ROUND2_STEP_BW(a, b, c, d, e, 20) + + ROUND1_STEP_BW(b, c, d, e, a, 19) + ROUND1_STEP_BW(c, d, e, a, b, 18) + ROUND1_STEP_BW(d, e, a, b, c, 17) + ROUND1_STEP_BW(e, a, b, c, d, 16) + ROUND1_STEP_BW(a, b, c, d, e, 15) + ROUND1_STEP_BW(b, c, d, e, a, 14) + ROUND1_STEP_BW(c, d, e, a, b, 13) + ROUND1_STEP_BW(d, e, a, b, c, 12) + ROUND1_STEP_BW(e, a, b, c, d, 11) + ROUND1_STEP_BW(a, b, c, d, e, 10) + ROUND1_STEP_BW(b, c, d, e, a, 9) + ROUND1_STEP_BW(c, d, e, a, b, 8) + ROUND1_STEP_BW(d, e, a, b, c, 7) + ROUND1_STEP_BW(e, a, b, c, d, 6) + ROUND1_STEP_BW(a, b, c, d, e, 5) + ROUND1_STEP_BW(b, c, d, e, a, 4) + ROUND1_STEP_BW(c, d, e, a, b, 3) + ROUND1_STEP_BW(d, e, a, b, c, 2) + ROUND1_STEP_BW(e, a, b, c, d, 1) + ROUND1_STEP_BW(a, b, c, d, e, 0) + + hIn.save(a, b, c, d, e); + a = s.a; b = s.b; c = s.c; d = s.d; e = s.e; + + /* Condition to go fowards: if (t <= step) */ + /* Earliest restart is T=58; skip. + ROUND1_STEP(a, b, c, d, e, 0) + ROUND1_STEP(e, a, b, c, d, 1) + ROUND1_STEP(d, e, a, b, c, 2) + ROUND1_STEP(c, d, e, a, b, 3) + ROUND1_STEP(b, c, d, e, a, 4) + ROUND1_STEP(a, b, c, d, e, 5) + ROUND1_STEP(e, a, b, c, d, 6) + ROUND1_STEP(d, e, a, b, c, 7) + ROUND1_STEP(c, d, e, a, b, 8) + ROUND1_STEP(b, c, d, e, a, 9) + ROUND1_STEP(a, b, c, d, e, 10) + ROUND1_STEP(e, a, b, c, d, 11) + ROUND1_STEP(d, e, a, b, c, 12) + ROUND1_STEP(c, d, e, a, b, 13) + ROUND1_STEP(b, c, d, e, a, 14) + ROUND1_STEP(a, b, c, d, e, 15) + ROUND1_STEP(e, a, b, c, d, 16) + ROUND1_STEP(d, e, a, b, c, 17) + ROUND1_STEP(c, d, e, a, b, 18) + ROUND1_STEP(b, c, d, e, a, 19) + + ROUND2_STEP(a, b, c, d, e, 20) + ROUND2_STEP(e, a, b, c, d, 21) + ROUND2_STEP(d, e, a, b, c, 22) + ROUND2_STEP(c, d, e, a, b, 23) + ROUND2_STEP(b, c, d, e, a, 24) + ROUND2_STEP(a, b, c, d, e, 25) + ROUND2_STEP(e, a, b, c, d, 26) + ROUND2_STEP(d, e, a, b, c, 27) + ROUND2_STEP(c, d, e, a, b, 28) + ROUND2_STEP(b, c, d, e, a, 29) + ROUND2_STEP(a, b, c, d, e, 30) + ROUND2_STEP(e, a, b, c, d, 31) + ROUND2_STEP(d, e, a, b, c, 32) + ROUND2_STEP(c, d, e, a, b, 33) + ROUND2_STEP(b, c, d, e, a, 34) + ROUND2_STEP(a, b, c, d, e, 35) + ROUND2_STEP(e, a, b, c, d, 36) + ROUND2_STEP(d, e, a, b, c, 37) + ROUND2_STEP(c, d, e, a, b, 38) + ROUND2_STEP(b, c, d, e, a, 39) + + ROUND3_STEP(a, b, c, d, e, 40) + ROUND3_STEP(e, a, b, c, d, 41) + ROUND3_STEP(d, e, a, b, c, 42) + ROUND3_STEP(c, d, e, a, b, 43) + ROUND3_STEP(b, c, d, e, a, 44) + ROUND3_STEP(a, b, c, d, e, 45) + ROUND3_STEP(e, a, b, c, d, 46) + ROUND3_STEP(d, e, a, b, c, 47) + ROUND3_STEP(c, d, e, a, b, 48) + ROUND3_STEP(b, c, d, e, a, 49) + ROUND3_STEP(a, b, c, d, e, 50) + ROUND3_STEP(e, a, b, c, d, 51) + ROUND3_STEP(d, e, a, b, c, 52) + ROUND3_STEP(c, d, e, a, b, 53) + ROUND3_STEP(b, c, d, e, a, 54) + ROUND3_STEP(a, b, c, d, e, 55) + ROUND3_STEP(e, a, b, c, d, 56) + ROUND3_STEP(d, e, a, b, c, 57) + */ + if (t == 58) { + ROUND3_STEP(c, d, e, a, b, 58) + ROUND3_STEP(b, c, d, e, a, 59) + + ROUND4_STEP(a, b, c, d, e, 60) + ROUND4_STEP(e, a, b, c, d, 61) + ROUND4_STEP(d, e, a, b, c, 62) + ROUND4_STEP(c, d, e, a, b, 63) + ROUND4_STEP(b, c, d, e, a, 64) + } + ROUND4_STEP(a, b, c, d, e, 65) + ROUND4_STEP(e, a, b, c, d, 66) + ROUND4_STEP(d, e, a, b, c, 67) + ROUND4_STEP(c, d, e, a, b, 68) + ROUND4_STEP(b, c, d, e, a, 69) + ROUND4_STEP(a, b, c, d, e, 70) + ROUND4_STEP(e, a, b, c, d, 71) + ROUND4_STEP(d, e, a, b, c, 72) + ROUND4_STEP(c, d, e, a, b, 73) + ROUND4_STEP(b, c, d, e, a, 74) + ROUND4_STEP(a, b, c, d, e, 75) + ROUND4_STEP(e, a, b, c, d, 76) + ROUND4_STEP(d, e, a, b, c, 77) + ROUND4_STEP(c, d, e, a, b, 78) + ROUND4_STEP(b, c, d, e, a, 79) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java new file mode 100644 index 0000000000..be126a570a --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017, 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.util.sha1; + +import java.text.MessageFormat; + +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.lib.ObjectId; + +/** + * Thrown by {@link SHA1} if it detects a likely hash collision. + * + * @since 4.7 + */ +public class Sha1CollisionException extends RuntimeException { + private static final long serialVersionUID = 1L; + + /** + * Initialize with default message. + * + * @param id + * object whose contents are a hash collision. + */ + public Sha1CollisionException(ObjectId id) { + super(MessageFormat.format( + JGitText.get().sha1CollisionDetected1, + id.name())); + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/UbcCheck.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/UbcCheck.java new file mode 100644 index 0000000000..cebdbee27a --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/UbcCheck.java @@ -0,0 +1,1040 @@ +/* +* Copyright 2017 Marc Stevens <marc@marc-stevens.nl>, Dan Shumow <danshu@microsoft.com> +* Distributed under the MIT Software License. +* MIT License +* +* Copyright (c) 2017: +* Marc Stevens +* Cryptology Group +* Centrum Wiskunde & Informatica +* P.O. Box 94079, 1090 GB Amsterdam, Netherlands +* marc@marc-stevens.nl +* +* Dan Shumow +* Microsoft Research +* danshu@microsoft.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ + +package org.eclipse.jgit.util.sha1; + +// Converted by hand by Shawn Pearce (Google), using lib/ubc_check.c from +// https://github.com/cr-marcstevens/sha1collisiondetection/ +// +// this file was generated by the 'parse_bitrel' program in the tools section +// using the data files from directory 'tools/data/3565' +// +// Array DV contains a list of SHA-1 Disturbance Vectors (DV) to check +// dvType, dvK and dvB define the DV: I(K,B) or II(K,B) (see the paper) +// dm[80] is the expanded message block XOR-difference defined by the DV +// testt is the step to do the recompression from for collision detection +// maski and maskb define the bit to check for each DV in the dvmask returned by ubc_check +// +// ubc_check takes as input an expanded message block and verifies the unavoidable bitconditions for all listed DVs +// it returns a dvmask where each bit belonging to a DV is set if all unavoidable bitconditions for that DV have been met +// thus one needs to do the recompression check for each DV that has its bit set +// +// ubc_check is programmatically generated and the unavoidable bitconditions have been hardcoded +// a directly verifiable version named ubc_check_verify can be found in ubc_check_verify.c +// ubc_check has been verified against ubc_check_verify using the 'ubc_check_test' program in the tools section + +final class UbcCheck { + private static final int DV_I_43_0_bit = 1 << 0; + private static final int DV_I_44_0_bit = 1 << 1; + private static final int DV_I_45_0_bit = 1 << 2; + private static final int DV_I_46_0_bit = 1 << 3; + private static final int DV_I_46_2_bit = 1 << 4; + private static final int DV_I_47_0_bit = 1 << 5; + private static final int DV_I_47_2_bit = 1 << 6; + private static final int DV_I_48_0_bit = 1 << 7; + private static final int DV_I_48_2_bit = 1 << 8; + private static final int DV_I_49_0_bit = 1 << 9; + private static final int DV_I_49_2_bit = 1 << 10; + private static final int DV_I_50_0_bit = 1 << 11; + private static final int DV_I_50_2_bit = 1 << 12; + private static final int DV_I_51_0_bit = 1 << 13; + private static final int DV_I_51_2_bit = 1 << 14; + private static final int DV_I_52_0_bit = 1 << 15; + private static final int DV_II_45_0_bit = 1 << 16; + private static final int DV_II_46_0_bit = 1 << 17; + private static final int DV_II_46_2_bit = 1 << 18; + private static final int DV_II_47_0_bit = 1 << 19; + private static final int DV_II_48_0_bit = 1 << 20; + private static final int DV_II_49_0_bit = 1 << 21; + private static final int DV_II_49_2_bit = 1 << 22; + private static final int DV_II_50_0_bit = 1 << 23; + private static final int DV_II_50_2_bit = 1 << 24; + private static final int DV_II_51_0_bit = 1 << 25; + private static final int DV_II_51_2_bit = 1 << 26; + private static final int DV_II_52_0_bit = 1 << 27; + private static final int DV_II_53_0_bit = 1 << 28; + private static final int DV_II_54_0_bit = 1 << 29; + private static final int DV_II_55_0_bit = 1 << 30; + private static final int DV_II_56_0_bit = 1 << 31; + + static int check(int[] w) { + int mask = ~0; + mask &= (((((w[44] ^ w[45]) >>> 29) & 1) - 1) | ~(DV_I_48_0_bit + | DV_I_51_0_bit | DV_I_52_0_bit | DV_II_45_0_bit + | DV_II_46_0_bit | DV_II_50_0_bit | DV_II_51_0_bit)); + mask &= (((((w[49] ^ w[50]) >>> 29) & 1) - 1) + | ~(DV_I_46_0_bit | DV_II_45_0_bit | DV_II_50_0_bit + | DV_II_51_0_bit | DV_II_55_0_bit | DV_II_56_0_bit)); + mask &= (((((w[48] ^ w[49]) >>> 29) & 1) - 1) + | ~(DV_I_45_0_bit | DV_I_52_0_bit | DV_II_49_0_bit + | DV_II_50_0_bit | DV_II_54_0_bit | DV_II_55_0_bit)); + mask &= ((((w[47] ^ (w[50] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit + | DV_II_45_0_bit | DV_II_51_0_bit | DV_II_56_0_bit)); + mask &= (((((w[47] ^ w[48]) >>> 29) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_51_0_bit | DV_II_48_0_bit + | DV_II_49_0_bit | DV_II_53_0_bit | DV_II_54_0_bit)); + mask &= (((((w[46] >>> 4) ^ (w[49] >>> 29)) & 1) - 1) + | ~(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit + | DV_I_52_0_bit | DV_II_50_0_bit | DV_II_55_0_bit)); + mask &= (((((w[46] ^ w[47]) >>> 29) & 1) - 1) + | ~(DV_I_43_0_bit | DV_I_50_0_bit | DV_II_47_0_bit + | DV_II_48_0_bit | DV_II_52_0_bit | DV_II_53_0_bit)); + mask &= (((((w[45] >>> 4) ^ (w[48] >>> 29)) & 1) - 1) + | ~(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit + | DV_I_51_0_bit | DV_II_49_0_bit | DV_II_54_0_bit)); + mask &= (((((w[45] ^ w[46]) >>> 29) & 1) - 1) + | ~(DV_I_49_0_bit | DV_I_52_0_bit | DV_II_46_0_bit + | DV_II_47_0_bit | DV_II_51_0_bit | DV_II_52_0_bit)); + mask &= (((((w[44] >>> 4) ^ (w[47] >>> 29)) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit + | DV_I_50_0_bit | DV_II_48_0_bit | DV_II_53_0_bit)); + mask &= (((((w[43] >>> 4) ^ (w[46] >>> 29)) & 1) - 1) + | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit + | DV_I_49_0_bit | DV_II_47_0_bit | DV_II_52_0_bit)); + mask &= (((((w[43] ^ w[44]) >>> 29) & 1) - 1) + | ~(DV_I_47_0_bit | DV_I_50_0_bit | DV_I_51_0_bit + | DV_II_45_0_bit | DV_II_49_0_bit | DV_II_50_0_bit)); + mask &= (((((w[42] >>> 4) ^ (w[45] >>> 29)) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit + | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_51_0_bit)); + mask &= (((((w[41] >>> 4) ^ (w[44] >>> 29)) & 1) - 1) + | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit + | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_50_0_bit)); + mask &= (((((w[40] ^ w[41]) >>> 29) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_47_0_bit | DV_I_48_0_bit + | DV_II_46_0_bit | DV_II_47_0_bit | DV_II_56_0_bit)); + mask &= (((((w[54] ^ w[55]) >>> 29) & 1) - 1) + | ~(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_50_0_bit + | DV_II_55_0_bit | DV_II_56_0_bit)); + mask &= (((((w[53] ^ w[54]) >>> 29) & 1) - 1) + | ~(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_49_0_bit + | DV_II_54_0_bit | DV_II_55_0_bit)); + mask &= (((((w[52] ^ w[53]) >>> 29) & 1) - 1) + | ~(DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit + | DV_II_53_0_bit | DV_II_54_0_bit)); + mask &= ((((w[50] ^ (w[53] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_50_0_bit | DV_I_52_0_bit | DV_II_46_0_bit + | DV_II_48_0_bit | DV_II_54_0_bit)); + mask &= (((((w[50] ^ w[51]) >>> 29) & 1) - 1) + | ~(DV_I_47_0_bit | DV_II_46_0_bit | DV_II_51_0_bit + | DV_II_52_0_bit | DV_II_56_0_bit)); + mask &= ((((w[49] ^ (w[52] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit + | DV_II_47_0_bit | DV_II_53_0_bit)); + mask &= ((((w[48] ^ (w[51] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit + | DV_II_46_0_bit | DV_II_52_0_bit)); + mask &= (((((w[42] ^ w[43]) >>> 29) & 1) - 1) + | ~(DV_I_46_0_bit | DV_I_49_0_bit | DV_I_50_0_bit + | DV_II_48_0_bit | DV_II_49_0_bit)); + mask &= (((((w[41] ^ w[42]) >>> 29) & 1) - 1) + | ~(DV_I_45_0_bit | DV_I_48_0_bit | DV_I_49_0_bit + | DV_II_47_0_bit | DV_II_48_0_bit)); + mask &= (((((w[40] >>> 4) ^ (w[43] >>> 29)) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_50_0_bit + | DV_II_49_0_bit | DV_II_56_0_bit)); + mask &= (((((w[39] >>> 4) ^ (w[42] >>> 29)) & 1) - 1) + | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_49_0_bit + | DV_II_48_0_bit | DV_II_55_0_bit)); + if ((mask & (DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit + | DV_II_54_0_bit | DV_II_56_0_bit)) != 0) + mask &= (((((w[38] >>> 4) ^ (w[41] >>> 29)) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit + | DV_II_54_0_bit | DV_II_56_0_bit)); + mask &= (((((w[37] >>> 4) ^ (w[40] >>> 29)) & 1) - 1) + | ~(DV_I_43_0_bit | DV_I_47_0_bit | DV_II_46_0_bit + | DV_II_53_0_bit | DV_II_55_0_bit)); + if ((mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_51_0_bit + | DV_II_56_0_bit)) != 0) + mask &= (((((w[55] ^ w[56]) >>> 29) & 1) - 1) | ~(DV_I_52_0_bit + | DV_II_48_0_bit | DV_II_51_0_bit | DV_II_56_0_bit)); + if ((mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit + | DV_II_56_0_bit)) != 0) + mask &= ((((w[52] ^ (w[55] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit + | DV_II_56_0_bit)); + if ((mask & (DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit + | DV_II_55_0_bit)) != 0) + mask &= ((((w[51] ^ (w[54] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit + | DV_II_55_0_bit)); + if ((mask & (DV_I_48_0_bit | DV_II_47_0_bit | DV_II_52_0_bit + | DV_II_53_0_bit)) != 0) + mask &= (((((w[51] ^ w[52]) >>> 29) & 1) - 1) | ~(DV_I_48_0_bit + | DV_II_47_0_bit | DV_II_52_0_bit | DV_II_53_0_bit)); + if ((mask & (DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit + | DV_II_48_0_bit)) != 0) + mask &= (((((w[36] >>> 4) ^ (w[40] >>> 29)) & 1) - 1) + | ~(DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit + | DV_II_48_0_bit)); + if ((mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit)) != 0) + mask &= ((0 - (((w[53] ^ w[56]) >>> 29) & 1)) + | ~(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit)); + if ((mask & (DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit)) != 0) + mask &= ((0 - (((w[51] ^ w[54]) >>> 29) & 1)) + | ~(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit)); + if ((mask & (DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit)) != 0) + mask &= ((0 - (((w[50] ^ w[52]) >>> 29) & 1)) + | ~(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit)); + if ((mask & (DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit)) != 0) + mask &= ((0 - (((w[49] ^ w[51]) >>> 29) & 1)) + | ~(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit)); + if ((mask & (DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit)) != 0) + mask &= ((0 - (((w[48] ^ w[50]) >>> 29) & 1)) + | ~(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit)); + if ((mask & (DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit)) != 0) + mask &= ((0 - (((w[47] ^ w[49]) >>> 29) & 1)) + | ~(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit)); + if ((mask & (DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit)) != 0) + mask &= ((0 - (((w[46] ^ w[48]) >>> 29) & 1)) + | ~(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit)); + mask &= ((((w[45] ^ w[47]) & (1 << 6)) - (1 << 6)) + | ~(DV_I_47_2_bit | DV_I_49_2_bit | DV_I_51_2_bit)); + if ((mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit)) != 0) + mask &= ((0 - (((w[45] ^ w[47]) >>> 29) & 1)) + | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit)); + mask &= (((((w[44] ^ w[46]) >>> 6) & 1) - 1) + | ~(DV_I_46_2_bit | DV_I_48_2_bit | DV_I_50_2_bit)); + if ((mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit)) != 0) + mask &= ((0 - (((w[44] ^ w[46]) >>> 29) & 1)) + | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit)); + mask &= ((0 - ((w[41] ^ (w[42] >>> 5)) & (1 << 1))) + | ~(DV_I_48_2_bit | DV_II_46_2_bit | DV_II_51_2_bit)); + mask &= ((0 - ((w[40] ^ (w[41] >>> 5)) & (1 << 1))) + | ~(DV_I_47_2_bit | DV_I_51_2_bit | DV_II_50_2_bit)); + if ((mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit)) != 0) + mask &= ((0 - (((w[40] ^ w[42]) >>> 4) & 1)) + | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit)); + mask &= ((0 - ((w[39] ^ (w[40] >>> 5)) & (1 << 1))) + | ~(DV_I_46_2_bit | DV_I_50_2_bit | DV_II_49_2_bit)); + if ((mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit)) != 0) + mask &= ((0 - (((w[39] ^ w[41]) >>> 4) & 1)) + | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit)); + if ((mask & (DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)) != 0) + mask &= ((0 - (((w[38] ^ w[40]) >>> 4) & 1)) + | ~(DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)); + if ((mask & (DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit)) != 0) + mask &= ((0 - (((w[37] ^ w[39]) >>> 4) & 1)) + | ~(DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit)); + mask &= ((0 - ((w[36] ^ (w[37] >>> 5)) & (1 << 1))) + | ~(DV_I_47_2_bit | DV_I_50_2_bit | DV_II_46_2_bit)); + if ((mask & (DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit)) != 0) + mask &= (((((w[35] >>> 4) ^ (w[39] >>> 29)) & 1) - 1) + | ~(DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit)); + if ((mask & (DV_I_48_0_bit | DV_II_48_0_bit)) != 0) + mask &= ((0 - ((w[63] ^ (w[64] >>> 5)) & (1 << 0))) + | ~(DV_I_48_0_bit | DV_II_48_0_bit)); + if ((mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0) + mask &= ((0 - ((w[63] ^ (w[64] >>> 5)) & (1 << 1))) + | ~(DV_I_45_0_bit | DV_II_45_0_bit)); + if ((mask & (DV_I_47_0_bit | DV_II_47_0_bit)) != 0) + mask &= ((0 - ((w[62] ^ (w[63] >>> 5)) & (1 << 0))) + | ~(DV_I_47_0_bit | DV_II_47_0_bit)); + if ((mask & (DV_I_46_0_bit | DV_II_46_0_bit)) != 0) + mask &= ((0 - ((w[61] ^ (w[62] >>> 5)) & (1 << 0))) + | ~(DV_I_46_0_bit | DV_II_46_0_bit)); + mask &= ((0 - ((w[61] ^ (w[62] >>> 5)) & (1 << 2))) + | ~(DV_I_46_2_bit | DV_II_46_2_bit)); + if ((mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0) + mask &= ((0 - ((w[60] ^ (w[61] >>> 5)) & (1 << 0))) + | ~(DV_I_45_0_bit | DV_II_45_0_bit)); + if ((mask & (DV_II_51_0_bit | DV_II_54_0_bit)) != 0) + mask &= (((((w[58] ^ w[59]) >>> 29) & 1) - 1) + | ~(DV_II_51_0_bit | DV_II_54_0_bit)); + if ((mask & (DV_II_50_0_bit | DV_II_53_0_bit)) != 0) + mask &= (((((w[57] ^ w[58]) >>> 29) & 1) - 1) + | ~(DV_II_50_0_bit | DV_II_53_0_bit)); + if ((mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0) + mask &= ((((w[56] ^ (w[59] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_II_52_0_bit | DV_II_54_0_bit)); + if ((mask & (DV_II_51_0_bit | DV_II_52_0_bit)) != 0) + mask &= ((0 - (((w[56] ^ w[59]) >>> 29) & 1)) + | ~(DV_II_51_0_bit | DV_II_52_0_bit)); + if ((mask & (DV_II_49_0_bit | DV_II_52_0_bit)) != 0) + mask &= (((((w[56] ^ w[57]) >>> 29) & 1) - 1) + | ~(DV_II_49_0_bit | DV_II_52_0_bit)); + if ((mask & (DV_II_51_0_bit | DV_II_53_0_bit)) != 0) + mask &= ((((w[55] ^ (w[58] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_II_51_0_bit | DV_II_53_0_bit)); + if ((mask & (DV_II_50_0_bit | DV_II_52_0_bit)) != 0) + mask &= ((((w[54] ^ (w[57] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_II_50_0_bit | DV_II_52_0_bit)); + if ((mask & (DV_II_49_0_bit | DV_II_51_0_bit)) != 0) + mask &= ((((w[53] ^ (w[56] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_II_49_0_bit | DV_II_51_0_bit)); + mask &= ((((w[51] ^ (w[50] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_I_50_2_bit | DV_II_46_2_bit)); + mask &= ((((w[48] ^ w[50]) & (1 << 6)) - (1 << 6)) + | ~(DV_I_50_2_bit | DV_II_46_2_bit)); + if ((mask & (DV_I_51_0_bit | DV_I_52_0_bit)) != 0) + mask &= ((0 - (((w[48] ^ w[55]) >>> 29) & 1)) + | ~(DV_I_51_0_bit | DV_I_52_0_bit)); + mask &= ((((w[47] ^ w[49]) & (1 << 6)) - (1 << 6)) + | ~(DV_I_49_2_bit | DV_I_51_2_bit)); + mask &= ((((w[48] ^ (w[47] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_I_47_2_bit | DV_II_51_2_bit)); + mask &= ((((w[46] ^ w[48]) & (1 << 6)) - (1 << 6)) + | ~(DV_I_48_2_bit | DV_I_50_2_bit)); + mask &= ((((w[47] ^ (w[46] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_I_46_2_bit | DV_II_50_2_bit)); + mask &= ((0 - ((w[44] ^ (w[45] >>> 5)) & (1 << 1))) + | ~(DV_I_51_2_bit | DV_II_49_2_bit)); + mask &= ((((w[43] ^ w[45]) & (1 << 6)) - (1 << 6)) + | ~(DV_I_47_2_bit | DV_I_49_2_bit)); + mask &= (((((w[42] ^ w[44]) >>> 6) & 1) - 1) + | ~(DV_I_46_2_bit | DV_I_48_2_bit)); + mask &= ((((w[43] ^ (w[42] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_II_46_2_bit | DV_II_51_2_bit)); + mask &= ((((w[42] ^ (w[41] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_I_51_2_bit | DV_II_50_2_bit)); + mask &= ((((w[41] ^ (w[40] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_I_50_2_bit | DV_II_49_2_bit)); + if ((mask & (DV_I_52_0_bit | DV_II_51_0_bit)) != 0) + mask &= ((((w[39] ^ (w[43] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_52_0_bit | DV_II_51_0_bit)); + if ((mask & (DV_I_51_0_bit | DV_II_50_0_bit)) != 0) + mask &= ((((w[38] ^ (w[42] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_51_0_bit | DV_II_50_0_bit)); + if ((mask & (DV_I_48_2_bit | DV_I_51_2_bit)) != 0) + mask &= ((0 - ((w[37] ^ (w[38] >>> 5)) & (1 << 1))) + | ~(DV_I_48_2_bit | DV_I_51_2_bit)); + if ((mask & (DV_I_50_0_bit | DV_II_49_0_bit)) != 0) + mask &= ((((w[37] ^ (w[41] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_50_0_bit | DV_II_49_0_bit)); + if ((mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0) + mask &= ((0 - ((w[36] ^ w[38]) & (1 << 4))) + | ~(DV_II_52_0_bit | DV_II_54_0_bit)); + mask &= ((0 - ((w[35] ^ (w[36] >>> 5)) & (1 << 1))) + | ~(DV_I_46_2_bit | DV_I_49_2_bit)); + if ((mask & (DV_I_51_0_bit | DV_II_47_0_bit)) != 0) + mask &= ((((w[35] ^ (w[39] >>> 25)) & (1 << 3)) - (1 << 3)) + | ~(DV_I_51_0_bit | DV_II_47_0_bit)); + + if (mask == 0) { + return mask; + } + + if ((mask & DV_I_43_0_bit) != 0) + if (0 == ((w[61] ^ (w[62] >>> 5)) & (1 << 1)) + || 0 != ((w[59] ^ (w[63] >>> 25)) & (1 << 5)) + || 0 == ((w[58] ^ (w[63] >>> 30)) & (1 << 0))) + mask &= ~DV_I_43_0_bit; + if ((mask & DV_I_44_0_bit) != 0) + if (0 == ((w[62] ^ (w[63] >>> 5)) & (1 << 1)) + || 0 != ((w[60] ^ (w[64] >>> 25)) & (1 << 5)) + || 0 == ((w[59] ^ (w[64] >>> 30)) & (1 << 0))) + mask &= ~DV_I_44_0_bit; + if ((mask & DV_I_46_2_bit) != 0) + mask &= ((~((w[40] ^ w[42]) >>> 2)) | ~DV_I_46_2_bit); + if ((mask & DV_I_47_2_bit) != 0) + if (0 == ((w[62] ^ (w[63] >>> 5)) & (1 << 2)) + || 0 != ((w[41] ^ w[43]) & (1 << 6))) + mask &= ~DV_I_47_2_bit; + if ((mask & DV_I_48_2_bit) != 0) + if (0 == ((w[63] ^ (w[64] >>> 5)) & (1 << 2)) + || 0 != ((w[48] ^ (w[49] << 5)) & (1 << 6))) + mask &= ~DV_I_48_2_bit; + if ((mask & DV_I_49_2_bit) != 0) + if (0 != ((w[49] ^ (w[50] << 5)) & (1 << 6)) + || 0 == ((w[42] ^ w[50]) & (1 << 1)) + || 0 != ((w[39] ^ (w[40] << 5)) & (1 << 6)) + || 0 == ((w[38] ^ w[40]) & (1 << 1))) + mask &= ~DV_I_49_2_bit; + if ((mask & DV_I_50_0_bit) != 0) + mask &= ((((w[36] ^ w[37]) << 7)) | ~DV_I_50_0_bit); + if ((mask & DV_I_50_2_bit) != 0) + mask &= ((((w[43] ^ w[51]) << 11)) | ~DV_I_50_2_bit); + if ((mask & DV_I_51_0_bit) != 0) + mask &= ((((w[37] ^ w[38]) << 9)) | ~DV_I_51_0_bit); + if ((mask & DV_I_51_2_bit) != 0) + if (0 != ((w[51] ^ (w[52] << 5)) & (1 << 6)) + || 0 != ((w[49] ^ w[51]) & (1 << 6)) + || 0 != ((w[37] ^ (w[37] >>> 5)) & (1 << 1)) + || 0 != ((w[35] ^ (w[39] >>> 25)) & (1 << 5))) + mask &= ~DV_I_51_2_bit; + if ((mask & DV_I_52_0_bit) != 0) + mask &= ((((w[38] ^ w[39]) << 11)) | ~DV_I_52_0_bit); + if ((mask & DV_II_46_2_bit) != 0) + mask &= ((((w[47] ^ w[51]) << 17)) | ~DV_II_46_2_bit); + if ((mask & DV_II_48_0_bit) != 0) + if (0 != ((w[36] ^ (w[40] >>> 25)) & (1 << 3)) + || 0 == ((w[35] ^ (w[40] << 2)) & (1 << 30))) + mask &= ~DV_II_48_0_bit; + if ((mask & DV_II_49_0_bit) != 0) + if (0 != ((w[37] ^ (w[41] >>> 25)) & (1 << 3)) + || 0 == ((w[36] ^ (w[41] << 2)) & (1 << 30))) + mask &= ~DV_II_49_0_bit; + if ((mask & DV_II_49_2_bit) != 0) + if (0 != ((w[53] ^ (w[54] << 5)) & (1 << 6)) + || 0 != ((w[51] ^ w[53]) & (1 << 6)) + || 0 == ((w[50] ^ w[54]) & (1 << 1)) + || 0 != ((w[45] ^ (w[46] << 5)) & (1 << 6)) + || 0 != ((w[37] ^ (w[41] >>> 25)) & (1 << 5)) + || 0 == ((w[36] ^ (w[41] >>> 30)) & (1 << 0))) + mask &= ~DV_II_49_2_bit; + if ((mask & DV_II_50_0_bit) != 0) + if (0 == ((w[55] ^ w[58]) & (1 << 29)) + || 0 != ((w[38] ^ (w[42] >>> 25)) & (1 << 3)) + || 0 == ((w[37] ^ (w[42] << 2)) & (1 << 30))) + mask &= ~DV_II_50_0_bit; + if ((mask & DV_II_50_2_bit) != 0) + if (0 != ((w[54] ^ (w[55] << 5)) & (1 << 6)) + || 0!=((w[52] ^ w[54]) & (1 << 6)) + || 0==((w[51] ^ w[55]) & (1 << 1)) + || 0==((w[45] ^ w[47]) & (1 << 1)) + || 0!=((w[38] ^ (w[42] >>> 25)) & (1 << 5)) + || 0==((w[37] ^ (w[42] >>> 30)) & (1 << 0))) + mask &= ~DV_II_50_2_bit; + if ((mask & DV_II_51_0_bit) != 0) + if (0 != ((w[39] ^ (w[43] >>> 25)) & (1 << 3)) + || 0 == ((w[38] ^ (w[43] << 2)) & (1 << 30))) + mask &= ~DV_II_51_0_bit; + if ((mask & DV_II_51_2_bit) != 0) + if (0 != ((w[55] ^ (w[56] << 5)) & (1 << 6)) + || 0 != ((w[53] ^ w[55]) & (1 << 6)) + || 0 == ((w[52] ^ w[56]) & (1 << 1)) + || 0 == ((w[46] ^ w[48]) & (1 << 1)) + || 0 != ((w[39] ^ (w[43] >>> 25)) & (1 << 5)) + || 0 == ((w[38] ^ (w[43] >>> 30)) & (1 << 0))) + mask &= ~DV_II_51_2_bit; + if ((mask & DV_II_52_0_bit) != 0) + if (0 != ((w[59] ^ w[60]) & (1 << 29)) + || 0 != ((w[40] ^ (w[44] >>> 25)) & (1 << 3)) + || 0 != ((w[40] ^ (w[44] >>> 25)) & (1 << 4)) + || 0==((w[39] ^ (w[44] << 2)) & (1 << 30))) + mask &= ~DV_II_52_0_bit; + if ((mask & DV_II_53_0_bit) != 0) + if (0==((w[58] ^ w[61]) & (1 << 29)) + || 0!=((w[57] ^ (w[61] >>> 25)) & (1 << 4)) + || 0!=((w[41] ^ (w[45] >>> 25)) & (1 << 3)) + || 0!=((w[41] ^ (w[45] >>> 25)) & (1 << 4))) + mask &= ~DV_II_53_0_bit; + if ((mask & DV_II_54_0_bit) != 0) + if (0 != ((w[58] ^ (w[62] >>> 25)) & (1 << 4)) + || 0 != ((w[42] ^ (w[46] >>> 25)) & (1 << 3)) + || 0 != ((w[42] ^ (w[46] >>> 25)) & (1 << 4))) + mask &= ~DV_II_54_0_bit; + if ((mask & DV_II_55_0_bit) != 0) + if (0 != ((w[59] ^ (w[63] >>> 25)) & (1 << 4)) + || 0 != ((w[57] ^ (w[59] >>> 25)) & (1 << 4)) + || 0 != ((w[43] ^ (w[47] >>> 25)) & (1 << 3)) + || 0 != ((w[43] ^ (w[47] >>> 25)) & (1 << 4))) + mask &= ~DV_II_55_0_bit; + if ((mask & DV_II_56_0_bit) != 0) + if (0 != ((w[60] ^ (w[64] >>> 25)) & (1 << 4)) + || 0 != ((w[44] ^ (w[48] >>> 25)) & (1 << 3)) + || 0 != ((w[44] ^ (w[48] >>> 25)) & (1 << 4))) + mask &= ~DV_II_56_0_bit; + return mask; + } + + private UbcCheck() { + } + + static final class DvInfo { + final int testt; + final int maskb; + final int[] dm; + + @SuppressWarnings("unused") + DvInfo(int dvType, int dvK, int dvB, int testt, int maskb, int[] dm) { + this.testt = testt; + this.maskb = maskb; + this.dm = dm; + + // Only states 58 and 65 are saved. + if (testt != 58 && testt != 65) { + throw new IllegalArgumentException(); + } + } + } + + static final DvInfo[] DV = new DvInfo[] { + new DvInfo(1, 43, 0, 58, 0, new int[] { 0x08000000, 0x9800000c, + 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, + 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, + 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, + 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, + 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, + 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, + 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, + 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, + 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, + 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, + 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, + 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, + 0x00000018, 0x00000164, 0x00000408, 0x800000e6, 0x8000004c, + 0x00000803, 0x80000161, 0x80000599 }), + new DvInfo(1, 44, 0, 58, 1, new int[] { 0xb4000008, 0x08000000, + 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, + 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, + 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, + 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, + 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, + 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, + 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, + 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, + 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, + 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, + 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, + 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, + 0x80000202, 0x00000018, 0x00000164, 0x00000408, 0x800000e6, + 0x8000004c, 0x00000803, 0x80000161 }), + new DvInfo(1, 45, 0, 58, 2, new int[] { 0xf4000014, 0xb4000008, + 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, + 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, + 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, + 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, + 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, + 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, + 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, + 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, + 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, + 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, + 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, + 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, + 0x80000012, 0x80000202, 0x00000018, 0x00000164, 0x00000408, + 0x800000e6, 0x8000004c, 0x00000803 }), + new DvInfo(1, 46, 0, 58, 3, new int[] { 0x2c000010, 0xf4000014, + 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, + 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, + 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, + 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, + 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, + 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, + 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, + 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, + 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, + 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, + 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, + 0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164, + 0x00000408, 0x800000e6, 0x8000004c }), + new DvInfo(1, 46, 2, 58, 4, new int[] { 0xb0000040, 0xd0000053, + 0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040, + 0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003, + 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, + 0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043, + 0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, + 0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001, + 0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040, + 0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000, + 0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040, + 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009, + 0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, + 0x00000026, 0x0000004a, 0x0000080a, 0x00000060, 0x00000590, + 0x00001020, 0x0000039a, 0x00000132 }), + new DvInfo(1, 47, 0, 58, 5, new int[] { 0xc8000010, 0x2c000010, + 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, + 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, + 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, + 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, + 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, + 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, + 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, + 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, + 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, + 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, + 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, + 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018, + 0x00000164, 0x00000408, 0x800000e6 }), + new DvInfo(1, 47, 2, 58, 6, new int[] { 0x20000043, 0xb0000040, + 0xd0000053, 0xd0000022, 0x20000000, 0x60000032, 0x60000043, + 0x20000040, 0xe0000042, 0x60000002, 0x80000001, 0x00000020, + 0x00000003, 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, + 0x80000040, 0x20000001, 0x20000060, 0x80000001, 0x40000042, + 0xc0000043, 0x40000022, 0x00000003, 0x40000042, 0xc0000043, + 0xc0000022, 0x00000001, 0x40000002, 0xc0000043, 0x40000062, + 0x80000001, 0x40000042, 0x40000042, 0x40000002, 0x00000002, + 0x00000040, 0x80000002, 0x80000000, 0x80000002, 0x80000040, + 0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000000, + 0x00000040, 0x80000002, 0x00000000, 0x80000000, 0x80000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000004, 0x00000080, 0x00000004, 0x00000009, 0x00000101, + 0x00000009, 0x00000012, 0x00000202, 0x0000001a, 0x00000124, + 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a, 0x00000060, + 0x00000590, 0x00001020, 0x0000039a }), + new DvInfo(1, 48, 0, 58, 7, new int[] { 0xb800000a, 0xc8000010, + 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, + 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, + 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, + 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, + 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, + 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, + 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, + 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, + 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, + 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, + 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, + 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, + 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, + 0x00000018, 0x00000164, 0x00000408 }), + new DvInfo(1, 48, 2, 58, 8, new int[] { 0xe000002a, 0x20000043, + 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000, 0x60000032, + 0x60000043, 0x20000040, 0xe0000042, 0x60000002, 0x80000001, + 0x00000020, 0x00000003, 0x40000052, 0x40000040, 0xe0000052, + 0xa0000000, 0x80000040, 0x20000001, 0x20000060, 0x80000001, + 0x40000042, 0xc0000043, 0x40000022, 0x00000003, 0x40000042, + 0xc0000043, 0xc0000022, 0x00000001, 0x40000002, 0xc0000043, + 0x40000062, 0x80000001, 0x40000042, 0x40000042, 0x40000002, + 0x00000002, 0x00000040, 0x80000002, 0x80000000, 0x80000002, + 0x80000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040, + 0x80000000, 0x00000040, 0x80000002, 0x00000000, 0x80000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000004, 0x00000080, 0x00000004, 0x00000009, + 0x00000101, 0x00000009, 0x00000012, 0x00000202, 0x0000001a, + 0x00000124, 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a, + 0x00000060, 0x00000590, 0x00001020 }), + new DvInfo(1, 49, 0, 58, 9, new int[] { 0x18000000, 0xb800000a, + 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, + 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, + 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, + 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, + 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, + 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, + 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, + 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, + 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, + 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, + 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, + 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, + 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, + 0x80000202, 0x00000018, 0x00000164 }), + new DvInfo(1, 49, 2, 58, 10, new int[] { 0x60000000, 0xe000002a, + 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000, + 0x60000032, 0x60000043, 0x20000040, 0xe0000042, 0x60000002, + 0x80000001, 0x00000020, 0x00000003, 0x40000052, 0x40000040, + 0xe0000052, 0xa0000000, 0x80000040, 0x20000001, 0x20000060, + 0x80000001, 0x40000042, 0xc0000043, 0x40000022, 0x00000003, + 0x40000042, 0xc0000043, 0xc0000022, 0x00000001, 0x40000002, + 0xc0000043, 0x40000062, 0x80000001, 0x40000042, 0x40000042, + 0x40000002, 0x00000002, 0x00000040, 0x80000002, 0x80000000, + 0x80000002, 0x80000040, 0x00000000, 0x80000040, 0x80000000, + 0x00000040, 0x80000000, 0x00000040, 0x80000002, 0x00000000, + 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004, + 0x00000009, 0x00000101, 0x00000009, 0x00000012, 0x00000202, + 0x0000001a, 0x00000124, 0x0000040c, 0x00000026, 0x0000004a, + 0x0000080a, 0x00000060, 0x00000590 }), + new DvInfo(1, 50, 0, 65, 11, new int[] { 0x0800000c, 0x18000000, + 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, + 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, + 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, + 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, + 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, + 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, + 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, + 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, + 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, + 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, + 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, + 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, + 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, + 0x80000012, 0x80000202, 0x00000018 }), + new DvInfo(1, 50, 2, 65, 12, new int[] { 0x20000030, 0x60000000, + 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022, + 0x20000000, 0x60000032, 0x60000043, 0x20000040, 0xe0000042, + 0x60000002, 0x80000001, 0x00000020, 0x00000003, 0x40000052, + 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, 0x20000001, + 0x20000060, 0x80000001, 0x40000042, 0xc0000043, 0x40000022, + 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, 0x00000001, + 0x40000002, 0xc0000043, 0x40000062, 0x80000001, 0x40000042, + 0x40000042, 0x40000002, 0x00000002, 0x00000040, 0x80000002, + 0x80000000, 0x80000002, 0x80000040, 0x00000000, 0x80000040, + 0x80000000, 0x00000040, 0x80000000, 0x00000040, 0x80000002, + 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080, + 0x00000004, 0x00000009, 0x00000101, 0x00000009, 0x00000012, + 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, 0x00000026, + 0x0000004a, 0x0000080a, 0x00000060 }), + new DvInfo(1, 51, 0, 65, 13, new int[] { 0xe8000000, 0x0800000c, + 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, + 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, + 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, + 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, + 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, + 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, + 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, + 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, + 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, + 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, + 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, + 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, + 0x80000009, 0x80000012, 0x80000202 }), + new DvInfo(1, 51, 2, 65, 14, new int[] { 0xa0000003, 0x20000030, + 0x60000000, 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053, + 0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040, + 0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003, + 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, + 0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043, + 0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, + 0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001, + 0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040, + 0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000, + 0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040, + 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009, + 0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, + 0x00000026, 0x0000004a, 0x0000080a }), + new DvInfo(1, 52, 0, 65, 15, new int[] { 0x04000010, 0xe8000000, + 0x0800000c, 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010, + 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, + 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, + 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, + 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, + 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, + 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, + 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, + 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, + 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, + 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, + 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, + 0x00000103, 0x80000009, 0x80000012 }), + new DvInfo(2, 45, 0, 58, 16, new int[] { 0xec000014, 0x0c000002, + 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, + 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, + 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, + 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, + 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, + 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, + 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, + 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, + 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, + 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, + 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, + 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, 0x8000041a, + 0x000002e4, 0x80000054, 0x00000967 }), + new DvInfo(2, 46, 0, 58, 17, new int[] { 0x2400001c, 0xec000014, + 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, + 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, + 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, + 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, + 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, + 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, + 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, + 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, + 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, + 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, + 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, + 0x8000041a, 0x000002e4, 0x80000054 }), + new DvInfo(2, 46, 2, 58, 18, new int[] { 0x90000070, 0xb0000053, + 0x30000008, 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062, + 0xc0000042, 0x00000030, 0xe0000042, 0x20000060, 0xe0000041, + 0x20000050, 0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012, + 0x60000041, 0xc0000032, 0x20000001, 0xc0000002, 0xe0000042, + 0x60000042, 0x80000002, 0x00000000, 0x00000000, 0x80000000, + 0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000000, + 0x00000040, 0x80000001, 0x00000060, 0x80000003, 0x40000002, + 0xc0000040, 0xc0000002, 0x80000000, 0x80000000, 0x80000002, + 0x00000040, 0x00000002, 0x80000000, 0x80000000, 0x80000000, + 0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000002, + 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000080, 0x00000004, 0x00000009, 0x00000105, 0x00000089, + 0x00000016, 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e, + 0x00000224, 0x00000050, 0x0000092e, 0x0000046c, 0x000005b6, + 0x0000106a, 0x00000b90, 0x00000152 }), + new DvInfo(2, 47, 0, 58, 19, new int[] { 0x20000010, 0x2400001c, + 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, + 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, + 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, + 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, + 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, + 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, + 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, + 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, + 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, + 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, + 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, + 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, + 0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, + 0x8000016d, 0x8000041a, 0x000002e4 }), + new DvInfo(2, 48, 0, 58, 20, new int[] { 0xbc00001a, 0x20000010, + 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, + 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, + 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, + 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, + 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, + 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, + 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, + 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, + 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, + 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, + 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, + 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, + 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b, + 0x0000011b, 0x8000016d, 0x8000041a }), + new DvInfo(2, 49, 0, 58, 21, new int[] { 0x3c000004, 0xbc00001a, + 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, + 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, + 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, + 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, + 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, + 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, + 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, + 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, + 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, + 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, + 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, + 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, + 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, + 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014, + 0x8000024b, 0x0000011b, 0x8000016d }), + new DvInfo(2, 49, 2, 58, 22, new int[] { 0xf0000010, 0xf000006a, + 0x80000040, 0x90000070, 0xb0000053, 0x30000008, 0x00000043, + 0xd0000072, 0xb0000010, 0xf0000062, 0xc0000042, 0x00000030, + 0xe0000042, 0x20000060, 0xe0000041, 0x20000050, 0xc0000041, + 0xe0000072, 0xa0000003, 0xc0000012, 0x60000041, 0xc0000032, + 0x20000001, 0xc0000002, 0xe0000042, 0x60000042, 0x80000002, + 0x00000000, 0x00000000, 0x80000000, 0x00000002, 0x00000040, + 0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000001, + 0x00000060, 0x80000003, 0x40000002, 0xc0000040, 0xc0000002, + 0x80000000, 0x80000000, 0x80000002, 0x00000040, 0x00000002, + 0x80000000, 0x80000000, 0x80000000, 0x00000002, 0x00000040, + 0x00000000, 0x80000040, 0x80000002, 0x00000000, 0x80000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004, + 0x00000009, 0x00000105, 0x00000089, 0x00000016, 0x0000020b, + 0x0000011b, 0x0000012d, 0x0000041e, 0x00000224, 0x00000050, + 0x0000092e, 0x0000046c, 0x000005b6 }), + new DvInfo(2, 50, 0, 65, 23, new int[] { 0xb400001c, 0x3c000004, + 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, + 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, + 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, + 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, + 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, + 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, + 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, + 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, + 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, + 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, + 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, + 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, + 0x00000014, 0x8000024b, 0x0000011b }), + new DvInfo(2, 50, 2, 65, 24, new int[] { 0xd0000072, 0xf0000010, + 0xf000006a, 0x80000040, 0x90000070, 0xb0000053, 0x30000008, + 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062, 0xc0000042, + 0x00000030, 0xe0000042, 0x20000060, 0xe0000041, 0x20000050, + 0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012, 0x60000041, + 0xc0000032, 0x20000001, 0xc0000002, 0xe0000042, 0x60000042, + 0x80000002, 0x00000000, 0x00000000, 0x80000000, 0x00000002, + 0x00000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040, + 0x80000001, 0x00000060, 0x80000003, 0x40000002, 0xc0000040, + 0xc0000002, 0x80000000, 0x80000000, 0x80000002, 0x00000040, + 0x00000002, 0x80000000, 0x80000000, 0x80000000, 0x00000002, + 0x00000040, 0x00000000, 0x80000040, 0x80000002, 0x00000000, + 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080, + 0x00000004, 0x00000009, 0x00000105, 0x00000089, 0x00000016, + 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e, 0x00000224, + 0x00000050, 0x0000092e, 0x0000046c }), + new DvInfo(2, 51, 0, 65, 25, new int[] { 0xc0000010, 0xb400001c, + 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, + 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, + 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, + 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, + 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, + 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, + 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, + 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, + 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, + 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, + 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, + 0x00000089, 0x00000014, 0x8000024b }), + new DvInfo(2, 51, 2, 65, 26, new int[] { 0x00000043, 0xd0000072, + 0xf0000010, 0xf000006a, 0x80000040, 0x90000070, 0xb0000053, + 0x30000008, 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062, + 0xc0000042, 0x00000030, 0xe0000042, 0x20000060, 0xe0000041, + 0x20000050, 0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012, + 0x60000041, 0xc0000032, 0x20000001, 0xc0000002, 0xe0000042, + 0x60000042, 0x80000002, 0x00000000, 0x00000000, 0x80000000, + 0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000000, + 0x00000040, 0x80000001, 0x00000060, 0x80000003, 0x40000002, + 0xc0000040, 0xc0000002, 0x80000000, 0x80000000, 0x80000002, + 0x00000040, 0x00000002, 0x80000000, 0x80000000, 0x80000000, + 0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000002, + 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000080, 0x00000004, 0x00000009, 0x00000105, 0x00000089, + 0x00000016, 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e, + 0x00000224, 0x00000050, 0x0000092e }), + new DvInfo(2, 52, 0, 65, 27, new int[] { 0x0c000002, 0xc0000010, + 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, + 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, + 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, + 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, + 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, + 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, + 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, + 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, + 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, + 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, + 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, + 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, + 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, + 0x80000107, 0x00000089, 0x00000014 }), + new DvInfo(2, 53, 0, 65, 28, new int[] { 0xcc000014, 0x0c000002, + 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, + 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, + 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, + 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, + 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, + 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, + 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, + 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, + 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, + 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, + 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, + 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, + 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, + 0x4000004b, 0x80000107, 0x00000089 }), + new DvInfo(2, 54, 0, 65, 29, new int[] { 0x0400001c, 0xcc000014, + 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, + 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, + 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, + 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, + 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, + 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, + 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, + 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, + 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, + 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, + 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, + 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, + 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, + 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, + 0xc0000046, 0x4000004b, 0x80000107 }), + new DvInfo(2, 55, 0, 65, 30, new int[] { 0x00000010, 0x0400001c, + 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, + 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, + 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, + 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, + 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, + 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, + 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, + 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, + 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, + 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, + 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, + 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, + 0xc0000082, 0xc0000046, 0x4000004b }), + new DvInfo(2, 56, 0, 65, 31, new int[] { 0x2600001a, 0x00000010, + 0x0400001c, 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, + 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, + 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, + 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, + 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, + 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, + 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, + 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, + 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, + 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, + 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, + 0x80000005, 0xc0000082, 0xc0000046 }), }; + + static { + // Assert the DV array is indexed by maskb; that is DV block using + // maskb = N must be at array index N. + for (int i = 0; i < DV.length; i++) { + if (i != DV[i].maskb) { + throw new IllegalStateException("must be indexed by maskb"); //$NON-NLS-1$ + } + } + } +} |