diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java index abfbd1548..c30f9a246 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, Chris Aniszczyk + * Copyright (C) 2010, 2013 Chris Aniszczyk * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -43,55 +43,129 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import java.io.IOException; import java.net.URISyntaxException; +import java.util.Collection; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.transport.FetchResult; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteConfig; +import org.eclipse.jgit.transport.TagOpt; +import org.eclipse.jgit.transport.TrackingRefUpdate; import org.eclipse.jgit.transport.URIish; +import org.junit.Before; import org.junit.Test; public class FetchCommandTest extends RepositoryTestCase { - @Test - public void testFetch() throws JGitInternalException, IOException, - GitAPIException, URISyntaxException { + private Git git; + private Git remoteGit; + + @Before + public void setupRemoteRepository() throws IOException, URISyntaxException { + git = new Git(db); // create other repository - Repository db2 = createWorkRepository(); - Git git2 = new Git(db2); + Repository remoteRepository = createWorkRepository(); + remoteGit = new Git(remoteRepository); // setup the first repository to fetch from the second repository final StoredConfig config = db.getConfig(); RemoteConfig remoteConfig = new RemoteConfig(config, "test"); - URIish uri = new URIish(db2.getDirectory().toURI().toURL()); + URIish uri = new URIish(remoteRepository.getDirectory().toURI().toURL()); remoteConfig.addURI(uri); remoteConfig.update(config); config.save(); + } - // create some refs via commits and tag - RevCommit commit = git2.commit().setMessage("initial commit").call(); - Ref tagRef = git2.tag().setName("tag").call(); + @Test + public void testFetch() throws JGitInternalException, IOException, + GitAPIException { - Git git1 = new Git(db); + // create some refs via commits and tag + RevCommit commit = remoteGit.commit().setMessage("initial commit").call(); + Ref tagRef = remoteGit.tag().setName("tag").call(); RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x"); - git1.fetch().setRemote("test").setRefSpecs(spec) + git.fetch().setRemote("test").setRefSpecs(spec) .call(); assertEquals(commit.getId(), db.resolve(commit.getId().getName() + "^{commit}")); assertEquals(tagRef.getObjectId(), db.resolve(tagRef.getObjectId().getName())); + } + + @Test + public void fetchShouldAutoFollowTag() throws Exception { + remoteGit.commit().setMessage("commit").call(); + Ref tagRef = remoteGit.tag().setName("foo").call(); + + RefSpec spec = new RefSpec("refs/heads/*:refs/remotes/origin/*"); + git.fetch().setRemote("test").setRefSpecs(spec) + .setTagOpt(TagOpt.AUTO_FOLLOW).call(); + assertEquals(tagRef.getObjectId(), db.resolve("foo")); } + @Test + public void fetchShouldAutoFollowTagForFetchedObjects() throws Exception { + remoteGit.commit().setMessage("commit").call(); + Ref tagRef = remoteGit.tag().setName("foo").call(); + remoteGit.commit().setMessage("commit2").call(); + RefSpec spec = new RefSpec("refs/heads/*:refs/remotes/origin/*"); + git.fetch().setRemote("test").setRefSpecs(spec) + .setTagOpt(TagOpt.AUTO_FOLLOW).call(); + assertEquals(tagRef.getObjectId(), db.resolve("foo")); + } + + @Test + public void fetchShouldNotFetchTagsFromOtherBranches() throws Exception { + remoteGit.commit().setMessage("commit").call(); + remoteGit.checkout().setName("other").setCreateBranch(true).call(); + remoteGit.commit().setMessage("commit2").call(); + remoteGit.tag().setName("foo").call(); + RefSpec spec = new RefSpec( + "refs/heads/master:refs/remotes/origin/master"); + git.fetch().setRemote("test").setRefSpecs(spec) + .setTagOpt(TagOpt.AUTO_FOLLOW).call(); + assertNull(db.resolve("foo")); + } + + @Test + public void fetchWithUpdatedTagShouldNotTryToUpdateLocal() throws Exception { + final String tagName = "foo"; + remoteGit.commit().setMessage("commit").call(); + Ref tagRef = remoteGit.tag().setName(tagName).call(); + ObjectId originalId = tagRef.getObjectId(); + + RefSpec spec = new RefSpec("refs/heads/*:refs/remotes/origin/*"); + git.fetch().setRemote("test").setRefSpecs(spec) + .setTagOpt(TagOpt.AUTO_FOLLOW).call(); + assertEquals(originalId, db.resolve(tagName)); + + remoteGit.commit().setMessage("commit 2").call(); + remoteGit.tag().setName(tagName).setForceUpdate(true).call(); + + FetchResult result = git.fetch().setRemote("test").setRefSpecs(spec) + .setTagOpt(TagOpt.AUTO_FOLLOW).call(); + + Collection refUpdates = result + .getTrackingRefUpdates(); + assertEquals(1, refUpdates.size()); + TrackingRefUpdate update = refUpdates.iterator().next(); + assertEquals("refs/heads/master", update.getRemoteName()); + + assertEquals(originalId, db.resolve(tagName)); + } } 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 d3e38f9c8..9a11dbda6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java @@ -382,23 +382,16 @@ class FetchProcess { continue; Ref local = haveRefs.get(r.getName()); - ObjectId obj = r.getObjectId(); - - if (r.getPeeledObjectId() == null) { - if (local != null && obj.equals(local.getObjectId())) - continue; - if (askFor.containsKey(obj) || transport.local.hasObject(obj)) - wantTag(r); - else - additionalTags.add(r); + if (local != null) + // We already have a tag with this name, don't fetch it (even if + // the local is different). continue; - } - if (local != null) { - if (!obj.equals(local.getObjectId())) - wantTag(r); - } else if (askFor.containsKey(r.getPeeledObjectId()) - || transport.local.hasObject(r.getPeeledObjectId())) + ObjectId obj = r.getPeeledObjectId(); + if (obj == null) + obj = r.getObjectId(); + + if (askFor.containsKey(obj) || transport.local.hasObject(obj)) wantTag(r); else additionalTags.add(r);