diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2019-04-28 00:21:16 +0200 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2019-04-28 00:30:47 +0200 |
commit | 32f0963b84b8e40d05f683752d6cec3c94d07279 (patch) | |
tree | 56ac47686fd6685109bc91363b30b4be56d4958b /org.eclipse.jgit | |
parent | c23ccd29b5269e68aa23cbbba30b1b2df521e81f (diff) | |
parent | a72e0b0188376c72d153d0e6fc784952274870ae (diff) | |
download | jgit-32f0963b84b8e40d05f683752d6cec3c94d07279.tar.gz jgit-32f0963b84b8e40d05f683752d6cec3c94d07279.zip |
Merge branch 'stable-5.2' into stable-5.3
* stable-5.2:
Prepare 5.2.3-SNAPSHOT builds
JGit v5.2.2.201904231744-r
Revert 4678f4b and provide another solution for bug 467631
Apache MINA sshd: make sendKexInit() work also for re-keying
Prepare 5.1.8-SNAPSHOT builds
JGit v5.1.7.201904200442-r
ObjectUploadListener: Add callback interface
Prepare 4.11.9-SNAPSHOT builds
JGit v4.11.8.201904181247-r
Prepare 4.9.11-SNAPSHOT builds
JGit v4.9.10.201904181027-r
Prepare 4.7.10-SNAPSHOT builds
JGit v4.7.9.201904161809-r
Prepare 4.5.8-SNAPSHOT builds
JGit v4.5.7.201904151645-r
Remember the cause for invalidating a packfile
Fix API problem filters
Fix pack files scan when filesnapshot isn't modified
Change-Id: Ie7e572ac7e346f21fe0c387d7448be168a9c127a
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Diffstat (limited to 'org.eclipse.jgit')
8 files changed, 115 insertions, 46 deletions
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index e90d41bfa8..771bdbb2f0 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters @@ -3,16 +3,22 @@ <resource path="META-INF/MANIFEST.MF"> <filter id="924844039"> <message_arguments> - <message_argument value="5.3.0"/> + <message_argument value="5.3.1"/> <message_argument value="5.3.0"/> </message_arguments> </filter> </resource> - <resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS"> + <resource path="src/org/eclipse/jgit/errors/PackInvalidException.java" type="org.eclipse.jgit.errors.PackInvalidException"> + <filter id="1142947843"> + <message_arguments> + <message_argument value="4.5.7"/> + <message_argument value="PackInvalidException(File, Throwable)"/> + </message_arguments> + </filter> <filter id="1142947843"> <message_arguments> - <message_argument value="4.5.6"/> - <message_argument value="fileAttributes(File)"/> + <message_argument value="4.5.7"/> + <message_argument value="PackInvalidException(String, Throwable)"/> </message_arguments> </filter> </resource> diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/PackInvalidException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/PackInvalidException.java index a83de06262..b238ab4718 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/PackInvalidException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/PackInvalidException.java @@ -60,9 +60,24 @@ public class PackInvalidException extends IOException { * * @param path * path of the invalid pack file. + * @deprecated Use {@link #PackInvalidException(File, Throwable)}. */ + @Deprecated public PackInvalidException(File path) { - this(path.getAbsolutePath()); + this(path, null); + } + + /** + * Construct a pack invalid error with cause. + * + * @param path + * path of the invalid pack file. + * @param cause + * cause of the pack file becoming invalid. + * @since 4.5.7 + */ + public PackInvalidException(File path, Throwable cause) { + this(path.getAbsolutePath(), cause); } /** @@ -70,8 +85,23 @@ public class PackInvalidException extends IOException { * * @param path * path of the invalid pack file. + * @deprecated Use {@link #PackInvalidException(String, Throwable)}. */ + @Deprecated public PackInvalidException(String path) { - super(MessageFormat.format(JGitText.get().packFileInvalid, path)); + this(path, null); + } + + /** + * Construct a pack invalid error with cause. + * + * @param path + * path of the invalid pack file. + * @param cause + * cause of the pack file becoming invalid. + * @since 4.5.7 + */ + public PackInvalidException(String path, Throwable cause) { + super(MessageFormat.format(JGitText.get().packFileInvalid, path), cause); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java index 4e4a26f4e6..c7d6c584e4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java @@ -83,6 +83,9 @@ abstract class BlockBasedFile { /** True once corruption has been detected that cannot be worked around. */ volatile boolean invalid; + /** Exception that caused the packfile to be flagged as invalid */ + protected volatile Exception invalidatingCause; + BlockBasedFile(DfsBlockCache cache, DfsPackDescription desc, PackExt ext) { this.cache = cache; this.key = desc.getStreamKey(ext); @@ -136,8 +139,9 @@ abstract class BlockBasedFile { DfsBlock readOneBlock(long pos, DfsReader ctx, ReadableChannel rc) throws IOException { - if (invalid) - throw new PackInvalidException(getFileName()); + if (invalid) { + throw new PackInvalidException(getFileName(), invalidatingCause); + } ctx.stats.readBlock++; long start = System.nanoTime(); 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 451986e831..be1387ed0c 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 @@ -181,7 +181,7 @@ public final class DfsPackFile extends BlockBasedFile { } if (invalid) { - throw new PackInvalidException(getFileName()); + throw new PackInvalidException(getFileName(), invalidatingCause); } Repository.getGlobalListenerList() @@ -240,6 +240,7 @@ public final class DfsPackFile extends BlockBasedFile { return index; } catch (IOException e) { invalid = true; + invalidatingCause = e; throw e; } } @@ -703,8 +704,10 @@ public final class DfsPackFile extends BlockBasedFile { private IOException packfileIsTruncated() { invalid = true; - return new IOException(MessageFormat.format( + IOException exc = new IOException(MessageFormat.format( JGitText.get().packfileIsTruncated, getFileName())); + invalidatingCause = exc; + return exc; } private void readFully(long position, byte[] dstbuf, int dstoff, int cnt, 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 3ffb8c424d..d502fea020 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 @@ -132,8 +132,6 @@ public class ObjectDirectory extends FileObjectDatabase { private final File alternatesFile; - private final AtomicReference<PackList> packList; - private final FS fs; private final AtomicReference<AlternateHandle[]> alternates; @@ -146,6 +144,8 @@ public class ObjectDirectory extends FileObjectDatabase { private Set<ObjectId> shallowCommitsIds; + final AtomicReference<PackList> packList; + /** * Initialize a reference to an on-disk object directory. * @@ -673,13 +673,8 @@ public class ObjectDirectory extends FileObjectDatabase { transientErrorCount = p.incrementTransientErrorCount(); } if (warnTmpl != null) { - if (LOG.isDebugEnabled()) { - LOG.debug(MessageFormat.format(warnTmpl, - p.getPackFile().getAbsolutePath()), e); - } else { - LOG.warn(MessageFormat.format(warnTmpl, - p.getPackFile().getAbsolutePath())); - } + LOG.warn(MessageFormat.format(warnTmpl, + p.getPackFile().getAbsolutePath()), e); } else { if (doLogExponentialBackoff(transientErrorCount)) { // Don't remove the pack from the list, as the error may be @@ -766,7 +761,7 @@ public class ObjectDirectory extends FileObjectDatabase { return InsertLooseObjectResult.FAILURE; } - private boolean searchPacksAgain(PackList old) { + boolean searchPacksAgain(PackList old) { // Whether to trust the pack folder's modification time. If set // to false we will always scan the .git/objects/pack folder to // check for new pack files. If set to true (default) we use the @@ -916,7 +911,8 @@ public class ObjectDirectory extends FileObjectDatabase { final String packName = base + PACK.getExtension(); final File packFile = new File(packDirectory, packName); final PackFile oldPack = forReuse.remove(packName); - if (oldPack != null && oldPack.getFileSnapshot().isModified(packFile)) { + if (oldPack != null + && !oldPack.getFileSnapshot().isModified(packFile)) { list.add(oldPack); continue; } @@ -1073,7 +1069,7 @@ public class ObjectDirectory extends FileObjectDatabase { return new File(new File(getDirectory(), d), f); } - private static final class PackList { + static final class PackList { /** State just before reading the pack directory. */ final FileSnapshot snapshot; 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 ee3c0a8dd9..d834b1a729 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 @@ -135,6 +135,8 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { private volatile boolean invalid; + private volatile Exception invalidatingCause; + private boolean invalidBitmap; private AtomicInteger transientErrorCount = new AtomicInteger(); @@ -184,7 +186,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { idx = loadedIdx; if (idx == null) { if (invalid) { - throw new PackInvalidException(packFile); + throw new PackInvalidException(packFile, invalidatingCause); } try { idx = PackIndex.open(extFile(INDEX)); @@ -208,6 +210,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { throw e; } catch (IOException e) { invalid = true; + invalidatingCause = e; throw e; } } @@ -661,7 +664,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { private void doOpen() throws IOException { if (invalid) { - throw new PackInvalidException(packFile); + throw new PackInvalidException(packFile, invalidatingCause); } try { synchronized (readLock) { @@ -671,13 +674,13 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { } } catch (InterruptedIOException e) { // don't invalidate the pack, we are interrupted from another thread - openFail(false); + openFail(false, e); throw e; } catch (FileNotFoundException fn) { // don't invalidate the pack if opening an existing file failed // since it may be related to a temporary lack of resources (e.g. // max open files) - openFail(!packFile.exists()); + openFail(!packFile.exists(), fn); throw fn; } catch (EOFException | AccessDeniedException | NoSuchFileException | CorruptObjectException | NoPackSignatureException @@ -685,20 +688,21 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { | UnsupportedPackIndexVersionException | UnsupportedPackVersionException pe) { // exceptions signaling permanent problems with a pack - openFail(true); + openFail(true, pe); throw pe; } catch (IOException | RuntimeException ge) { // generic exceptions could be transient so we should not mark the // pack invalid to avoid false MissingObjectExceptions - openFail(false); + openFail(false, ge); throw ge; } } - private void openFail(boolean invalidate) { + private void openFail(boolean invalidate, Exception cause) { activeWindows = 0; activeCopyRawData = 0; invalid = invalidate; + invalidatingCause = cause; doClose(); } @@ -725,7 +729,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { // Detect the situation and throw a proper exception so that can be properly // managed by the main packfile search loop and the Git client won't receive // any failures. - throw new PackInvalidException(packFile); + throw new PackInvalidException(packFile, invalidatingCause); } if (length < pos + size) size = (int) (length - pos); 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 94b9ddc188..f37c310752 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java @@ -47,7 +47,11 @@ package org.eclipse.jgit.lib; +import java.io.File; import java.io.IOException; +import java.nio.file.DirectoryIteratorException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; @@ -261,6 +265,8 @@ public class IndexDiff { private Set<String> missing = new HashSet<>(); + private Set<String> missingSubmodules = new HashSet<>(); + private Set<String> modified = new HashSet<>(); private Set<String> untracked = new HashSet<>(); @@ -501,9 +507,15 @@ public class IndexDiff { if (dirCacheIterator != null) { if (workingTreeIterator == null) { // in index, not in workdir => missing - if (!isEntryGitLink(dirCacheIterator) - || ignoreSubmoduleMode != IgnoreSubmoduleMode.ALL) - missing.add(treeWalk.getPathString()); + boolean isGitLink = isEntryGitLink(dirCacheIterator); + if (!isGitLink + || ignoreSubmoduleMode != IgnoreSubmoduleMode.ALL) { + String path = treeWalk.getPathString(); + missing.add(path); + if (isGitLink) { + missingSubmodules.add(path); + } + } } else { if (workingTreeIterator.isModified( dirCacheIterator.getDirCacheEntry(), true, @@ -543,8 +555,8 @@ public class IndexDiff { smw.getPath()), e); } try (Repository subRepo = smw.getRepository()) { + String subRepoPath = smw.getPath(); if (subRepo != null) { - String subRepoPath = smw.getPath(); ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$ if (subHead != null && !subHead.equals(smw.getObjectId())) { @@ -573,6 +585,21 @@ public class IndexDiff { recordFileMode(subRepoPath, FileMode.GITLINK); } } + } else if (missingSubmodules.remove(subRepoPath)) { + // If the directory is there and empty but the submodule + // repository in .git/modules doesn't exist yet it isn't + // "missing". + File gitDir = new File( + new File(repository.getDirectory(), + Constants.MODULES), + subRepoPath); + if (!gitDir.isDirectory()) { + File dir = SubmoduleWalk.getSubmoduleDirectory( + repository, subRepoPath); + if (dir.isDirectory() && !hasFiles(dir)) { + missing.remove(subRepoPath); + } + } } } } @@ -592,6 +619,15 @@ public class IndexDiff { return true; } + private boolean hasFiles(File directory) { + try (DirectoryStream<java.nio.file.Path> dir = Files + .newDirectoryStream(directory.toPath())) { + return dir.iterator().hasNext(); + } catch (DirectoryIteratorException | IOException e) { + return false; + } + } + private void recordFileMode(String path, FileMode mode) { Set<String> values = fileModes.get(mode); if (path != null) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/Paths.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/Paths.java index be1b95e0d4..6be7ddbe12 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/Paths.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/Paths.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016, 2018 Google Inc. + * Copyright (C) 2016, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -43,7 +43,6 @@ package org.eclipse.jgit.util; -import static org.eclipse.jgit.lib.FileMode.TYPE_GITLINK; import static org.eclipse.jgit.lib.FileMode.TYPE_MASK; import static org.eclipse.jgit.lib.FileMode.TYPE_TREE; @@ -107,7 +106,7 @@ public class Paths { aPath, aPos, aEnd, aMode, bPath, bPos, bEnd, bMode); if (cmp == 0) { - cmp = modeCompare(aMode, bMode); + cmp = lastPathChar(aMode) - lastPathChar(bMode); } return cmp; } @@ -184,15 +183,6 @@ public class Paths { return 0; } - private static int modeCompare(int aMode, int bMode) { - if ((aMode & TYPE_MASK) == TYPE_GITLINK - || (bMode & TYPE_MASK) == TYPE_GITLINK) { - // Git links can be equal to files or folders - return 0; - } - return lastPathChar(aMode) - lastPathChar(bMode); - } - private Paths() { } } |