- repository heads are not associated with the closed attribute, so
remove it making the code in line with the concept.
- Fix functions that were calling heads with the parameter.
- Adjust webcommands.branches to include the concept of inactive
as well as open and closed branches
- Fix code and docstrings in commands to make the correct use of
closed branches & branch heads clearer
- Improve grammar of 'hg heads' help text (2nd submission)
this does not alter the cli for hg branches, that work is
still to be done
This records the branches starting at individual CVS file revisions,
using the symbolic names map rather than just the branches
information. This information is used to generate Mercurial
changesets. Despite the changes, the CVS conversion still suffers
heavily from cvsps' deficiencies in generating a correct
representation of the CVS repository history.
New behavior is generally superior and more correct, except possibly
with regards to missing files. hg up . is now effectively a no-op,
which is probably the desired behavior for people expecting to move to
tip, but may surprise people who were expecting deleted files to
reappear.
case 1: update to .
a-w -> a-w
classic: ancestor a
missing recreated right?
rmed recreated WRONG
added forgotten WRONG
changed preserved RIGHT
conflicted can't happen
backward merge: ancestor a (NO EFFECT)
missing missing wrong?
rm'ed rm'ed RIGHT
added preserved RIGHT
changed preserved RIGHT
conflicted can't happen
case 2: update to ancestor of .
a-b-w -> b-w
\
a
classic: ancestor a
missing recreated right?
rmed recreated wrong?
added forgotten wrong?
changed preserved RIGHT
conflicted preserved wrong?
backwards merge: ancestor b
missing missing or conflict right?
rm'ed missing or conflict right?
changed preserved RIGHT
conflicted merge RIGHT
added preserved right?
Different platforms implement -R differently (and it produces
unneccessarily verbose output in this case). find is just as
good and more consistent. Unbreaks test on OpenBSD.
Edited by pmezard: added 'sort' call
Add a --closed (-c) option to 'hg heads' to show all heads and change the
default behavior to refrain from showing fully closed branches.
Enhance 'hg heads <branch>' so that:
* default: displays normal & inactive heads, not closed heads
* --closed: displays normal, inactive & closed heads
* --active: displays only normal heads
* both --closed and --active: displays normal & closed heads only
The heads(...) and branchheads(...) functions will now only return closed
heads when explicitly asked for them. This will cause 'hg merge' to have
better behavior in the presence of a branch that has closed heads when no
explicit rev is passed.
(Needed at least for Subversion bindings on OS X, which are in
/opt/subversion. Useful for other external libraries installed in
non-standard places too.)
- in parseargs(), check that --with-hg value is valid
- add handy --local option for "--with-hg=../hg"
- ensure that we always set PATH and PYTHONPATH (not just
when doing a temporary install)
- override any existing PYTHONPATH, so test success does not
depend on whatever happens to be in the caller's environment
- give tests a little more control by exporting $PYTHON to the
environment; needed by test-convert and test-mergetool when
they run hg with a stripped-down $PATH
Also, add a big comment explaining all the corner cases to test for the
next person who tries to modify this script.
- rename _hgpath() to _gethgpath() and move it down next to _checkhglib()
- change _gethgpath() so it caches its result: replaces global 'hgpkg'
that anyone can use with global '_hgpath' that is only for _gethgpath()
- no need to pass 'expecthg' to runchildren() or runtests() anymore
Also: do not change global PYTHON when doing coverage; this seems to
be unnecessary, since we create a dummy 'hg' script that handles
coverage for us, and it made things brittle. (E.g. the rest of this
patch makes the call to _hgpath() come later, and it was broken by
enabling coverage.)
(Extremely handy when you break parallel operation and need to figure
out what's going on. The assumption is that if you run with -v, you
want more details.)
This error trigger if one calls bundle with the wrong parameters and
it is thus not an error scripts will want to look for (they could and
should ensure that they call bundle with the correct parameters).
The fstat function was undefined, but never used since a stat object
was always passed in the optional st argument. Passing st is now
mandatory.
This bug crept in when util was split up into posix and windows
modules. The fstat function is still defined in util, but importing it
into posix would create an import cycle which seems unnecessary.
Using '-r null' instead of '-v' as the overriden command default.
The latter did not have any effect on output, thus not giving much
indication on whether the modified defaults were really in use or not.
Each named branch is considered separately, and the push is allowed if
no new branch heads are created for any named branch to be pushed.
Due to some tests's use of --debug, their output will change after this
addition. This has been fixed as well.
Co-contributor: Henrik Stuart <henrik.stuart@edlund.dk>
The repository command, 'branchmap', returns a dictionary, branchname
-> [branchheads], and will be implemented for localrepo, httprepo and
sshrepo.
The following wire format is used for returning data:
branchname1 branch1head2 branch1head2 ...
branchname2 ...
...
Branch names are URL encoded to escape white space, and branch heads
are sent as hex encoded node ids. All branches and all their heads are
sent.
The background and motivation for this command is the desire for a
richer named branch semantics when pushing changesets. The details are
explained in the original proposal which is included below.
1. BACKGROUND
The algorithm currently implemented in Mercurial only considers the
graph theoretical heads when determining whether new heads are
created, rather than using the branch heads as a count (the algorithm
considers a branch head effectively closed when it is merged into
another branch or a new named branch is started from that point
onward).
Our particular problem with the algorithm is that we'd like to see the
following case working without forcing a push:
Upsteam has:
(0:dev) ---- (1:dev)
\
`--- (2:stable)
Someone merges stable into dev:
(0:dev) ---- (1:dev) ------(3:dev)
\ /
`--- (2:stable) --------´
This can be pushed without --force (as it should).
Now someone else does some coding on stable (a bug fix, say):
(0:dev) ---- (1:dev) ------(3:dev)
\ /
`--- (2:stable) ---------´---------(4:stable)
This time we need --force to push.
We allow this to be pushed without using --force by getting all the
remote branch heads (by extending the wire protocol with a new
function).
We would, furthermore, also prefer if it is impossible to push a new
branch without --force (or a later --newbranch option so --force isn't
shoe-horned into too many disparate functions, if need be), except of
course in the case where the remote repository is empty.
This is what our patches accomplish.
2. ALTERNATIVES
We have, of course, considered some alternatives to reconstructing
enough information to decide whether we are creating new remote branch
heads, before we added the new wire protocol command.
2.1. LOOKUP ON REMOTE
The main alternative is to use the information from remote.heads() and
remote.lookup() to try to reconstruct enough graph information to
decide whether we are creating new heads. This is not adequate as
illustrated below.
Remember that each lookup is typically a request-response pair over
SSH or HTTP(S).
If we have a simple repository at the remote end like this:
(0:dev) ---- (1:dev) ---- (3:stable)
\
`--- (2:dev)
then remote.heads() will yield [2, 3]. Assume we have nodes [0, 1, 2]
locally and want to create a new node, 4:dev, as a descendant from
(1:dev), which should be OK as 1:dev is a branch head.
If we do remote.lookup('dev') we will get [2]. Thus, we can get
information about whether a branch exists on the remote server or not,
but this does not solve our problem of figuring out whether we are
creating new heads or not.
Pushing 4:dev ought to be OK, since after the push, we still only have
two heads on branch a.
Using remote.lookup() and remote.heads() is thus not adequate to
consistently decide whether we are creating new remote heads (e.g. in
this situation the latter would never return 1:dev).
2.2. USING INCOMING TO RECONSTRUCT THE GRAPH
An alternative would be to use information equivalent to hg incoming
to get the full remote graph in addition to the local graph.
To do this, we would have to get a changegroup(subset) bundle
representing the remote end (which may be a substantial amount of
data), getting the branch heads from an instantiated bundlerepository,
deleting the bundle, and finally, we can compute the prepush logic.
While this is backwards compatible, it will cause a possibly
substantial slowdown of the push command as it first needs to pull in
all changes.
3. FURTHER ARGUMENTS IN FAVOUR OF THE BRANCHMAP WIRE-PROTOCOL EXTENSION
Currently, the commands incoming and pull, work based on the tip of a
given branch if used with "-r branchname", making it hard to get all
revisions of a certain branch only (if it has multiple heads). This
can be solved by requesting the remote's branchheads and letting the
revisions to be used with the command be these heads. This can be done
by extending the commands with a new option, e.g.:
hg pull -b branchname
which will be turned into the equivalent of:
hg pull -r branchhead1 -r branchhead2 -r branchhead3
We have a simple follow-up patch that can do this ready as well
(although not submitted yet as it is pending the acceptance of the
branch patch).
4. WRAP-UP
We generally find that the branchmap wire protocol extension can
provide better named branch support to Mercurial. Currently, some
things, like the initial push scenario in this mail, are fairly
counter-intuitive, and the more often you have to force push, the more
it is likely you will get a lot of spurious and unnecessary merge
nodes. Also, restricting incoming and pull to all changes on a branch
rather than changes on the tip-most head would be a sensible extension
to making named branches a first class citizen in Mercurial.
Currently, named branches sometimes feel like a late-coming unwanted
step-child.
We have run it in a production environment for a while, with fewer
multiple heads occurring in our repositories and fewer confused users
as a result.
Also, it fixes the long-standing issue 736.
Co-contributor: Sune Foldager <cryo@cyanite.org>