All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.atlassian.jgitflow.core.JGitFlowInitCommand Maven / Gradle / Ivy

There is a newer version: 0.21
Show newest version
package com.atlassian.jgitflow.core;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.Callable;

import com.atlassian.jgitflow.core.exception.AlreadyInitializedException;
import com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException;
import com.atlassian.jgitflow.core.exception.JGitFlowIOException;
import com.atlassian.jgitflow.core.exception.SameBranchException;
import com.atlassian.jgitflow.core.util.GitHelper;

import com.google.common.base.Strings;

import org.eclipse.jgit.api.CreateBranchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.*;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * Initializes a project for use with git flow
 * 

* Examples: *

* Initialize with the defaults or throw an exception if it's already initialized * *

 * JGitFlow flow = JGitFlow.init(new File("some dir"));
 * 
*

* Initialize with the defaults or return the instance if it's already initialized * *

 * JGitFlow flow = JGitFlow.getOrInit(new File("some dir"));
 * 
*

* Initialize with custom overrides or return the instance if it's already initialized * *

 * InitContext ctx = new InitContext();
 * ctx.setMaster("GA");
 *
 * JGitFlow flow = JGitFlow.getOrInit(new File("some dir"), ctx);
 * 
*

* Initialize with custom overrides replacing any existing configuration * *

 * InitContext ctx = new InitContext();
 * ctx.setMaster("GA");
 *
 * JGitFlow flow = JGitFlow.forceInit(new File("some dir"), ctx);
 * 
