1 package com.proalpha.pds.gitutils.common;
3 import java.io.IOException;
4 import java.lang.reflect.InvocationTargetException;
5 import java.net.URISyntaxException;
6 import java.text.MessageFormat;
7 import java.util.Collection;
10 import org.eclipse.core.runtime.IProgressMonitor;
11 import org.eclipse.egit.core.op.FetchOperation;
12 import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
13 import org.eclipse.egit.ui.internal.SecureStoreUtils;
14 import org.eclipse.egit.ui.internal.credentials.EGitCredentialsProvider;
15 import org.eclipse.jgit.api.CheckoutCommand;
16 import org.eclipse.jgit.api.CheckoutResult;
17 import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
18 import org.eclipse.jgit.api.Git;
19 import org.eclipse.jgit.api.MergeCommand;
20 import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
21 import org.eclipse.jgit.api.MergeResult;
22 import org.eclipse.jgit.api.errors.GitAPIException;
23 import org.eclipse.jgit.errors.InvalidObjectIdException;
24 import org.eclipse.jgit.lib.Constants;
25 import org.eclipse.jgit.lib.Ref;
26 import org.eclipse.jgit.lib.Repository;
27 import org.eclipse.jgit.transport.RefSpec;
28 import org.eclipse.jgit.transport.RemoteConfig;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 import com.proalpha.git.PaGit;
33 import com.proalpha.git.util.PaBranchName;
34 import com.proalpha.git.util.PaRepository;
40 protected static final String DEFAULT_SOURCE =
"HEAD";
42 protected String targetRef;
43 protected String sourceRef;
44 protected boolean updateTargetRef;
45 protected boolean updateSourceRef;
47 protected String remote;
51 protected IProgressMonitor monitor;
53 private CheckoutCommand cmd;
55 protected MergeCommand mergeCmd;
57 protected MergeResult mergeResult;
79 boolean updateSourceRef,
boolean updateTargetRef) {
80 this.repository = repository;
82 this.sourceRef = sourceRef;
83 this.targetRef = targetRef;
85 this.updateSourceRef = updateSourceRef;
86 this.updateTargetRef = updateTargetRef;
89 PaGit.init(
new Git(repository));
100 this(repository, Constants.DEFAULT_REMOTE_NAME, DEFAULT_SOURCE, targetRef,
false,
false);
108 public void run() throws InvocationTargetException {
110 if (logger.isInfoEnabled())
111 logger.info(MessageFormat.format(
"Checkout/creation of branch {0}",
this.targetRef));
116 checkoutLocalBranch();
120 checkoutServerBranch();
128 PaGit.getInstance().close();
144 @SuppressWarnings(
"restriction")
156 RefSpec spec =
new RefSpec(
"+refs/heads/" + ref +
":refs/remotes/" + remote +
"/" + ref);
157 config.addFetchRefSpec(spec);
159 FetchOperation op =
new FetchOperation(this.repository, config, config.getTimeout(),
false );
165 }
catch (URISyntaxException ex) {
166 logger.warn(
"The remote config seems to be strange", ex);
167 }
catch (InvocationTargetException ex) {
168 logger.warn(
"Error while running the fetch operation ()", ex);
179 List<RemoteConfig> configs = RemoteConfig.getAllRemoteConfigs(repository.getConfig());
181 for (RemoteConfig c : configs) {
182 if (c.getName().equals(
this.remote)) {
195 this.monitor = monitor;
209 if (mergeResult ==
null || (mergeResult
210 .getMergeStatus() == MergeResult.MergeStatus.FAST_FORWARD
211 || mergeResult.getMergeStatus() == MergeResult.MergeStatus.MERGED
212 || mergeResult.getMergeStatus() == MergeResult.MergeStatus.ALREADY_UP_TO_DATE))
213 return cmd.getResult();
218 return CheckoutResult.ERROR_RESULT;
232 String shortRef = PaBranchName.getShortBranchName(ref);
233 List<Ref> refs = PaGit.getInstance().getGit().branchList().call();
236 if (PaBranchName.getShortBranchName(r.getName()).equals(shortRef)) {
241 }
catch (GitAPIException ex) {
242 logger.error(ex.getMessage(), ex);
256 String shortRef = PaBranchName.getShortBranchName(ref);
257 Collection<Ref> refs = PaGit.getInstance().getGit().lsRemote().setHeads(
true).setTags(
false)
261 if (PaBranchName.getShortBranchName(r.getName()).equals(shortRef)) {
266 }
catch (GitAPIException ex) {
267 logger.error(
"Error while retrieving server branches.", ex);
279 UserPasswordCredentials credentials =
null;
287 credentials = SecureStoreUtils.getCredentials(config.getURIs().get(0));
289 }
catch (IllegalArgumentException ex) {
290 logger.warn(
"Could not get credentials for the URI of following git repository: {}",
291 (config.getURIs().isEmpty()) ? config.getName() +
" - NO URI!" : config.getURIs().get(0));
293 }
catch (URISyntaxException ex) {
294 logger.warn(
"Could not get credentials for the URI due to URI syntax exception", ex);
297 if (credentials !=
null)
298 return new EGitCredentialsProvider(credentials.getUser(), credentials.getPassword());
300 return new EGitCredentialsProvider();
312 private void checkoutLocalBranch() throws InvocationTargetException {
316 cmd = PaGit.getInstance().getGit().checkout().setName(this.targetRef);
319 if (logger.isInfoEnabled())
320 logger.info(MessageFormat.format(
"Checkout of existing local branch {0} successful",
this.targetRef));
322 if (this.updateTargetRef &&
tryFetch(this.targetRef)) {
325 mergeCmd = PaGit.getInstance().getGit().merge().setFastForward(MergeCommand.FastForwardMode.FF)
326 .include(this.repository.resolve(
this.remote +
"/" +
this.targetRef));
327 mergeResult = mergeCmd.call();
329 if (mergeResult.getMergeStatus().isSuccessful())
330 if (logger.isInfoEnabled())
331 logger.info(MessageFormat.format(
"Merge of remote branch {0} successful",
332 this.remote +
"/" +
this.targetRef));
334 if (logger.isInfoEnabled())
335 logger.error(MessageFormat.format(
"Error while updating local ref {0} while merging",
337 throw new InvocationTargetException(
new Throwable(
"Merge into {0} failed"));
341 }
catch (GitAPIException | IOException e1) {
342 logger.error(MessageFormat.format(
"Error while checkout of local branch {0}",
this.targetRef), e1);
343 throw new InvocationTargetException(e1.getCause() !=
null ? e1.getCause() : e1);
355 private void checkoutServerBranch() throws InvocationTargetException {
359 cmd = PaGit.getInstance().getGit().checkout().setCreateBranch(
true).setName(this.targetRef)
360 .setUpstreamMode(SetupUpstreamMode.TRACK).setStartPoint(this.remote +
"/" + this.targetRef);
363 logger.info(MessageFormat.format(
"Branch {0} created by checkout of remote branch {1}",
this.targetRef,
364 this.remote +
"/" +
this.targetRef));
365 }
catch (GitAPIException e1) {
366 logger.error(MessageFormat.format(
"Error while checkout of server branch {0}", targetRef), e1);
367 throw new InvocationTargetException(e1.getCause() !=
null ? e1.getCause() : e1);
377 private void createNewBranch() throws InvocationTargetException {
379 if (this.updateSourceRef &&
tryFetch(this.sourceRef) && !PaRepository.isRemoteTrackingBranch(
this.sourceRef)) {
381 PaGit.getInstance().getGit().checkout().setCreateBranch(
false).setName(this.sourceRef).call();
382 mergeCmd = PaGit.getInstance().getGit().merge().setFastForward(FastForwardMode.FF_ONLY)
383 .include(this.repository.resolve(
this.remote +
"/" +
this.sourceRef));
384 mergeResult = mergeCmd.call();
386 if (mergeResult.getMergeStatus().isSuccessful()) {
387 if (logger.isInfoEnabled())
388 logger.info(MessageFormat.format(
"Merge of remote branch {0} successful",
389 this.remote +
"/" +
this.targetRef));
392 if (logger.isInfoEnabled())
393 logger.error(MessageFormat.format(
"Error while updating local ref {0} while merging",
395 throw new InvocationTargetException(
new Throwable(
"Merge into {0} failed"));
397 }
catch (InvalidObjectIdException | IOException ioie) {
398 if (logger.isWarnEnabled())
399 logger.warn(MessageFormat.format(
"Source ref {0} could not be updated and/or merged into {1}.",
400 this.sourceRef,
this.targetRef), ioie);
404 cmd = PaGit.getInstance().getGit().checkout().setCreateBranch(
true).setName(this.targetRef)
405 .setUpstreamMode(SetupUpstreamMode.NOTRACK).setStartPoint(this.sourceRef);
408 if (logger.isInfoEnabled())
409 logger.info(MessageFormat.format(
"Creation of branch {0} by branching-off local branch {1}",
this.targetRef,
this.sourceRef));
410 }
catch (GitAPIException e1) {
411 if (logger.isErrorEnabled())
412 logger.error(MessageFormat.format(
"Error while creating new local branch {0}", targetRef), e1);
413 throw new InvocationTargetException(e1.getCause() !=
null ? e1.getCause() : e1);
EGitCredentialsProvider getCredentialProvider()
CheckoutResult getResult()
boolean isServerBranch(String ref)
RemoteConfig getRemoteConfig()
boolean tryFetch(String ref)
CheckoutOperation(Repository repository, String targetRef)
void setProgressMonitor(IProgressMonitor monitor)
CheckoutOperation(Repository repository, String remote, String sourceRef, String targetRef, boolean updateSourceRef, boolean updateTargetRef)
boolean isLocalBranch(String ref)