Search in sources :

Example 71 with RemoteRefUpdate

use of org.eclipse.jgit.transport.RemoteRefUpdate in project studio by craftercms.

the class RepositoryManagementServiceInternalImpl method pushToRemote.

@Override
public boolean pushToRemote(String siteId, String remoteName, String remoteBranch, boolean force) throws CryptoException, ServiceLayerException, InvalidRemoteUrlException {
    logger.debug("Get remote data from database for remote " + remoteName + " and site " + siteId);
    RemoteRepository remoteRepository = getRemoteRepository(siteId, remoteName);
    logger.debug("Prepare push command.");
    GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
    Repository repo = helper.getRepository(siteId, SANDBOX);
    try (Git git = new Git(repo)) {
        Iterable<PushResult> pushResultIterable = null;
        PushCommand pushCommand = git.push();
        logger.debug("Set remote " + remoteName);
        pushCommand.setRemote(remoteRepository.getRemoteName());
        logger.debug("Set branch to be " + remoteBranch);
        RefSpec r = new RefSpec();
        r = r.setSourceDestination(Constants.R_HEADS + repo.getBranch(), Constants.R_HEADS + remoteBranch);
        pushCommand.setRefSpecs(r);
        Path tempKey = Files.createTempFile(UUID.randomUUID().toString(), ".tmp");
        pushCommand = helper.setAuthenticationForCommand(pushCommand, remoteRepository.getAuthenticationType(), remoteRepository.getRemoteUsername(), remoteRepository.getRemotePassword(), remoteRepository.getRemoteToken(), remoteRepository.getRemotePrivateKey(), tempKey, true);
        pushCommand.setForce(force);
        pushResultIterable = retryingRepositoryOperationFacade.call(pushCommand);
        Files.delete(tempKey);
        boolean toRet = true;
        for (PushResult pushResult : pushResultIterable) {
            String pushResultMessage = pushResult.getMessages();
            if (StringUtils.isNotEmpty(pushResultMessage)) {
                logger.info(pushResultMessage);
            }
            Collection<RemoteRefUpdate> updates = pushResult.getRemoteUpdates();
            for (RemoteRefUpdate remoteRefUpdate : updates) {
                switch(remoteRefUpdate.getStatus()) {
                    case REJECTED_NODELETE:
                        toRet = false;
                        logger.error("Remote ref " + remoteRefUpdate.getSrcRef() + " update was rejected, " + "because remote side doesn't support/allow deleting refs.\n" + remoteRefUpdate.getMessage());
                    case REJECTED_NONFASTFORWARD:
                        toRet = false;
                        logger.error("Remote ref " + remoteRefUpdate.getSrcRef() + " update was rejected, as it " + "would cause non fast-forward update.\n" + remoteRefUpdate.getMessage());
                    case REJECTED_REMOTE_CHANGED:
                        toRet = false;
                        logger.error("Remote ref " + remoteRefUpdate.getSrcRef() + " update was rejected, because" + " old object id on remote repository " + remoteRefUpdate.getRemoteName() + " wasn't the same as defined expected old object. \n" + remoteRefUpdate.getMessage());
                    case REJECTED_OTHER_REASON:
                        toRet = false;
                        logger.error("Remote ref " + remoteRefUpdate.getSrcRef() + " update was rejected for " + "other reason.\n" + remoteRefUpdate.getMessage());
                    default:
                        break;
                }
            }
        }
        return toRet;
    } catch (InvalidRemoteException e) {
        logger.error("Remote is invalid " + remoteName, e);
        throw new InvalidRemoteUrlException();
    } catch (IOException | JGitInternalException | GitAPIException | CryptoException e) {
        logger.error("Error while pushing to remote " + remoteName + " branch " + remoteBranch + " for site " + siteId, e);
        throw new ServiceLayerException("Error while pushing to remote " + remoteName + " branch " + remoteBranch + " for site " + siteId, e);
    }
}
Also used : Path(java.nio.file.Path) RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) PushResult(org.eclipse.jgit.transport.PushResult) IOException(java.io.IOException) InvalidRemoteUrlException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException) PushCommand(org.eclipse.jgit.api.PushCommand) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) Git(org.eclipse.jgit.api.Git) RefSpec(org.eclipse.jgit.transport.RefSpec) InvalidRemoteException(org.eclipse.jgit.api.errors.InvalidRemoteException) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) CryptoException(org.craftercms.commons.crypto.CryptoException)

Example 72 with RemoteRefUpdate

use of org.eclipse.jgit.transport.RemoteRefUpdate in project git-client-plugin by jenkinsci.

the class JGitAPIImpl method push.

/**
 * push.
 *
 * @return a {@link org.jenkinsci.plugins.gitclient.PushCommand} object.
 */
@Override
public PushCommand push() {
    return new PushCommand() {

        private URIish remote;

        private String refspec;

        private boolean force;

        private boolean tags;

        private Integer timeout;

        @Override
        public PushCommand to(URIish remote) {
            this.remote = remote;
            return this;
        }

        @Override
        public PushCommand ref(String refspec) {
            this.refspec = refspec;
            return this;
        }

        @Override
        public PushCommand force() {
            return force(true);
        }

        @Override
        public PushCommand force(boolean force) {
            this.force = force;
            return this;
        }

        @Override
        public PushCommand tags(boolean tags) {
            this.tags = tags;
            return this;
        }

        @Override
        public PushCommand timeout(Integer timeout) {
            this.timeout = timeout;
            return this;
        }

        @Override
        public void execute() throws GitException {
            try (Repository repo = getRepository()) {
                RefSpec ref = (refspec != null) ? new RefSpec(fixRefSpec(refspec, repo)) : Transport.REFSPEC_PUSH_ALL;
                listener.getLogger().println("RefSpec is \"" + ref + "\".");
                Git g = git(repo);
                Config config = g.getRepository().getConfig();
                if (remote == null) {
                    throw new GitException("PushCommand requires a remote repository URL");
                }
                config.setString("remote", "org_jenkinsci_plugins_gitclient_JGitAPIImpl", "url", remote.toPrivateASCIIString());
                org.eclipse.jgit.api.PushCommand pc = g.push().setRemote("org_jenkinsci_plugins_gitclient_JGitAPIImpl").setRefSpecs(ref).setProgressMonitor(new JGitProgressMonitor(listener)).setCredentialsProvider(getProvider()).setForce(force);
                if (tags) {
                    pc.setPushTags();
                }
                setTransportTimeout(pc, "push", timeout);
                Iterable<PushResult> results = pc.call();
                for (PushResult result : results) for (RemoteRefUpdate update : result.getRemoteUpdates()) {
                    RemoteRefUpdate.Status status = update.getStatus();
                    if (!OK.equals(status) && !UP_TO_DATE.equals(status)) {
                        throw new GitException(update.getMessage() + " " + status + " for '" + ref + "' refspec '" + refspec + "' to " + remote.toPrivateASCIIString());
                    }
                }
                config.unset("remote", "org_jenkinsci_plugins_gitclient_JGitAPIImpl", "url");
            } catch (IOException | JGitInternalException | GitAPIException e) {
                throw new GitException(e);
            }
        }

        /**
         * Currently JGit does not parse refspecs as well as Git CLI.
         * This method attempts to fix the refspec as a workaround until JGit
         * implements parsing arbitrary refspecs (see JENKINS-20393).
         *
         * @return a (hopefully) fixed refspec string.
         */
        private String fixRefSpec(@NonNull String srcRefspec, Repository repository) throws IOException {
            int colon = srcRefspec.indexOf(':');
            String[] specs = new String[] { (colon != -1 ? srcRefspec.substring(0, colon) : srcRefspec).trim(), srcRefspec.substring(colon + 1).trim() };
            for (int spec = 0; spec < specs.length; spec++) {
                if (specs[spec].isEmpty() || "HEAD".equalsIgnoreCase(specs[spec])) {
                    switch(spec) {
                        default:
                        case 0:
                            // empty / HEAD for the first ref. if fine for JGit (see https://github.com/eclipse/jgit/blob/master/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java#L104-L122)
                            break;
                        case // empty second ref. generally means to push "matching" branches, hard to implement the right way, same goes for special case "HEAD" / "HEAD:HEAD" simple-fix here
                        1:
                            specs[spec] = repository.getFullBranch();
                            break;
                    }
                } else if (!specs[spec].startsWith("refs/") && !specs[spec].startsWith("+refs/")) {
                    switch(spec) {
                        default:
                        case // for the source ref. we use the repository to determine what should be pushed
                        0:
                            Ref ref = repository.findRef(specs[spec]);
                            if (ref == null) {
                                throw new IOException(String.format("Ref %s not found.", specs[spec]));
                            }
                            specs[spec] = ref.getTarget().getName();
                            break;
                        case // for the target ref. we can't use the repository, so we try our best to determine the ref.
                        1:
                            if (!specs[spec].startsWith("/")) {
                                specs[spec] = "/" + specs[spec];
                            }
                            if (!specs[spec].startsWith("/heads/") && !specs[spec].startsWith("/remotes/") && !specs[spec].startsWith("/tags/")) {
                                specs[spec] = "/heads" + specs[spec];
                            }
                            specs[spec] = "refs" + specs[spec];
                            break;
                    }
                }
            }
            return specs[0] + ":" + specs[1];
        }
    };
}
Also used : URIish(org.eclipse.jgit.transport.URIish) RemoteConfig(org.eclipse.jgit.transport.RemoteConfig) Config(org.eclipse.jgit.lib.Config) StoredConfig(org.eclipse.jgit.lib.StoredConfig) Constants.typeString(org.eclipse.jgit.lib.Constants.typeString) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) RefSpec(org.eclipse.jgit.transport.RefSpec) NonNull(edu.umd.cs.findbugs.annotations.NonNull) RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) GitException(hudson.plugins.git.GitException) PushResult(org.eclipse.jgit.transport.PushResult) IOException(java.io.IOException) FileRepository(org.eclipse.jgit.internal.storage.file.FileRepository) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) Git(org.eclipse.jgit.api.Git) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException)

