Refresh native Git helper aliases after app upgrade
- Rebuild the app-private git-exec helper directory when the packaged native Git binary changes. - Remove stale helper aliases before recreating symlinks/copies. - Add regression coverage for refreshing cached Git exec aliases across binary changes.
This commit is contained in:
@@ -19,8 +19,8 @@ android {
|
|||||||
applicationId = "solutions.tretter.githugandroid"
|
applicationId = "solutions.tretter.githugandroid"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 136
|
versionCode = 137
|
||||||
versionName = "0.1.135"
|
versionName = "0.1.136"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|||||||
@@ -852,6 +852,7 @@ class GitRepositoryRuntime private constructor(
|
|||||||
} else {
|
} else {
|
||||||
File(binary.parentFile ?: binary.absoluteFile.parentFile ?: sandboxesRoot, "git-exec")
|
File(binary.parentFile ?: binary.absoluteFile.parentFile ?: sandboxesRoot, "git-exec")
|
||||||
}
|
}
|
||||||
|
refreshGitExecDirectoryIfNeeded(directory, binary)
|
||||||
directory.mkdirs()
|
directory.mkdirs()
|
||||||
|
|
||||||
File(directory, "git").also { alias ->
|
File(directory, "git").also { alias ->
|
||||||
@@ -870,7 +871,27 @@ class GitRepositoryRuntime private constructor(
|
|||||||
return directory
|
return directory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun refreshGitExecDirectoryIfNeeded(directory: File, binary: File) {
|
||||||
|
val fingerprint = buildString {
|
||||||
|
append(binary.absolutePath)
|
||||||
|
append('\n')
|
||||||
|
append(binary.length())
|
||||||
|
append('\n')
|
||||||
|
append(binary.lastModified())
|
||||||
|
}
|
||||||
|
val stamp = File(directory, ".binary-fingerprint")
|
||||||
|
val previousFingerprint = stamp.takeIf { it.isFile }?.readText()
|
||||||
|
if (previousFingerprint != fingerprint) {
|
||||||
|
directory.deleteRecursively()
|
||||||
|
}
|
||||||
|
directory.mkdirs()
|
||||||
|
stamp.writeText(fingerprint)
|
||||||
|
}
|
||||||
|
|
||||||
private fun createGitAlias(binary: File, alias: File) {
|
private fun createGitAlias(binary: File, alias: File) {
|
||||||
|
if (alias.exists() || Files.isSymbolicLink(alias.toPath())) {
|
||||||
|
alias.delete()
|
||||||
|
}
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
try {
|
try {
|
||||||
Os.symlink(binary.absolutePath, alias.absolutePath)
|
Os.symlink(binary.absolutePath, alias.absolutePath)
|
||||||
|
|||||||
@@ -185,6 +185,37 @@ class GitSandboxEngineTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun nativeGitExecAliasesRefreshWhenBinaryChanges() {
|
||||||
|
val git = testGitBinary()
|
||||||
|
assumeTrue(git.exists() && git.canExecute())
|
||||||
|
val root = Files.createTempDirectory("githug-exec-refresh").toFile()
|
||||||
|
try {
|
||||||
|
val firstGit = File(root, "first-git").also { git.copyTo(it); it.setExecutable(true) }
|
||||||
|
val secondGit = File(root, "second-git").also { git.copyTo(it); it.setExecutable(true) }
|
||||||
|
val level = level(
|
||||||
|
id = "exec-refresh-test",
|
||||||
|
title = "Exec Refresh Test",
|
||||||
|
description = "",
|
||||||
|
hints = emptyList(),
|
||||||
|
commandSuggestions = emptyList(),
|
||||||
|
setup = { RepoState(initialized = true) },
|
||||||
|
validator = { _, _ -> false },
|
||||||
|
)
|
||||||
|
|
||||||
|
GitRepositoryRuntime(root, firstGit).prepareLevel(level)
|
||||||
|
val alias = File(root, "git-exec/git")
|
||||||
|
assertTrue(alias.exists())
|
||||||
|
assertTrue(File(root, "git-exec/.binary-fingerprint").readText().contains(firstGit.absolutePath))
|
||||||
|
|
||||||
|
GitRepositoryRuntime(root, secondGit).prepareLevel(level)
|
||||||
|
assertTrue(alias.exists())
|
||||||
|
assertTrue(File(root, "git-exec/.binary-fingerprint").readText().contains(secondGit.absolutePath))
|
||||||
|
} finally {
|
||||||
|
root.deleteRecursively()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun nativePushLevelHasDivergedStatusAndRebasesCleanly() {
|
fun nativePushLevelHasDivergedStatusAndRebasesCleanly() {
|
||||||
val git = testGitBinary()
|
val git = testGitBinary()
|
||||||
|
|||||||
Reference in New Issue
Block a user