Browse Source

Merge branch 'stable-5.0' into stable-5.1

* stable-5.0:
  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: I172136a031ff0730e575327cafb3527c9650a71d
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
stable-5.1
Matthias Sohn 5 years ago
parent
commit
7aec793266
  1. 2
      WORKSPACE
  2. 8
      org.eclipse.jgit.lfs.server/.settings/.api_filters
  3. 11
      org.eclipse.jgit.lfs/.settings/.api_filters
  4. 29
      org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
  5. 36
      org.eclipse.jgit/.settings/.api_filters
  6. 110
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java

2
WORKSPACE

@ -2,7 +2,7 @@ workspace(name = "jgit")
load("//tools:bazlets.bzl", "load_bazlets") load("//tools:bazlets.bzl", "load_bazlets")
load_bazlets(commit = "8528a0df69dadf6311d8d3f81c1b693afda8bcf1") load_bazlets(commit = "09a035e98077dce549d5f6a7472d06c4b8f792d2")
load( load(
"@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl", "@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl",

8
org.eclipse.jgit.lfs.server/.settings/.api_filters

@ -1,13 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.jgit.lfs.server" version="2"> <component id="org.eclipse.jgit.lfs.server" version="2">
<resource path="META-INF/MANIFEST.MF">
<filter id="924844039">
<message_arguments>
<message_argument value="5.1.11"/>
<message_argument value="5.1.0"/>
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java" type="org.eclipse.jgit.lfs.server.fs.ObjectUploadListener"> <resource path="src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java" type="org.eclipse.jgit.lfs.server.fs.ObjectUploadListener">
<filter id="1142947843"> <filter id="1142947843">
<message_arguments> <message_arguments>

11
org.eclipse.jgit.lfs/.settings/.api_filters

@ -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.1.11"/>
<message_argument value="5.1.0"/>
</message_arguments>
</filter>
</resource>
</component>

29
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java

@ -43,6 +43,7 @@
package org.eclipse.jgit.internal.storage.file; 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.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.eclipse.jgit.internal.storage.file.BatchRefUpdateTest.Result.LOCK_FAILURE; 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.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -161,6 +163,33 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase {
refsChangedEvents = 0; refsChangedEvents = 0;
} }
@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 @Test
public void simpleNoForce() throws IOException { public void simpleNoForce() throws IOException {
writeLooseRef("refs/heads/master", A); writeLooseRef("refs/heads/master", A);

36
org.eclipse.jgit/.settings/.api_filters

@ -1,13 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.jgit" version="2"> <component id="org.eclipse.jgit" version="2">
<resource path="META-INF/MANIFEST.MF">
<filter id="924844039">
<message_arguments>
<message_argument value="5.1.11"/>
<message_argument value="5.1.0"/>
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/jgit/dircache/DirCacheEntry.java" type="org.eclipse.jgit.dircache.DirCacheEntry"> <resource path="src/org/eclipse/jgit/dircache/DirCacheEntry.java" type="org.eclipse.jgit.dircache.DirCacheEntry">
<filter id="1142947843"> <filter id="1142947843">
<message_arguments> <message_arguments>
@ -43,6 +35,11 @@
</filter> </filter>
</resource> </resource>
<resource path="src/org/eclipse/jgit/lib/ConfigConstants.java" type="org.eclipse.jgit.lib.ConfigConstants"> <resource path="src/org/eclipse/jgit/lib/ConfigConstants.java" type="org.eclipse.jgit.lib.ConfigConstants">
<filter id="337768515">
<message_arguments>
<message_argument value="org.eclipse.jgit.lib.ConfigConstants"/>
</message_arguments>
</filter>
<filter id="1142947843"> <filter id="1142947843">
<message_arguments> <message_arguments>
<message_argument value="5.1.9"/> <message_argument value="5.1.9"/>
@ -134,6 +131,13 @@
</message_arguments> </message_arguments>
</filter> </filter>
</resource> </resource>
<resource path="src/org/eclipse/jgit/transport/GitProtocolConstants.java" type="org.eclipse.jgit.transport.GitProtocolConstants">
<filter id="337768515">
<message_arguments>
<message_argument value="org.eclipse.jgit.transport.GitProtocolConstants"/>
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/jgit/transport/TransferConfig.java" type="org.eclipse.jgit.transport.TransferConfig"> <resource path="src/org/eclipse/jgit/transport/TransferConfig.java" type="org.eclipse.jgit.transport.TransferConfig">
<filter id="1159725059"> <filter id="1159725059">
<message_arguments> <message_arguments>
@ -171,6 +175,13 @@
</filter> </filter>
</resource> </resource>
<resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS"> <resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS">
<filter id="1141899266">
<message_arguments>
<message_argument value="4.7"/>
<message_argument value="5.1"/>
<message_argument value="createNewFileAtomic(File)"/>
</message_arguments>
</filter>
<filter id="1142947843"> <filter id="1142947843">
<message_arguments> <message_arguments>
<message_argument value="4.5.6"/> <message_argument value="4.5.6"/>
@ -224,6 +235,15 @@
</message_arguments> </message_arguments>
</filter> </filter>
</resource> </resource>
<resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS$LockToken">
<filter id="1141899266">
<message_arguments>
<message_argument value="4.7"/>
<message_argument value="5.1"/>
<message_argument value="LockToken"/>
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/jgit/util/FileUtils.java" type="org.eclipse.jgit.util.FileUtils"> <resource path="src/org/eclipse/jgit/util/FileUtils.java" type="org.eclipse.jgit.util.FileUtils">
<filter id="1142947843"> <filter id="1142947843">
<message_arguments> <message_arguments>

110
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.io.IOException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -364,65 +364,72 @@ class PackedBatchRefUpdate extends BatchRefUpdate {
private static RefList<Ref> applyUpdates(RevWalk walk, RefList<Ref> refs, private static RefList<Ref> applyUpdates(RevWalk walk, RefList<Ref> refs,
List<ReceiveCommand> commands) throws IOException { List<ReceiveCommand> commands) throws IOException {
int nDeletes = 0; // Construct a new RefList by merging the old list with the updates.
List<ReceiveCommand> adds = new ArrayList<>(commands.size()); // 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) { for (ReceiveCommand c : commands) {
if (c.getType() == ReceiveCommand.Type.CREATE) { switch (c.getType()) {
adds.add(c); case DELETE:
} else if (c.getType() == ReceiveCommand.Type.DELETE) { delta--;
nDeletes++; break;
} case CREATE:
} delta++;
int addIdx = 0; break;
default:
// 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())) { }
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;
}
if (cmp < 0) {
b.add(ref);
refIdx++;
} else if (cmp > 0) {
assert cmd != null;
if (cmd.getType() != ReceiveCommand.Type.CREATE) {
lockFailure(cmd, commands); lockFailure(cmd, commands);
return null; return null;
} }
// Consume any adds between the last and current ref. b.add(peeledRef(walk, cmd));
while (addIdx < adds.size()) { cmdIdx++;
ReceiveCommand currAdd = adds.get(addIdx);
if (currAdd.getRefName().compareTo(name) < 0) {
b.add(peeledRef(walk, currAdd));
byName.remove(currAdd.getRefName());
} else { } else {
break; assert cmd != null;
} assert ref != null;
addIdx++; if (!cmd.getOldId().equals(ref.getObjectId())) {
lockFailure(cmd, commands);
return null;
} }
if (cmd.getType() != ReceiveCommand.Type.DELETE) { if (cmd.getType() != ReceiveCommand.Type.DELETE) {
b.add(peeledRef(walk, cmd)); b.add(peeledRef(walk, cmd));
} }
cmdIdx++;
refIdx++;
} }
// 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));
}
// 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;
} }
return b.toRefList(); 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) private static Ref peeledRef(RevWalk walk, ReceiveCommand cmd)
throws IOException { throws IOException {
ObjectId newId = cmd.getNewId().copy(); ObjectId newId = cmd.getNewId().copy();

Loading…
Cancel
Save