Browse Source

Don't prune symbolic refs when fetch.prune = true

The canonical implementation also doesn't. Compare current
code in remote.c, function get_stale_heads_cb.[1] Not handling
symrefs in this case was introduced in canonical git in [2]
in 2008.

[1] https://github.com/git/git/blob/v2.17.0/remote.c#L2259
[2] https://github.com/git/git/commit/740fdd27f0

Bug: 533549
Change-Id: If348d56bb4a96b8aa7141f7e7b5a0d3dd4e7808b
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
stable-5.0
Thomas Wolf 7 years ago committed by Matthias Sohn
parent
commit
de21c58d03
  1. 44
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
  2. 3
      org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java

44
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java

@ -43,10 +43,15 @@
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.Collection;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
@ -204,4 +209,43 @@ public class FetchCommandTest extends RepositoryTestCase {
assertEquals(RefUpdate.Result.FORCED, update.getResult());
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"));
}
}

3
org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java

@ -480,6 +480,9 @@ class FetchProcess {
private void deleteStaleTrackingRefs(FetchResult result,
BatchRefUpdate batch) throws IOException {
for (Ref ref : localRefs().values()) {
if (ref.isSymbolic()) {
continue;
}
final String refname = ref.getName();
for (RefSpec spec : toFetch) {
if (spec.matchDestination(refname)) {

Loading…
Cancel
Save