@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.

In Git repositories, use "git symbolic-ref HEAD ..." to select the default branch

Summary:
Depends on D20434. Fixes T5963. Broadly, the issue here is that when:

- You create a new, empty repository.
- Then, you work on some branch other than `master`, without ever creating `master`.

...you get a warning on `git clone`:

> warning: remote HEAD refers to nonexistent ref, unable to checkout

To fix this, point the symbolic-ref HEAD at `refs/heads/<default-branch>` after installing commit hooks.

This fixes the warning, and also means that `git clone` will check out the repository default branch by default, which is nice.

There are a few caveats about this behavior (see T5963 for discussion) but nothing too substantial.

The only real issue is that Git prevents deletion of the default branch without a config setting. Just set that settting.

Test Plan:
See T5963.

In a repository, set `HEAD` to point somewhere invalid. Ran `bin/repository update ...`. Saw HEAD pointed back at the repository default branch.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T5963

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

+41
+41
src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
··· 142 142 } 143 143 } 144 144 145 + if ($is_git) { 146 + $this->updateGitWorkingCopyConfiguration(); 147 + } 148 + 145 149 } catch (Exception $ex) { 146 150 $this->abortPull( 147 151 pht( ··· 418 422 } 419 423 420 424 $this->installHook($root.$path); 425 + } 426 + 427 + private function updateGitWorkingCopyConfiguration() { 428 + $repository = $this->getRepository(); 429 + 430 + // See T5963. When you "git clone" from a remote with no "master", the 431 + // client warns you that it isn't sure what it should check out as an 432 + // initial state: 433 + 434 + // warning: remote HEAD refers to nonexistent ref, unable to checkout 435 + 436 + // We can tell the client what it should check out by making "HEAD" 437 + // point somewhere. However: 438 + // 439 + // (1) If we don't set "receive.denyDelteCurrent" to "ignore" and a user 440 + // tries to delete the default branch, Git raises an error and refuses. 441 + // We want to allow this; we already have sufficient protections around 442 + // dangerous changes and do not need to special case the default branch. 443 + // 444 + // (2) A repository may have a nonexistent default branch configured. 445 + // For now, we just respect configuration. This will raise a warning when 446 + // users clone the repository. 447 + // 448 + // In any case, these changes are both advisory, so ignore any errors we 449 + // may encounter. 450 + 451 + // We do this for both hosted and observed repositories. Although it is 452 + // not terribly common to clone from Phabricator's copy of an observed 453 + // repository, it works fine and makes sense occasionally. 454 + 455 + if ($repository->isWorkingCopyBare()) { 456 + $repository->execLocalCommand( 457 + 'config -- receive.denyDeleteCurrent ignore'); 458 + $repository->execLocalCommand( 459 + 'symbolic-ref HEAD %s', 460 + 'refs/heads/'.$repository->getDefaultBranch()); 461 + } 421 462 } 422 463 423 464 private function loadGitRemoteRefs(