*/ public class JGitFlowInitCommand implements Callable { private static final String SHORT_NAME = "init"; private File directory; private boolean force; private InitContext context; JGitFlowReporter reporter; private String defaultOriginUrl; /** * Create a new init command instance. *

* An instance of this class is usually obtained by calling one of the static {@link JGitFlow} init methods */ public JGitFlowInitCommand() { this.force = false; this.reporter = new JGitFlowReporter(); } /** * * @return A {@link JGitFlow} instance * @throws JGitFlowIOException * @throws JGitFlowGitAPIException * @throws AlreadyInitializedException * @throws SameBranchException */ @Override public JGitFlow call() throws JGitFlowIOException, JGitFlowGitAPIException, AlreadyInitializedException, SameBranchException { Git git = null; reporter.debugCommandCall(SHORT_NAME); if (null == this.context) { this.context = new InitContext(); } try { git = getOrInitGit(directory); } catch (IOException e) { reporter.errorText(SHORT_NAME, e.getMessage()); reporter.endCommand(); throw new JGitFlowIOException(e); } catch (GitAPIException e) { reporter.errorText(SHORT_NAME, e.getMessage()); reporter.endCommand(); throw new JGitFlowGitAPIException(e); } Repository repo = git.getRepository(); GitFlowConfiguration gfConfig = new GitFlowConfiguration(git); RevWalk walk = null; try { //set origin if we need to if(!Strings.isNullOrEmpty(defaultOriginUrl)) { StoredConfig gitConfig = git.getRepository().getConfig(); String originUrl = gitConfig.getString(ConfigConstants.CONFIG_REMOTE_SECTION, Constants.DEFAULT_REMOTE_NAME, "url"); if (Strings.isNullOrEmpty(originUrl)) { String newOriginUrl = defaultOriginUrl; if(defaultOriginUrl.startsWith("file://")) { File originFile = new File(defaultOriginUrl.substring(7)); newOriginUrl = "file://" + originFile.getCanonicalPath(); } gitConfig.setString(ConfigConstants.CONFIG_REMOTE_SECTION, Constants.DEFAULT_REMOTE_NAME, "url", newOriginUrl); gitConfig.setString(ConfigConstants.CONFIG_REMOTE_SECTION, Constants.DEFAULT_REMOTE_NAME, "fetch", "+refs/heads/*:refs/remotes/origin/*"); gitConfig.save(); } } if (!force && gfConfig.gitFlowIsInitialized()) { reporter.errorText(SHORT_NAME,"git flow is already initialized and force flag is false"); reporter.endCommand(); throw new AlreadyInitializedException("Already initialized for git flow."); } //First setup master if (gfConfig.hasMasterConfigured() && !force) { context.setMaster(gfConfig.getMaster()); } //if no local master exists, but a remote does, check it out if (!GitHelper.localBranchExists(git, context.getMaster()) && GitHelper.remoteBranchExists(git, context.getMaster(), reporter)) { reporter.debugText(SHORT_NAME,"creating new local master branch from origin master"); git.branchCreate() .setName(context.getMaster()) .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.SET_UPSTREAM) .setStartPoint("origin/" + context.getMaster()) .call(); } gfConfig.setMaster(context.getMaster()); //now setup develop if (gfConfig.hasDevelopConfigured() && !force) { context.setDevelop(gfConfig.getDevelop()); } if (context.getDevelop().equals(context.getMaster())) { reporter.errorText(SHORT_NAME,"master and develop branches configured with the same name: [" + context.getMaster() + "]"); reporter.endCommand(); throw new SameBranchException("master and develop branches cannot be the same: [" + context.getMaster() + "]"); } gfConfig.setDevelop(context.getDevelop()); //Creation of HEAD walk = new RevWalk(repo); ObjectId masterBranch = repo.resolve(Constants.R_HEADS + context.getMaster()); RevCommit masterCommit = null; if (null != masterBranch) { try { masterCommit = walk.parseCommit(masterBranch); } catch (MissingObjectException e) { //ignore } catch (IncorrectObjectTypeException e) { //ignore } } if (null == masterCommit) { reporter.debugText(SHORT_NAME,"no commits found on master. creating initial commit."); RefUpdate refUpdate = repo.getRefDatabase().newUpdate(Constants.HEAD, false); refUpdate.setForceUpdate(true); refUpdate.link(Constants.R_HEADS + context.getMaster()); git.commit().setMessage("Initial Commit").call(); } //creation of develop if (!GitHelper.localBranchExists(git, context.getDevelop())) { if (GitHelper.remoteBranchExists(git, context.getDevelop(), reporter)) { reporter.debugText(SHORT_NAME,"creating new local develop branch from origin develop"); git.branchCreate() .setName(context.getDevelop()) .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.SET_UPSTREAM) .setStartPoint("origin/" + context.getDevelop()) .call(); } else { reporter.debugText(SHORT_NAME,"creating new local develop branch without origin"); git.branchCreate() .setName(context.getDevelop()) .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.NOTRACK) .call(); } } //don't do this as it breaks feature finish //git.checkout().setName(context.getDevelop()).call(); //setup prefixes for (String prefixName : gfConfig.getPrefixNames()) { if (gfConfig.hasPrefixConfigured(prefixName) && !force) { context.setPrefix(prefixName, gfConfig.getPrefixValue(prefixName)); } gfConfig.setPrefix(prefixName, context.getPrefix(prefixName)); } } catch (IOException e) { reporter.errorText(SHORT_NAME, e.getMessage()); reporter.flush(); throw new JGitFlowIOException(e); } catch (GitAPIException e) { reporter.errorText(SHORT_NAME, e.getMessage()); reporter.flush(); throw new JGitFlowGitAPIException(e); } finally { if (null != walk) { walk.release(); } reporter.endCommand(); } return new JGitFlow(git, gfConfig, reporter); } /** * Sets the project root folder * @param directory * @return {@code this} */ public JGitFlowInitCommand setDirectory(File directory) { this.directory = directory; return this; } /** * Set the initialization context * @param context * @return {@code this} */ public JGitFlowInitCommand setInitContext(InitContext context) { this.context = context; return this; } /** * Whether to override the current configuration * @param force * true to override, false(default) otherwise * @return {@code this} */ public JGitFlowInitCommand setForce(boolean force) { this.force = force; return this; } public JGitFlowInitCommand setDefaultOriginUrl(String defaultOriginUrl) { this.defaultOriginUrl = defaultOriginUrl; return this; } private Git getOrInitGit(File folder) throws IOException, GitAPIException { reporter.debugMethod(SHORT_NAME,"getOrInitGit"); Git gitRepo; try { reporter.debugText(SHORT_NAME,"looking for git folder in " + folder.getAbsolutePath()); RepositoryBuilder rb = new RepositoryBuilder() .readEnvironment() .findGitDir(folder); File gitDir = rb.getGitDir(); if(null != gitDir) { reporter.debugText(SHORT_NAME,"found existing git folder"); gitRepo = Git.open(gitDir); } else { reporter.debugText(SHORT_NAME,"no git folder found, initializing"); gitRepo = Git.init().setDirectory(folder).call(); } } catch (RepositoryNotFoundException e) { reporter.debugText(SHORT_NAME,"no git folder found, initializing"); gitRepo = Git.init().setDirectory(folder).call(); } reporter.endMethod(); return gitRepo; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy