Skip to content

Commit

Permalink
fixes #778 so that the history, getContent and diff commands work pro…
Browse files Browse the repository at this point in the history
…perly with branches (and so Fabric)
  • Loading branch information
jstrachan committed Nov 26, 2013
1 parent 34f3901 commit 57e07a0
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 28 deletions.
43 changes: 43 additions & 0 deletions hawtio-core/src/main/java/io/hawt/util/Files.java
@@ -0,0 +1,43 @@
/**
* Copyright (C) 2013 the original author or authors.
* See the notice.md file distributed with this work for additional
* information regarding copyright ownership.
*
* Licensed 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.hawt.util;

import java.io.File;

/**
*/
public class Files {
/**
* Recursively deletes the given file whether its a file or directory returning the number
* of files deleted
*/
public static int recursiveDelete(File file) {
int answer = 0;
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File child : files) {
answer += recursiveDelete(child);
}
}
}
if (file.delete()) {
answer += 1;
}
return answer;
}}
35 changes: 30 additions & 5 deletions hawtio-git/src/main/java/io/hawt/git/GitFacade.java
Expand Up @@ -58,6 +58,14 @@ public class GitFacade extends GitFacadeSupport {
private String defaultBranch;
private boolean firstPull = true;

public static String trimLeadingSlash(String path) {
String name = path;
if (name != null && name.startsWith("/")) {
name = name.substring(1);
}
return name;
}


public void init() throws Exception {
// lets check if we have a config directory if not lets create one...
Expand Down Expand Up @@ -364,6 +372,23 @@ public CommitInfo call() throws Exception {
});
}

@Override
public void createBranch(final String fromBranch, final String newBranch) {
gitOperation(getStashPersonIdent(), new Callable<Object>() {
@Override
public String toString() {
return "createBranch(" + fromBranch + ", " + newBranch + ")";
}

public Object call() throws Exception {
checkoutBranch(git, fromBranch);
git.branchCreate().setName(newBranch).call();
checkoutBranch(git, newBranch);
return null;
}
});
}

