diff --git a/src/applications/repository/storage/PhabricatorRepositoryURI.php b/src/applications/repository/storage/PhabricatorRepositoryURI.php --- a/src/applications/repository/storage/PhabricatorRepositoryURI.php +++ b/src/applications/repository/storage/PhabricatorRepositoryURI.php @@ -105,7 +105,7 @@ public function getEffectiveDisplayType() { $display = $this->getDisplayType(); - if ($display != self::IO_DEFAULT) { + if ($display != self::DISPLAY_DEFAULT) { return $display; } @@ -116,47 +116,40 @@ switch ($this->getEffectiveIOType()) { case self::IO_MIRROR: case self::IO_OBSERVE: - return self::DISPLAY_NEVER; case self::IO_NONE: - if ($this->isBuiltin()) { - return self::DISPLAY_NEVER; - } else { - return self::DISPLAY_ALWAYS; - } + return self::DISPLAY_NEVER; case self::IO_READ: case self::IO_READWRITE: // By default, only show the "best" version of the builtin URI, not the // other redundant versions. - if ($this->isBuiltin()) { - $repository = $this->getRepository(); - $other_uris = $repository->getURIs(); - - $identifier_value = array( - self::BUILTIN_IDENTIFIER_CALLSIGN => 3, - self::BUILTIN_IDENTIFIER_SHORTNAME => 2, - self::BUILTIN_IDENTIFIER_ID => 1, - ); - - $have_identifiers = array(); - foreach ($other_uris as $other_uri) { - if ($other_uri->getIsDisabled()) { - continue; - } - - $identifier = $other_uri->getBuiltinIdentifier(); - if (!$identifier) { - continue; - } - - $have_identifiers[$identifier] = $identifier_value[$identifier]; + $repository = $this->getRepository(); + $other_uris = $repository->getURIs(); + + $identifier_value = array( + self::BUILTIN_IDENTIFIER_CALLSIGN => 3, + self::BUILTIN_IDENTIFIER_SHORTNAME => 2, + self::BUILTIN_IDENTIFIER_ID => 1, + ); + + $have_identifiers = array(); + foreach ($other_uris as $other_uri) { + if ($other_uri->getIsDisabled()) { + continue; } - $best_identifier = max($have_identifiers); - $this_identifier = $identifier_value[$this->getBuiltinIdentifier()]; - - if ($this_identifier < $best_identifier) { - return self::DISPLAY_NEVER; + $identifier = $other_uri->getBuiltinIdentifier(); + if (!$identifier) { + continue; } + + $have_identifiers[$identifier] = $identifier_value[$identifier]; + } + + $best_identifier = max($have_identifiers); + $this_identifier = $identifier_value[$this->getBuiltinIdentifier()]; + + if ($this_identifier < $best_identifier) { + return self::DISPLAY_NEVER; } return self::DISPLAY_ALWAYS; diff --git a/src/docs/user/userguide/diffusion_uris.diviner b/src/docs/user/userguide/diffusion_uris.diviner --- a/src/docs/user/userguide/diffusion_uris.diviner +++ b/src/docs/user/userguide/diffusion_uris.diviner @@ -9,8 +9,8 @@ WARNING: This document describes a feature which is still under development, and is not necessarily accurate or complete. -Phabricator can host, observe, mirror, and proxy repositories. For example, -here are some supported use cases: +Phabricator can create, host, observe, mirror, proxy, and import repositories. +For example, you can: **Host Repositories**: Phabricator can host repositories locally. Phabricator maintains the writable master version of the repository, and you can push and @@ -45,3 +45,231 @@ and so on. By configuring all the URIs that a repository should interact with and expose to users, you configure the read, write, and mirroring behavior of the repository. + +The remainder of this document walks through this configuration in greater +detail. + + +Host a Repository +================= + +You can create new repositories that Phabricator will host, like you would +create repositories on services like GitHub or Bitbucket. Phabricator will +serve a read-write copy of the repository and you can clone it from Phabricator +and push changes to Phabricator. + +If you haven't already, you may need to configure Phabricator for hosting +before you can create your first hosted repository. For a detailed guide, +see @{article:Diffusion User Guide: Repository Hosting}. + +This is the default mode for new repositories. To host a repository: + + - Create a new repository. + - Activate it. + +Phabricator will create an empty repository and allow you to fetch from it and +push to it. + + +Observe a Repository +==================== + +If you have an existing repository hosted on another service (like GitHub, +Bitbucket, or a private server) that you want to work with in Phabricator, +you can configure Phabricator to observe it. + +When observing a repository, Phabricator will keep track of changes in the +remote repository and allow you to browse and interact with the repository from +the web UI in Diffusion and other applications, but you can continue hosting it +elsewhere. + +To observe a repository: + + - Create a new repository, but don't activate it yet. + - Add the remote URI you want to observe as a repository URI. + - Set the **I/O Type** for the URI to **Observe**. + - If necessary, configure a credential. + - Activate the repository. + +Phabricator will perform an initial import of the repository, creating a local +read-only copy. Once this process completes, it will continue keeping track of +changes in the remote, fetching them, and reflecting them in the UI. + + +Mirror a Repository +=================== + +NOTE: Mirroring is not supported in Subversion. + +You can create a read-only mirror of an existing repository. Phabricator will +push all changes made to the repository to the mirror. + +For example, if you have a repository hosted in Phabricator that you want to +mirror to GitHub, you can configure Phabricator to automatically maintain the +mirror. This is how the upstream repositories are set up. + +You can mirror any repository, even if Phabricator is only observing it and not +hosting it directly. + +To begin mirroring a repository: + + - Create a hosted or observed repository by following the relevant + instructions above. + - Add the remote URI you want to mirror to as a repository URI. + - Set the **I/O Type** for the URI to **Mirror**. + - If necessary, configure a credential. + +To stop mirroring: + + - Disable the mirror URI; or + - Change the **I/O Type** for the URI to **None**. + + +Import a Repository +=================== + +If you have an existing repository that you want to move so it is hosted on +Phabricator, there are three ways to do it: + +**Push Everything**: //(Git, Mercurial)// Create a new empty hosted repository +according to the instructions above. Once the empty repository initializes, +push your entire existing repository to it. + +**Observe First**: //(Git, Mercurial)// Observe the existing repository first, +according to the instructions above. Once Phabricator's copy of the repository +is fully synchronized, change the **I/O Type** for the **Observe** URI to +**None** to stop fetching changes from the remote. + +By default, this will automatically make Phabricator's copy of the repository +writable, and you can begin pushing to it. If you've adjusted URI +configuration away from the defaults, you may need to set at least one URI +to **Read/Write** mode so you can push to it. + +**Copy on Disk**: //(Git, Mercurial, Subversion)// Create a new empty hosted +repository according to the instructions above, but do not activate it yet. + +Using the **Storage** tab, find the location of the repository's working copy +on disk, and place a working copy of the repository you wish to import there. + +For Git and Mercurial, use a bare working copy for best results. + +This is the only way to import a Subversion repository because only the master +copy of the repository has history. + +Once you've put a working copy in the right place on disk, activate the +repository. + + +Customizing Displayed Clone URIs +================================ + +If you have an unusual configuration and want the UI to offers users specific +clone URIs other than the URIs that Phabricator serves or interacts with, you +can add those URIs with the **I/O Type** set to **None** and then set their +**Display Type** to **Always**. + +Likewise, you can set the **Display Type** of any URIs you do //not// want +to be visible to **Never**. + +This allows you to precisely configure which clone URIs are shown to users for +a repository. + + +Reference: I/O Types +==================== + +This section details the available **I/O Type** options for URIs. + +Each repository has some **builtin** URIs. These are URIs hosted by Phabricator +itself. The modes available for each URI depend primarily on whether it is a +builtin URI or not. + +**Default**: This setting has Phabricator guess the correct option for the +URI. + +For **builtin** URIs, the default behavior is //Read/Write// if the repository +is hosted, and //Read-Only// if the repository is observed. + +For custom URIs, the default type is //None// because we can not automatically +guess if you want to ignore, observe, or mirror a URI and //None// is the +safest default. + +**Observe**: Phabricator will observe this repository and regularly fetch any +changes made to it to a local read-only copy. + +You can not observe builtin URIs because reading a repository from itself +does not make sense. + +You can not add a URI in Observe mode if an existing builtin URI is in +//Read/Write// mode, because this would mean the repository had two different +authorities: the observed remote copy and the hosted local copy. Take the +other URI out of //Read/Write// mode first. + +**Mirror**: Phabricator will push any changes made to this repository to the +remote URI, keeping a read-only mirror hosted at that URI up to date. + +This works for both observed and hosted repositories. + +This option is not available for builtin URIs because it does not make sense +to mirror a repository to itself. + +It is possible to mirror a repository to another repository that is also +hosted by Phabricator by adding that other repository's URI, although this is +silly and probably very rarely of any use. + +**None**: Phabricator will not fetch changes from or push changes to this URI. +For builtin URIs, it will not let users fetch changes from or push changes to +this URI. + +You can use this mode to turn off an Observe URI after an import, stop a Mirror +URI from updating, or to add URIs that you're only using to customize which +clone URIs are displayed to the user but don't want Phabricator to interact +with directly. + +**Read Only**: Phabricator will serve the repository from this URI in read-only +mode. Users will be able to fetch from it but will not be able to push to it. + +Because Phabricator must be able to serve the repository from URIs configured +in this mode, this option is only available for builtin URIs. + +**Read/Write**: Phabricator will serve the repository from this URI in +read/write mode. Users will be able to fetch from it and push to it. + +URIs can not be set into this mode if another URI is set to //Observe// mode, +because that would mean the repository had two different authorities: the +observed remote copy and the hosted local copy. Take the other URI out of +//Observe// mode first. + +Because Phabricator must be able to serve the repository from URIs configured +in this mode, this option is only available for builtin URIs. + + +Reference: Display Types +======================== + +This section details the available **Display Type** options for URIs. + +**Default**: Phabricator will guess the correct option for the URI. It +guesses based on the configured **I/O Type** and whether the URI is +**builtin** or not. + +For //Observe//, //Mirror// and //None// URIs, the default is //Never//. + +For builtin URIs in //Read Only// or //Read/Write// mode, the most +human-readable URI defaults to //Always// and the others default to //Never//. + +**Always**: This URI will be shown to users as a clone/checkout URI. You can +add URIs in this mode to cutomize exactly what users are shown. + +**Never**: This URI will not be shown to users. You can hide less-preferred +URIs to guide users to the URIs they should be using to interact with the +repository. + + +Next Steps +========== + +Continue by: + + - configuring Phabricator to host repositories with + @{article:Diffusion User Guide: Repository Hosting}.