]> source.dussan.org Git - jgit.git/commitdiff
Merge branch 'stable-4.11' into stable-5.0 70/127970/3
authorMatthias Sohn <matthias.sohn@sap.com>
Sat, 25 Aug 2018 06:56:45 +0000 (08:56 +0200)
committerMatthias Sohn <matthias.sohn@sap.com>
Sat, 25 Aug 2018 06:56:45 +0000 (08:56 +0200)
* stable-4.11:
  Silence API warning for new ObjectIdSerializer introduced in 4.11.1
  Ignore API warnings
  Fix photon target platform to use photon version of org.eclipse.osgi
  Update Photon orbit repository to R20180606145124
  Suppress warning for trying to delete non-empty directory
  Fix fetching with duplicate ref updates
  Fetch(Process): should tolerate duplicate refspecs
  FetchCommandTest: test add/update/delete fetch

Change-Id: I2497f99b7d0686a0e0f773c39c8725e813ce9d4a
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
1  2 
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180606145124-Photon.tpd
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
org.eclipse.jgit/.settings/.api_filters
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java

index 9fab2455025c840a8fb68fcc54827db00fcf2c94,0c1d5bb8099d9b708b623ba830bc5186b0489903..dfb5a8f4424e2c30b74f827380aee5aa529074cd
@@@ -1,7 -1,7 +1,7 @@@
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <?pde?>
  <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
- <target name="jgit-4.5" sequenceNumber="1528375371">
 -<target name="jgit-4.5" sequenceNumber="1535176347">
++<target name="jgit-4.5" sequenceNumber="1535179254">
    <locations>
      <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
        <unit id="org.eclipse.jetty.client" version="9.4.8.v20171121"/>
index 909b3307e065b6d691410328ade58e8ed111c2ee,e05c410128403b3e17139353c53e7dc760e95d2e..dbfd694b24aa482453612eb5f15399069b6e0925
@@@ -1,7 -1,7 +1,7 @@@
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <?pde?>
  <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
- <target name="jgit-4.6" sequenceNumber="1528375359">
 -<target name="jgit-4.6" sequenceNumber="1535176335">
++<target name="jgit-4.6" sequenceNumber="1535179241">
    <locations>
      <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
        <unit id="org.eclipse.jetty.client" version="9.4.8.v20171121"/>
index 8b064bc1cea1722536a79e2658a0c4b8224eb373,20b0a294a60d0179218731bc7a7760dfbe2a5661..be7719d88f3c0d1117f3ab4a839d00fae9403da4
@@@ -1,7 -1,7 +1,7 @@@
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <?pde?>
  <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
- <target name="jgit-4.7" sequenceNumber="1528375339">
 -<target name="jgit-4.7" sequenceNumber="1535176314">
++<target name="jgit-4.7" sequenceNumber="1535179221">
    <locations>
      <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
        <unit id="org.eclipse.jetty.client" version="9.4.8.v20171121"/>
index 6f57c9d6a182666d4a6b3d7cb7eb8dfa73fbebf9,b84fc208f709741d8854623f7431c33b3323134b..3de172b822c03f2d2e31efe61996e8585d2190d2
@@@ -1,7 -1,7 +1,7 @@@
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <?pde?>
  <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
- <target name="jgit-4.8" sequenceNumber="1528872727">
 -<target name="jgit-4.8" sequenceNumber="1535176301">
++<target name="jgit-4.8" sequenceNumber="1535179205">
    <locations>
      <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
        <unit id="org.eclipse.jetty.client" version="9.4.8.v20171121"/>
index 808b9d6944d23f2397b85267c5bc21db9e841d81,f4ec50dc79861bae534393cb6a3092ef5fa23142..ecec41d8c6fbdcab11c8996cd1c56cc338667763
@@@ -43,10 -44,4 +45,4 @@@ location "http://download.eclipse.org/t
        org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
        com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
        com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
 -}
 +}