Example 73 with RemoteRefUpdate

use of org.eclipse.jgit.transport.RemoteRefUpdate in project catma by forTEXT.

the class JGitRepoManager method push.

/**
 * Pushes commits made locally to the associated remote repository ('origin' remote).
 *
 * @param username the username to authenticate with
 * @param password the password to authenticate with
 * @throws IOException if the push operation failed
 */
@Override
public void push(CredentialsProvider credentialsProvider) throws IOException {
    if (!isAttached()) {
        throw new IllegalStateException("Can't call `push` on a detached instance");
    }
    try {
        if (!CATMAPropertyKey.devPreventPush.getValue(false)) {
            PushCommand pushCommand = this.gitApi.push();
            pushCommand.setCredentialsProvider(credentialsProvider);
            pushCommand.setRemote(Constants.DEFAULT_REMOTE_NAME);
            Iterable<PushResult> pushResults = pushCommand.call();
            for (PushResult pushResult : pushResults) {
                for (RemoteRefUpdate remoteRefUpdate : pushResult.getRemoteUpdates()) {
                    logger.info("PushResult " + remoteRefUpdate);
                }
            }
        } else {
            System.out.println(String.format("FAKE PUSH - %1$s", this.getRemoteUrl(null)));
        }
    } catch (GitAPIException e) {
        throw new IOException("Failed to push", e);
    }
}
Also used : RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) PushResult(org.eclipse.jgit.transport.PushResult) IOException(java.io.IOException) PushCommand(org.eclipse.jgit.api.PushCommand)

Example 74 with RemoteRefUpdate

use of org.eclipse.jgit.transport.RemoteRefUpdate in project plugins_replication by GerritCodeReview.

the class PushOne method push.

@VisibleForTesting
void push(List<RemoteRefUpdate> cmds, RefSpec spec, Ref src) throws IOException {
    String dst = spec.getDestination();
    boolean force = spec.isForceUpdate();
    cmds.add(new RemoteRefUpdate(git, src, dst, force, null, null));
}
Also used : RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 75 with RemoteRefUpdate

use of org.eclipse.jgit.transport.RemoteRefUpdate in project plugins_replication by GerritCodeReview.

the class PushOne method doPushAll.

private List<RemoteRefUpdate> doPushAll(Transport tn, Map<String, Ref> local) throws IOException {
    List<RemoteRefUpdate> cmds = new ArrayList<>();
    boolean noPerms = !pool.isReplicatePermissions();
    Map<String, Ref> remote = listRemote(tn);
    for (Ref src : local.values()) {
        if (!canPushRef(src.getName(), noPerms)) {
            repLog.atFine().log("Skipping push of ref %s", src.getName());
            continue;
        }
        RefSpec spec = matchSrc(src.getName());
        if (spec != null) {
            Ref dst = remote.get(spec.getDestination());
            if (dst == null || !src.getObjectId().equals(dst.getObjectId())) {
                // Doesn't exist yet, or isn't the same value, request to push.
                push(cmds, spec, src);
            }
        }
    }
    if (config.isMirror()) {
        for (Ref ref : remote.values()) {
            if (Constants.HEAD.equals(ref.getName())) {
                repLog.atFine().log("Skipping deletion of %s", ref.getName());
                continue;
            }
            RefSpec spec = matchDst(ref.getName());
            if (spec != null && !local.containsKey(spec.getSource())) {
                // No longer on local side, request removal.
                delete(cmds, spec);
            }
        }
    }
    return cmds;
}
Also used : RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) Ref(org.eclipse.jgit.lib.Ref) RefSpec(org.eclipse.jgit.transport.RefSpec) ArrayList(java.util.ArrayList)

Aggregations

RemoteRefUpdate (org.eclipse.jgit.transport.RemoteRefUpdate)81 PushResult (org.eclipse.jgit.transport.PushResult)58 Git (org.eclipse.jgit.api.Git)23 RefSpec (org.eclipse.jgit.transport.RefSpec)20 Test (org.junit.Test)19 File (java.io.File)18 IOException (java.io.IOException)17 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)15 URIish (org.eclipse.jgit.transport.URIish)15 CloneCommand (org.eclipse.jgit.api.CloneCommand)14 UsernamePasswordCredentialsProvider (org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider)14 ArrayList (java.util.ArrayList)12 PushCommand (org.eclipse.jgit.api.PushCommand)12 BufferedWriter (java.io.BufferedWriter)11 FileOutputStream (java.io.FileOutputStream)11 OutputStreamWriter (java.io.OutputStreamWriter)11 Date (java.util.Date)11 Repository (org.eclipse.jgit.lib.Repository)11 RepositoryModel (com.gitblit.models.RepositoryModel)10 RevCommit (org.eclipse.jgit.revwalk.RevCommit)10