summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2019-09-03 23:41:03 +0200
committerMatthias Sohn <matthias.sohn@sap.com>2019-09-04 00:08:21 +0200
commitaa62f191d02c19073c22a5e33e4a07c54a67efa7 (patch)
treee3ca1dce3fc78830075f84a90b0a12b338cb8416
parent60283a58a79578a41ba31d2f57ac2ef7cf2e1521 (diff)
parentc8e42ca3ba646afe35e635eb0ebac6c76ddca6cd (diff)
downloadjgit-aa62f191d02c19073c22a5e33e4a07c54a67efa7.tar.gz
jgit-aa62f191d02c19073c22a5e33e4a07c54a67efa7.zip
Merge branch 'stable-5.1' into stable-5.2
* stable-5.1: Prepare 5.1.12-SNAPSHOT builds JGit v5.1.11.201909031202-r Prepare 4.11.10-SNAPSHOT builds JGit v4.11.9.201909030838-r Bazel: Update bazlets to the latest master revision Bazel: Remove FileTreeIteratorWithTimeControl from BUILD file BatchRefUpdate: repro racy atomic update, and fix it Delete unused FileTreeIteratorWithTimeControl Fix RacyGitTests#testRacyGitDetection Change RacyGitTests to create a racy git situation in a stable way Silence API warnings Change-Id: Iac5dc9683cea97db04d20f27c10f2e103d3ae7b5 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--WORKSPACE2
-rw-r--r--org.eclipse.jgit.lfs.server/.settings/.api_filters8
-rw-r--r--org.eclipse.jgit.lfs/.settings/.api_filters11
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java29
-rw-r--r--org.eclipse.jgit/.settings/.api_filters82
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java118
6 files changed, 162 insertions, 88 deletions
diff --git a/WORKSPACE b/WORKSPACE
index 1796d3e8d6..67b08d2a4d 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -15,7 +15,7 @@ versions.check(minimum_bazel_version = "0.19.0")
load("//tools:bazlets.bzl", "load_bazlets")
-load_bazlets(commit = "8528a0df69dadf6311d8d3f81c1b693afda8bcf1")
+load_bazlets(commit = "09a035e98077dce549d5f6a7472d06c4b8f792d2")
load(
"@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl",
diff --git a/org.eclipse.jgit.lfs.server/.settings/.api_filters b/org.eclipse.jgit.lfs.server/.settings/.api_filters
index 3e60680cf7..6609c3d40d 100644
--- a/org.eclipse.jgit.lfs.server/.settings/.api_filters
+++ b/org.eclipse.jgit.lfs.server/.settings/.api_filters
@@ -1,13 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.jgit.lfs.server" version="2">
- <resource path="META-INF/MANIFEST.MF">
- <filter id="924844039">
- <message_arguments>
- <message_argument value="5.2.3"/>
- <message_argument value="5.2.0"/>
- </message_arguments>
- </filter>
- </resource>
<resource path="src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java" type="org.eclipse.jgit.lfs.server.fs.ObjectUploadListener">
<filter id="1142947843">
<message_arguments>
diff --git a/org.eclipse.jgit.lfs/.settings/.api_filters b/org.eclipse.jgit.lfs/.settings/.api_filters
deleted file mode 100644
index 95a45574ec..0000000000
--- a/org.eclipse.jgit.lfs/.settings/.api_filters
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.jgit.lfs" version="2">
- <resource path="META-INF/MANIFEST.MF">
- <filter id="924844039">
- <message_arguments>
- <message_argument value="5.2.3"/>
- <message_argument value="5.2.0"/>
- </message_arguments>
- </filter>
- </resource>
-</component>
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
index 3c4b8cf4bc..2ac4a846ea 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
@@ -43,6 +43,7 @@
package org.eclipse.jgit.internal.storage.file;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.eclipse.jgit.internal.storage.file.BatchRefUpdateTest.Result.LOCK_FAILURE;
@@ -64,6 +65,7 @@ import static org.junit.Assume.assumeTrue;
import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -162,6 +164,33 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase {
}
@Test
+ public void packedRefsFileIsSorted() throws IOException {
+ assumeTrue(atomic);
+
+ for (int i = 0; i < 2; i++) {
+ BatchRefUpdate bu = diskRepo.getRefDatabase().newBatchUpdate();
+ String b1 = String.format("refs/heads/a%d",i);
+ String b2 = String.format("refs/heads/b%d",i);
+ bu.setAtomic(atomic);
+ ReceiveCommand c1 = new ReceiveCommand(ObjectId.zeroId(), A, b1);
+ ReceiveCommand c2 = new ReceiveCommand(ObjectId.zeroId(), B, b2);
+ bu.addCommand(c1, c2);
+ try (RevWalk rw = new RevWalk(diskRepo)) {
+ bu.execute(rw, NullProgressMonitor.INSTANCE);
+ }
+ assertEquals(c1.getResult(), ReceiveCommand.Result.OK);
+ assertEquals(c2.getResult(), ReceiveCommand.Result.OK);
+ }
+
+ File packed = new File(diskRepo.getDirectory(), "packed-refs");
+ String packedStr = new String(Files.readAllBytes(packed.toPath()), UTF_8);
+
+ int a2 = packedStr.indexOf("refs/heads/a1");
+ int b1 = packedStr.indexOf("refs/heads/b0");
+ assertTrue(a2 < b1);
+ }
+
+ @Test
public void simpleNoForce() throws IOException {
writeLooseRef("refs/heads/master", A);
writeLooseRef("refs/heads/masters", B);
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
index cbb9de113d..857fcac17d 100644
--- a/org.eclipse.jgit/.settings/.api_filters
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -1,13 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.jgit" version="2">
- <resource path="META-INF/MANIFEST.MF">
- <filter id="924844039">
- <message_arguments>
- <message_argument value="5.2.3"/>
- <message_argument value="5.2.0"/>
- </message_arguments>
- </filter>
- </resource>
<resource path="src/org/eclipse/jgit/dircache/DirCacheEntry.java" type="org.eclipse.jgit.dircache.DirCacheEntry">
<filter id="1142947843">
<message_arguments>
@@ -42,6 +34,28 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/jgit/gitrepo/RepoCommand.java" type="org.eclipse.jgit.gitrepo.RepoCommand$DefaultRemoteReader">
+ <filter id="338792546">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.gitrepo.RepoCommand.DefaultRemoteReader"/>
+ <message_argument value="readFile(String, String, String)"/>
+ </message_arguments>
+ </filter>
+ <filter id="338792546">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.gitrepo.RepoCommand.DefaultRemoteReader"/>
+ <message_argument value="readFileFromRepo(Repository, String, String)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/jgit/gitrepo/RepoCommand.java" type="org.eclipse.jgit.gitrepo.RepoCommand$RemoteReader">
+ <filter id="403804204">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.gitrepo.RepoCommand.RemoteReader"/>
+ <message_argument value="readFileWithMode(String, String, String)"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/jgit/lib/ConfigConstants.java" type="org.eclipse.jgit.lib.ConfigConstants">
<filter id="1142947843">
<message_arguments>
@@ -62,6 +76,42 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/jgit/lib/GitmoduleEntry.java" type="org.eclipse.jgit.lib.GitmoduleEntry">
+ <filter id="1109393411">
+ <message_arguments>
+ <message_argument value="4.7.5"/>
+ <message_argument value="org.eclipse.jgit.lib.GitmoduleEntry"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/jgit/lib/ObjectChecker.java" type="org.eclipse.jgit.lib.ObjectChecker">
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="4.7.5"/>
+ <message_argument value="getGitsubmodules()"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/jgit/revwalk/DepthWalk.java" type="org.eclipse.jgit.revwalk.DepthWalk">
+ <filter id="403804204">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.revwalk.DepthWalk"/>
+ <message_argument value="getDeepenNotFlag()"/>
+ </message_arguments>
+ </filter>
+ <filter id="404000815">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.revwalk.DepthWalk"/>
+ <message_argument value="getDeepenNots()"/>
+ </message_arguments>
+ </filter>
+ <filter id="404000815">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.revwalk.DepthWalk"/>
+ <message_argument value="getDeepenSince()"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/jgit/storage/pack/PackConfig.java" type="org.eclipse.jgit.storage.pack.PackConfig">
<filter id="336658481">
<message_arguments>
@@ -118,6 +168,14 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/jgit/transport/RemoteSession.java" type="org.eclipse.jgit.transport.RemoteSession">
+ <filter id="404000815">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.transport.RemoteSession"/>
+ <message_argument value="getFtpChannel()"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/jgit/transport/TransferConfig.java" type="org.eclipse.jgit.transport.TransferConfig">
<filter id="1159725059">
<message_arguments>
@@ -132,6 +190,14 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/jgit/transport/http/HttpConnection.java" type="org.eclipse.jgit.transport.http.HttpConnection">
+ <filter id="403804204">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.transport.http.HttpConnection"/>
+ <message_argument value="getHeaderFields(String)"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java" type="org.eclipse.jgit.treewalk.WorkingTreeIterator">
<filter id="1142947843">
<message_arguments>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java
index 200c63c17a..e45b53ea68 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java
@@ -51,10 +51,10 @@ import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_RE
import java.io.IOException;
import java.text.MessageFormat;
-import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -364,65 +364,72 @@ class PackedBatchRefUpdate extends BatchRefUpdate {
private static RefList<Ref> applyUpdates(RevWalk walk, RefList<Ref> refs,
List<ReceiveCommand> commands) throws IOException {
- int nDeletes = 0;
- List<ReceiveCommand> adds = new ArrayList<>(commands.size());
+ // Construct a new RefList by merging the old list with the updates.
+ // This assumes that each ref occurs at most once as a ReceiveCommand.
+ Collections.sort(commands, new Comparator<ReceiveCommand>() {
+ @Override
+ public int compare(ReceiveCommand a, ReceiveCommand b) {
+ return a.getRefName().compareTo(b.getRefName());
+ }
+ });
+
+ int delta = 0;
for (ReceiveCommand c : commands) {
- if (c.getType() == ReceiveCommand.Type.CREATE) {
- adds.add(c);
- } else if (c.getType() == ReceiveCommand.Type.DELETE) {
- nDeletes++;
+ switch (c.getType()) {
+ case DELETE:
+ delta--;
+ break;
+ case CREATE:
+ delta++;
+ break;
+ default:
}
}
- int addIdx = 0;
-
- // Construct a new RefList by linearly scanning the old list, and merging in
- // any updates.
- Map<String, ReceiveCommand> byName = byName(commands);
- RefList.Builder<Ref> b =
- new RefList.Builder<>(refs.size() - nDeletes + adds.size());
- for (Ref ref : refs) {
- String name = ref.getName();
- ReceiveCommand cmd = byName.remove(name);
- if (cmd == null) {
- b.add(ref);
- continue;
- }
- if (!cmd.getOldId().equals(ref.getObjectId())) {
- lockFailure(cmd, commands);
- return null;
+
+ RefList.Builder<Ref> b = new RefList.Builder<>(refs.size() + delta);
+ int refIdx = 0;
+ int cmdIdx = 0;
+ while (refIdx < refs.size() || cmdIdx < commands.size()) {
+ Ref ref = (refIdx < refs.size()) ? refs.get(refIdx) : null;
+ ReceiveCommand cmd = (cmdIdx < commands.size())
+ ? commands.get(cmdIdx)
+ : null;
+ int cmp = 0;
+ if (ref != null && cmd != null) {
+ cmp = ref.getName().compareTo(cmd.getRefName());
+ } else if (ref == null) {
+ cmp = 1;
+ } else if (cmd == null) {
+ cmp = -1;
}
- // Consume any adds between the last and current ref.
- while (addIdx < adds.size()) {
- ReceiveCommand currAdd = adds.get(addIdx);
- if (currAdd.getRefName().compareTo(name) < 0) {
- b.add(peeledRef(walk, currAdd));
- byName.remove(currAdd.getRefName());
- } else {
- break;
+ if (cmp < 0) {
+ b.add(ref);
+ refIdx++;
+ } else if (cmp > 0) {
+ assert cmd != null;
+ if (cmd.getType() != ReceiveCommand.Type.CREATE) {
+ lockFailure(cmd, commands);
+ return null;
}
- addIdx++;
- }
- if (cmd.getType() != ReceiveCommand.Type.DELETE) {
b.add(peeledRef(walk, cmd));
- }
- }
-
- // All remaining adds are valid, since the refs didn't exist.
- while (addIdx < adds.size()) {
- ReceiveCommand cmd = adds.get(addIdx++);
- byName.remove(cmd.getRefName());
- b.add(peeledRef(walk, cmd));
- }
+ cmdIdx++;
+ } else {
+ assert cmd != null;
+ assert ref != null;
+ if (!cmd.getOldId().equals(ref.getObjectId())) {
+ lockFailure(cmd, commands);
+ return null;
+ }
- // Any remaining updates/deletes do not correspond to any existing refs, so
- // they are lock failures.
- if (!byName.isEmpty()) {
- lockFailure(byName.values().iterator().next(), commands);
- return null;
+ if (cmd.getType() != ReceiveCommand.Type.DELETE) {
+ b.add(peeledRef(walk, cmd));
+ }
+ cmdIdx++;
+ refIdx++;
+ }
}
-
return b.toRefList();
}
@@ -501,15 +508,6 @@ class PackedBatchRefUpdate extends BatchRefUpdate {
}
}
- private static Map<String, ReceiveCommand> byName(
- List<ReceiveCommand> commands) {
- Map<String, ReceiveCommand> ret = new LinkedHashMap<>();
- for (ReceiveCommand cmd : commands) {
- ret.put(cmd.getRefName(), cmd);
- }
- return ret;
- }
-
private static Ref peeledRef(RevWalk walk, ReceiveCommand cmd)
throws IOException {
ObjectId newId = cmd.getNewId().copy();