- location "http://download.eclipse.org/tools/orbit/downloads/drops/R20170919201930/repository/" {
-       // platform uses this outdated version of httpclient in Photon
-       org.apache.httpcomponents.httpclient [4.5.2.v20170210-0925,4.5.2.v20170210-0925]
-       org.apache.httpcomponents.httpclient.source [4.5.2.v20170210-0925,4.5.2.v20170210-0925]
- }
index 4c2c0e8d1f2032684cc6441bcc6d2ae23df7b936,530fb1b2fea572bdf07aebe8f1e892eabf638d8f..adc4d9848893353d63b2b5376ba9c752b339fd1f
  package org.eclipse.jgit.api;
  
  import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertNotEquals;
 +import static org.junit.Assert.assertNotNull;
  import static org.junit.Assert.assertNull;
 +import static org.junit.Assert.assertTrue;
  
 +import java.io.File;
+ import java.util.ArrayList;
  import java.util.Collection;
+ import java.util.List;
  
 +import org.eclipse.jgit.junit.JGitTestUtil;
  import org.eclipse.jgit.junit.RepositoryTestCase;
  import org.eclipse.jgit.lib.Constants;
  import org.eclipse.jgit.lib.ObjectId;
@@@ -106,25 -104,91 +109,110 @@@ public class FetchCommandTest extends R
                                db.resolve(tagRef.getObjectId().getName()));
        }
  
 +      @Test
 +      public void testForcedFetch() throws Exception {
 +              remoteGit.commit().setMessage("commit").call();
 +              remoteGit.commit().setMessage("commit2").call();
 +              git.fetch().setRemote("test")
 +                              .setRefSpecs("refs/heads/master:refs/heads/master").call();
 +
 +              remoteGit.commit().setAmend(true).setMessage("amended").call();
 +              FetchResult res = git.fetch().setRemote("test")
 +                              .setRefSpecs("refs/heads/master:refs/heads/master").call();
 +              assertEquals(RefUpdate.Result.REJECTED,
 +                              res.getTrackingRefUpdate("refs/heads/master").getResult());
 +              res = git.fetch().setRemote("test")
 +                              .setRefSpecs("refs/heads/master:refs/heads/master")
 +                              .setForceUpdate(true).call();
 +              assertEquals(RefUpdate.Result.FORCED,
 +                              res.getTrackingRefUpdate("refs/heads/master").getResult());
 +      }
 +
