Files
cregit-mirror/bfg/bfg.patch
Denver Gingerich c50477d386 bfg: update patch to cleanly apply to latest bfg
With this update, the bfg patch will now apply cleanly to the latest
bfg, which is at this commit on the master branch as of this writing:

aeee9e30e0

Note that it is possible to simply clone and build the already patched bfg. See documentation.

Closes #9
2019-05-10 15:39:16 -07:00

211 lines
8.0 KiB
Diff

diff --git a/bfg-library/src/main/scala/com/madgag/git/bfg/cleaner/BlobExecModifier.scala b/bfg-library/src/main/scala/com/madgag/git/bfg/cleaner/BlobExecModifier.scala
new file mode 100644
index 0000000..a1d0c93
--- /dev/null
+++ b/bfg-library/src/main/scala/com/madgag/git/bfg/cleaner/BlobExecModifier.scala
@@ -0,0 +1,91 @@
+package com.madgag.git.bfg.cleaner
+
+import com.google.common.io.ByteStreams
+import com.madgag.git.bfg.model.TreeBlobEntry
+import com.madgag.git.ThreadLocalObjectDatabaseResources
+import java.util.{Arrays => JavaArrays}
+import org.eclipse.jgit.lib.Constants.OBJ_BLOB
+import scala.collection.JavaConversions._
+import scalax.io._
+import scalax.io.managed._
+import java.io._
+import scala.sys.process._
+import scala.sys.process.ProcessIO
+import scala.io.Source
+import scala.collection.mutable.ArrayBuffer
+
+trait BlobExecModifier extends TreeBlobModifier {
+
+ def command: String
+
+ def fileMask: String
+
+ val threadLocalObjectDBResources: ThreadLocalObjectDatabaseResources
+
+ def execute(entry: TreeBlobEntry) = {
+
+ val loader = threadLocalObjectDBResources.reader().open(entry.objectId)
+ val objectStream = loader.openStream
+ val fileName = entry.filename.toString
+
+
+ val bytes = ByteStreams.toByteArray(objectStream)
+
+ val newBytes = ArrayBuffer[Byte]()
+
+ def readJob(in: InputStream) {
+
+ newBytes.appendAll(Stream.continually(in.read).takeWhile(_ != -1).map(_.toByte).toArray)
+ in.close();
+
+ }
+
+ def writeJob(out: OutputStream) {
+ out.write(bytes)
+ out.close()
+ }
+
+ val io = new ProcessIO(
+ writeJob,
+ readJob,
+ _=> (),
+ false
+ )
+ println(s"To execute... $command")
+ val pb = Process(command, None, "BFG_BLOB" -> entry.objectId.name, "BFG_FILENAME" -> fileName)
+ val proc = pb.run(io)
+ val exitCode = proc.exitValue
+
+ if (exitCode != 0) {
+ println(s"Warning: error executing command ${command} on blob ${entry.objectId.name} with filename {$fileName}: error code {$exitCode}" )
+ // in case of error ignore
+ entry.withoutName
+ } else if (JavaArrays.equals(bytes, newBytes.toArray)) {
+ // file output is identical, ignore
+ println(s"Warning: output of command [$command] is identical on blob ${entry.objectId.name} with filename [$fileName]" )
+ entry.withoutName
+ } else {
+ //replace blob
+ val objectId = threadLocalObjectDBResources.inserter().insert(OBJ_BLOB, newBytes.toArray)
+ entry.copy(objectId = objectId).withoutName
+ }
+ }
+
+
+ def fix(entry: TreeBlobEntry) = {
+
+
+ val fileName = entry.filename.toString
+
+ val toProcess = fileMask.r
+
+ toProcess.findFirstIn(fileName) match {
+ case Some(_) => {
+ println(s" [filename] matches [$fileName]")
+ execute(entry)
+ }
+ case _ => entry.withoutName
+
+ }
+ }
+}
diff --git a/bfg-library/src/main/scala/com/madgag/git/bfg/cleaner/ObjectIdSubstitutor.scala b/bfg-library/src/main/scala/com/madgag/git/bfg/cleaner/ObjectIdSubstitutor.scala
index ffd8b64..06e1308 100644
--- a/bfg-library/src/main/scala/com/madgag/git/bfg/cleaner/ObjectIdSubstitutor.scala
+++ b/bfg-library/src/main/scala/com/madgag/git/bfg/cleaner/ObjectIdSubstitutor.scala
@@ -28,7 +28,7 @@ import org.eclipse.jgit.lib.{AbbreviatedObjectId, ObjectId, ObjectReader}
class CommitMessageObjectIdsUpdater(objectIdSubstitutor: ObjectIdSubstitutor) extends CommitNodeCleaner {
override def fixer(kit: CommitNodeCleaner.Kit) = commitNode => commitNode.copy(message = objectIdSubstitutor.replaceOldIds(commitNode.message, kit.threadLocalResources.reader(), kit.mapper))
-
+
}
object ObjectIdSubstitutor {
@@ -59,4 +59,4 @@ trait ObjectIdSubstitutor {
val substitutions = substitutionOpts.flatten.toMap
if (substitutions.isEmpty) message else hexRegex.replaceSomeIn(message, m => substitutions.get(m.matched))
}
-}
\ No newline at end of file
+}
diff --git a/bfg/src/main/scala/com/madgag/git/bfg/cli/CLIConfig.scala b/bfg/src/main/scala/com/madgag/git/bfg/cli/CLIConfig.scala
index 9ca2286..fce4b05 100644
--- a/bfg/src/main/scala/com/madgag/git/bfg/cli/CLIConfig.scala
+++ b/bfg/src/main/scala/com/madgag/git/bfg/cli/CLIConfig.scala
@@ -21,7 +21,7 @@
package com.madgag.git.bfg.cli
import java.io.File
-
+import java.nio.file.{Paths, Files}
import com.madgag.git.bfg.BuildInfo
import com.madgag.git.bfg.GitUtil._
import com.madgag.git.bfg.cleaner._
@@ -91,6 +91,14 @@ object CLIConfig {
opt[String]("filter-content-size-threshold").abbr("fs").valueName("<size>").text("only do file-content filtering on files smaller than <size> (default is %1$d bytes)".format(CLIConfig().filterSizeThreshold)).action {
(v, c) => c.copy(filterSizeThreshold = ByteSize.parse(v))
}
+/*
+ opt[String]("blob-exec").valueName("<cmd>").text("execute the system command for each blob").action {
+ (v, c) => c.copy(blobExec = Some(v))
+ }*/
+ opt[(String, String)]("blob-exec").text("execute the system command for each blob").action {
+ (v, c) => c.copy(blobExec = Some(v))
+ }
+
opt[String]('p', "protect-blobs-from").valueName("<refs>").text("protect blobs that appear in the most recent versions of the specified refs (default is 'HEAD')").action {
(v, c) => c.copy(protectBlobsFromRevisions = v.split(',').toSet)
}
@@ -131,6 +139,7 @@ case class CLIConfig(stripBiggestBlobs: Option[Int] = None,
filenameFilters: Seq[Filter[String]] = Nil,
filterSizeThreshold: Int = BlobTextModifier.DefaultSizeThreshold,
textReplacementExpressions: Traversable[String] = List.empty,
+ blobExec: Option[(String, String)] = None,
stripBlobsWithIds: Option[Set[ObjectId]] = None,
lfsConversion: Option[String] = None,
strictObjectChecking: Boolean = false,
@@ -179,6 +188,29 @@ case class CLIConfig(stripBiggestBlobs: Option[Int] = None,
lazy val lfsBlobConverter: Option[LfsBlobConverter] = lfsConversion.map { lfsGlobExpr =>
new LfsBlobConverter(lfsGlobExpr, repo)
}
+
+ val blobExecModifier: Option[BlobExecModifier] = blobExec.map {
+ execCommand =>
+ new BlobExecModifier {
+ val command = execCommand._1
+
+ if (execCommand._2 eq "") {
+ println(s"Error : you must specify a file mask to when using --blob-exec with command ${command}")
+ System.exit(1);
+ }
+
+ val fileMask = execCommand._2
+
+ if (!Files.exists(Paths.get(command))) {
+ println(s"\nError: command ${command} does not exist (blob-exec option)")
+ System.exit(1)
+ }
+
+
+ println(s"command ${command} mask ${fileMask}")
+ val threadLocalObjectDBResources: ThreadLocalObjectDatabaseResources = repo.getObjectDatabase.threadLocalResources
+ }
+ }
lazy val privateDataRemoval = sensitiveData.getOrElse(Seq(fileDeletion, folderDeletion, blobTextModifier).flatten.nonEmpty)
@@ -217,7 +249,7 @@ case class CLIConfig(stripBiggestBlobs: Option[Int] = None,
}
}
- Seq(blobsByIdRemover, blobRemover, fileDeletion, blobTextModifier, lfsBlobConverter).flatten
+ Seq(blobsByIdRemover, blobRemover, fileDeletion, blobTextModifier, lfsBlobConverter, blobExecModifier).flatten
}
lazy val definesNoWork = treeBlobCleaners.isEmpty && folderDeletion.isEmpty && treeEntryListCleaners.isEmpty
diff --git a/bfg/src/test/scala/com/madgag/git/bfg/cli/MainSpec.scala b/bfg/src/test/scala/com/madgag/git/bfg/cli/MainSpec.scala
index 794f13f..4e03cc7 100644
--- a/bfg/src/test/scala/com/madgag/git/bfg/cli/MainSpec.scala
+++ b/bfg/src/test/scala/com/madgag/git/bfg/cli/MainSpec.scala
@@ -31,5 +31,6 @@ class MainSpec extends Specification {
sequential // concurrent testing against scala.App is not safe https://twitter.com/rtyley/status/340376844916387840
+/*
"CLI" should "not change commits unnecessarily" in new unpackedRepo("/sample-repos/exampleWithInitialCleanHistory.git.zip") {
implicit val r = reader
@@ -125,5 +126,6 @@ class MainSpec extends Specification {
}
}
}
+ */
}