@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update "git rev-parse" invocation to work in Git 2.25.0

Summary:
Fixes T13479. The behavior of "git rev-parse --show-toplevel" has changed in Git 2.25.0, and it now fails in bare repositories.

Instead, use "git rev-parse --git-dir" to sanity-check the working copy. This appears to have more stable behavior across Git versions, although it's a little more complicated for our purposes.

Test Plan:
- Ran `bin/repository update ...` on an observed, bare repository.
- ...on an observed, non-bare ("legacy") repository.
- ...on a hosted, bare repository.

Maniphest Tasks: T13479

Differential Revision: https://secure.phabricator.com/D20945

+38 -11
+38 -11
src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
··· 275 275 private function executeGitUpdate() { 276 276 $repository = $this->getRepository(); 277 277 278 + // See T13479. We previously used "--show-toplevel", but this stopped 279 + // working in Git 2.25.0 when run in a bare repository. 280 + 281 + // NOTE: As of Git 2.21.1, "git rev-parse" can not parse "--" in its 282 + // argument list, so we can not specify arguments unambiguously. Any 283 + // version of Git which does not recognize the "--git-dir" flag will 284 + // treat this as a request to parse the literal refname "--git-dir". 285 + 278 286 list($err, $stdout) = $repository->execLocalCommand( 279 - 'rev-parse --show-toplevel'); 287 + 'rev-parse --git-dir'); 288 + 289 + $repository_root = null; 290 + $path = $repository->getLocalPath(); 291 + 292 + if (!$err) { 293 + $repository_root = Filesystem::resolvePath( 294 + rtrim($stdout, "\n"), 295 + $path); 296 + 297 + // If we're in a bare Git repository, the "--git-dir" will be the 298 + // root directory. If we're in a working copy, the "--git-dir" will 299 + // be the ".git/" directory. 300 + 301 + // Test if the result is the root directory. If it is, we're in good 302 + // shape and appear to be inside a bare repository. If not, take the 303 + // parent directory to get out of the ".git/" folder. 304 + 305 + if (!Filesystem::pathsAreEquivalent($repository_root, $path)) { 306 + $repository_root = dirname($repository_root); 307 + } 308 + } 280 309 281 310 $message = null; 282 - $path = $repository->getLocalPath(); 283 311 if ($err) { 284 312 // Try to raise a more tailored error message in the more common case 285 313 // of the user creating an empty directory. (We could try to remove it, ··· 313 341 $path); 314 342 } 315 343 } else { 316 - $repo_path = rtrim($stdout, "\n"); 344 + 345 + // Prior to Git 2.25.0, we used "--show-toplevel", which had a weird 346 + // case here when the working copy was inside another working copy. 347 + // The switch to "--git-dir" seems to have resolved this; we now seem 348 + // to find the nearest git directory and thus the correct repository 349 + // root. 317 350 318 - if (empty($repo_path)) { 319 - // This can mean one of two things: we're in a bare repository, or 320 - // we're inside a git repository inside another git repository. Since 321 - // the first is dramatically more likely now that we perform bare 322 - // clones and I don't have a great way to test for the latter, assume 323 - // we're OK. 324 - } else if (!Filesystem::pathsAreEquivalent($repo_path, $path)) { 351 + if (!Filesystem::pathsAreEquivalent($repository_root, $path)) { 325 352 $err = true; 326 353 $message = pht( 327 354 'Expected to find a Git repository at "%s", but the actual Git '. ··· 329 356 'misconfigured. This directory should be writable by the daemons '. 330 357 'and not inside another Git repository.', 331 358 $path, 332 - $repo_path); 359 + $repository_root); 333 360 } 334 361 } 335 362