+       @Test
+       public void fetchAddsBranches() throws Exception {
+               final String branch1 = "b1";
+               final String branch2 = "b2";
+               final String remoteBranch1 = "test/" + branch1;
+               final String remoteBranch2 = "test/" + branch2;
+               remoteGit.commit().setMessage("commit").call();
+               Ref branchRef1 = remoteGit.branchCreate().setName(branch1).call();
+               remoteGit.commit().setMessage("commit").call();
+               Ref branchRef2 = remoteGit.branchCreate().setName(branch2).call();
+               String spec = "refs/heads/*:refs/remotes/test/*";
+               git.fetch().setRemote("test").setRefSpecs(spec).call();
+               assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
+               assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
+       }
+       @Test
+       public void fetchDoesntDeleteBranches() throws Exception {
+               final String branch1 = "b1";
+               final String branch2 = "b2";
+               final String remoteBranch1 = "test/" + branch1;
+               final String remoteBranch2 = "test/" + branch2;
+               remoteGit.commit().setMessage("commit").call();
+               Ref branchRef1 = remoteGit.branchCreate().setName(branch1).call();
+               remoteGit.commit().setMessage("commit").call();
+               Ref branchRef2 = remoteGit.branchCreate().setName(branch2).call();
+               String spec = "refs/heads/*:refs/remotes/test/*";
+               git.fetch().setRemote("test").setRefSpecs(spec).call();
+               assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
+               assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
+               remoteGit.branchDelete().setBranchNames(branch1).call();
+               git.fetch().setRemote("test").setRefSpecs(spec).call();
+               assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
+               assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
+       }
+       @Test
+       public void fetchUpdatesBranches() throws Exception {
+               final String branch1 = "b1";
+               final String branch2 = "b2";
+               final String remoteBranch1 = "test/" + branch1;
+               final String remoteBranch2 = "test/" + branch2;
+               remoteGit.commit().setMessage("commit").call();
+               Ref branchRef1 = remoteGit.branchCreate().setName(branch1).call();
+               remoteGit.commit().setMessage("commit").call();
+               Ref branchRef2 = remoteGit.branchCreate().setName(branch2).call();
+               String spec = "refs/heads/*:refs/remotes/test/*";
+               git.fetch().setRemote("test").setRefSpecs(spec).call();
+               assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
+               assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
+               remoteGit.commit().setMessage("commit").call();
+               branchRef2 = remoteGit.branchCreate().setName(branch2).setForce(true).call();
+               git.fetch().setRemote("test").setRefSpecs(spec).call();
+               assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
+               assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
+       }
+       @Test
+       public void fetchPrunesBranches() throws Exception {
+               final String branch1 = "b1";
+               final String branch2 = "b2";
+               final String remoteBranch1 = "test/" + branch1;
+               final String remoteBranch2 = "test/" + branch2;
+               remoteGit.commit().setMessage("commit").call();
+               Ref branchRef1 = remoteGit.branchCreate().setName(branch1).call();
+               remoteGit.commit().setMessage("commit").call();
+               Ref branchRef2 = remoteGit.branchCreate().setName(branch2).call();
+               String spec = "refs/heads/*:refs/remotes/test/*";
+               git.fetch().setRemote("test").setRefSpecs(spec).call();
+               assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
+               assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
+               remoteGit.branchDelete().setBranchNames(branch1).call();
+               git.fetch().setRemote("test").setRefSpecs(spec)
+                               .setRemoveDeletedRefs(true).call();
+               assertNull(db.resolve(remoteBranch1));
+               assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
+       }
        @Test
        public void fetchShouldAutoFollowTag() throws Exception {
                remoteGit.commit().setMessage("commit").call();
                assertEquals(tagRef2.getObjectId(), db.resolve(tagName));
        }
  
 +      @Test
 +      public void testFetchWithPruneShouldKeepOriginHead() throws Exception {
 +              // Create a commit in the test repo.
 +              commitFile("foo", "foo", "master");
 +              // Produce a real clone of the git repo
 +              Git cloned = Git.cloneRepository()
 +                              .setDirectory(createTempDirectory("testCloneRepository"))
 +                              .setURI("file://"
 +                                              + git.getRepository().getWorkTree().getAbsolutePath())
 +                              .call();
 +              assertNotNull(cloned);
 +              Repository clonedRepo = cloned.getRepository();
 +              addRepoToClose(clonedRepo);
 +              ObjectId originMasterId = clonedRepo
 +                              .resolve("refs/remotes/origin/master");
 +              assertNotNull("Should have origin/master", originMasterId);
 +              assertNotEquals("origin/master should not be zero ID",
 +                              ObjectId.zeroId(), originMasterId);
 +              // Canonical git creates origin/HEAD; JGit (for now) doesn't. Let's
 +              // pretend we did the clone via command-line git.
 +              ObjectId originHeadId = clonedRepo.resolve("refs/remotes/origin/HEAD");
 +              if (originHeadId == null) {
 +                      JGitTestUtil.write(
 +                                      new File(clonedRepo.getDirectory(),
 +                                                      "refs/remotes/origin/HEAD"),
 +                                      "ref: refs/remotes/origin/master\n");
 +                      originHeadId = clonedRepo.resolve("refs/remotes/origin/HEAD");
 +              }
 +              assertEquals("Should have origin/HEAD", originMasterId, originHeadId);
 +              FetchResult result = cloned.fetch().setRemote("origin")
 +                              .setRemoveDeletedRefs(true).call();
 +              assertTrue("Fetch after clone should be up-to-date",
 +                              result.getTrackingRefUpdates().isEmpty());
 +              assertEquals("origin/master should still exist", originMasterId,
 +                              clonedRepo.resolve("refs/remotes/origin/master"));
 +              assertEquals("origin/HEAD should be unchanged", originHeadId,
 +                              clonedRepo.resolve("refs/remotes/origin/HEAD"));
 +      }
