/jgit-flow-core/src/main/java/com/atlassian/jgitflow/core/JGitFlowInitCommand.java
https://bitbucket.org/nmi-uk/jgit-flow · Java · 293 lines · 188 code · 33 blank · 72 comment · 24 complexity · c1467212f7f186b4eef54c7555a39e40 MD5 · raw file
- 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 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
- * <p>
- * Examples:
- * <p>
- * Initialize with the defaults or throw an exception if it's already initialized
- *
- * <pre>
- * JGitFlow flow = JGitFlow.init(new File("some dir"));
- * </pre>
- * <p>
- * Initialize with the defaults or return the instance if it's already initialized
- *
- * <pre>
- * JGitFlow flow = JGitFlow.getOrInit(new File("some dir"));
- * </pre>
- * <p>
- * Initialize with custom overrides or return the instance if it's already initialized
- *
- * <pre>
- * InitContext ctx = new InitContext();
- * ctx.setMaster("GA");
- *
- * JGitFlow flow = JGitFlow.getOrInit(new File("some dir"), ctx);
- * </pre>
- * <p>
- * Initialize with custom overrides replacing any existing configuration
- *
- * <pre>
- * InitContext ctx = new InitContext();
- * ctx.setMaster("GA");
- *
- * JGitFlow flow = JGitFlow.forceInit(new File("some dir"), ctx);
- * </pre>
- */
- public class JGitFlowInitCommand implements Callable<JGitFlow>
- {
- private File directory;
- private boolean force;
- private InitContext context;
- /**
- * Create a new init command instance.
- * <p></p>
- * An instance of this class is usually obtained by calling one of the static {@link JGitFlow} init methods
- */
- public JGitFlowInitCommand()
- {
- this.force = false;
- }
- /**
- *
- * @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;
- if (null == this.context)
- {
- this.context = new InitContext();
- }
- try
- {
- git = getOrInitGit(directory);
- }
- catch (IOException e)
- {
- throw new JGitFlowIOException(e);
- }
- catch (GitAPIException e)
- {
- throw new JGitFlowGitAPIException(e);
- }
- Repository repo = git.getRepository();
- GitFlowConfiguration gfConfig = new GitFlowConfiguration(git);
- RevWalk walk = null;
- try
- {
- if (!force && gfConfig.gitFlowIsInitialized())
- {
- throw new AlreadyInitializedException("Already initialized for git flow.");
- }
- //First setup master
- if (gfConfig.hasMasterConfigured() && !force)
- {
- context.setMaster(gfConfig.getMaster());
- }
- else
- {
- //if no local master exists, but a remote does, check it out
- if (!GitHelper.localBranchExists(git, context.getMaster()) && GitHelper.remoteBranchExists(git, context.getMaster()))
- {
- 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()))
- {
- 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)
- {
- 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()))
- {
- git.branchCreate()
- .setName(context.getDevelop())
- .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.SET_UPSTREAM)
- .setStartPoint("origin/" + context.getDevelop())
- .call();
- }
- else
- {
- git.branchCreate()
- .setName(context.getDevelop())
- .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.NOTRACK)
- .call();
- }
- }
- git.checkout().setName(context.getDevelop()).call();
- //setup prefixes
- for (String prefixName : gfConfig.getPrefixNames())
- {
- if (!gfConfig.hasPrefixConfigured(prefixName) || force)
- {
- gfConfig.setPrefix(prefixName, context.getPrefix(prefixName));
- }
- }
- }
- catch (IOException e)
- {
- throw new JGitFlowIOException(e);
- }
- catch (GitAPIException e)
- {
- throw new JGitFlowGitAPIException(e);
- }
- finally
- {
- if (null != walk)
- {
- walk.release();
- }
- }
- return new JGitFlow(git, gfConfig);
- }
- /**
- * 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
- * <code>true</code> to override, <code>false</code>(default) otherwise
- * @return {@code this}
- */
- public JGitFlowInitCommand setForce(boolean force)
- {
- this.force = force;
- return this;
- }
- private Git getOrInitGit(File folder) throws IOException, GitAPIException
- {
- Git gitRepo;
- try
- {
- RepositoryBuilder rb = new RepositoryBuilder()
- .readEnvironment()
- .findGitDir(folder);
- File gitDir = rb.getGitDir();
-
- if(null != gitDir)
- {
- gitRepo = Git.open(gitDir);
- }
- else
- {
- gitRepo = Git.init().setDirectory(folder).call();
- }
- }
- catch (RepositoryNotFoundException e)
- {
- gitRepo = Git.init().setDirectory(folder).call();
- }
- return gitRepo;
- }
- }