Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,10 @@ class ConsoleGitReadableOnly(git: GitRunner, cwd: File, log: Logger) extends Git
def remoteOrigin: String = git("ls-remote", "--get-url", "origin")(cwd, log)

def headCommitMessage: Option[String] = Try(git("log", "--pretty=%s\n\n%b", "-n", "1")(cwd, log)).toOption

def changedFiles: Seq[String] =
headCommitSha
.flatMap(headCommit => Try(git("diff-tree", "--no-commit-id", "--name-only", "-r", headCommit)(cwd, log)).toOption)
.map(_.split('\n').map(_.trim).toSeq)
.getOrElse(Seq.empty)
}
22 changes: 22 additions & 0 deletions src/main/scala/com/github/sbt/git/GitPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ object SbtGit {
val gitHeadCommitDate = SettingKey[Option[String]]("git-head-commit-date", "The commit date for the top commit of this project in ISO-8601 format.")
val gitDescribedVersion = SettingKey[Option[String]]("git-described-version", "Version as returned by `git describe --tags`.")
val gitUncommittedChanges = SettingKey[Boolean]("git-uncommitted-changes", "Whether there are uncommitted changes.")
val gitMergeMessagePatterns = settingKey[Seq[String]]("Collection of regex patterns with one sub-group to parse commit messages of merge commits")
val gitMergeFrom = SettingKey[Option[String]]("git-merge-from", "Possible name of a branch HEAD is a merge from")
val gitFilesChangedLastCommit = SettingKey[Seq[String]]("git-last-changes", "List of files changed in the last commit")

// A Mechanism to run Git directly.
val gitRunner = TaskKey[GitRunner]("git-runner", "The mechanism used to run git in the current build.")
Expand Down Expand Up @@ -124,6 +127,22 @@ object SbtGit {
gitCurrentTags := gitReader.value.withGit(_.currentTags),
gitCurrentBranch := Option(gitReader.value.withGit(_.branch)).getOrElse(""),
ThisBuild / gitUncommittedChanges := gitReader.value.withGit(_.hasUncommittedChanges),
gitMergeMessagePatterns := Seq.empty[String],
gitFilesChangedLastCommit := gitReader.value.withGit(_.changedFiles),
gitMergeFrom := {
for {
headMessage <- gitHeadMessage.value.map(_.trim)
mergedFrom <- gitMergeMessagePatterns.value
.map(_.r.unanchored)
.flatMap { regex =>
headMessage match {
case regex(branch) => Option(branch)
case _ => None
}
}
.headOption
} yield mergedFrom
},
scmInfo := parseScmInfo(gitReader.value.withGit(_.remoteOrigin))
)
private[sbt] def parseScmInfo(remoteOrigin: String): Option[ScmInfo] = {
Expand Down Expand Up @@ -260,6 +279,9 @@ object SbtGit {
val baseVersion = ThisBuild / GitKeys.baseVersion
val versionProperty = ThisBuild / GitKeys.versionProperty
val gitUncommittedChanges = ThisBuild / GitKeys.gitUncommittedChanges
val gitFilesChangedLastCommit = ThisBuild / GitKeys.gitFilesChangedLastCommit
val gitMergeFrom = ThisBuild / GitKeys.gitMergeFrom
val gitMergeMessagePatterns = ThisBuild / GitKeys.gitMergeMessagePatterns
val uncommittedSignifier = ThisBuild / GitKeys.uncommittedSignifier
val formattedShaVersion = ThisBuild / GitKeys.formattedShaVersion
val formattedDateVersion = ThisBuild / GitKeys.formattedDateVersion
Expand Down
30 changes: 23 additions & 7 deletions src/main/scala/com/github/sbt/git/JGit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ package com.github.sbt.git

import org.eclipse.jgit.lib.Repository
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
import org.eclipse.jgit.api.{Git => PGit}
import java.io.File
import org.eclipse.jgit.api.Git as PGit
import org.eclipse.jgit.diff.DiffFormatter

import java.io.{ByteArrayOutputStream, File}
import java.text.SimpleDateFormat
import java.util.Date

import org.eclipse.jgit.lib.ObjectId
import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.revwalk.{RevCommit, RevWalk}

import scala.util.Try
import scala.collection.JavaConverters.*


// TODO - This class needs a bit more work, but at least it lets us use porcelain and wrap some higher-level
Expand All @@ -29,12 +31,10 @@ final class JGit(val repo: Repository) extends GitReadonlyInterface {
def branch: String = repo.getBranch

private def branchesRef: Seq[Ref] = {
import collection.JavaConverters._
porcelain.branchList.call.asScala
}

def tags: Seq[Ref] = {
import collection.JavaConverters._
porcelain.tagList.call().asScala
}

Expand Down Expand Up @@ -96,14 +96,12 @@ final class JGit(val repo: Repository) extends GitReadonlyInterface {
override def branches: Seq[String] = branchesRef.filter(_.getName.startsWith("refs/heads")).map(_.getName.drop(11))

override def remoteBranches: Seq[String] = {
import collection.JavaConverters._
import org.eclipse.jgit.api.ListBranchCommand.ListMode
porcelain.branchList.setListMode(ListMode.REMOTE).call.asScala.filter(_.getName.startsWith("refs/remotes")).map(_.getName.drop(13))
}

override def remoteOrigin: String = {
// same functionality as Process("git ls-remote --get-url origin").lines_!.head
import collection.JavaConverters._
porcelain.remoteList().call.asScala
.filter(_.getName == "origin")
.flatMap(_.getURIs.asScala)
Expand All @@ -125,6 +123,24 @@ final class JGit(val repo: Repository) extends GitReadonlyInterface {
format.format(new Date(millis))
}
}

/** Files changed in current commit * */
override def changedFiles: Seq[String] = {
val walk = new RevWalk(repo)
val maybeChanges = for {
head <- headCommit.map(walk.parseCommit)
parent <- Try(head.getParent(0)).toOption
} yield {
val os = new ByteArrayOutputStream()
val diffFormatter = new DiffFormatter(os)
diffFormatter.setRepository(repo)
diffFormatter.scan(parent, head)
.asScala
.flatMap(entry => Set(entry.getOldPath, entry.getNewPath))
.filterNot(_.startsWith("/"))
}
maybeChanges.getOrElse(Seq.empty)
}
}

object JGit {
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/com/github/sbt/git/ReadableGit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ trait GitReadonlyInterface {
def remoteOrigin: String
/** The message of current commit **/
def headCommitMessage: Option[String]
/** Files changed in current commit **/
def changedFiles: Seq[String]
}


Expand Down
Empty file.
Empty file.
Empty file.
16 changes: 16 additions & 0 deletions src/sbt-test/git-plugin/files-changed/changes/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
def proj(name: String) = Project(name, file(name)).enablePlugins(GitVersioning)


lazy val a = proj("a")
lazy val b = proj("b")

enablePlugins(GitVersioning)

git.baseVersion := "1.0"
git.versionProperty := "DUMMY_BUILD_VERSION"

val checkChangedFiles = taskKey[Unit]("checks the files changed in the last commit")
checkChangedFiles := {
val value = git.gitFilesChangedLastCommit.value
assert(value sameElements Seq("README2.md", "README3.md"), s"changed files should return 2 entries, got $value")
}
1 change: 1 addition & 0 deletions src/sbt-test/git-plugin/files-changed/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("com.github.sbt" % "sbt-git" % sys.props("project.version"))
11 changes: 11 additions & 0 deletions src/sbt-test/git-plugin/files-changed/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
> git init
> git config user.email "[email protected]"
> git config user.name "Tester"
> git add README.md
> git commit -m "test"
> git add README2.md
> git add README3.md
> git commit -m "test2"
$ copy-file changes/build.sbt build.sbt
> reload
> checkChangedFiles
Empty file.
Empty file.
Empty file.
19 changes: 19 additions & 0 deletions src/sbt-test/git-plugin/merged-from/changes/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
def proj(name: String) = Project(name, file(name)).enablePlugins(GitVersioning)


lazy val a = proj("a")
lazy val b = proj("b")

enablePlugins(GitVersioning)

git.baseVersion := "1.0"
git.versionProperty := "DUMMY_BUILD_VERSION"
git.gitMergeMessagePatterns := Seq(
raw"Merge branch '(.*?)'"
)

val checkMergedFrom = taskKey[Unit]("checks the merged from branch is correct")
checkMergedFrom := {
val value = git.gitMergeFrom.value
assert(value == Option("branch_2"), s"Merged from should return the correct branch, got $value")
}
1 change: 1 addition & 0 deletions src/sbt-test/git-plugin/merged-from/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("com.github.sbt" % "sbt-git" % sys.props("project.version"))
15 changes: 15 additions & 0 deletions src/sbt-test/git-plugin/merged-from/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
> git init
> git config user.email "[email protected]"
> git config user.name "Tester"
> git add README.md
> git commit -m "test"
> git checkout -b branch_2
> git add README2.md
> git commit -m "test2"
> git checkout master
> git add README3.md
> git commit -m "test3"
> git merge --no-edit branch_2
$ copy-file changes/build.sbt build.sbt
> reload
> checkMergedFrom