mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-20 13:52:40 +01:00
Fix various branch/ref issues with bare repositories in Git
Summary: Ref T2230. Although all the non-bare commands //run// fine in bare repos, not all of them do exactly the same thing. This could use further cleanup, but at least get it working again for now. Test Plan: Ran `bin/repository pull`, `bin/repository discover`, viewed Diffusion (looked at branch table), viewed a commit (looked at "Branches"), for bare and non-bare git repos. Reviewers: avive, btrahan, avivey Reviewed By: avivey CC: aran Maniphest Tasks: T2230 Differential Revision: https://secure.phabricator.com/D7442
This commit is contained in:
parent
cdcfbb69a0
commit
19124554d8
6 changed files with 98 additions and 22 deletions
|
@ -30,14 +30,22 @@ final class ConduitAPI_diffusion_branchquery_Method
|
|||
// We need to add 1 in case we pick up HEAD.
|
||||
$count = $offset + $limit + 1;
|
||||
|
||||
if ($repository->isWorkingCopyBare()) {
|
||||
list($stdout) = $repository->execxLocalCommand(
|
||||
'for-each-ref %C --sort=-creatordate --format=%s refs/heads',
|
||||
$count ? '--count='.(int)$count : null,
|
||||
'%(refname:short) %(objectname)');
|
||||
$branch_list = DiffusionGitBranch::parseLocalBranchOutput(
|
||||
$stdout);
|
||||
} else {
|
||||
list($stdout) = $repository->execxLocalCommand(
|
||||
'for-each-ref %C --sort=-creatordate --format=%s refs/remotes',
|
||||
$count ? '--count='.(int)$count : null,
|
||||
'%(refname:short) %(objectname)');
|
||||
|
||||
$branch_list = DiffusionGitBranch::parseRemoteBranchOutput(
|
||||
$stdout,
|
||||
$only_this_remote = DiffusionBranchInformation::DEFAULT_GIT_REMOTE);
|
||||
}
|
||||
|
||||
$branches = array();
|
||||
foreach ($branch_list as $name => $head) {
|
||||
|
|
|
@ -25,14 +25,21 @@ final class ConduitAPI_diffusion_commitbranchesquery_Method
|
|||
$repository = $drequest->getRepository();
|
||||
$commit = $request->getValue('commit');
|
||||
|
||||
if ($repository->isWorkingCopyBare()) {
|
||||
list($contains) = $repository->execxLocalCommand(
|
||||
'branch --verbose --no-abbrev --contains %s',
|
||||
$commit);
|
||||
return DiffusionGitBranch::parseLocalBranchOutput(
|
||||
$contains);
|
||||
} else {
|
||||
list($contains) = $repository->execxLocalCommand(
|
||||
'branch -r --verbose --no-abbrev --contains %s',
|
||||
$commit);
|
||||
|
||||
return DiffusionGitBranch::parseRemoteBranchOutput(
|
||||
$contains,
|
||||
DiffusionBranchInformation::DEFAULT_GIT_REMOTE);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getMercurialResult(ConduitAPIRequest $request) {
|
||||
$drequest = $this->getDiffusionRequest();
|
||||
|
|
|
@ -70,4 +70,31 @@ final class DiffusionGitBranch {
|
|||
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* As above, but with no `-r`. Used for bare repositories.
|
||||
*/
|
||||
public static function parseLocalBranchOutput($stdout) {
|
||||
$map = array();
|
||||
|
||||
$lines = array_filter(explode("\n", $stdout));
|
||||
$regex = '/^[* ]*(\(no branch\)|\S+)\s+([a-z0-9]{40})/';
|
||||
foreach ($lines as $line) {
|
||||
$matches = null;
|
||||
if (!preg_match($regex, $line, $matches)) {
|
||||
throw new Exception("Failed to parse {$line}!");
|
||||
}
|
||||
|
||||
$branch = $matches[1];
|
||||
$branch_head = $matches[2];
|
||||
if ($branch == '(no branch)') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$map[$branch] = $branch_head;
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -526,12 +526,18 @@ final class PhabricatorRepositoryPullLocalDaemon
|
|||
$repository->getRemoteURI(),
|
||||
$repository->getLocalPath());
|
||||
|
||||
if ($repository->isWorkingCopyBare()) {
|
||||
list($stdout) = $repository->execxLocalCommand(
|
||||
'branch --verbose --no-abbrev');
|
||||
$branches = DiffusionGitBranch::parseLocalBranchOutput(
|
||||
$stdout);
|
||||
} else {
|
||||
list($stdout) = $repository->execxLocalCommand(
|
||||
'branch -r --verbose --no-abbrev');
|
||||
|
||||
$branches = DiffusionGitBranch::parseRemoteBranchOutput(
|
||||
$stdout,
|
||||
$only_this_remote = DiffusionBranchInformation::DEFAULT_GIT_REMOTE);
|
||||
}
|
||||
|
||||
if (!$branches) {
|
||||
// This repository has no branches at all, so we don't need to do
|
||||
|
|
|
@ -177,7 +177,16 @@ final class PhabricatorRepositoryPullEngine
|
|||
$retry = false;
|
||||
do {
|
||||
// This is a local command, but needs credentials.
|
||||
$future = $repository->getRemoteCommandFuture('fetch --all --prune');
|
||||
if ($repository->isWorkingCopyBare()) {
|
||||
// For bare working copies, we need this magic incantation.
|
||||
$future = $repository->getRemoteCommandFuture(
|
||||
'fetch origin %s --prune',
|
||||
'+refs/heads/*:refs/heads/*');
|
||||
} else {
|
||||
$future = $repository->getRemoteCommandFuture(
|
||||
'fetch --all --prune');
|
||||
}
|
||||
|
||||
$future->setCWD($path);
|
||||
list($err, $stdout, $stderr) = $future->resolve();
|
||||
|
||||
|
|
|
@ -786,6 +786,25 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
|||
Filesystem::assertReadable($local);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the working copy is bare or not. In Git, this corresponds
|
||||
* to `--bare`. In Mercurial, `--noupdate`.
|
||||
*/
|
||||
public function isWorkingCopyBare() {
|
||||
switch ($this->getVersionControlSystem()) {
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
||||
return false;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
||||
$local = $this->getLocalPath();
|
||||
if (Filesystem::pathExists($local.'/.git')) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
|
Loading…
Reference in a new issue