Search in sources :

Example 81 with RevCommit

use of org.eclipse.jgit.revwalk.RevCommit in project fabric8 by jboss-fuse.

the class GitPatchManagementServiceImpl method commitInstallation.

@Override
public void commitInstallation(String transaction) {
    transactionIsValid(transaction, null);
    Git fork = pendingTransactions.get(transaction);
    try {
        switch(pendingTransactionsTypes.get(transaction)) {
            case ROLLUP:
                {
                    // hard reset of main patch branch to point to transaction branch + apply changes to ${karaf.home}
                    gitPatchRepository.checkout(fork).setName(gitPatchRepository.getMainBranchName()).call();
                    // before we reset main patch branch to originate from new baseline, let's find previous baseline
                    RevTag baseline = gitPatchRepository.findCurrentBaseline(fork);
                    RevCommit c1 = new RevWalk(fork.getRepository()).parseCommit(fork.getRepository().resolve(baseline.getTagName() + "^{commit}"));
                    // hard reset of main patch branch - to point to other branch, originating from new baseline
                    fork.reset().setMode(ResetCommand.ResetType.HARD).setRef(transaction).call();
                    gitPatchRepository.push(fork);
                    RevCommit c2 = new RevWalk(fork.getRepository()).parseCommit(fork.getRepository().resolve("HEAD"));
                    // apply changes from single range of commits
                    // applyChanges(fork, c1, c2);
                    applyChanges(fork, false);
                    break;
                }
            case NON_ROLLUP:
                {
                    // fast forward merge of main patch branch with transaction branch
                    gitPatchRepository.checkout(fork).setName(gitPatchRepository.getMainBranchName()).call();
                    // current version of ${karaf.home}
                    RevCommit c1 = new RevWalk(fork.getRepository()).parseCommit(fork.getRepository().resolve("HEAD"));
                    // fast forward over patch-installation branch - possibly over more than 1 commit
                    fork.merge().setFastForward(MergeCommand.FastForwardMode.FF_ONLY).include(fork.getRepository().resolve(transaction)).call();
                    gitPatchRepository.push(fork);
                    // apply a change from commits of all installed patches
                    RevCommit c2 = new RevWalk(fork.getRepository()).parseCommit(fork.getRepository().resolve("HEAD"));
                    applyChanges(fork, c1, c2);
                    // applyChanges(fork);
                    break;
                }
        }
        gitPatchRepository.push(fork);
    } catch (GitAPIException | IOException e) {
        throw new PatchException(e.getMessage(), e);
    } finally {
        gitPatchRepository.closeRepository(fork, true);
    }
    pendingTransactions.remove(transaction);
    pendingTransactionsTypes.remove(transaction);
}
Also used : GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Git(org.eclipse.jgit.api.Git) RevTag(org.eclipse.jgit.revwalk.RevTag) IOException(java.io.IOException) PatchException(io.fabric8.patch.management.PatchException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 82 with RevCommit

use of org.eclipse.jgit.revwalk.RevCommit in project fabric8 by jboss-fuse.

the class GitPatchManagementServiceImpl method loadPatch.

@Override
public Patch loadPatch(PatchDetailsRequest request) throws PatchException {
    File descriptor = new File(patchesDir, request.getPatchId() + ".patch");
    try {
        Patch patch = loadPatch(descriptor, true);
        if (patch == null) {
            return null;
        }
        Git repo = gitPatchRepository.findOrCreateMainGitRepository();
        List<DiffEntry> diff = null;
        if (request.isFiles() || request.isDiff()) {
            // fetch the information from git
            ObjectId commitId = repo.getRepository().resolve(patch.getManagedPatch().getCommitId());
            RevCommit commit = new RevWalk(repo.getRepository()).parseCommit(commitId);
            diff = gitPatchRepository.diff(repo, commit.getParent(0), commit);
        }
        if (request.isBundles()) {
        // it's already in PatchData
        }
        if (request.isFiles() && diff != null) {
            for (DiffEntry de : diff) {
                DiffEntry.ChangeType ct = de.getChangeType();
                String newPath = de.getNewPath();
                String oldPath = de.getOldPath();
                switch(ct) {
                    case ADD:
                        patch.getManagedPatch().getFilesAdded().add(newPath);
                        break;
                    case MODIFY:
                        patch.getManagedPatch().getFilesModified().add(newPath);
                        break;
                    case DELETE:
                        patch.getManagedPatch().getFilesRemoved().add(oldPath);
                        break;
                }
            }
        }
        if (request.isDiff() && diff != null) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DiffFormatter formatter = new DiffFormatter(baos);
            formatter.setContext(4);
            formatter.setRepository(repo.getRepository());
            for (DiffEntry de : diff) {
                formatter.format(de);
            }
            formatter.flush();
            patch.getManagedPatch().setUnifiedDiff(new String(baos.toByteArray(), "UTF-8"));
        }
        return patch;
    } catch (IOException | GitAPIException e) {
        throw new PatchException(e.getMessage(), e);
    }
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) ByteArrayOutputStream(org.apache.commons.io.output.ByteArrayOutputStream) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Git(org.eclipse.jgit.api.Git) PatchException(io.fabric8.patch.management.PatchException) DiffFormatter(org.eclipse.jgit.diff.DiffFormatter) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) File(java.io.File) ManagedPatch(io.fabric8.patch.management.ManagedPatch) Patch(io.fabric8.patch.management.Patch) DiffEntry(org.eclipse.jgit.diff.DiffEntry) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 83 with RevCommit

