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);
}
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);
}
}
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());
}
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);
}
}
}
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;
}
Aggregations