From 24c16ed2ad9d42585423ca99d69b7342bc582744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Mon, 7 Sep 2026 18:17:51 +0200 Subject: [PATCH] Fix relative paths not resolving against the repository in Repository::run() The git process spawned by Repository::run() never had its working directory set, so Symfony Process defaulted it to the calling PHP script's cwd. Commands such as "apply" resolve the paths referenced inside their arguments (e.g. the files listed in a patch) against the process cwd rather than --work-tree, so running them from outside the repository directory failed with errors like "No such file or directory" even though --git-dir/--work-tree were correctly set. Fixes #67 --- src/Gitonomy/Git/Repository.php | 1 + tests/Gitonomy/Git/Tests/RepositoryTest.php | 34 +++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/Gitonomy/Git/Repository.php b/src/Gitonomy/Git/Repository.php index 3e49988..49cd235 100644 --- a/src/Gitonomy/Git/Repository.php +++ b/src/Gitonomy/Git/Repository.php @@ -594,6 +594,7 @@ private function getProcess(string $command, array $args = []): Process $base[] = $command; $process = new Process(array_merge($base, $args)); + $process->setWorkingDirectory($this->getPath()); if ($this->inheritEnvironmentVariables) { $process->setEnv(array_replace($_SERVER, $this->environmentVariables)); diff --git a/tests/Gitonomy/Git/Tests/RepositoryTest.php b/tests/Gitonomy/Git/Tests/RepositoryTest.php index e7bc480..6565167 100644 --- a/tests/Gitonomy/Git/Tests/RepositoryTest.php +++ b/tests/Gitonomy/Git/Tests/RepositoryTest.php @@ -116,4 +116,38 @@ public function testLoggerNOk(Repository $repository): void $repository->run('not-work'); } + + /** + * @see https://github.com/gitonomy/gitlib/issues/67 + */ + public function testRunResolvesRelativePathsAgainstTheRepositoryRegardlessOfCwd(): void + { + $repository = self::createFoobarRepository(false); + + $file = $repository->getWorkingDir().'/README.md'; + $original = file_get_contents($file); + file_put_contents($file, $original."Applied line.\n"); + + $patch = $repository->run('diff', ['--', 'README.md']); + file_put_contents($file, $original); + + $patchFile = tempnam(sys_get_temp_dir(), 'gitlib_patch_'); + file_put_contents($patchFile, $patch); + + $previousCwd = getcwd(); + $this->assertIsString($previousCwd); + chdir(sys_get_temp_dir()); + + try { + // "README.md" is relative to the repository work-tree, not to the + // process cwd (which is an unrelated directory here). This only + // works if the git process is run with its cwd set to the repository. + $repository->run('apply', [$patchFile]); + } finally { + chdir($previousCwd); + unlink($patchFile); + } + + $this->assertSame($original."Applied line.\n", file_get_contents($file)); + } }