diff options
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java | 5 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java | 32 |
2 files changed, 31 insertions, 6 deletions
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 732691dacc..9d51f4b1de 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.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.InterruptedIOException; +import java.nio.file.DirectoryNotEmptyException; import java.nio.file.Files; import java.security.DigestInputStream; import java.security.MessageDigest; @@ -1286,6 +1287,10 @@ public class RefDirectory extends RefDatabase { for (int i = 0; i < depth; ++i) { try { Files.delete(dir.toPath()); + } catch (DirectoryNotEmptyException e) { + // Don't log; normal case when there are other refs with the + // same prefix + break; } catch (IOException e) { LOG.warn("Unable to remove path {}", dir, e); break; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java index dd26fe59ad..ed10f449df 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java @@ -203,12 +203,10 @@ class FetchProcess { ((BatchingProgressMonitor) monitor).setDelayStart( 250, TimeUnit.MILLISECONDS); } - if (transport.isRemoveDeletedRefs()) + if (transport.isRemoveDeletedRefs()) { deleteStaleTrackingRefs(result, batch); - for (TrackingRefUpdate u : localUpdates) { - result.add(u); - batch.addCommand(u.asReceiveCommand()); } + addUpdateBatchCommands(result, batch); for (ReceiveCommand cmd : batch.getCommands()) { cmd.updateType(walk); if (cmd.getType() == UPDATE_NONFASTFORWARD @@ -221,8 +219,11 @@ class FetchProcess { if (cmd.getResult() == NOT_ATTEMPTED) cmd.setResult(OK); } - } else + } else { batch.execute(walk, monitor); + } + } catch (TransportException e) { + throw e; } catch (IOException err) { throw new TransportException(MessageFormat.format( JGitText.get().failureUpdatingTrackingRef, @@ -239,6 +240,23 @@ class FetchProcess { } } + private void addUpdateBatchCommands(FetchResult result, + BatchRefUpdate batch) throws TransportException { + Map<String, ObjectId> refs = new HashMap<>(); + for (TrackingRefUpdate u : localUpdates) { + // Try to skip duplicates if they'd update to the same object ID + ObjectId existing = refs.get(u.getLocalName()); + if (existing == null) { + refs.put(u.getLocalName(), u.getNewObjectId()); + result.add(u); + batch.addCommand(u.asReceiveCommand()); + } else if (!existing.equals(u.getNewObjectId())) { + throw new TransportException(MessageFormat + .format(JGitText.get().duplicateRef, u.getLocalName())); + } + } + } + private void fetchObjects(final ProgressMonitor monitor) throws TransportException { try { @@ -481,12 +499,14 @@ class FetchProcess { private void deleteStaleTrackingRefs(FetchResult result, BatchRefUpdate batch) throws IOException { + final Set<Ref> processed = new HashSet<>(); for (final Ref ref : localRefs().values()) { final String refname = ref.getName(); for (final RefSpec spec : toFetch) { if (spec.matchDestination(refname)) { final RefSpec s = spec.expandFromDestination(refname); - if (result.getAdvertisedRef(s.getSource()) == null) { + if (result.getAdvertisedRef(s.getSource()) == null + && processed.add(ref)) { deleteTrackingRef(result, batch, s, ref); } } |