Remove brittle interactive rebase shortcuts
This commit is contained in:
@@ -127,7 +127,8 @@ class GitRepositoryRuntime private constructor(
|
||||
.takeIf { it.path.startsWith(sandboxRoot.path) } ?: sandboxRoot
|
||||
|
||||
val shellTokens = GitSandboxEngine.tokenizeShellCommand(command)
|
||||
val tokens = shellTokens.map { it.value }
|
||||
val invocation = parseEnvironmentPrefixedCommand(shellTokens)
|
||||
val tokens = invocation.command.map { it.value }
|
||||
if (tokens.isEmpty()) return inspectSandbox(level).copy(currentDir = currentRepo.currentDir) to emptyList()
|
||||
if (currentRepo.interactiveAddSession != null) {
|
||||
val (updatedRepo, output) = GitSandboxEngine.execute(currentRepo, command)
|
||||
@@ -146,13 +147,13 @@ class GitRepositoryRuntime private constructor(
|
||||
val expandedTokens = if (tokens.firstOrNull() == "echo") {
|
||||
tokens
|
||||
} else {
|
||||
expandShellPathspecs(currentRepo, shellTokens)
|
||||
expandShellPathspecs(currentRepo, invocation.command)
|
||||
}.normalizeGitStageAlias()
|
||||
|
||||
executeSyntheticGitCommand(currentRepo, command, expandedTokens)?.let { return it }
|
||||
executeSyntheticGitCommand(currentRepo, command, expandedTokens, invocation.environment)?.let { return it }
|
||||
|
||||
val result = when (expandedTokens.first()) {
|
||||
"git" -> currentRepo to runGit(nativeGit, workingDir, expandedTokens.drop(1)).outputLines
|
||||
"git" -> currentRepo to runGit(nativeGit, workingDir, expandedTokens.drop(1), invocation.environment).outputLines
|
||||
"help", "?" -> currentRepo to commandReferenceLines()
|
||||
else -> executeHelperCommand(sandboxRoot, workingDir, currentRepo, expandedTokens)
|
||||
}
|
||||
@@ -551,7 +552,9 @@ class GitRepositoryRuntime private constructor(
|
||||
currentRepo: RepoState,
|
||||
command: String,
|
||||
tokens: List<String>,
|
||||
environment: Map<String, String> = emptyMap(),
|
||||
): Pair<RepoState, List<String>>? {
|
||||
if (environment.isNotEmpty()) return null
|
||||
if (tokens.firstOrNull() != "git") return null
|
||||
val gitCommand = tokens.getOrNull(1) ?: return null
|
||||
if (gitCommand == "clone" && tokens.getOrNull(2)?.startsWith("https://github.com/Gazler/cloneme") == true) {
|
||||
@@ -562,7 +565,7 @@ class GitRepositoryRuntime private constructor(
|
||||
}
|
||||
val shouldUseSandboxSemantics = when (gitCommand) {
|
||||
"add" -> tokens.any { it == "-p" || it == "--patch" || it == "-i" || it == "--interactive" }
|
||||
"rebase" -> "-i" in tokens || "--interactive" in tokens || "--onto" in tokens
|
||||
"rebase" -> "--onto" in tokens
|
||||
"merge" -> "--squash" in tokens || tokens.lastOrNull() == "mybranch" || tokens.lastOrNull() == "feature"
|
||||
"revert", "stash" -> true
|
||||
"checkout" -> tokens.any { it == "file3" } || tokens.takeLast(2) == listOf("--", "config.rb")
|
||||
@@ -829,11 +832,47 @@ class GitRepositoryRuntime private constructor(
|
||||
return (first + second).distinct()
|
||||
}
|
||||
|
||||
private fun runGit(binary: File, workingDir: File, arguments: List<String>): ProcessExecutionResult {
|
||||
return runProcess(binary, workingDir, arguments)
|
||||
private data class EnvironmentPrefixedCommand(
|
||||
val environment: Map<String, String>,
|
||||
val command: List<GitSandboxEngine.ShellToken>,
|
||||
)
|
||||
|
||||
private fun parseEnvironmentPrefixedCommand(tokens: List<GitSandboxEngine.ShellToken>): EnvironmentPrefixedCommand {
|
||||
val environment = linkedMapOf<String, String>()
|
||||
var commandStart = 0
|
||||
while (commandStart < tokens.size) {
|
||||
val value = tokens[commandStart].value
|
||||
val assignmentIndex = value.indexOf('=')
|
||||
if (assignmentIndex <= 0) break
|
||||
val name = value.take(assignmentIndex)
|
||||
if (!name.isShellEnvironmentName()) break
|
||||
environment[name] = value.substring(assignmentIndex + 1)
|
||||
commandStart += 1
|
||||
}
|
||||
return EnvironmentPrefixedCommand(environment, tokens.drop(commandStart))
|
||||
}
|
||||
|
||||
private fun runProcess(binary: File, workingDir: File, arguments: List<String>): ProcessExecutionResult {
|
||||
private fun String.isShellEnvironmentName(): Boolean {
|
||||
if (isEmpty()) return false
|
||||
if (first() != '_' && !first().isLetter()) return false
|
||||
return all { it == '_' || it.isLetterOrDigit() }
|
||||
}
|
||||
|
||||
private fun runGit(
|
||||
binary: File,
|
||||
workingDir: File,
|
||||
arguments: List<String>,
|
||||
environment: Map<String, String> = emptyMap(),
|
||||
): ProcessExecutionResult {
|
||||
return runProcess(binary, workingDir, arguments, environment)
|
||||
}
|
||||
|
||||
private fun runProcess(
|
||||
binary: File,
|
||||
workingDir: File,
|
||||
arguments: List<String>,
|
||||
extraEnvironment: Map<String, String> = emptyMap(),
|
||||
): ProcessExecutionResult {
|
||||
return try {
|
||||
val gitExecPath = gitExecDirectory(binary)
|
||||
val process = ProcessBuilder(listOf(binary.absolutePath) + arguments)
|
||||
@@ -842,13 +881,17 @@ class GitRepositoryRuntime private constructor(
|
||||
.apply {
|
||||
environment()["HOME"] = workingDir.absolutePath
|
||||
environment()["GIT_EXEC_PATH"] = gitExecPath.absolutePath
|
||||
environment()["PATH"] = gitExecPath.absolutePath
|
||||
environment()["PATH"] = listOfNotNull(
|
||||
gitExecPath.absolutePath,
|
||||
System.getenv("PATH")?.takeIf { it.isNotBlank() },
|
||||
).joinToString(File.pathSeparator)
|
||||
environment()["GIT_CONFIG_NOSYSTEM"] = "1"
|
||||
environment()["GIT_AUTHOR_NAME"] = "GitHug"
|
||||
environment()["GIT_AUTHOR_EMAIL"] = "githug@example.com"
|
||||
environment()["GIT_COMMITTER_NAME"] = "GitHug"
|
||||
environment()["GIT_COMMITTER_EMAIL"] = "githug@example.com"
|
||||
environment()["LC_ALL"] = "C"
|
||||
environment().putAll(extraEnvironment)
|
||||
}
|
||||
.start()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user