mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
ab3a7cb21f
Summary: In preparation for merging fb-mercurial sources to the Eden repository, move everything from the top-level directory into an `eden/scm` subdirectory. |
||
---|---|---|
.. | ||
README |
.. -*-restructuredtext-*- =========== remotenames =========== ------------ Introduction ------------ Keep track of remote names (branches and bookmarks) in Mercurial. With this extension installed, Mercurial's behavior regarding bookmarks is changed. The core of this extension is to keep track of remote bookmarks and branches and to make a better user experience. It exposes up to three new namespaces based on the branch heads and bookmarks available in other repositories. The three namespaces are: * remotebranches: the heads of each branch on the peer repo (default: on) * remotebookmarks: the bookmarks from the peer repo (default: on) * hoistedbookmarks: a "short name" interface for hoisting a single peer's remote bookmarks into the top-level namespace, allowing workflows to stay the same when referring to bookmarks on the chosen peer (default: 'default') For example, when you pull from a repository listed in .hg/hgrc's ``[paths]`` section, you get output similar to the following:: o f3d8 @ | more trunk | o 824e | trunk | | o 2b7b feature | | feature: more new stuff | | | o a342 |/ feature: new stuff | o 52a8 (smf/default) [smf/@] |\ merge stable into default | | | o 9c95 | | chug along trunk | | o | ea15 stable (smf/stable) | | fix for stable What this output is showing is that the head of the default branch in a repo at path ``smf`` is ``52a8``. This is labeled above as ``(smf/default)``. Similarly, the bookmark ``@`` was last seen on ``smf`` at the ``52a8`` changeset. Both remote names cannot move unless you push or pull from the remote server. Remote names are discovered by sending a single extra request to the Mercurial server after a push or pull is complete. This extension works properly with paths from the schemes extension included with Mercurial. Other extensions which perform varying kinds of manipulation on the repository path may not function as expected. This extension is built on top of the Mercurial namespace API introduced in 3.3. ------------ Installation ------------ To enable the extension, you must add an entry to the ``[extensions]`` section of your ``hgrc`` file:: [extensions] remotenames = /path/to/hgremotenames/remotenames.py ---------------- Behavior Changes ---------------- Expect changes. Most features are enabled by default to give you an idea of the possibilities available with this workflow. Since this extensions keeps track of remote bookmarks, we no longer clone or pull remote bookmarks by default. Therefore, pulling from a remote server will no longer update your local bookmarks. This has the rather large beneficial side-effect of completely eliminating bookmark divergence, a complicated and difficult concept to understand, explain, and work with. The commands ``bookmarks``, ``branches``, and ``log`` all gain a ``--remote`` flag to display remote names. This will also unhide obsolete changesets if you are working with the Changeset Evolution extension. Another big behavior change is that of a bare ``hg push``. For changesets that do not create a new remote head AND are only reachable by a local bookmark, ``hg push`` will abort and not push these changesets. Hopefully, this is behavior is clear with the following example:: hg clone foo cd foo hg book feature # <hack, hack, hack> hg push pushing to foo searching for changes abort: push creates new anonymous head without the bookmark: 'feature' (use 'hg push -B feature' to create a new remote bookmark) This behavior change is intended to prevent accidentally pushing an unnamed ('anonymous') head to a remote repository. To enforce this style of workflow, read about the ``forceto`` configuration option below. ------------------- Cloning and Pulling ------------------- As mentioned above under the ``Behavior Changes`` section, pulls by default will not sync normal bookmarks between the two repositories. This is also the case with cloning. In effect, bookmarks in the ``remotenames`` world are no longer a shared namespace among peers; rather, they are distinct namespaces that need to be manually and explicitly synchronized among peers during pull operations. During push operations, the manual synchronization can be achieved with the ``--to`` option described in the previous section. To re-enable the bookmark synchronizing behavior on ``clone`` and ``pull``, set the ``syncbookmarks`` configuration option:: [remotenames] syncbookmarks = True ------- Pushing ------- When pushing changes to another repository, ``remotenames`` introduces a new flag, ``--to`` (``-t``) which drastically changes the behavior of ``push`` to be more friendly in a ``remotenames`` world. The ``--to`` flag requires the name of the remote bookmark to push (without any ``remote/`` prefix). For more on ``hg push`` behaviour, see the Tracking section. When ``--to`` is specified, the default push rev (``-r``) will be ``.``. Another rev may be specified, but only one rev may be specified or the push will abort. The specified rev, and it's ancestors, will be pushed to the remote repository, and the remote repository will have the named bookmark updated to point to this revision, subject to the following constraints (unless ``--force``/``-f`` is specified): * The remote bookmark must already exist (it will be created with ``-f``) * The remote bookmark rev must exist in the local repo (subset of the below) * The pushed rev must be a descendant of the current remote bookmark * A special case of the above: the remote bookmark already points at rev Using ``--to`` also disables other flags to avoid confusion. ``hg push --to`` will abort if any of the following flags are specified: * ``--bookmark`` / ``-B`` * ``--branch`` / ``-b`` * ``--delete`` / ``-d`` There is a new config option to enforce using ``--to`` if that is appropriate in your chosen workflow. To enable it, set the option ``forceto``:: [remotenames] forceto = True In this mode, to push revs to a peer, you must specify a name with the ``--to`` flag. You can still delete a remote bookmark in this mode with the added ``--delete`` flag to push as well. Finally, there is another new flag for push, ``--delete``, which allows remote bookmark to be deleted without deleting any local bookmark or pushing any revs. --------- Templates --------- Remotenames adds up to four new template keywords: ``remotebranches``, ``remotebookmarks``, ``remotenames`` (a combination of the first two), and ``hoistedbookmarks``, which are up to one peer's remote bookmarks, lifted into the main namespace (eg, not requiring a pathname prefix). For example, the diagram in the introduction above uses the template ``({remotebranches}) [{remotebookmarks}]``. Alternatively, you could use ``remotenames`` to include both namespaces. If you set the configurable option ``suppressbranches``:: [remotenames] suppressbranches = True Then ``remotenames`` will only display the branch name if there is no bookmark present on the same node. --------------------------- Aliasing and Renaming Paths --------------------------- For the example in the Introduction, the name ``smf`` is used instead of ``default`` because the .hg/hgrc is as follows:: [paths] default = http://smf.io/hgremotenames smf = http://smf.io/hgremotenames Since those two paths are equal, the non-default name is chosen. This effect can also be achieved by using the 'rename' configuration option: [remotenames] rename.default = smf Mercurial has several overloaded terms, including ther word ``default`` which can refer to the implicit named branch or the clone source path. Since remotenames uses the peer's path name, it is common to see remotenames prefixed with ``default/``. This can be confusing since branches also often have that name. Therefore, remotenames allows you to rename a path to something else. One common choice is to rename ``default`` to ``remote``. Thsi would result in remote names from this repository showing up as ``remote/bookmark`` instead of ``default/bookmark``. Push and pull to this name will also work. Finally, there is an ``alias.default`` setting: [remotenames] alias.default = True Setting this will drop the remotebranch name ``smf/default`` into just ``smf``. It is another way to reduce the nubmer of times that ``default`` shows up in the UI. ------------------ Transition Helpers ------------------ Using remotenames can be a big departure from previous workflows, so in addition to renaming and aliasing, the remotenames extension offers a few other options to make migrating to a remotenames easier. First is the ``transitionbookmarks`` configuration option: [remotenames] transitionbookmarks = @ foo With this setting, remotenames will delete the local bookmarks ``@`` and ``foo`` the first time the extension is run (and pulls the remotenames from a peer). In order to prevent these bookmarks from being re-created and causing confusion, you can set the ``disllowedbookmarks`` config: [remotenames] disallowedbookmarks = @ foo At which point mercurial's ``bookmarks`` command will refuse to create new bookmarks with these names. ------- Revsets ------- Remotenames makes the following new revsets available: ``pushed()``, ``upstream()``, ``remotebranches()``, ``remotebookmarks()`` and ``remotenames()``. The ``pushed()`` revset returns all revisions that are have been pushed to any repository tracked by remotenames. The ``upstream()`` set is those revisions which are in a repository whose path is listed in the ``upstream`` field of the ``[remotenames]`` configuration section. If there is no ``remotenames.upstream`` setting, it defaults to behaving identically to ``pushed()``. The ``remotenames()`` revset simply returns all remote branches head changesets. -------- Tracking -------- Remotenames introduces a new concept to bookmarks called ``tracking``. Its use it entirely optional. In order to start using it, pass the --track (-t) flag to the bookmarks command: hg bookmarks mybook --track remote/@ Tracking sets up several default behaviors: * When pushing, if the current bookmark tracks a remote bookmark, the push destination will default to the tracked path and bookmark. For example, if the ``mybook`` local bookmark is current and is tracking ``remote/@``, then calling ``hg push`` with be equivalent to calling ``hg push remote -r mybook --to @``. This gives a default peer and default name to push to. We hope this will optimize many workflows. * When rebasing (if the rebase extension is enabled), ``hg rebase`` with no arguments changes behavior as well. When the current bookmark is tracking another name, ``hg rebase`` will default to rebasing on top of the tracked name. For example, if ``mybook`` is the current bookmark, ``hg rebase`` with no arguments will be the equivalent of: ``hg rebase -b mybook -d remote/@``. Note that in this usage, the tracked name does not have to be a remote bookmark: bookmarks can track other local bookmarks, and rebase will use that as a default rebase destination. * When pulling with the ``--rebase`` flag from an active bookmark that's tracking a remote bookmark, local changes are rebased on that remote bookmark. * Finally, tracking allows a distance calculation, so you know how far ahead and behind a given bookmark is from the name it is tracking. In the diagram in the Introduction above, for example, the ``feature`` bookmark is 2 behind and 2 ahead of the @ bookmark. Distance is covered in more detail in the next section. To see a listing of what a bookmark is tracking, use ``hg bookmarks -v``. -------- Distance -------- For actions that create commits or update to another changeset (``commit``, ``rebase``, ``histedit``, ``update``, etc.), the distance to the default path is written in .hg/remotedistance. The format of this file is ``'SIGN NUMBER'``, e.g. ``'+ 10'`` or ``'- 7'``. This is handy for use in your shell prompt. For example, the following is in my bash prompt:: remote="$(less $repo_dir/.hg/remotedistance 2>/dev/null)" sign="⇡" [[ ${remote:0:1} == "-" ]] && sign="⇣" distance="$(echo $remote | cut -d ' ' -f2)" remote="" [[ "$distance" != "" && "$distance" != "0" ]] && remote=" $distance$sign" This tells me how many commits I'm ahead or behind in my prompt. By default, the distance is caclulated after each write operation and cached for quick lookup. However, in repositories with high commit rates, the distance calculation can take a long time, so you can disable it using the following configuration bits: [remotenames] cachedistance = False It is also possible to disable all distance calculation (even those in tracked bookmarks) with the ``calculatedistance`` knob: [remotenames] calculatedistance = False -------- Feedback -------- The authors appreciate feedback and would be glad to hear from you. Please ask questions or provide feedback on the Mercurial mailing lists. We actively follow these lists and are excited to have people try this extension and let us know what they think. Thank you for trying out remotenames!