Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15416869
D20892.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Referenced Files
None
Subscribers
None
D20892.id.diff
View Options
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
@@ -353,13 +353,56 @@
// Load the refs we're planning to fetch from the remote repository.
$remote_refs = $this->loadGitRemoteRefs(
$repository,
- $repository->getRemoteURIEnvelope());
+ $repository->getRemoteURIEnvelope(),
+ $is_local = false);
// Load the refs we're planning to fetch from the local repository, by
// using the local working copy path as the "remote" repository URI.
$local_refs = $this->loadGitRemoteRefs(
$repository,
- new PhutilOpaqueEnvelope($path));
+ new PhutilOpaqueEnvelope($path),
+ $is_local = true);
+
+ // See T13448. The "git fetch --prune ..." flag only prunes local refs
+ // matching the refspecs we pass it. If "Fetch Refs" is configured, we'll
+ // pass it a very narrow list of refspecs, and it won't prune older refs
+ // that aren't currently subject to fetching.
+
+ // Since we want to prune everything that isn't (a) on the fetch list and
+ // (b) in the remote, handle pruning of any surplus leftover refs ourselves
+ // before we fetch anything.
+
+ // (We don't have to do this if "Fetch Refs" isn't set up, since "--prune"
+ // will work in that case, but it's a little simpler to always go down the
+ // same code path.)
+
+ $surplus_refs = array();
+ foreach ($local_refs as $local_ref => $local_hash) {
+ $remote_hash = idx($remote_refs, $local_ref);
+ if ($remote_hash === null) {
+ $surplus_refs[] = $local_ref;
+ }
+ }
+
+ if ($surplus_refs) {
+ $this->log(
+ pht(
+ 'Found %s surplus local ref(s) to delete.',
+ phutil_count($surplus_refs)));
+ foreach ($surplus_refs as $surplus_ref) {
+ $this->log(
+ pht(
+ 'Deleting surplus local ref "%s" ("%s").',
+ $surplus_ref,
+ $local_refs[$surplus_ref]));
+
+ $repository->execLocalCommand(
+ 'update-ref -d %R --',
+ $surplus_ref);
+
+ unset($local_refs[$surplus_ref]);
+ }
+ }
if ($remote_refs === $local_refs) {
$this->log(
@@ -378,7 +421,7 @@
// checked out. See T13280.
$future = $repository->getRemoteCommandFuture(
- 'fetch --prune --update-head-ok -- %P %Ls',
+ 'fetch --update-head-ok -- %P %Ls',
$repository->getRemoteURIEnvelope(),
$fetch_rules);
@@ -474,21 +517,32 @@
private function loadGitRemoteRefs(
PhabricatorRepository $repository,
- PhutilOpaqueEnvelope $remote_envelope) {
+ PhutilOpaqueEnvelope $remote_envelope,
+ $is_local) {
- $ref_rules = $this->getGitRefRules($repository);
+ // See T13448. When listing local remotes, we want to list everything,
+ // not just refs we expect to fetch. This allows us to detect that we have
+ // undesirable refs (which have been deleted in the remote, but are still
+ // present locally) so we can update our state to reflect the correct
+ // remote state.
- // NOTE: "git ls-remote" does not support "--" until circa January 2016.
- // See T12416. None of the flags to "ls-remote" appear dangerous, but
- // refuse to list any refs beginning with "-" just in case.
+ if ($is_local) {
+ $ref_rules = array();
+ } else {
+ $ref_rules = $this->getGitRefRules($repository);
- foreach ($ref_rules as $ref_rule) {
- if (preg_match('/^-/', $ref_rule)) {
- throw new Exception(
- pht(
- 'Refusing to list potentially dangerous ref ("%s") beginning '.
- 'with "-".',
- $ref_rule));
+ // NOTE: "git ls-remote" does not support "--" until circa January 2016.
+ // See T12416. None of the flags to "ls-remote" appear dangerous, but
+ // refuse to list any refs beginning with "-" just in case.
+
+ foreach ($ref_rules as $ref_rule) {
+ if (preg_match('/^-/', $ref_rule)) {
+ throw new Exception(
+ pht(
+ 'Refusing to list potentially dangerous ref ("%s") beginning '.
+ 'with "-".',
+ $ref_rule));
+ }
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Mar 21, 2:08 PM (2 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7589009
Default Alt Text
D20892.id.diff (4 KB)
Attached To
Mode
D20892: Manually prune Git working copy refs instead of using "--prune", to improve "Fetch Refs" behavior
Attached
Detach File
Event Timeline
Log In to Comment