summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2019-03-10 18:02:54 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2019-04-20 11:19:34 +0200
commit8277f62897a99539c6a3654e3a9ae8357d0f74be (patch)
treeb7af9d907be807d35a4220003c89d44b2ad50c0a /org.eclipse.jgit
parent62675c48de09a30c769bcba06ebf5a312d3b9f8b (diff)
downloadjgit-8277f62897a99539c6a3654e3a9ae8357d0f74be.tar.gz
jgit-8277f62897a99539c6a3654e3a9ae8357d0f74be.zip
Revert 4678f4b and provide another solution for bug 467631
Making gitlinks and folders match in a tree walk was the wrong approach to fix bug 467631. The problem is that in such a conflict the tree walk may then not descend into the folder. Revert the changes to Paths.java and PathsTest.java from commit 4678f4b. Instead test for the problem case from bug 467631 explicitly in IndexDiff. Add Daniel's test case from bug 545162, and add yet another test case for DiffEntry.scan() that covers the problem originally reported in bug 545162. Bug: 545162 Change-Id: Ie2214c5d5ee32ac6596b621f0f1c7b86d38fa9b7 Also-by: Daniel Veihelmann <daniel.veihelmann@gmail.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java44
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/Paths.java14
2 files changed, 42 insertions, 16 deletions
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() {
}
}