Last active
August 19, 2024 16:10
-
-
Save gerin98/bf22ebcef8db77d7440fe557896f86ac to your computer and use it in GitHub Desktop.
[Blogpost] Files changed component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FilesChangedComponent(project: Project) { | |
private val git: Git by lazy { | |
Git.open(File("${project.rootDir}/.git")) | |
} | |
private val repository: Repository by lazy { | |
git.repository | |
} | |
private val head: ObjectId | |
get() = repository.resolve(Constants.HEAD) | |
private val master: ObjectId | |
get() = repository.resolve("origin/master") | |
@Throws(IOException::class) | |
fun diff(): Set<String> { | |
Git(repository).use { | |
val diff = gitDiff(it) | |
return getChangedFiles(diff) | |
} | |
} | |
@Throws(MissingObjectException::class, IncorrectObjectTypeException::class, IOException::class, IllegalArgumentException::class) | |
private fun gitDiff(git: Git): MutableList<DiffEntry> { | |
var newTreeParser: AbstractTreeIterator | |
var oldTreeParser: AbstractTreeIterator | |
RevWalk(repository).use { rw -> | |
val headCommit = rw.parseCommit(head) | |
val masterCommit = rw.parseCommit(master) | |
val mergeBase = findMergeBase(rw, headCommit, masterCommit) | |
newTreeParser = prepareTreeParser(repository, headCommit) | |
oldTreeParser = prepareTreeParser(repository, mergeBase) | |
rw.dispose() | |
} | |
return git.diff() | |
.setOldTree(oldTreeParser) | |
.setNewTree(newTreeParser) | |
.setPathFilter(getSourceFilesFilter()) | |
.call() | |
} | |
@Throws(IncorrectObjectTypeException::class, IOException::class) | |
private fun prepareTreeParser(repository: Repository, commit: RevCommit): AbstractTreeIterator { | |
val treeParser = CanonicalTreeParser() | |
repository.newObjectReader().use { reader -> | |
treeParser.reset(reader, commit.tree) | |
} | |
return treeParser | |
} | |
@Throws(MissingObjectException::class, IncorrectObjectTypeException::class, IOException::class) | |
private fun findMergeBase(rw: RevWalk, commitA: RevCommit, commitB: RevCommit): RevCommit { | |
rw.markStart(commitA) | |
rw.markStart(commitB) | |
rw.revFilter = RevFilter.MERGE_BASE | |
return rw.parseCommit(rw.next()) | |
} | |
@Throws(IllegalArgumentException::class) | |
private fun getSourceFilesFilter(): TreeFilter { | |
val javaFilter = PathSuffixFilter.create(".java") | |
val kotlinFilter = PathSuffixFilter.create(".kt") | |
return OrTreeFilter.create(listOf(javaFilter, kotlinFilter)) | |
} | |
private fun getChangedFiles(diff: List<DiffEntry>): Set<String> { | |
val filesChanged = mutableSetOf<String>() | |
diff.forEach { | |
when (it.changeType) { | |
DiffEntry.ChangeType.MODIFY -> filesChanged.add(it.oldPath) | |
DiffEntry.ChangeType.ADD, DiffEntry.ChangeType.RENAME, DiffEntry.ChangeType.COPY -> filesChanged.add(it.newPath) | |
DiffEntry.ChangeType.DELETE, null -> {} | |
} | |
} | |
return filesChanged | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment