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 ad2500059..a69f51928 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 @@ -186,11 +186,19 @@ public void execute(RevWalk walk, ProgressMonitor monitor, Map locks = null; refdb.inProcessPackedRefsLock.lock(); try { - locks = lockLooseRefs(pending); - if (locks == null) { - return; + PackedRefList oldPackedList; + if (!refdb.isInClone()) { + locks = lockLooseRefs(pending); + if (locks == null) { + return; + } + oldPackedList = refdb.pack(locks); + } else { + // During clone locking isn't needed since no refs exist yet. + // This also helps to avoid problems with refs only differing in + // case on a case insensitive filesystem (bug 528497) + oldPackedList = refdb.getPackedRefs(); } - PackedRefList oldPackedList = refdb.pack(locks); RefList newRefs = applyUpdates(walk, oldPackedList, pending); if (newRefs == null) { return; 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 a44acacd1..bd39e6565 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 @@ -65,6 +65,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.InterruptedIOException; +import java.nio.file.Files; import java.security.DigestInputStream; import java.security.MessageDigest; import java.text.MessageFormat; @@ -901,7 +902,7 @@ else if (0 <= (idx = packed.find(dst.getName()))) return ref; } - private PackedRefList getPackedRefs() throws IOException { + PackedRefList getPackedRefs() throws IOException { boolean trustFolderStat = getRepository().getConfig().getBoolean( ConfigConstants.CONFIG_CORE_SECTION, ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true); @@ -1188,6 +1189,29 @@ private static boolean isSymRef(final byte[] buf, int n) { && buf[4] == ' '; } + /** + * Detect if we are in a clone command execution + * + * @return {@code true} if we are currently cloning a repository + * @throws IOException + */ + boolean isInClone() throws IOException { + return hasDanglingHead() && !packedRefsFile.exists() && !hasLooseRef(); + } + + private boolean hasDanglingHead() throws IOException { + Ref head = exactRef(Constants.HEAD); + if (head != null) { + ObjectId id = head.getObjectId(); + return id == null || id.equals(ObjectId.zeroId()); + } + return false; + } + + private boolean hasLooseRef() throws IOException { + return Files.walk(refsDir.toPath()).anyMatch(Files::isRegularFile); + } + /** If the parent should fire listeners, fires them. */ void fireRefsChanged() { final int last = lastNotifiedModCnt.get();