++
+       @Test
+       public void fetchAddRefsWithDuplicateRefspec() throws Exception {
+               final String branchName = "branch";
+               final String remoteBranchName = "test/" + branchName;
+               remoteGit.commit().setMessage("commit").call();
+               Ref branchRef = remoteGit.branchCreate().setName(branchName).call();
+               final String spec1 = "+refs/heads/*:refs/remotes/test/*";
+               final String spec2 = "refs/heads/*:refs/remotes/test/*";
+               final StoredConfig config = db.getConfig();
+               RemoteConfig remoteConfig = new RemoteConfig(config, "test");
+               remoteConfig.addFetchRefSpec(new RefSpec(spec1));
+               remoteConfig.addFetchRefSpec(new RefSpec(spec2));
+               remoteConfig.update(config);
+               git.fetch().setRemote("test").setRefSpecs(spec1).call();
+               assertEquals(branchRef.getObjectId(), db.resolve(remoteBranchName));
+       }
+       @Test
+       public void fetchPruneRefsWithDuplicateRefspec()
+                       throws Exception {
+               final String branchName = "branch";
+               final String remoteBranchName = "test/" + branchName;
+               remoteGit.commit().setMessage("commit").call();
+               Ref branchRef = remoteGit.branchCreate().setName(branchName).call();
+               final String spec1 = "+refs/heads/*:refs/remotes/test/*";
+               final String spec2 = "refs/heads/*:refs/remotes/test/*";
+               final StoredConfig config = db.getConfig();
+               RemoteConfig remoteConfig = new RemoteConfig(config, "test");
+               remoteConfig.addFetchRefSpec(new RefSpec(spec1));
+               remoteConfig.addFetchRefSpec(new RefSpec(spec2));
+               remoteConfig.update(config);
+               git.fetch().setRemote("test").setRefSpecs(spec1).call();
+               assertEquals(branchRef.getObjectId(), db.resolve(remoteBranchName));
+               remoteGit.branchDelete().setBranchNames(branchName).call();
+               git.fetch().setRemote("test").setRefSpecs(spec1)
+                               .setRemoveDeletedRefs(true).call();
+               assertNull(db.resolve(remoteBranchName));
+       }
+       @Test
+       public void fetchUpdateRefsWithDuplicateRefspec() throws Exception {
+               final String tagName = "foo";
+               remoteGit.commit().setMessage("commit").call();
+               Ref tagRef1 = remoteGit.tag().setName(tagName).call();
+               List<RefSpec> refSpecs = new ArrayList<>();
+               refSpecs.add(new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
+               refSpecs.add(new RefSpec("+refs/tags/*:refs/tags/*"));
+               // Updating tags via the RefSpecs and setting TagOpt.FETCH_TAGS (or
+               // AUTO_FOLLOW) will result internally in *two* updates for the same
+               // ref.
+               git.fetch().setRemote("test").setRefSpecs(refSpecs)
+                               .setTagOpt(TagOpt.AUTO_FOLLOW).call();
+               assertEquals(tagRef1.getObjectId(), db.resolve(tagName));
+               remoteGit.commit().setMessage("commit 2").call();
+               Ref tagRef2 = remoteGit.tag().setName(tagName).setForceUpdate(true)
+                               .call();
+               FetchResult result = git.fetch().setRemote("test").setRefSpecs(refSpecs)
+                               .setTagOpt(TagOpt.FETCH_TAGS).call();
+               assertEquals(2, result.getTrackingRefUpdates().size());
+               TrackingRefUpdate update = result
+                               .getTrackingRefUpdate(Constants.R_TAGS + tagName);
+               assertEquals(RefUpdate.Result.FORCED, update.getResult());
+               assertEquals(tagRef2.getObjectId(), db.resolve(tagName));
+       }
  }
diff --cc org.eclipse.jgit/.settings/.api_filters
index e51bf20c22ab58ebad637b276747a8fe271ee1be,67d731bd70c79a7297a28619efcf3695e414d48e..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,19 -1,73 +1,0 @@@
--<?xml version="1.0" encoding="UTF-8" standalone="no"?>
--<component id="org.eclipse.jgit" version="2">
-     <resource path="src/org/eclipse/jgit/lib/ObjectIdSerializer.java" type="org.eclipse.jgit.lib.ObjectIdSerializer">
-         <filter id="1141899266">
 -    <resource path="META-INF/MANIFEST.MF">
 -        <filter id="924844039">
--            <message_arguments>
-                 <message_argument value="4.11"/>
-                 <message_argument value="5.0"/>
-                 <message_argument value="readWithoutMarker(InputStream)"/>
 -                <message_argument value="4.11.1"/>
 -                <message_argument value="4.11.0"/>
--            </message_arguments>
--        </filter>
-         <filter id="1141899266">
 -        <filter id="924844039">
