Page MenuHomePhabricator

D17497.id42110.diff
No OneTemporary

D17497.id42110.diff

diff --git a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
--- a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
+++ b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
@@ -120,6 +120,7 @@
pht(
'Updating the working copy for repository "%s".',
$repository->getDisplayName()));
+
if ($is_git) {
$this->verifyGitOrigin($repository);
$this->executeGitUpdate();
@@ -157,7 +158,7 @@
}
private function skipPull($message) {
- $this->log('%s', $message);
+ $this->log($message);
$this->donePull();
}
@@ -172,7 +173,7 @@
}
private function logPull($message) {
- $this->log('%s', $message);
+ $this->log($message);
}
private function donePull() {
@@ -190,7 +191,7 @@
}
private function installHook($path, array $hook_argv = array()) {
- $this->log('%s', pht('Installing commit hook to "%s"...', $path));
+ $this->log(pht('Installing commit hook to "%s"...', $path));
$repository = $this->getRepository();
$identifier = $this->getHookContextIdentifier($repository);
@@ -339,6 +340,18 @@
throw new Exception($message);
}
+ $remote_refs = $this->loadGitRemoteRefs($repository);
+ $local_refs = $this->loadGitLocalRefs($repository);
+ if ($remote_refs === $local_refs) {
+ $this->log(
+ pht(
+ 'Skipping fetch because local and remote refs are already '.
+ 'identical.'));
+ return false;
+ }
+
+ $this->logRefDifferences($remote_refs, $local_refs);
+
$retry = false;
do {
// This is a local command, but needs credentials.
@@ -396,6 +409,75 @@
$this->installHook($root.$path);
}
+ private function loadGitRemoteRefs(PhabricatorRepository $repository) {
+ $remote_envelope = $repository->getRemoteURIEnvelope();
+
+ list($stdout) = $repository->execxRemoteCommand(
+ 'ls-remote -- %P',
+ $remote_envelope);
+
+ $map = array();
+ $lines = phutil_split_lines($stdout, false);
+ foreach ($lines as $line) {
+ list($hash, $name) = preg_split('/\s+/', $line, 2);
+
+ // If the remote has a HEAD, just ignore it.
+ if ($name == 'HEAD') {
+ continue;
+ }
+
+ // If the remote ref is itself a remote ref, ignore it.
+ if (preg_match('(^refs/remotes/)', $name)) {
+ continue;
+ }
+
+ $map[$name] = $hash;
+ }
+
+ ksort($map);
+
+ return $map;
+ }
+
+ private function loadGitLocalRefs(PhabricatorRepository $repository) {
+ $refs = id(new DiffusionLowLevelGitRefQuery())
+ ->setRepository($repository)
+ ->execute();
+
+ $map = array();
+ foreach ($refs as $ref) {
+ $fields = $ref->getRawFields();
+ $map[idx($fields, 'refname')] = $ref->getCommitIdentifier();
+ }
+
+ ksort($map);
+
+ return $map;
+ }
+
+ private function logRefDifferences(array $remote, array $local) {
+ $all = $local + $remote;
+
+ $differences = array();
+ foreach ($all as $key => $ignored) {
+ $remote_ref = idx($remote, $key, pht('<null>'));
+ $local_ref = idx($local, $key, pht('<null>'));
+ if ($remote_ref !== $local_ref) {
+ $differences[] = pht(
+ '%s (remote: "%s", local: "%s")',
+ $key,
+ $remote_ref,
+ $local_ref);
+ }
+ }
+
+ $this->log(
+ pht(
+ "Updating repository after detecting ref differences:\n%s",
+ implode("\n", $differences)));
+ }
+
+
/* -( Pulling Mercurial Working Copies )----------------------------------- */

File Metadata

Mime Type
text/plain
Expires
Wed, May 15, 1:59 PM (2 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6293950
Default Alt Text
D17497.id42110.diff (3 KB)

Event Timeline