diff options
Diffstat (limited to 'src/main/scala')
7 files changed, 85 insertions, 34 deletions
diff --git a/src/main/scala/com/google/gimd/jgit/InvalidJGitBranchNameException.scala b/src/main/scala/com/google/gimd/jgit/InvalidJGitBranchNameException.scala new file mode 100644 index 0000000..e3c65f7 --- /dev/null +++ b/src/main/scala/com/google/gimd/jgit/InvalidJGitBranchNameException.scala @@ -0,0 +1,22 @@ +// Copyright (C) 2009 The Android Open Source Project +// +// 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 com.google.gimd.jgit + +import org.spearce.jgit.lib.Repository + +final class InvalidJGitBranchNameException(val repository: Repository, name: String) + extends JGitDatabaseException(JGitBranch(repository, ""), //not sure if creating artificial + //branch istance is a good idea + "'%1s' is invalid branch name".format(name)) diff --git a/src/main/scala/com/google/gimd/jgit/JGitBranch.scala b/src/main/scala/com/google/gimd/jgit/JGitBranch.scala new file mode 100644 index 0000000..081463d --- /dev/null +++ b/src/main/scala/com/google/gimd/jgit/JGitBranch.scala @@ -0,0 +1,30 @@ +// Copyright (C) 2009 The Android Open Source Project +// +// 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 com.google.gimd.jgit + +import org.spearce.jgit.lib.Repository + +/** + * <p>Class that stores information about branch which consists of name of branch and repository + * where that branch is stored.</p> + * + * @throws InvalidJGitBranchNameException if supplied <code>name</code> does not pass + * <code>Repository.isValidRefName</code> test. + */ +@throws(classOf[InvalidJGitBranchNameException]) +final case class JGitBranch(repository: Repository, name: String) { + if (!Repository.isValidRefName(name)) + throw new InvalidJGitBranchNameException(repository, name) +} diff --git a/src/main/scala/com/google/gimd/jgit/JGitDatabase.scala b/src/main/scala/com/google/gimd/jgit/JGitDatabase.scala index 0b02a6f..760ccb8 100644 --- a/src/main/scala/com/google/gimd/jgit/JGitDatabase.scala +++ b/src/main/scala/com/google/gimd/jgit/JGitDatabase.scala @@ -24,7 +24,7 @@ import org.spearce.jgit.lib.RefUpdate.Result import org.spearce.jgit.dircache.{DirCache, DirCacheEditor, DirCacheEntry} import org.spearce.jgit.revwalk.{RevCommit, RevTree, RevWalk} -final class JGitDatabase(repository: Repository) extends Database { +final class JGitDatabase(branch: JGitBranch) extends Database { /** * The maximal number of merge/transaction rebase retries. @@ -42,12 +42,14 @@ final class JGitDatabase(repository: Repository) extends Database { */ private val MERGE_RETRIES = 10 + private val repository = branch.repository + def latestSnapshot: JGitSnapshot = { try { - val id = repository.resolve(Constants.HEAD) - new JGitSnapshot(repository, new RevWalk(repository).parseCommit(id)) + val id = repository.resolve(branch.name) + new JGitSnapshot(branch, new RevWalk(repository).parseCommit(id)) } catch { - case e: IOException => throw new JGitDatabaseException(repository, e) + case e: IOException => throw new JGitDatabaseException(branch, e) } } @@ -56,37 +58,37 @@ final class JGitDatabase(repository: Repository) extends Database { retry(MERGE_RETRIES) { val snapshot = latestSnapshot val dbModification = modification(snapshot) - applyModification(dbModification, Constants.HEAD, snapshot.commit) + applyModification(dbModification, snapshot.commit) } } catch { - case e: IOException => throw new JGitDatabaseException(repository, e) + case e: IOException => throw new JGitDatabaseException(branch, e) } if (!successful) - throw new JGitMergeRetriesExceededException(repository, MERGE_RETRIES) + throw new JGitMergeRetriesExceededException(branch, MERGE_RETRIES) } - def applyModification(modification: DatabaseModification, branch: String, onto: RevCommit): + def applyModification(modification: DatabaseModification, onto: RevCommit): Boolean = { val treeId = writeMessages(modification, onto.getTree) val commitId = createCommit(treeId, onto) - val result = updateRef(branch, onto, commitId) + val result = updateRef(onto, commitId) result match { //there was no change to database since onto commit so changes were applied cleanly case Result.FAST_FORWARD => true //if there was a change since onto commit update gets rejected. Still it might be that change //did not affected files we are trying to modify. Thus we are trying merging both changes. - case Result.REJECTED => tryMerging(branch, commitId) + case Result.REJECTED => tryMerging(commitId) //TODO: There should be a special treatment of LOCK_FAILURE case but it's low-priority task //the idea is to not try merging if just JGit fails to obtain lock for given reference case _ => - throw new JGitDatabaseException(repository, + throw new JGitDatabaseException(branch, "RefUpdate returned unexpected result: %1s.".format(result)) } } - private def updateRef(name: String, oldCommit: ObjectId, newCommit: ObjectId): Result = { - val refUpdate = repository.updateRef(name) + private def updateRef(oldCommit: ObjectId, newCommit: ObjectId): Result = { + val refUpdate = repository.updateRef(branch.name) refUpdate.setExpectedOldObjectId(oldCommit) refUpdate.setNewObjectId(newCommit) refUpdate.update() @@ -130,20 +132,20 @@ final class JGitDatabase(repository: Repository) extends Database { dirCache.writeTree(objectWriter) } - private def merge(branch: String, commitToBeMerged: ObjectId): Boolean = { - val baseCommit = repository.resolve(branch) + private def merge(commitToBeMerged: ObjectId): Boolean = { + val baseCommit = repository.resolve(branch.name) val merger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(repository) if (merger.merge(baseCommit, commitToBeMerged)) { val treeId = merger.getResultTreeId val mergeCommit = createCommit(treeId, baseCommit, commitToBeMerged) - val result = updateRef(branch, baseCommit, mergeCommit) + val result = updateRef(baseCommit, mergeCommit) Result.FAST_FORWARD == result } else false } - private def tryMerging(branch: String, commitToBeMerged: ObjectId) = - retry(MERGE_RETRIES)(merge(branch, commitToBeMerged)) + private def tryMerging(commitToBeMerged: ObjectId) = + retry(MERGE_RETRIES)(merge(commitToBeMerged)) private def retry(howManyTimes: Int)(what: => Boolean): Boolean = if (howManyTimes > 0) diff --git a/src/main/scala/com/google/gimd/jgit/JGitDatabaseException.scala b/src/main/scala/com/google/gimd/jgit/JGitDatabaseException.scala index 1245df9..16429a3 100644 --- a/src/main/scala/com/google/gimd/jgit/JGitDatabaseException.scala +++ b/src/main/scala/com/google/gimd/jgit/JGitDatabaseException.scala @@ -14,14 +14,11 @@ package com.google.gimd.jgit +case class JGitDatabaseException(val branch: JGitBranch, + val msg: String, + val cause: Throwable) extends GimdException(msg, cause) { -import org.spearce.jgit.lib.Repository + def this(branch: JGitBranch, msg: String) = this(branch, msg, null) -class JGitDatabaseException(val repository: Repository, - val msg: String, - val cause: Throwable) extends GimdException(msg, cause) { - - def this(repository: Repository, msg: String) = this(repository, msg, null) - - def this(repository: Repository, cause: Throwable) = this(repository, null, cause) + def this(branch: JGitBranch, cause: Throwable) = this(branch, null, cause) } diff --git a/src/main/scala/com/google/gimd/jgit/JGitFile.scala b/src/main/scala/com/google/gimd/jgit/JGitFile.scala index dd110d5..4cdf3ca 100644 --- a/src/main/scala/com/google/gimd/jgit/JGitFile.scala +++ b/src/main/scala/com/google/gimd/jgit/JGitFile.scala @@ -20,15 +20,15 @@ import org.spearce.jgit.lib.{ObjectId, Repository} import text.Parser final class JGitFile[T](val path: String, val blobId: ObjectId, val fileType: FileType[T], - val repository: Repository) extends File[T] { + val branch: JGitBranch) extends File[T] { lazy val message = Parser.parse(new InputStreamReader(blobInputStream, "UTF-8")) lazy val userObject = fileType.userType.toUserObject(message) private lazy val blobInputStream = { - val objectLoader = repository.openBlob(blobId) + val objectLoader = branch.repository.openBlob(blobId) if (objectLoader == null) - throw new JGitDatabaseException(repository, "Blob '" + blobId.name + "' does not exist.") + throw new JGitDatabaseException(branch, "Blob '" + blobId.name + "' does not exist.") new ByteArrayInputStream(objectLoader.getCachedBytes) } diff --git a/src/main/scala/com/google/gimd/jgit/JGitMergeRetriesExceededException.scala b/src/main/scala/com/google/gimd/jgit/JGitMergeRetriesExceededException.scala index b982850..ca2bb2a 100644 --- a/src/main/scala/com/google/gimd/jgit/JGitMergeRetriesExceededException.scala +++ b/src/main/scala/com/google/gimd/jgit/JGitMergeRetriesExceededException.scala @@ -21,6 +21,6 @@ import org.spearce.jgit.lib.Repository * * @see JGitDatabase */ -class JGitMergeRetriesExceededException(override val repository: Repository, val retries: Int) - extends JGitDatabaseException(repository, ("Tried to rebase transaction %1s times and " + +class JGitMergeRetriesExceededException(override val branch: JGitBranch, val retries: Int) + extends JGitDatabaseException(branch, ("Tried to rebase transaction %1s times and " + "failed to merge changes successfuly. Aborting.").format(retries)) diff --git a/src/main/scala/com/google/gimd/jgit/JGitSnapshot.scala b/src/main/scala/com/google/gimd/jgit/JGitSnapshot.scala index 2fd01ef..1f8f553 100644 --- a/src/main/scala/com/google/gimd/jgit/JGitSnapshot.scala +++ b/src/main/scala/com/google/gimd/jgit/JGitSnapshot.scala @@ -20,10 +20,10 @@ import org.spearce.jgit.revwalk.RevCommit import org.spearce.jgit.treewalk.filter.{PathFilter, PathSuffixFilter, AndTreeFilter, TreeFilter} import org.spearce.jgit.treewalk.TreeWalk -final class JGitSnapshot(val repository: Repository, val commit: RevCommit) extends Snapshot { +final class JGitSnapshot(val branch: JGitBranch, val commit: RevCommit) extends Snapshot { def all[T](fileType: FileType[T]): Iterator[File[T]] = { - val treeWalk = new TreeWalk(repository) + val treeWalk = new TreeWalk(branch.repository) treeWalk.reset(commit.getTree) treeWalk.setRecursive(true) treeWalk.setFilter(treeFilter(fileType)) @@ -35,7 +35,7 @@ final class JGitSnapshot(val repository: Repository, val commit: RevCommit) exte if (!hasNext) throw new NoSuchElementException val result = - new JGitFile(treeWalk.getPathString, treeWalk.getObjectId(0), fileType, repository) + new JGitFile(treeWalk.getPathString, treeWalk.getObjectId(0), fileType, branch) doesHasNext = treeWalk.next result } |