@Override
public void revertTo(final String branch, final String objectId, final String blobPath, final String commitMessage,
final String authorName, final String authorEmail) {
Expand Down Expand Up @@ -653,11 +678,11 @@ protected void checkoutBranch(Git git, String branch) throws GitAPIException {
}
// lets check if the branch exists
CheckoutCommand command = git.checkout().setName(branch);
boolean exists = localBranchExists(branch);
if (!exists) {
command = command.setCreateBranch(true).setForce(true).
setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK).
setStartPoint(getRemote() + "/" + branch);
boolean exists = localBranchExists(branch);
if (!exists) {
command = command.setCreateBranch(true).setForce(true).
setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK).
setStartPoint(getRemote() + "/" + branch);
}
Ref ref = command.call();
if (LOG.isDebugEnabled()) {
Expand Down
4 changes: 4 additions & 0 deletions hawtio-git/src/main/java/io/hawt/git/GitFacadeMXBean.java
Expand Up @@ -34,6 +34,10 @@ CommitInfo write(String branch, String path, String commitMessage,
CommitInfo createDirectory(String branch, String path, String commitMessage,
String authorName, String authorEmail);

/**
* Creates a new branch from the given branch
*/
void createBranch(String fromBranch, String newBranch);

/**
* Renames the given oldPath to the newPath location for the given branch, commit message and user
Expand Down
57 changes: 46 additions & 11 deletions hawtio-git/src/main/java/io/hawt/git/GitFacadeSupport.java
Expand Up @@ -20,6 +20,7 @@
import io.hawt.util.FileFilters;
import io.hawt.util.IOHelper;
import io.hawt.util.MBeanSupport;
import io.hawt.util.Objects;
import io.hawt.util.Strings;
import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.CommitCommand;
Expand All @@ -29,12 +30,14 @@
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.RevWalkUtils;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.gitective.core.BlobUtils;
Expand All @@ -57,6 +60,8 @@
import java.util.SortedSet;
import java.util.TreeSet;

import static io.hawt.git.GitFacade.trimLeadingSlash;

/**
* A based class for implementations of {@link GitFacadeMXBean}
*/
Expand All @@ -65,8 +70,9 @@ public abstract class GitFacadeSupport extends MBeanSupport implements GitFacade

private int shortCommitIdLength = 6;

protected String doDiff(Git git, String objectId, String baseObjectId, String path) {
protected String doDiff(Git git, String objectId, String baseObjectId, String pathOrBlobPath) {
Repository r = git.getRepository();
String blobPath = trimLeadingSlash(pathOrBlobPath);
/*
RevCommit commit = JGitUtils.getCommit(r, objectId);
Expand Down Expand Up @@ -131,9 +137,9 @@ protected String doDiff(Git git, String objectId, String baseObjectId, String pa
}

List<DiffEntry> diffEntries = formatter.scan(baseTree, commitTree);
if (path != null && path.length() > 0) {
if (blobPath != null && blobPath.length() > 0) {
for (DiffEntry diffEntry : diffEntries) {
if (diffEntry.getNewPath().equalsIgnoreCase(path)) {
if (diffEntry.getNewPath().equalsIgnoreCase(blobPath)) {
formatter.format(diffEntry);
break;
}
Expand Down Expand Up @@ -232,30 +238,36 @@ protected String doGetHead(Git git) {
return commit.getName();
}

protected List<CommitInfo> doHistory(Git git, String branch, String objectId, String path, int limit) {
protected List<CommitInfo> doHistory(Git git, String branch, String objectId, String pathOrBlobPath, int limit) {
Repository r = git.getRepository();
String path = trimLeadingSlash(pathOrBlobPath);

CommitFinder finder = new CommitFinder(r);
CommitListFilter block = new CommitListFilter();
CommitListFilter filter = new CommitListFilter();
if (Strings.isNotBlank(path)) {
finder.setFilter(PathFilterUtils.and(path));
}
finder.setFilter(block);
finder.setFilter(filter);

if (limit > 0) {
finder.setFilter(new CommitLimitFilter(100).setStop(true));
finder.setFilter(new CommitLimitFilter(limit).setStop(true));
}
if (Strings.isNotBlank(objectId)) {
finder.findFrom(objectId);
} else {
if (Strings.isNotBlank(branch)) {
RevCommit base = CommitUtils.getBase(r, branch);
finder.findFrom(base);
ObjectId branchObjectId = getBranchObjectId(git, branch);
if (branchObjectId != null) {
finder = finder.findFrom(branchObjectId);
} else {
finder = finder.findInBranches();
}

} else {
finder.find();
}
}
List<RevCommit> commits = block.getCommits();
List<RevCommit> commits = filter.getCommits();
List<CommitInfo> results = new ArrayList<CommitInfo>();
for (RevCommit entry : commits) {
CommitInfo commitInfo = createCommitInfo(entry);
Expand All @@ -264,16 +276,39 @@ protected List<CommitInfo> doHistory(Git git, String branch, String objectId, St
return results;
}

protected ObjectId getBranchObjectId(Git git, String branch) {
Ref branchRef = null;
try {
String branchRevName = "refs/heads/" + branch;
List<Ref> branches = git.branchList().call();
for (Ref ref : branches) {
String revName = ref.getName();
if (Objects.equals(branchRevName, revName)) {
branchRef = ref;
break;
}
}
} catch (GitAPIException e) {
LOG.warn("Failed to find branches " + e, e);
}

ObjectId branchObjectId = null;
if (branchRef != null) {
branchObjectId = branchRef.getObjectId();
}
return branchObjectId;
}


@Override
protected String getDefaultObjectName() {
return "io.hawt.git:type=GitFacade";
}

protected String doGetContent(Git git, String objectId, String blobPath) {
protected String doGetContent(Git git, String objectId, String pathOrBlobPath) {
objectId = defaultObjectId(git, objectId);
Repository r = git.getRepository();
String blobPath = trimLeadingSlash(pathOrBlobPath);
return BlobUtils.getContent(r, objectId, blobPath);
}

Expand Down
112 changes: 112 additions & 0 deletions hawtio-git/src/test/java/io/hawt/git/GitBranchDiffTest.java
@@ -0,0 +1,112 @@
package io.hawt.git;

import io.hawt.util.Strings;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.management.ObjectName;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import static io.hawt.git.GitFacadeTest.assertConfigDirectoryExists;
import static io.hawt.git.GitFacadeTest.createTestGitFacade;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
* Tests we create a configuration directory
*/
public class GitBranchDiffTest {
private static final transient Logger LOG = LoggerFactory.getLogger(GitBranchDiffTest.class);

GitFacade git = createTestGitFacade("git-branch-diff-test");

public static void main(String[] args) {
GitBranchDiffTest test = new GitBranchDiffTest();
try {
test.init();
test.testBranchesAndDiff();
test.destroy();
} catch (Throwable e) {
System.out.println("FAILED: " + e);
e.printStackTrace();
}
}
String authorName = "jstrachan";
String authorEmail = "james.strachan@gmail.com";

@Before
public void init() throws Exception {
git.setCloneRemoteRepoOnStartup(false);
git.init();
}

@After
public void destroy() throws Exception {
git.destroy();
}

@Test
public void testBranchesAndDiff() throws Exception {
assertConfigDirectoryExists(git);

// lets do a dummy commit
String master = "master";
String branch = "1.0";

git.write(master, "dummy.txt", "Initial commit", authorName, authorEmail, "hey");

git.createBranch(master, branch);

String contentV1 = "Hello world!";
String contentV2 = "Hello James!";
String readMePath = "/ReadMe.md";
String anotherPath = "/Another.md";

git.write(branch, readMePath, "Initial commit", authorName, authorEmail, contentV1);
git.write(branch, readMePath, "Updated", authorName, authorEmail, contentV2);

// force checkout of master branch
git.read(master, "/");


// now lets find the versions
List<CommitInfo> history = git.history(branch, null, readMePath, 0);
assertSize("history", 2, history);
for (CommitInfo commitInfo : history) {
System.out.println("Version: " + commitInfo);
}

String id1 = history.get(1).getCommitHashText();
String id2 = history.get(0).getCommitHashText();
String version1 = git.getContent(id1, readMePath);
String version2 = git.getContent(id2, readMePath);
assertEquals("version1", contentV1, version1);
assertEquals("version2", contentV2, version2);

String diff = git.diff(id2, id1, readMePath);
assertNotNull("diff", diff);
assertTrue("diff is blank: " + diff, Strings.isNotBlank(diff));
LOG.info("Diff is: " + diff);
}

public static void assertSize(String message, int expectedSize, Collection<?> collection) {
assertNotNull(message + " is null", collection);
assertEquals(message + " size when is " + collection, expectedSize, collection.size());
}

}

0 comments on commit 57e07a0

Please sign in to comment.