--            <message_arguments>
-                 <message_argument value="4.11"/>
-                 <message_argument value="5.0"/>
-                 <message_argument value="writeWithoutMarker(OutputStream, AnyObjectId)"/>
 -                <message_argument value="4.11.2"/>
 -                <message_argument value="4.11.0"/>
 -            </message_arguments>
 -        </filter>
 -    </resource>
 -    <resource path="src/org/eclipse/jgit/diff/DiffEntry.java" type="org.eclipse.jgit.diff.DiffEntry">
 -        <filter id="336658481">
 -            <message_arguments>
 -                <message_argument value="org.eclipse.jgit.diff.DiffEntry"/>
 -                <message_argument value="diffAttribute"/>
 -            </message_arguments>
 -        </filter>
 -    </resource>
 -    <resource path="src/org/eclipse/jgit/lib/ConfigConstants.java" type="org.eclipse.jgit.lib.ConfigConstants">
 -        <filter id="336658481">
 -            <message_arguments>
 -                <message_argument value="org.eclipse.jgit.lib.ConfigConstants"/>
 -                <message_argument value="CONFIG_KEY_REQUIRED"/>
 -            </message_arguments>
 -        </filter>
 -        <filter id="336658481">
 -            <message_arguments>
 -                <message_argument value="org.eclipse.jgit.lib.ConfigConstants"/>
 -                <message_argument value="CONFIG_SECTION_LFS"/>
 -            </message_arguments>
 -        </filter>
 -    </resource>
 -    <resource path="src/org/eclipse/jgit/merge/ResolveMerger.java" type="org.eclipse.jgit.merge.ResolveMerger">
 -        <filter id="336658481">
 -            <message_arguments>
 -                <message_argument value="org.eclipse.jgit.merge.ResolveMerger"/>
 -                <message_argument value="workingTreeOptions"/>
 -            </message_arguments>
 -        </filter>
 -    </resource>
 -    <resource path="src/org/eclipse/jgit/storage/pack/PackStatistics.java" type="org.eclipse.jgit.storage.pack.PackStatistics$Accumulator">
 -        <filter id="336658481">
 -            <message_arguments>
 -                <message_argument value="org.eclipse.jgit.storage.pack.PackStatistics.Accumulator"/>
 -                <message_argument value="advertised"/>
 -            </message_arguments>
 -        </filter>
 -        <filter id="336658481">
 -            <message_arguments>
 -                <message_argument value="org.eclipse.jgit.storage.pack.PackStatistics.Accumulator"/>
 -                <message_argument value="haves"/>
 -            </message_arguments>
 -        </filter>
 -        <filter id="336658481">
 -            <message_arguments>
 -                <message_argument value="org.eclipse.jgit.storage.pack.PackStatistics.Accumulator"/>
 -                <message_argument value="timeNegotiating"/>
 -            </message_arguments>
 -        </filter>
 -        <filter id="336658481">
 -            <message_arguments>
 -                <message_argument value="org.eclipse.jgit.storage.pack.PackStatistics.Accumulator"/>
 -                <message_argument value="wants"/>
--            </message_arguments>
--        </filter>
--    </resource>
--</component>
index ff183c897457c8beafeb97aebc1a0291ed30590a,117e8447f272985017b30526e89e556f0e4ebf30..c43ab18c356ea66dacf2b3c97730502eab369b75
@@@ -239,7 -240,24 +240,24 @@@ class FetchProcess 
                }
        }
  
 -      private void fetchObjects(final ProgressMonitor monitor)
+       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(ProgressMonitor monitor)
                        throws TransportException {
                try {
                        conn.setPackLockMessage("jgit fetch " + transport.uri); //$NON-NLS-1$
  
        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) {
++              Set<Ref> processed = new HashSet<>();
 +              for (Ref ref : localRefs().values()) {
 +                      if (ref.isSymbolic()) {
 +                              continue;
 +                      }
-                       final String refname = ref.getName();
++                      String refname = ref.getName();
 +                      for (RefSpec spec : toFetch) {
                                if (spec.matchDestination(refname)) {
--                                      final RefSpec s = spec.expandFromDestination(refname);
-                                       if (result.getAdvertisedRef(s.getSource()) == null) {
++                                      RefSpec s = spec.expandFromDestination(refname);
+                                       if (result.getAdvertisedRef(s.getSource()) == null
+                                                       && processed.add(ref)) {
                                                deleteTrackingRef(result, batch, s, ref);
                                        }
                                }