mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
0a050806aa
Preparation for merge. Let's move everything (except for .hgtags) inside to avoid merge conflicts.
346 lines
13 KiB
ReStructuredText
346 lines
13 KiB
ReStructuredText
.. -*-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!
|