/******************************************************************************* * Copyright (c) 2013, 2016 Robin Stocker <robin@nibor.org> and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.eclipse.egit.ui.internal.push; import static org.junit.Assert.*; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.util.Set; import org.eclipse.egit.core.op.BranchOperation; import org.eclipse.egit.core.op.CreateLocalBranchOperation; import org.eclipse.egit.ui.common.LocalRepositoryTestCase; import org.eclipse.egit.ui.test.TestUtil; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.BranchConfig.BranchRebaseMode; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.transport.URIish; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; import org.junit.Before; import org.junit.Test; /** * Tests for "Push Branch..." wizard. */ public class PushBranchWizardTest extends LocalRepositoryTestCase { private Repository repository; private Repository remoteRepository; @Before public void createRepositories() throws Exception { File repositoryFile = createProjectAndCommitToRepository(); File remoteRepositoryFile = createRemoteRepository(repositoryFile); repository = lookupRepository(repositoryFile); remoteRepository = lookupRepository(remoteRepositoryFile); } @Test public void pushToExistingRemote() throws Exception { checkoutNewLocalBranch("foo"); PushBranchWizardTester wizard = PushBranchWizardTester.startWizard( selectProject(), "foo"); wizard.selectRemote("fetch"); wizard.selectMerge(); wizard.next(); wizard.finish(); assertBranchPushed("foo", remoteRepository); assertBranchConfig("foo", "fetch", "refs/heads/foo", "false"); } @Test public void pushHeadToExistingRemote() throws Exception { try (Git git = new Git(repository)) { AnyObjectId head = repository.resolve(Constants.HEAD); git.checkout().setName(head.name()).call(); } PushBranchWizardTester wizard = PushBranchWizardTester .startWizard(selectProject(), Constants.HEAD); wizard.selectRemote("fetch"); wizard.enterBranchName("foo"); wizard.next(); wizard.finish(); assertBranchPushed("foo", remoteRepository); } @Test public void pushToExistingRemoteAndSetRebase() throws Exception { checkoutNewLocalBranch("bar"); PushBranchWizardTester wizard = PushBranchWizardTester.startWizard( selectProject(), "bar"); wizard.selectRemote("fetch"); wizard.selectRebase(); assertFalse(wizard.isUpstreamConfigOverwriteWarningShown()); wizard.next(); wizard.finish(); assertBranchPushed("bar", remoteRepository); assertBranchConfig("bar", "fetch", "refs/heads/bar", "true"); } @Test public void pushToExistingRemoteWithoutConfiguringUpstream() throws Exception { checkoutNewLocalBranch("baz"); PushBranchWizardTester wizard = PushBranchWizardTester.startWizard( selectProject(), "baz"); wizard.selectRemote("fetch"); wizard.deselectConfigureUpstream(); wizard.next(); wizard.finish(); assertBranchPushed("baz", remoteRepository); assertBranchConfig("baz", null, null, null); } @Test public void pushToNewRemote() throws Exception { checkoutNewLocalBranch("qux"); Repository newRemoteRepository = createRemoteRepository(); URIish remoteUri = getUri(newRemoteRepository); PushBranchWizardTester wizard = PushBranchWizardTester.startWizard( selectProject(), "qux"); wizard.selectNewRemoteOnBranchPage("quxremote", remoteUri.toString()); wizard.selectMerge(); wizard.next(); wizard.finish(); assertRemoteConfig("quxremote", remoteUri); assertBranchPushed("qux", newRemoteRepository); assertBranchConfig("qux", "quxremote", "refs/heads/qux", "false"); } @Test public void pushWhenNoRemoteExistsYet() throws Exception { removeExistingRemotes(); checkoutNewLocalBranch("foo"); Repository other = createRemoteRepository(); URIish uri = getUri(other); PushBranchWizardTester wizard = PushBranchWizardTester.startWizard( selectProject(), "foo"); wizard.enterRemoteOnInitialPage("origin", uri.toString()); wizard.next(); wizard.selectMerge(); wizard.next(); wizard.finish(); assertRemoteConfig("origin", uri); assertBranchPushed("foo", other); assertBranchConfig("foo", "origin", "refs/heads/foo", "false"); } @Test public void pushWithDifferentBranchName() throws Exception { checkoutNewLocalBranch("localname"); PushBranchWizardTester wizard = PushBranchWizardTester.startWizard( selectProject(), "localname"); wizard.selectRemote("fetch"); wizard.selectMerge(); wizard.enterBranchName("remotename"); wizard.next(); wizard.finish(); ObjectId pushed = remoteRepository.resolve("remotename"); assertNotNull(pushed); assertEquals(repository.resolve("localname"), pushed); assertBranchConfig("localname", "fetch", "refs/heads/remotename", "false"); } @Test public void pushWithRemoteUpstreamConfiguration() throws Exception { checkoutNewLocalBranch("foo"); // Existing configuration repository.getConfig().setString(ConfigConstants.CONFIG_BRANCH_SECTION, "foo", ConfigConstants.CONFIG_KEY_REMOTE, "fetch"); repository.getConfig().setString(ConfigConstants.CONFIG_BRANCH_SECTION, "foo", ConfigConstants.CONFIG_KEY_MERGE, "refs/heads/foo-on-remote"); repository.getConfig().setEnum( ConfigConstants.CONFIG_BRANCH_SECTION, "foo", ConfigConstants.CONFIG_KEY_REBASE, BranchRebaseMode.REBASE); // Make sure the repository does not have autosetuprebase set repository.getConfig().setBoolean( ConfigConstants.CONFIG_BRANCH_SECTION, null, ConfigConstants.CONFIG_KEY_AUTOSETUPREBASE, false); PushBranchWizardTester wizard = PushBranchWizardTester.startWizard( selectProject(), "foo"); wizard.selectRemote("fetch"); wizard.assertBranchName("foo-on-remote"); wizard.assertRebaseSelected(); assertFalse(wizard.isUpstreamConfigOverwriteWarningShown()); wizard.selectMerge(); assertTrue(wizard.isUpstreamConfigOverwriteWarningShown()); wizard.deselectConfigureUpstream(); assertFalse(wizard.isUpstreamConfigOverwriteWarningShown()); wizard.next(); wizard.finish(); ObjectId remoteId = remoteRepository.resolve("foo-on-remote"); ObjectId localId = repository.resolve("foo"); assertEquals(localId, remoteId); // Still configured assertBranchConfig("foo", "fetch", "refs/heads/foo-on-remote", "true"); } @Test public void pushWithLocalUpstreamConfiguration() throws Exception { checkoutNewLocalBranch("foo"); // Existing configuration repository.getConfig().setString(ConfigConstants.CONFIG_BRANCH_SECTION, "foo", ConfigConstants.CONFIG_KEY_REMOTE, "."); repository.getConfig().setString(ConfigConstants.CONFIG_BRANCH_SECTION, "foo", ConfigConstants.CONFIG_KEY_MERGE, "refs/heads/master"); PushBranchWizardTester wizard = PushBranchWizardTester.startWizard( selectProject(), "foo"); wizard.selectRemote("fetch"); wizard.assertBranchName("foo"); wizard.assertMergeSelected(); assertTrue(wizard.isUpstreamConfigOverwriteWarningShown()); wizard.deselectConfigureUpstream(); assertFalse(wizard.isUpstreamConfigOverwriteWarningShown()); wizard.selectMerge(); wizard.next(); wizard.finish(); ObjectId remoteId = remoteRepository.resolve("foo"); ObjectId localId = repository.resolve("foo"); assertEquals(localId, remoteId); // Newly configured assertBranchConfig("foo", "fetch", "refs/heads/foo", "false"); } private void removeExistingRemotes() throws IOException { StoredConfig config = repository.getConfig(); Set<String> remotes = config .getSubsections(ConfigConstants.CONFIG_REMOTE_SECTION); for (String remoteName : remotes) config.unsetSection(ConfigConstants.CONFIG_REMOTE_SECTION, remoteName); config.save(); } private void checkoutNewLocalBranch(String branchName) throws Exception { CreateLocalBranchOperation createBranch = new CreateLocalBranchOperation( repository, branchName, repository.findRef("master"), null); createBranch.execute(null); BranchOperation checkout = new BranchOperation(repository, branchName); checkout.execute(null); } private Repository createRemoteRepository() throws IOException { File gitDir = new File(getTestDirectory(), "pushbranchremote"); Repository repo = FileRepositoryBuilder.create(gitDir); repo.create(true); assertTrue(repo.isBare()); return repo; } private URIish getUri(Repository repo) throws MalformedURLException { return new URIish(repo.getDirectory().toURI().toURL()); } private SWTBotTree selectProject() { SWTBotTree projectExplorerTree = TestUtil.getExplorerTree(); getProjectItem(projectExplorerTree, PROJ1).select(); return projectExplorerTree; } private void assertBranchPushed(String branchName, Repository remoteRepo) throws Exception { ObjectId pushed = remoteRepo.resolve(branchName); assertNotNull("Expected '" + branchName + "' to resolve to non-null ObjectId on remote repository", pushed); ObjectId local = repository.resolve(branchName); assertEquals( "Expected local branch to be the same as branch on remote after pushing", local, pushed); } private void assertBranchConfig(String branchName, String remoteName, String mergeRef, String rebase) { StoredConfig config = repository.getConfig(); assertEquals(remoteName, config.getString( ConfigConstants.CONFIG_BRANCH_SECTION, branchName, ConfigConstants.CONFIG_KEY_REMOTE)); assertEquals(mergeRef, config.getString( ConfigConstants.CONFIG_BRANCH_SECTION, branchName, ConfigConstants.CONFIG_KEY_MERGE)); assertEquals(rebase, config.getString( ConfigConstants.CONFIG_BRANCH_SECTION, branchName, ConfigConstants.CONFIG_KEY_REBASE)); } private void assertRemoteConfig(String remoteName, URIish remoteUri) { StoredConfig config = repository.getConfig(); assertEquals(remoteUri.toString(), config.getString( ConfigConstants.CONFIG_REMOTE_SECTION, remoteName, ConfigConstants.CONFIG_KEY_URL)); assertEquals("+refs/heads/*:refs/remotes/" + remoteName + "/*", config.getString(ConfigConstants.CONFIG_REMOTE_SECTION, remoteName, "fetch")); } }