PageRenderTime 26ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/jgit-flow-core/src/main/java/com/atlassian/jgitflow/core/JGitFlowInitCommand.java

https://bitbucket.org/ronsmits/jgit-flow
Java | 293 lines | 188 code | 33 blank | 72 comment | 24 complexity | c1467212f7f186b4eef54c7555a39e40 MD5 | raw file
  1. package com.atlassian.jgitflow.core;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.util.concurrent.Callable;
  5. import com.atlassian.jgitflow.core.exception.AlreadyInitializedException;
  6. import com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException;
  7. import com.atlassian.jgitflow.core.exception.JGitFlowIOException;
  8. import com.atlassian.jgitflow.core.exception.SameBranchException;
  9. import com.atlassian.jgitflow.core.util.GitHelper;
  10. import org.eclipse.jgit.api.CreateBranchCommand;
  11. import org.eclipse.jgit.api.Git;
  12. import org.eclipse.jgit.api.errors.GitAPIException;
  13. import org.eclipse.jgit.errors.IncorrectObjectTypeException;
  14. import org.eclipse.jgit.errors.MissingObjectException;
  15. import org.eclipse.jgit.errors.RepositoryNotFoundException;
  16. import org.eclipse.jgit.lib.*;
  17. import org.eclipse.jgit.revwalk.RevCommit;
  18. import org.eclipse.jgit.revwalk.RevWalk;
  19. /**
  20. * Initializes a project for use with git flow
  21. * <p>
  22. * Examples:
  23. * <p>
  24. * Initialize with the defaults or throw an exception if it's already initialized
  25. *
  26. * <pre>
  27. * JGitFlow flow = JGitFlow.init(new File(&quot;some dir&quot;));
  28. * </pre>
  29. * <p>
  30. * Initialize with the defaults or return the instance if it's already initialized
  31. *
  32. * <pre>
  33. * JGitFlow flow = JGitFlow.getOrInit(new File(&quot;some dir&quot;));
  34. * </pre>
  35. * <p>
  36. * Initialize with custom overrides or return the instance if it's already initialized
  37. *
  38. * <pre>
  39. * InitContext ctx = new InitContext();
  40. * ctx.setMaster("GA");
  41. *
  42. * JGitFlow flow = JGitFlow.getOrInit(new File(&quot;some dir&quot;), ctx);
  43. * </pre>
  44. * <p>
  45. * Initialize with custom overrides replacing any existing configuration
  46. *
  47. * <pre>
  48. * InitContext ctx = new InitContext();
  49. * ctx.setMaster("GA");
  50. *
  51. * JGitFlow flow = JGitFlow.forceInit(new File(&quot;some dir&quot;), ctx);
  52. * </pre>
  53. */
  54. public class JGitFlowInitCommand implements Callable<JGitFlow>
  55. {
  56. private File directory;
  57. private boolean force;
  58. private InitContext context;
  59. /**
  60. * Create a new init command instance.
  61. * <p></p>
  62. * An instance of this class is usually obtained by calling one of the static {@link JGitFlow} init methods
  63. */
  64. public JGitFlowInitCommand()
  65. {
  66. this.force = false;
  67. }
  68. /**
  69. *
  70. * @return A {@link JGitFlow} instance
  71. * @throws JGitFlowIOException
  72. * @throws JGitFlowGitAPIException
  73. * @throws AlreadyInitializedException
  74. * @throws SameBranchException
  75. */
  76. @Override
  77. public JGitFlow call() throws JGitFlowIOException, JGitFlowGitAPIException, AlreadyInitializedException, SameBranchException
  78. {
  79. Git git = null;
  80. if (null == this.context)
  81. {
  82. this.context = new InitContext();
  83. }
  84. try
  85. {
  86. git = getOrInitGit(directory);
  87. }
  88. catch (IOException e)
  89. {
  90. throw new JGitFlowIOException(e);
  91. }
  92. catch (GitAPIException e)
  93. {
  94. throw new JGitFlowGitAPIException(e);
  95. }
  96. Repository repo = git.getRepository();
  97. GitFlowConfiguration gfConfig = new GitFlowConfiguration(git);
  98. RevWalk walk = null;
  99. try
  100. {
  101. if (!force && gfConfig.gitFlowIsInitialized())
  102. {
  103. throw new AlreadyInitializedException("Already initialized for git flow.");
  104. }
  105. //First setup master
  106. if (gfConfig.hasMasterConfigured() && !force)
  107. {
  108. context.setMaster(gfConfig.getMaster());
  109. }
  110. else
  111. {
  112. //if no local master exists, but a remote does, check it out
  113. if (!GitHelper.localBranchExists(git, context.getMaster()) && GitHelper.remoteBranchExists(git, context.getMaster()))
  114. {
  115. git.branchCreate()
  116. .setName(context.getMaster())
  117. .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.SET_UPSTREAM)
  118. .setStartPoint("origin/" + context.getMaster())
  119. .call();
  120. }
  121. }
  122. gfConfig.setMaster(context.getMaster());
  123. //now setup develop
  124. if (gfConfig.hasDevelopConfigured() && !force)
  125. {
  126. context.setDevelop(gfConfig.getDevelop());
  127. }
  128. if (context.getDevelop().equals(context.getMaster()))
  129. {
  130. throw new SameBranchException("master and develop branches cannot be the same: [" + context.getMaster() + "]");
  131. }
  132. gfConfig.setDevelop(context.getDevelop());
  133. //Creation of HEAD
  134. walk = new RevWalk(repo);
  135. ObjectId masterBranch = repo.resolve(Constants.R_HEADS + context.getMaster());
  136. RevCommit masterCommit = null;
  137. if (null != masterBranch)
  138. {
  139. try
  140. {
  141. masterCommit = walk.parseCommit(masterBranch);
  142. }
  143. catch (MissingObjectException e)
  144. {
  145. //ignore
  146. }
  147. catch (IncorrectObjectTypeException e)
  148. {
  149. //ignore
  150. }
  151. }
  152. if (null == masterCommit)
  153. {
  154. RefUpdate refUpdate = repo.getRefDatabase().newUpdate(Constants.HEAD, false);
  155. refUpdate.setForceUpdate(true);
  156. refUpdate.link(Constants.R_HEADS + context.getMaster());
  157. git.commit().setMessage("Initial Commit").call();
  158. }
  159. //creation of develop
  160. if (!GitHelper.localBranchExists(git, context.getDevelop()))
  161. {
  162. if (GitHelper.remoteBranchExists(git, context.getDevelop()))
  163. {
  164. git.branchCreate()
  165. .setName(context.getDevelop())
  166. .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.SET_UPSTREAM)
  167. .setStartPoint("origin/" + context.getDevelop())
  168. .call();
  169. }
  170. else
  171. {
  172. git.branchCreate()
  173. .setName(context.getDevelop())
  174. .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.NOTRACK)
  175. .call();
  176. }
  177. }
  178. git.checkout().setName(context.getDevelop()).call();
  179. //setup prefixes
  180. for (String prefixName : gfConfig.getPrefixNames())
  181. {
  182. if (!gfConfig.hasPrefixConfigured(prefixName) || force)
  183. {
  184. gfConfig.setPrefix(prefixName, context.getPrefix(prefixName));
  185. }
  186. }
  187. }
  188. catch (IOException e)
  189. {
  190. throw new JGitFlowIOException(e);
  191. }
  192. catch (GitAPIException e)
  193. {
  194. throw new JGitFlowGitAPIException(e);
  195. }
  196. finally
  197. {
  198. if (null != walk)
  199. {
  200. walk.release();
  201. }
  202. }
  203. return new JGitFlow(git, gfConfig);
  204. }
  205. /**
  206. * Sets the project root folder
  207. * @param directory
  208. * @return {@code this}
  209. */
  210. public JGitFlowInitCommand setDirectory(File directory)
  211. {
  212. this.directory = directory;
  213. return this;
  214. }
  215. /**
  216. * Set the initialization context
  217. * @param context
  218. * @return {@code this}
  219. */
  220. public JGitFlowInitCommand setInitContext(InitContext context)
  221. {
  222. this.context = context;
  223. return this;
  224. }
  225. /**
  226. * Whether to override the current configuration
  227. * @param force
  228. * <code>true</code> to override, <code>false</code>(default) otherwise
  229. * @return {@code this}
  230. */
  231. public JGitFlowInitCommand setForce(boolean force)
  232. {
  233. this.force = force;
  234. return this;
  235. }
  236. private Git getOrInitGit(File folder) throws IOException, GitAPIException
  237. {
  238. Git gitRepo;
  239. try
  240. {
  241. RepositoryBuilder rb = new RepositoryBuilder()
  242. .readEnvironment()
  243. .findGitDir(folder);
  244. File gitDir = rb.getGitDir();
  245. if(null != gitDir)
  246. {
  247. gitRepo = Git.open(gitDir);
  248. }
  249. else
  250. {
  251. gitRepo = Git.init().setDirectory(folder).call();
  252. }
  253. }
  254. catch (RepositoryNotFoundException e)
  255. {
  256. gitRepo = Git.init().setDirectory(folder).call();
  257. }
  258. return gitRepo;
  259. }
  260. }