use of org.eclipse.jgit.revwalk.RevCommit in project fabric8 by jboss-fuse.

the class GitPatchManagementServiceImpl method ensureCorrectContainerHistory.

/**
 * Update private history tracking branch in fabric env or for standalone child container - generally
 * when patch management is done in another container. This method is called when it's needed, not every time
 * patch-management bundle is started/stopped/updated.
 * Method <strong>always</strong> changes private history branch and align current version
 * @param fork
 */
private void ensureCorrectContainerHistory(Git fork, String version) throws IOException, GitAPIException {
    if (fork.getRepository().getRef("refs/heads/" + gitPatchRepository.getMainBranchName()) == null) {
        String startPoint = "patch-management^{commit}";
        if (fork.getRepository().getRef("refs/remotes/origin/" + gitPatchRepository.getMainBranchName()) != null) {
            startPoint = "refs/remotes/origin/" + gitPatchRepository.getMainBranchName();
        }
        gitPatchRepository.checkout(fork).setName(gitPatchRepository.getMainBranchName()).setStartPoint(startPoint).setCreateBranch(true).setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK).call();
    } else {
        gitPatchRepository.checkout(fork).setName(gitPatchRepository.getMainBranchName()).call();
    }
    // we may still be on the baseline from the time before fabric:create!
    // user changes in history
    ObjectId since = fork.getRepository().resolve("patch-management^{commit}");
    // we'll pick all user changes between baseline and main patch branch without P installations
    ObjectId to = fork.getRepository().resolve(gitPatchRepository.getMainBranchName() + "^{commit}");
    Iterable<RevCommit> mainChanges = fork.log().addRange(since, to).call();
    List<RevCommit> userChanges = new LinkedList<>();
    for (RevCommit rc : mainChanges) {
        if (isUserChangeCommit(rc)) {
            userChanges.add(rc);
        }
    }
    // let's rewrite history
    fork.reset().setMode(ResetCommand.ResetType.HARD).setRef(String.format(env.getBaselineTagFormat(), version)).call();
    // and pick up user changes just like we'd install Rollup patch
    // reapply those user changes that are not conflicting
    // for each conflicting cherry-pick we do a backup of user files, to be able to restore them
    // when rollup patch is rolled back
    ListIterator<RevCommit> it = userChanges.listIterator(userChanges.size());
    int prefixSize = Integer.toString(userChanges.size()).length();
    int count = 1;
    // we may have unadded changes - when file mode is changed
    fork.reset().setMode(ResetCommand.ResetType.MIXED).call();
    fork.reset().setMode(ResetCommand.ResetType.HARD).call();
    while (it.hasPrevious()) {
        RevCommit userChange = it.previous();
        String prefix = String.format("%0" + prefixSize + "d-%s", count++, userChange.getName());
        CherryPickResult result = fork.cherryPick().include(userChange).setNoCommit(true).call();
        // no backup (!?)
        handleCherryPickConflict(null, fork, result, userChange, false, PatchKind.ROLLUP, null, false, false);
        gitPatchRepository.prepareCommit(fork, userChange.getFullMessage()).call();
        // we may have unadded changes - when file mode is changed
        fork.reset().setMode(ResetCommand.ResetType.MIXED).call();
        fork.reset().setMode(ResetCommand.ResetType.HARD).call();
    }
    gitPatchRepository.push(fork, gitPatchRepository.getMainBranchName());
}
Also used : CherryPickResult(org.eclipse.jgit.api.CherryPickResult) ObjectId(org.eclipse.jgit.lib.ObjectId) LinkedList(java.util.LinkedList) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 84 with RevCommit

