From 5972d8bb6ab2369e298be0e6641d92ab8f1b2f7a Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Mon, 2 Nov 2026 12:59:30 +0100 Subject: build(deps): update JGit from 4.5.7 to 5.13.5 JGit 4.5.7 dates from 2019. 5.13 is the last line that needs only Java 8 APIs, so it works with Android's desugaring; it also fixes GHSA-3p86-9955-h393 (arbitrary file overwrite on checkout). GHSA-vrpq-qp53-qv56 (XXE in repo manifest parsing) has no 5.x fix but the app never parses repo manifests. API changes: - SshSessionFactory now requires getType(). - CheckoutCommand.setForce is deprecated; setForceRefUpdate is its documented replacement with the same meaning. JGit 5 references java.lang.management and javax.management, which Android lacks; R8 flagged them. Both paths are made unreachable rather than only silenced: - WindowCache registers JMX statistics by default; Application.onCreate now installs a WindowCacheConfig with exposeStatsViaJmx = false. - GC.gc() takes a PID lock that queries ManagementFactory and would throw NoClassDefFoundError on a device. GcOperation now runs the GC steps (packRefs, repack, prune) directly; the lock only guards against concurrent gc processes, which cannot happen in the app. Aggressive packing is dropped. The R8 -dontwarn rules and the lint baseline entries are added only for those two now-unreachable references. JGitBehaviourTest covers the operations' command chains plus the GC steps and passes on 5.13.5. It now ignores the developer's global git config, which JGit 5 reads (commit.gpgsign made test commits try to sign). Co-Authored-By: Claude Opus 5.5 --- .../passwordstore/util/git/JGitBehaviourTest.kt | 28 +++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'app/src/test/java') diff --git a/app/src/test/java/app/passwordstore/util/git/JGitBehaviourTest.kt b/app/src/test/java/app/passwordstore/util/git/JGitBehaviourTest.kt index 43f8b66a..b0eeb4ea 100644 --- a/app/src/test/java/app/passwordstore/util/git/JGitBehaviourTest.kt +++ b/app/src/test/java/app/passwordstore/util/git/JGitBehaviourTest.kt @@ -17,9 +17,12 @@ import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode.TRACK import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.RebaseCommand import org.eclipse.jgit.api.ResetCommand +import org.eclipse.jgit.internal.storage.file.FileRepository +import org.eclipse.jgit.internal.storage.file.GC import org.eclipse.jgit.lib.PersonIdent import org.eclipse.jgit.lib.RepositoryState import org.eclipse.jgit.transport.RemoteRefUpdate +import org.eclipse.jgit.util.FS /** * Runs the JGit command chains the git operations in `util/git/operation` use, against a local bare @@ -33,6 +36,8 @@ class JGitBehaviourTest { private val identity = PersonIdent("test", "test@example.org") init { + // Ignore the developer's ~/.gitconfig (e.g. commit.gpgsign); the app has no global config. + FS.DETECTED.setUserHome(root) Git.init().setBare(true).setDirectory(remote).call().close() clone("seed").use { git -> git.write("example.org.gpg", "initial") @@ -147,7 +152,7 @@ class JGitBehaviourTest { // ResetToRemoteOperation b.fetch().setRemote("origin").setRemoveDeletedRefs(true).call() b.branchCreate().setName("master").setForce(true).call() - b.checkout().setName("master").setForce(true).setUpstreamMode(TRACK).call() + b.checkout().setName("master").setForceRefUpdate(true).setUpstreamMode(TRACK).call() b.reset().setRef("origin/master").setMode(ResetCommand.ResetType.HARD).call() assertEquals("edited by a", b.read("example.org.gpg")) @@ -155,4 +160,25 @@ class JGitBehaviourTest { a.close() b.close() } + + @Test + fun gcStepsPackObjectsWithoutThePidLock() { + clone("a").use { a -> + repeat(3) { + a.write("e$it.gpg", "entry $it") + a.commitAll("e$it") + } + val repo = a.repository as FileRepository + // GcOperation + GC(repo).run { + setExpire(null) + packRefs() + repack() + prune(emptySet()) + } + assertEquals(0, GC(repo).statistics.numberOfLooseObjects) + assertTrue(GC(repo).statistics.numberOfPackedObjects > 0) + assertEquals("entry 2", a.read("e2.gpg")) + } + } } -- cgit v1.2.3