Skip to content

Commit

Permalink
[git-patching][ENTESB-4184] Add some hacks to make fast filesystem op…
Browse files Browse the repository at this point in the history
…erations work on Windows™
  • Loading branch information
grgrzybek committed Oct 26, 2015
1 parent df9431a commit 3101f32
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 29 deletions.
Expand Up @@ -100,6 +100,7 @@ public PatchData(String id, String description, List<String> bundles, List<Strin

/**
* Static constructor of PatchData object that takes initialization data from {@link java.io.InputStream}.
* {@link InputStream} is closed after reading.
* @param inputStream
* @return
* @throws IOException
Expand Down
Expand Up @@ -88,6 +88,7 @@ public PatchResult(PatchData patchData, boolean simulation, long date,

/**
* Static constructor of PatchResult object that takes initialization data from {@link java.io.InputStream}.
* {@link InputStream} is closed after reading.
* @param patchData patch data this result relates to
* @param inputStream
* @return
Expand Down
Expand Up @@ -554,13 +554,7 @@ public static long checksum(InputStream is) throws IOException {
}
return crc.getValue();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// Ignore
}
}
IOUtils.closeQuietly(is);
}
}

Expand Down
Expand Up @@ -606,7 +606,7 @@ public Patch trackPatch(PatchData patchData) throws PatchException {

// create dedicated branch for this patch. We'll immediately add patch content there so we can examine the
// changes from the latest baseline
fork.checkout()
gitPatchRepository.checkout(fork)
.setCreateBranch(true)
.setName("patch-" + patchData.getId())
.setStartPoint(commit)
Expand Down Expand Up @@ -673,7 +673,7 @@ public String beginInstallation(PatchKind kind) {
// create temporary branch from the current baseline - rollup patch installation is a rebase
// of existing user changes on top of new baseline
RevTag currentBaseline = gitPatchRepository.findCurrentBaseline(fork);
installationBranch = fork.checkout()
installationBranch = gitPatchRepository.checkout(fork)
.setName(String.format("patch-install-%s", GitPatchRepository.TS.format(new Date())))
.setCreateBranch(true)
.setStartPoint(currentBaseline.getTagName() + "^{commit}")
Expand All @@ -682,7 +682,7 @@ public String beginInstallation(PatchKind kind) {
case NON_ROLLUP:
// create temporary branch from main-patch-branch/HEAD - non-rollup patch installation is cherry-pick
// of non-rollup patch commit over existing user changes - we can fast forward when finished
installationBranch = fork.checkout()
installationBranch = gitPatchRepository.checkout(fork)
.setName(String.format("patch-install-%s", GitPatchRepository.TS.format(new Date())))
.setCreateBranch(true)
.setStartPoint(gitPatchRepository.getMainBranchName())
Expand Down Expand Up @@ -933,7 +933,7 @@ public void commitInstallation(String transaction) {
switch (pendingTransactionsTypes.get(transaction)) {
case ROLLUP: {
// hard reset of main patch branch to point to transaction branch + apply changes to ${karaf.home}
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getMainBranchName())
.call();

Expand All @@ -959,7 +959,7 @@ public void commitInstallation(String transaction) {
}
case NON_ROLLUP: {
// fast forward merge of main patch branch with transaction branch
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getMainBranchName())
.call();
// current version of ${karaf.home}
Expand Down Expand Up @@ -1069,7 +1069,7 @@ public void rollback(PatchData patchData) {
.setMode(ResetCommand.ResetType.MIXED)
.call();
for (String p : status.getModified()) {
fork.checkout().addPath(p).call();
gitPatchRepository.checkout(fork).addPath(p).call();
}
}
while (it.hasPrevious()) {
Expand Down Expand Up @@ -1714,12 +1714,16 @@ private String determineVersion(File home, String product) {
File versions = new File(home, "fabric/import/fabric/profiles/default.profile/io.fabric8.version.properties");
if (versions.exists() && versions.isFile()) {
Properties props = new Properties();
FileInputStream fis = null;
try {
props.load(new FileInputStream(versions));
fis = new FileInputStream(versions);
props.load(fis);
return props.getProperty(product);
} catch (IOException e) {
Activator.log(LogService.LOG_ERROR, null, e.getMessage(), e, true);
return null;
} finally {
IOUtils.closeQuietly(fis);
}
} else {
Activator.log2(LogService.LOG_ERROR, "Can't find io.fabric8.version.properties file in default profile");
Expand Down Expand Up @@ -1784,14 +1788,14 @@ private RevCommit trackBaselineRepository(Git git) throws IOException, GitAPIExc
private void trackBaselinesForChildContainers(Git fork) throws IOException, GitAPIException {
if (fork.getRepository().getRef("refs/heads/" + gitPatchRepository.getChildBranchName()) == null) {
// checkout patches-child branch - it'll track baselines for fabric:container-create-child containers
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getChildBranchName())
.setStartPoint("patch-management^{commit}")
.setCreateBranch(true)
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
.call();
} else {
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getChildBranchName())
.call();
}
Expand Down Expand Up @@ -1908,15 +1912,15 @@ private void unzipKarafAdminJar(File artifact, File targetDirectory) throws IOEx
public void trackBaselinesForSSHContainers(Git fork) throws IOException, GitAPIException {
// two separate branches for two kinds of baselines for SSH containers
if (fork.getRepository().getRef("refs/heads/" + gitPatchRepository.getFuseSSHContainerPatchBranchName()) == null) {
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getFuseSSHContainerPatchBranchName())
.setStartPoint("patch-management^{commit}")
.setCreateBranch(true)
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
.call();
}
if (fork.getRepository().getRef("refs/heads/" + gitPatchRepository.getFabric8SSHContainerPatchBranchName()) == null) {
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getFabric8SSHContainerPatchBranchName())
.setStartPoint("patch-management^{commit}")
.setCreateBranch(true)
Expand Down Expand Up @@ -2014,11 +2018,11 @@ private String unzipFabric8Distro(String rootDir, File artifact, Git fork) throw
}
// checkout correct branch
if (officialFabric8) {
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getFabric8SSHContainerPatchBranchName())
.call();
} else {
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getFuseSSHContainerPatchBranchName())
.call();
}
Expand Down Expand Up @@ -2065,15 +2069,15 @@ private String unzipFabric8Distro(String rootDir, File artifact, Git fork) throw
private void trackBaselinesForRootContainer(Git fork) throws IOException, GitAPIException {
// two separate branches for two kinds of baselines for root containers
if (fork.getRepository().getRef("refs/heads/" + gitPatchRepository.getFuseRootContainerPatchBranchName()) == null) {
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getFuseRootContainerPatchBranchName())
.setStartPoint("patch-management^{commit}")
.setCreateBranch(true)
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
.call();
}
if (fork.getRepository().getRef("refs/heads/" + gitPatchRepository.getAmqRootContainerPatchBranchName()) == null) {
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getAmqRootContainerPatchBranchName())
.setStartPoint("patch-management^{commit}")
.setCreateBranch(true)
Expand All @@ -2089,7 +2093,9 @@ private void trackBaselinesForRootContainer(Git fork) throws IOException, GitAPI
File[] versionDirs = new File(systemRepo, "org/jboss/fuse/jboss-fuse-full").listFiles();
Map<Version, File> versions = new TreeMap<>();

fork.checkout().setName(gitPatchRepository.getFuseRootContainerPatchBranchName()).call();
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getFuseRootContainerPatchBranchName())
.call();

// we'll look for Fuse/AMQ baseline in /patches dir too - it doesn't have to be present
versions.put(new Version(currentFuseVersion), patchesDir);
Expand Down Expand Up @@ -2126,7 +2132,9 @@ private void trackBaselinesForRootContainer(Git fork) throws IOException, GitAPI
versionDirs = new File(systemRepo, "org/jboss/amq/jboss-a-mq").listFiles();
versions.clear();

fork.checkout().setName(gitPatchRepository.getAmqRootContainerPatchBranchName()).call();
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getAmqRootContainerPatchBranchName())
.call();

// we'll look for Fuse/AMQ baseline in /patches dir too - it doesn't have to be present
versions.put(new Version(currentFuseVersion), patchesDir);
Expand Down Expand Up @@ -2241,14 +2249,14 @@ private RevCommit trackBaselineRepository(Git git, File baselineDistribution, St
*/
private void trackFabricContainerBaselineRepository(Git fork, String version) throws IOException, GitAPIException {
if (fork.getRepository().getRef("refs/heads/" + gitPatchRepository.getMainBranchName()) == null) {
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getMainBranchName())
.setStartPoint("patch-management^{commit}")
.setCreateBranch(true)
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
.call();
} else {
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getMainBranchName())
.call();
}
Expand Down Expand Up @@ -2717,7 +2725,7 @@ public boolean alignTo(Map<String, String> versions) throws PatchException {
// we have to be at that tag
Git mainRepository = gitPatchRepository.findOrCreateMainGitRepository();
fork = gitPatchRepository.cloneRepository(mainRepository, true);
fork.checkout()
gitPatchRepository.checkout(fork)
.setName(gitPatchRepository.getMainBranchName())
.call();

Expand Down
Expand Up @@ -23,6 +23,7 @@
import java.util.Map;

import io.fabric8.patch.management.ManagedPatch;
import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
Expand Down Expand Up @@ -84,6 +85,14 @@ public interface GitPatchRepository {
*/
void closeRepository(Git git, boolean deleteWorkingCopy);

/**
* Special <code>git checkout</code> that does several attempts to checkout a revision. This is mainly for
* Windows...
* @param git
* @return
*/
CheckoutCommand checkout(Git git);

/**
* Checks whether a branch in repository contains named commit
* @param git
Expand Down
Expand Up @@ -29,6 +29,8 @@

import io.fabric8.patch.management.ManagedPatch;
import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.CheckoutCommand;
import io.fabric8.patch.management.io.NtfsAwareCheckoutCommand;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.CreateBranchCommand;
import org.eclipse.jgit.api.Git;
Expand Down Expand Up @@ -257,6 +259,11 @@ public void closeRepository(Git git, boolean deleteWorkingCopy) {
}
}

@Override
public CheckoutCommand checkout(Git git) {
return new NtfsAwareCheckoutCommand(git.getRepository());
}

@Override
public boolean containsCommit(Git git, String branch, String commitMessage) throws IOException, GitAPIException {
ObjectId head = git.getRepository().resolve(branch);
Expand Down
Expand Up @@ -90,7 +90,18 @@ private static void doCopyDirectory(File srcDir, File baseDestDir, File destDir,
throw new IOException("Destination '" + destDir + "' exists but is not a directory");
}
} else {
if (!destDir.mkdirs() && !destDir.isDirectory()) {
for (int i=0; i<10; i++) {
if (!destDir.mkdirs()) {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
} else {
break;
}
}
if (!destDir.isDirectory()) {
throw new IOException("Destination '" + destDir + "' directory cannot be created");
}
}
Expand Down
@@ -0,0 +1,59 @@
/**
* Copyright 2005-2015 Red Hat, Inc.
*
* Red Hat licenses this file to you under the Apache License, version
* 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package io.fabric8.patch.management.io;

import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;

public class NtfsAwareCheckoutCommand extends CheckoutCommand {

/**
* @param repo
*/
public NtfsAwareCheckoutCommand(Repository repo) {
super(repo);
}

@Override
public Ref call() throws GitAPIException {
JGitInternalException lastException = null;
for (int i=0; i<5; i++) {
try {
return super.call();
} catch (JGitInternalException e) {
if (!e.getMessage().toLowerCase().contains("Could not rename file")) {
throw e;
} else {
lastException = e;
}
try {
Thread.sleep(250);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
}
if (lastException != null) {
throw lastException;
} else {
return null;
}
}

}
Expand Up @@ -104,7 +104,18 @@ private static void doCopyDirectory(File srcDir, File destDir, List<String> excl
throw new IOException("Destination '" + destDir + "' exists but is not a directory");
}
} else {
if (!destDir.mkdirs() && !destDir.isDirectory()) {
for (int i=0; i<10; i++) {
if (!destDir.mkdirs()) {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
} else {
break;
}
}
if (!destDir.isDirectory()) {
throw new IOException("Destination '" + destDir + "' directory cannot be created");
}
}
Expand Down

0 comments on commit 3101f32

Please sign in to comment.