use of org.eclipse.jgit.revwalk.RevCommit in project fabric8 by jboss-fuse.

the class GitPatchManagementServiceImpl method ensurePatchManagementInitialized.

/**
 * Check if Fuse/Fabric8 installation is correctly managed by patch mechanism. Check if main git repository
 * is created and is intialized with correct content, there are no conflicts and no pending updates in main Karaf
 * directory. After this method is invoked, we're basically ready to perform rollup patches backed up by git
 * repository.
 */
@Override
public void ensurePatchManagementInitialized() {
    Activator.log(LogService.LOG_INFO, "Configuring patch management system");
    Git fork = null;
    try {
        Git mainRepository = gitPatchRepository.findOrCreateMainGitRepository();
        ensuringLock.lock();
        if (env.isFabric()) {
            // let's fetch from origin to check if someone else already does fabric patch management
            fetchFabricPatchData(mainRepository);
            if (env == EnvType.FABRIC_FUSE || env == EnvType.FABRIC_AMQ) {
                // I think it's enough to compare the main HEADs. if there are no remote branches
                // for patch management or their HEADs are the same, we are the MAIN container that performs
                // git patch management
                ObjectId ours = mainRepository.getRepository().resolve("refs/heads/" + gitPatchRepository.getFuseRootContainerPatchBranchName());
                ObjectId theirs = mainRepository.getRepository().resolve("refs/remotes/origin/" + gitPatchRepository.getFuseRootContainerPatchBranchName());
                if (theirs == null || theirs.equals(ours)) {
                    // if ours is null, then we've just started git patch management
                    // but there's little chance that we're just doing fabric:join... there's only one
                    // way to test it
                    boolean hasZookeeperUrlSetInSystemProperties = false;
                    Properties systemProperties = new Properties();
                    try (FileInputStream fis = new FileInputStream(new File(karafBase, "etc/system.properties"))) {
                        systemProperties.load(fis);
                        String zookeeperUrl = systemProperties.getProperty("zookeeper.url");
                        hasZookeeperUrlSetInSystemProperties = zookeeperUrl != null && !zookeeperUrl.trim().equals("");
                    }
                    master = !hasZookeeperUrlSetInSystemProperties;
                    gitPatchRepository.setMaster(master);
                }
            }
        }
        // prepare single fork for all the below operations - switch to different branches later, as needed
        fork = gitPatchRepository.cloneRepository(mainRepository, true);
        if (env.isFabric() && master) {
            // track baselines for future - when containers are upgraded and their static resources
            // have to be rebased on new baselines
            // new baselines will be added when patches are installed
            trackBaselinesForRootContainer(fork);
            trackBaselinesForChildContainers(fork);
            trackBaselinesForSSHContainers(fork);
        }
        if (env == EnvType.STANDALONE) {
            boolean possiblyInFabric8KarafDistro = new File(karafHome, "bin/fabric8").isFile() || new File(karafHome, "bin/fabric8.bat").isFile();
            if (!possiblyInFabric8KarafDistro) {
                // ENTESB-5761: let's skip the initialization in fabric8-karaf distro - probably we're in SSH container
                // that's just being created
                // do standalone history initialization. We're in root Fuse/AMQ container
                String currentFuseVersion = determineVersion(karafHome, "fuse");
                // one of the steps may return a commit that has to be tagged as first baseline
                RevCommit baselineCommit = null;
                if (!gitPatchRepository.containsTag(fork, String.format(env.getBaselineTagFormat(), currentFuseVersion))) {
                    baselineCommit = trackBaselineRepository(fork);
                    RevCommit c2 = installPatchManagementBundle(fork);
                    if (c2 != null) {
                        baselineCommit = c2;
                    }
                }
                // because patch management is already installed, we have to add consecutive (post patch-management installation) changes
                applyUserChanges(fork);
                if (baselineCommit != null) {
                    // and we'll tag the baseline *after* steps related to first baseline
                    fork.tag().setName(String.format(env.getBaselineTagFormat(), currentFuseVersion)).setObjectId(baselineCommit).call();
                    gitPatchRepository.push(fork);
                }
                // now we have to do the same for existing/future admin:create based child containers
                // it's the root container that takes care of this
                trackBaselinesForChildContainers(fork);
                // repository of patch data - already installed patches
                migrateOldPatchData();
            }
        } else if (env == EnvType.STANDALONE_CHILD) {
            // we're in admin:create based child container. we share patch management git repository
            // with the container that created us
            String currentKarafVersion = determineVersion(karafBase, "karaf");
            String tagName = String.format(env.getBaselineTagFormat(), currentKarafVersion);
            handleNonCurrentBaseline(fork, currentKarafVersion, tagName, true, true);
        } else {
            // do fabric history branch initialization
            // each container has to make sure their private history branch is created and that it contains
            // tag related to the "version" of container (child: karaf, ssh: fabric8 or fuse, root: fuse or amq)
            String currentKarafVersion = determineVersion(karafBase, env.getProductId());
            String tagName = String.format(env.getBaselineTagFormat(), currentKarafVersion);
            handleNonCurrentBaseline(fork, currentKarafVersion, tagName, true, false);
        }
        // remove pending patches listeners
        for (BundleListener bl : pendingPatchesListeners.values()) {
            systemContext.removeBundleListener(bl);
        }
    } catch (GitAPIException | IOException e) {
        Activator.log(LogService.LOG_ERROR, null, e.getMessage(), e, true);
    } finally {
        ensuringLock.unlock();
        initialized.countDown();
        if (fork != null) {
            gitPatchRepository.closeRepository(fork, true);
        }
    }
}
Also used : GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Git(org.eclipse.jgit.api.Git) ObjectId(org.eclipse.jgit.lib.ObjectId) BundleListener(org.osgi.framework.BundleListener) SynchronousBundleListener(org.osgi.framework.SynchronousBundleListener) IOException(java.io.IOException) Properties(java.util.Properties) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) File(java.io.File) FileInputStream(java.io.FileInputStream) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 85 with RevCommit

use of org.eclipse.jgit.revwalk.RevCommit in project fabric8 by jboss-fuse.

the class GitPatchRepositoryImpl method containsCommit.

@Override
public boolean containsCommit(Git git, String branch, String commitMessage) throws IOException, GitAPIException {
    ObjectId head = git.getRepository().resolve(branch);
    Iterable<RevCommit> log = git.log().add(head).call();
    for (RevCommit rc : log) {
        if (rc.getFullMessage().equals(commitMessage)) {
            return true;
        }
    }
    return false;
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Aggregations

RevCommit (org.eclipse.jgit.revwalk.RevCommit)1302 Test (org.junit.Test)650 RevWalk (org.eclipse.jgit.revwalk.RevWalk)333 ObjectId (org.eclipse.jgit.lib.ObjectId)295 Repository (org.eclipse.jgit.lib.Repository)273 IOException (java.io.IOException)222 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)190 Ref (org.eclipse.jgit.lib.Ref)174 File (java.io.File)134 ArrayList (java.util.ArrayList)134 PushOneCommit (com.google.gerrit.acceptance.PushOneCommit)133 Git (org.eclipse.jgit.api.Git)133 PersonIdent (org.eclipse.jgit.lib.PersonIdent)105 Change (com.google.gerrit.entities.Change)87 TestRepository (org.eclipse.jgit.junit.TestRepository)72 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)70 ObjectReader (org.eclipse.jgit.lib.ObjectReader)64 ChangeInfo (com.google.gerrit.extensions.common.ChangeInfo)61 List (java.util.List)61 HashMap (java.util.HashMap)57