If the selected formatter is other than plainformatter, raw data are passed
to the formatter. In this case, it isn't necessary (and not possible) to
calculate column widths.
Field names are substituted to be the same as "log" command.
There are a few limitations:
- "binary file" message is not included in formatted output.
- no data structure for multiple files. all lines are packed to single list.
This prepares for porting to generic templater API, where raw data should
be passed to the formatter.
makefunc() is necessary to build closure in list comprehension.
This prepares for porting to generic templater API.
Note that we cannot use '%*s' to pad white spaces because it doesn't take
into account character widths, as described in b021170a2284.
This wraps all the locations of dirstate.setparent with the appropriate
begin/endparentchange calls. This will prevent exceptions during those calls
from causing incoherent dirstates (issue4353).
Functions like getbundle and classes like unbundle10 really manipulate
changegroups and not bundles. A HG10 bundle is the same as a changegroup
plus a small header, but this is no longer the case for a HG2X bundle,
so it's better to separate the names a bit.
The hgrc for user config is typically different from the hgrc at the
system-wide or repository level. This patch provides different sample
hgrcs for each level. Sometimes when copying repos around, the copy or
the original don't have a default path yet, so at least for `hg config
-l`, this ought to provide a more reasonable default and suggestions
of what typically goes there.
The actual sample configs go in the config.py file, to minimise
clutter. In order to avoid an unnecessary import, the corresponding
import for this dictionary is at the file level.
Before this patch, "hg import" allows combination of "--exact" and
"--edit", even though editing commit message breaks exact-ness.
This patch disallows meaningless combination of "--exact" and "--edit".
We add a ``--record-parents`` flag to debugobsolete. This can be used to record
parent information in the marker when the precursors are known locally. This
will be useful to test the "relevant markers" computation.
"editform" argument for "getcommiteditor" is decided according to the
format below:
COMMAND[.ROUTE]
- COMMAND: name of command
- ROUTE: name of route, if there are two or more routes in COMMAND
This patch uses "normal.normal" and "normal.merge" as ROUTE of
"editform" instead of "normal", to distinguish merge commits from
others in "hg commit" without "--amend" case.
This patch assumes "editform" variations for "hg commit" below:
commit.normal.normal
commit.normal.merge
commit.amend.normal
commit.amend.merge
"mergeeditform" is factored out for subsequent patches. It takes
"ctxorbool" argument, because context object can't be passed in some
cases.
We are about to add more arguments to this function (date, parents, etc).
Passing metadata as a keyword argument gives us more flexibility when adding
them.
In all the remaining cases the comprehension variable is used for the same
thing as a previous loop variable.
This will mute some pyflakes "list comprehension redefines" warnings.
We now pass a transaction option to this phase movement function. The
object is currently not used by the function, but it will be in the
future.
All call sites have been updated. Most call sites were already enclosed in a
transaction for a long time. The handful of others have been recently
updated in previous commit.
We now pass a transaction option to this phase movement function. The object
is currently not used by the function, but it will be in the future.
All call sites have been updated. Most call sites were already enclosed in a
transaction for a long time. The handful of others have been recently
updated in previous commit.
The retractboundary function remains to be upgraded.
This patch passes 'editform' argument according to the format below:
COMMAND[.ROUTE]
- ROUTE: name of route, if there are two or more routes in COMMAND
In this patch, 'normal' and 'amend' are used as ROUTE.
This patch passes 'editform' argument according to the format below:
COMMAND[.ROUTE]
- ROUTE: name of route, if there are two or more routes in COMMAND
In this patch, 'add' and 'remove' are used as ROUTE
This patch passes 'editform' argument according to the format below:
COMMAND[.ROUTE]
- ROUTE: name of route, if there are two or more routes in COMMAND
In this patch, ROUTE is omitted.
This patch passes 'editform' argument according to the format below:
COMMAND[.ROUTE]
- ROUTE: name of route, if there are two or more routes in COMMAND
In this patch, ROUTE is omitted..
Since --force determines the list of revisions to be grafted, it doesn't really
make sense for users to have to keep typing --force --continue as they continue
grafting.
If stdout is piped, status message won't be flushed until client connects to
the server and access log is written to stdout. It seems bad idea to queue
start-up banner of server process.
Since decorators are evaluated at module load time and since the
@command decorator imports commands, the norepo variable (along with
its friends) may not be declared yet. These variables are now declared
before @command usage to ensure they are present.
This will make resolve use correct locking and thus make it more safe.
Resolve is usually a long running command spending a lot of time waiting for
user input on hard problems. It is thus a real world scenario to start multiple
resolves at once or run other commands (such as up -C and merge) while resolve
is running. Proper locking prevents that.
Revset calls use to return a list. Graft use to mutate that list. We cannot do
this anymore leading to a crash when grafting multiple changeset with a revset.
File ".../mercurial/commands.py", line 3117, in graft
revs.remove(rev)
AttributeError: '_addset' object has no attribute 'remove'
We are late in code-freeze so we make the shortest possible fix by turning it
back to a list.
Now that revsets work in a lazy way, log code can be changed to parse every
option into a revset and then evaluate it lazily.
Now expressions like
"hg log -b default -b ."
are converted into a revset using the same code as graphlog.
If two revisions are linearly related, there will only be one ancestor, and
commonancestors and commonancestorsheads would give the same result.
commonancestorsheads is however slightly simpler, faster and more correct.
This patch changes the calling signature of memfilectx's __init__ to fall in
line with the other file contexts.
Calling code and tests have been updated accordingly.
The `hg import` command gains a `--partial` flag. When specified, a commit will
always be created from a patch import. Any hunk that fails to apply will
create .rej file, same as what `hg qimport` would do. This change is mainly
aimed at preserving changeset metadata when applying a patch, something very
important for reviewers.
In case of failure with `--partial`, `hg import` returns 1 and the following
message is displayed:
patch applied partially
(fix the .rej files and run `hg commit --amend`)
When multiple patches are imported, we stop at the first one with failed hunks.
In the future, someone may feel brave enough to tackle a --continue flag to
import.
This broke some internal automation that was quite reasonably checking for
unresolved files as a way to determine whether a merge happened cleanly. We
still abort for resolve --mark etc.
The previous documentation pointed to the export command, but even if the user
recognized that instead of only reading the cat specific list of rules, not all
of the export rules applied anyway (specifically %N, %n and %m). The new items
are a copy/paste from export's list. These rules have existed since at least
version 0.5.
Note that %m gets substituted with 'None' because the commit message isn't
passed to cmdutil.makefilename(). %R and %r are currently effectively the same,
since no revwidth is passed, however they both work.
There aren't any existing tests for these rules, so they are added to prevent
future regression.
This patch introduces "outgoinghooks" to avoid redundant outgoing
check for "hg outgoing" in other than "commands.outgoing" (or utility
functions used by it).
This patch makes "_outgoing()" return peer object for remote
repository, to avoid re-execution "expandpath()", "parseurl()", and
"peer()" on caller side for specified URL.
This patch makes "_outgoing()" return empty list instead of "None", if
there are no outgoing changesets, because:
- returning "None" requires callers to examine whether returned
value is "None" or not explicitly, if callers want to execute loop
on returned value, but
- there are no explicit needs to return "None"
This patch introduces "summaryremotehooks" to avoid redundant
incoming/outgoing check for "hg summary" in other than
"commands.summary".
Only if "--remote" is not specified for "hg summary", hooks registered
in "summaryremotehooks" are invoked with "None" as "changes" argument
at first, and they should return tuple of two booleans meaning
"whether incomings are needed" and "whether outgoings are needed".
If no hooks return tuple containing "True", "hg summary" does nothing
any more, because incoming/outgoing check is not needed.
Otherwise, hooks are invoked again: at this time, "changes" argument
refers the result of incoming/outgoing check.
This patch also prevents RepoError from being raised if "--remote" is
not specified for "hg summary", because of backward compatibility for
"hg summary --large" without "--remote".
This patch separates checking incoming/outgoing and showing remote
summary, as a preparation for refactoring in succeeding patches,
because:
- checking incoming/outgoing may be needed, even if "--remote" is
not specified for "hg summary"
- checking incoming/outgoing may not be needed simultaneously
"hg summary --large" without "--remote" is typical case for these.
The cat command with an explicit path into a subrepo is now handled by invoking
cat on the file, from that subrepo. The previous behavior was to complain that
the file didn't exist in the revision (of the top most repo). Now when the file
is actually missing, the revision of the subrepo is named instead (though it is
probably desirable to continue naming the top level repo).
The documented output formatters %d and %p reflect the path from the top level
repo, since the purpose of this is to give the illusion of a unified repository.
Support for the undocumented (for cat) formatters %H, %R, %h, %m and %r was
added long ago (I tested back as far as 0.5), but unfortunately these will
reflect the subrepo node instead of the parent context.
The previous implementation was a bit loose with the return value, i.e. it would
return 0 if _any_ file requested was cat'd successfully. This maintains that
behavior.
1fc59036a99b introduces "--edit" option into "hg commit", but it
doesn't work for "hg commit --amend", because 1fc59036a99b prepares
for editor invocation only around "commitfunc()" internal function,
which is used only for temporary amend commit by "cmdutil.amend()".
Actual commit message editing is executed in "cmdutil.amend()".
This patch invokes editor forcibly when "--edit" option is specified
for "hg commit --amend", even if commit message is specified
explicitly by "--message" or "--logfile".
This patch also removes useless handling for commit message and editor
invocation around "commitfunc()" internal function.
"--force-editor" option for "hg commit" has been useless since
074e6345f65e, which makes "commands.tag()" invoke "cmdutil.commit()"
directly instead of "commands.commit()" with "--force-editor" internal
option.
This patch abolishes useless "--force-editor" internal option for "hg
commit".
The --edit/-e option for the 'commit' command forces editor, even when a
commit message has been provided already by other means, such as by the -m or
-l options.
This is a gratuitous code move aimed at reducing the localrepo bloatness.
The method had few callers, not enough to be kept in local repo.
The peer API remains unchanged.
Before this patch, "contrib/check-code.py" can't detect these
problems, because the regexp pattern to detect "% inside _()" doesn't
suppose the case that the format string and "%" aren't placed in the
same line.
This patch replaces "\s" in that regexp pattern with "[ \t\n]" to
detect "% inside _()" problems in such case.
"[\s\n]" can't be used in this purpose, because "\s" is automatically
replaced with "[ \t]" by "_preparepats()" and "\s" in "[]" causes
nested "[]" unexpectedly.
If backout generated no changes to commit, it showed wrong status, "changeset
<target> backs out changeset <target>", and raised TypeError with -v option.
This changes the return code to 1, which is the same as "hg commit" and
"hg rebase".
Before this patch, `hg commit --secret` was not getting propagated
correctly, and subrepos were not getting the commit in the secret
phase. The problem is that subrepos get their ui from the base repo's
baseui object and ignore the ui object passed on to them. This sets
and restores both ui objects with the appropriate option.
Before this patch, manually edited commit message for "hg tag -e"
isn't saved into ".hg/last-message.txt" until it is saved by
"localrepository.savecommitmessage()" in "localrepository.commit()".
This may lose such commit message, if unexpected exception is raised.
This patch saves manually edited commit message for "hg tag -e" into
".hg/last-message.txt" just after user editing. This patch doesn't
save the message specified by -m option (-l is not supported for "hg
tag") as same as other commands.
This is the simplest implementation to fix on stable. Editing and
saving commit message should be centralized into the framework of
"localrepository.commit()" with "editor" argument in the future.
Before this patch, "hg commit --amend --secret" doesn't create new
amend changeset as secret, even though the internal function
"commitfunc()" passed to "cmdutil.amend()" make "phases.new-commit"
configuration as "secret" temporarily.
"cmdutil.amend()" uses specified "commitfunc" only for temporary amend
commit, and creates the final amend commit changeset by
"localrepository.commitctx()" directly with memctx.
This patch creates new amend changeset as secret correctly for
"--secret" option, by changing "phases.new-commit" configuration
temporarily before "localrepository.commitctx()".
We can use the "other" data from the recorded merge state instead of inferring
what the other could be from working copy parent. This will allow resolve to
fulfil its duty even when the second parent have been dropped.
Most direct benefit is fixing a regression in backout.
When pulling changes from a compressed bundle Mercurial first uncompresses it
to a temporary file in .hg directory. This file will not be deleted unless
the bundlerepo (other) is explicitly closed.
This is similar to cleanup that occurs after incoming.
Before this patch, internal function "display()" of "hg grep" is not
efficient for "-l"/"--files-with-matches", because loop is continued,
even after the first matching is found in the specified file.
This patch exits loop immediately, if matching is found for
"--files-with-matches".
In this case, "before is None" is equal to "opts.get('files_with_matches')".
Before this patch, internal function "display()" of "hg grep" stores
whether matching is already found or not into the dictionary
"filerevmatches" by "(fn, rev)" tuple as the key.
But this is redundant, because:
- "filerevmatches" is local variable of "display()", so each
"display()" invocations don't affect others
- both "fn" and "rev" (gotten from "ctx" argument) are never changed
in each "display()" invocations
Then, "filerevmatches" should have only one entry at most, and "(fn,
rev) in filerevmatches" should be equal to "found".
This patch uses "found" instead of "filerevmatches" examination for
efficiency.
Before this patch, to check whether the file in the specified revision
is binary or not, "util.binary()" is invoked via internal function
"binary()" of "hg grep" once per a line of "hg grep" output, even
though binary-ness is not changed in the same file.
This patch reuses the first "util.binary()" invocation result by
annotating internal function "binary()" with "@util.cachefunc".
Performance improvement measured by "hgperf grep -r 5e9e7af9ae01 vfs
mercurial/scmutil.py":
before this patch:
! wall 0.024000 comb 0.015600 user 0.015600 sys 0.000000 (best of 118)
after this patch:
! wall 0.023000 comb 0.015600 user 0.015600 sys 0.000000 (best of 123)
Status of recent(5e9e7af9ae01) "mercurial/scmutil.py":
# of lines: 919 (may affect cost of search)
# of bytes: 29633 (may affect cost of "util.binary()")
# of matches: 22 (may affect frequency of "util.binary()")
Some extensions set configuration settings that showed up in 'hg showconfig
--debug' with 'none' as source. That was confusing.
Instead, they will now tell which extension they come from.
This change tries to be consistent and specify a source everywhere - also where
it perhaps is less relevant.
This change adds to the output of "hg debuginstall" information about the
Python being used by Mercurial. It adds both the path to the Python
executable (i.e. the value of sys.executable) and the version of Python
(specifically the major, minor, and micro versions).
Below is an example of what the output looks like after this change.
The marked lines are the new output lines:
$ hg debuginstall
checking encoding (UTF-8)...
-->showing Python executable (/Users/chris/.virtualenvs/default/bin/python)
-->showing Python version (2.7.6)
checking Python lib (/Users/chris/.virtualenvs/default/lib/python2.7)...
checking installed modules (/Users/chris/mercurial)...
checking templates (/Users/chris/mercurial/templates)...
checking commit editor...
checking username...
no problems detected
Note that we use the word "showing" without an ellipsis for the new lines
because, unlike the other lines (except for "Python lib" which will be
adjusted in a subsequent commit), no check follows the display of this
information.
Typical use case is to clone repository through command server. Clone may
require user interaction, so command-server protocol is beneficial over
raw stdio channels.
When user type "hg push" command then this patch helps user by
providing hint if no default path is configured.
Second patch is the test coverage, to test the change behaviour of
first patch.
We extract the `tryone` function into the `cmdutil` module. A lot of the command
context have to be passed to the utility function, but having and explicit
declaration will allow extension to wrap it. This will allows use to make
changeset evolution related experiment in dedicated extension.
Improving the API of this function is noble goal but outside of the scope of
this patches.
Missing templates where not reported as a problem, only an empty bracket
were shown as indication of no found template directory:
$ hg debuginstall
*...some lines*
checking templates ()...
*...some lines*
no problems detected
Now the problem is reported and extended with some information. The style
of the messages is adapted to the other messages of debuginstall.
When no templates directories exist, it writes:
$ hg debuginstall
*...some lines*
checking templates ()...
no template directories found
(templates seem to have been installed incorrectly)
*...some lines*
1 problems detected, please check your install!
When the template map is not found, it writes:
$ hg debuginstall
*...some lines*
checking templates (/path/to/mercurial/templates)...
template 'default' not found
(templates seem to have been installed incorrectly)
*...some lines*
1 problems detected, please check your install!
When the template map is buggy the message is the same as before. The error
message is shown before the line "(templates seem ...)".
No test is added because testing this failure is complicated. It would
require to modify the templates directory of the mercurial installation,
or to monkey patch a function (os.listdir or any from mercurial.templater)
by a test extension.
When updating to a bookmark, mention that the bookmark is now
active. This is a reminder that update does not move the
current bookmark if an explicit target is given - instead
it activates that target.
This patch also eliminates "forceeditor" no more referred.
This patch doesn't change any tests like as preceding patches, because
editor invocation is already tested well.
Before this patch, "hg backout" examines "--message" and "--logfile"
options explicitly.
But this examination is redundant, because "commitfunc()" can receive
the result of same examination by "cmdutil.logmessage()" in
"cmdutil.commit()" through "message" argument.
This patch avoids redundant message examination by "message"
examination in "commitfunc()".
Special case the single file case in hg cat. This allows us to avoid
parsing the manifest, which shaves 15% off hg cat perf. This is worth
it, since automation often uses hg cat for retrieving single files.
In some case Backout silently succeeded to back out but left all the change
uncommitted. This may be confusing for user so this changeset add a note
reminding to commit. Other backout case already actively informs the user about
created commit.
Before the changeset the backout process was:
1) go to <target>
2) revert to <target> parent
3) update back to changeset we came from
The two update steps can takes a very long time to move back and forth unrelated
file change between <target> and current working directory.
The new process is just merging current working directory with the parent of
<target> using <target> as ancestor. This give the very same result but skip
the two updates. On big repo with a lot of files and changes that save a lots of
time (x20 for one week window).
The "merge" version (hg backout --merge) is still done with upgrades. We could
imagine using in memory commit to speed it up but this is another fish.
b33db384a66e not only introduced the 'bisect(current)' revset predicate, it
also changed how the 'current' revision is used in combination with --command.
The new behaviour might be ok for --noupdate where the working directory and
its revision shouldn't be used, but it also did that when --command is used to
run a command on the currently checked out revision then it could register the
test result on the wrong revision.
An example:
Before, bisect with --command could use the wrong revision when recording the
test result:
$ hg up -qr 0
$ hg bisect --command "python \"$TESTTMP/script.py\" and some parameters"
changeset 31:58c80a7c8a40: bad
abort: inconsistent state, 31:58c80a7c8a40 is good and bad
Now it works as before and as expected and uses the working directory revision
for the --command result:
$ hg up -qr 0
$ hg bisect --command "python \"$TESTTMP/script.py\" and some parameters"
changeset 0:b99c7b9c8e11: bad
...
Any invocations of bookmarks other than a plain 'hg bookmarks' will likely
cause a write to the bookmark store. These should be guarded by the wlock.
The repo._bookmarks read should be similarly guarded by the wlock if we're
going to be subsequently writing to it.
Upcoming patches will acquire the wlock for write operations, such as make
inactive, but not read-only ones, such as list bookmarks. Separate out the
status messages so that the code paths can be separated.
Push is currently allowed to create a new head if there is a remote
bookmark that will be updated to point to the new head. If the
bookmark is not known remotely then push aborts, even if a -B argument
is about to push the bookmark. This change allows push to continue in
this case. This does not require a wireproto force.
Previously, directories were added with the trailing slash and, if there was
only one completion, then another ambiguous entry was created using '.', as
follows:
$ hg rm mer<TAB>
mercurial/./ mercurial//
This was added in bc559aff745c (though, some logic existed before that) to work
around bash completion adding a space after the sole entry because we treated
directories and files the same. We no longer do that now so we remove this
unneeded code.
Tests have been updated to match this new behavior.
There are currently two different ways we can have no active bookmark:
.hg/bookmarks.current being missing and it being an empty file. This patch and
upcoming ones make an empty file the only way to represent no active bookmarks.
This is the right choice because it matches the state that a new repository
without bookmarks will be in.
When trying to turn a draft changeset into a secret changeset, I was
told:
% hg phase -s .
cannot move 1 changesets to a more permissive phase, use --force
no phases changed
That message struck me as being backwards -- the secret phase feels
less permissive to me since it restricts the changesets from being
pushed.
We don't use the word "permissive" elsewhere, 'hg help phase' talks
about "lower phases" and "higher phases". I therefore reformulated the
error message to be
cannot move 1 changesets to a higher phase, use --force
That is not perfect either, but more in line with the help text. An
alternative could be
cannot move phase backwards for 1 changesets, use --force
which fits better with the help text for --force.
Previously, this required -f because we didn't consider obsolete changesets
(and their children ... or successors of those children, etc.). We now use
obsolete.foreground to calculate acceptable changesets when advancing the
bookmark.
Test coverage has been added.
This patch adds "pushtoremote()", which uses "compare()" to compare
bookmarks between the local and the remote repositories, to replace
pushing local bookmarks in "commands.push()".
On Windows, only double quotation mark can quote command line
arguments.
So, this patch uses double quotation mark to quote command line
arguments in all examples of online help document.
This patch adds more detailed explanation about "--force" to online
help document of "hg push" to prevent novice users to execute "push
--force" easily without understanding about problems of multiple
branch heads in the repository.
This makes `hg pull --update` behave the same wrt the active bookmark as
`hg pull && hg update` does as of 13ea5e437ff8. A helper function,
bookmarks.calculateupdate, is added to prevent code duplication between
postincoming and update.
The old docs emphasized topological heads rather than branch heads and
incorrectly defined branch heads as not having children rather than
descendants.
At the moment, creating secret commits is slightly cumbersome. They
can either be created by changing the default commit phase to secret
or by doing `hg phase --secret --force`. Both of these make secret
commits appear to be like some kind of advanced feature.
Secret commits, however, should be a convenient feature for people who
want to work on a private branch without affecting anyone else. There
should therefore be a prominent and convenient method for creating
secret commits.
Since the default phase is draft and there is no need to use --force
to go from a secret phase to any other phase, this patch
intentionally does not add --draft and --public options.
The --force option in merge does not make what people think it does so
it may not be visible to everyone.
I have local changes and want to pull one's changes which made 2 heads.
The --force option in help says
-f --force force a merge with outstanding changes
so I can expect that I can use it to force the merge and commit it in my
local repository without taking my local changes into account. But
merging with -f keeps local changes and "add" them: they must be
committed or reverted before doing the merge commit. The merge -f cannot
be reverted so it leads my repository in a bad state: cannot commit
merge and don't want to revert/commit local changes yet.
Message in help have been updated to emphasize the fact that local
changes are included in the merge.
Changes the parents command to use filectx to look up the change node
instead of doing it manually. This allows extensions to modify the
file-to-commit relationship behind the filectx api.
RST's role syntax means something different sometimes when it's in
some places that are poorly documented and vary betwen minirst and
docutils. Line wrapping will thus sometimes break everything.
Markup for links to mercurial commands is appearing in the help
documentation.
This patch fixes the markup so mercurial command reference links are
correctly generated in the help documentation.
Because dirstate._branch() strips leading/trailing spaces from .hg/branch,
"hg branch ' foo '" should abort if branch "foo" exists in another head.
tag command had a similar bug and fixed by 11d102903884.
You can't close a branch that hasn't got a head.
newbranch + commit --close-branch must fail
newbranch + commit + commit --amend --close-branch must fail
You must not be allowed to close a branch that is not defined.
This patch resolves a single divergent bookmark if a divergent bookmark exists
in the target revision and it current bookmark is not an ancestor of the target
revision, else it would already be handled by the previous patch in this
series.
Test coverage is added.
This patch is a follow-up to 00b2764d68e4 that resolves divergent bookmarks
between the to-be-forwarded bookmark MARK and the new descendant. This
situation can happen when pulling new changesets, updating to the divergent
bookmark, abandoning the previous changesets with strip, and then moving MARK
to MARK@N.
Test coverage is added.
This change allows setting or deleting multiple bookmarks at once. If more than
one is being set and --inactive is not given, the first one is made active.
Before this patch, "commonincoming" calculated by
"discovery.findcommonincoming()" is cleared, only if "default" URL
without branch part (tail "#branch" of URL) differs from
"default-push" URL without branch part.
But common revisions in "commonincoming" calculated for a branch
doesn't include ones for another branch, even if URLs without branch
part are same. The result of "discovery.findcommonoutgoing()"
invocation with such "commonincoming" becomes incorrect in some cases.
This patch clears "commonincoming", also if branch part of "default"
differs from one of "default-push".
To avoid redundant looking up:
- "ui.expandpath('default')" and "ui.expandpath('default-push',
'default')" are not compared directly, even though they contain
branch information, because they are not yet normalized by
"hg.parseurl()": tail "/" of path, for example
- "commonincoming" is not cleared, if branch isn't specified in
"default" URL, because such "commonincoming" contains common
revisions for all branches
This patch also tests "different path, same branch" pattern to check
careless degrading around comparison between source and destination.
Before this patch, "incoming" information of "hg summary --remote" is
not sensitive to the branch specified in the URL of the destination
repository, even though "hg pull"/"hg incoming" are so.
Invocation of "discovery.findcommonincoming()" without "heads"
argument treats revisions on branches other than the one specified in
the URL as incoming ones unexpectedly.
This patch looks head revisions, which are already detected by
"hg.addbranchrevs()" from URL, up against "other" repository, and
invokes "discovery.findcommonincoming()" with list of them as "heads"
to limit calculation of incoming revisions.
Before this patch, "outgoing" information of "hg summary --remote" is
not sensitive to the branch specified in the URL of the destination
repository, even though "hg push"/"hg outgoing" are so:
Invocation of "discovery.findcommonoutgoing()" without "onlyheads"
argument treats revisions on branches other than the one specified in
the URL as outgoing ones unexpectedly.
This patch looks head revisions, which are already detected by
"hg.addbranchrevs()" from URL, up against local repository, and
invokes "discovery.findcommonoutgoing()" with list of them as
"onlyheads" to limit calculation of outgoing revisions.
-r has a default value of '' in the command line. The function default value of
'tip' is thus never used and any attempt at specifying revisions without -r
will fail.
It seems like then intended behavior was that 'hg debugrebuildstate' without
any parameters should set the parents to tip. That would be very confusing now
when the command primarily is used to recover from incorrect stat info.
It is apparently undocumented that '' is the same as '.' ... unless it is
passed in a place where revsets are used.
A common usecase for export is to preview the patch that will be patchbombed or
to see what changed in a revision found by bisect. Showing the working
directory parent is thus a useful and obvious default.
Backout 308a153b9120. The changeset prevented closing non-head changesets but
did not provide any rationale or test case and I don't see what value it adds.
Users might have their reasons to commit something anywhere - and close it
immediately.
And contrary to the comment that is removed: The topo heads set is _not_
included in the branch heads set of the current branch. It do not include
closed topological heads.
The change thus prevented closing commits on top of closing commits. A valid
usecase for that is to merge closed heads to reduce the number of topological
heads.
The only existing test coverage for this is the failing double close in
test-revset.t. It was added in dc0e42c06b4e and seems to not be intentional.
When the revisions to graft are numerically close to the destination, this
avoids two walks up the DAG, which for a repository with over 470,000
changesets translates to around 2.2 seconds.
When the revisions to graft are numerically close to the destination, this
avoids one walk up the DAG, which for a repository with over 470,000
changesets translates to around 1.1 seconds.
Consider a bookmark B that exists both locally and remotely. If B is updated
remotely, and then a pull is performed where the pull set contains the new
location of B, the bookmark is updated locally. However, if remote B is
updated in the middle of a pull to a location not in the pull set, the
bookmark won't be updated locally at all.
To fix this, list bookmarks before pulling in changesets, not after. This
still leaves a race open if B gets moved in between listing bookmarks and
pulling in changesets, but the race window is much smaller. Fixing the race
properly would require a bundle format upgrade.
test-hook.t's output changes because we no longer do two listkeys calls during
pull, just one.
test-pull-http.t's output changes because we now search for bookmarks before
searching for changes.
Before this patch, "hg bundle --branch foo other" fails to create
bundle file, if specified "foo" branch is created newly on the local
repository.
"hg bundle" uses "hg.addbranchrevs(repo, other, ...)" to look branch
names up, even though other outgoing-like implementation uses
"hg.addbranchrevs(repo, repo, ...)". In the former invocation, "other"
repository recognizes such branches as unknown, so execution is
aborted.
This patch uses "hg.addbranchrevs(repo, repo, ..)" in "hg bundle" to
bundle revisions on such branches correctly.
If the active bookmark doesn't point at a parent of the working dir
(e.g. a pull moved it out from under us), we nonetheless show it as
active. This follows on 13ea5e437ff8 in removing the dichotomy (at least
in the UI) between "current" and "active" bookmarks.
If the current bookmark (the one listed in .hg/bookmarks.current)
doesn't point to a parent of the working directory, e.g. if it was moved
by a pull, use that as the update target instead of the tipmost
descendent.
A small predicate is (finally) added to the bookmarks module to check
whether the current bookmark is also active.
We can not use `len(repo,changelog)`, it may be a filtered revision. We now use
`repo,changelog.tip()` to fetch this information.
The `tip` command is also fixed and tested
Thanks goes to Idan Kamara for the initial report.
Suppose we want to perform a single-level completion (i.e. without
--full) of "fi" in a repo containing "fee", "fie/dead", "fie/live",
and "foe".
If we give back "fie/" as the only answer, the shell will consider
the completion to be unambiguous, and will append a space after the
completion. We can't complete "fie/live" or "fie/dead" without
first backspacing over that space.
We used to thus create two fake names, "fie/a" and "fie/b", to force
the shell to consider the completion to be ambiguous. It would then
stop at "fie/" without appending a space, allowing us to hit tab
again to complete "fie/live" or "fie/dead".
The change here arises from realising that we only need to force
the shell to consider a completion as ambiguous if we have exactly
one directory and zero files as possible completions.
This prevents spurious names from showing up as possible completions
when they don't need to be invented in the first place.
The bash_completion code uses "hg status" to generate a list of
possible completions for commands that operate on files in the
working directory. In a large working directory, this can result
in a single tab-completion being very slow (several seconds) as a
result of checking the status of every file, even when there is no
need to check status or no possible matches.
The new debugpathcomplete command gains performance in a few simple
ways:
* Allow completion to operate on just a single directory. When used
to complete the right commands, this considerably reduces the
number of completions returned, at no loss in functionality.
* Never check the status of files. For completions that really must
know if a file is modified, it is faster to use status:
hg status -nm 'glob:myprefix**'
Performance:
Here are the commands used by bash_completion to complete, run in
the root of the mozilla-central working dir (~77,000 files) and
another repo (~165,000 files):
All "normal state" files (used by e.g. remove, revert):
mozilla other
status -nmcd 'glob:**' 1.77 4.10 sec
debugpathcomplete -f -n 0.53 1.26
debugpathcomplete -n 0.17 0.41
("-f" means "complete full paths", rather than the current directory)
Tracked files matching "a":
mozilla other
status -nmcd 'glob:a**' 0.26 0.47
debugpathcomplete -f -n a 0.10 0.24
debugpathcomplete -n a 0.10 0.22
We should be able to further improve completion performance once
the critbit work lands. Right now, our performance is limited by
the need to iterate over all keys in the dirstate.
When completing a "label" (a symbolic name for a commit), the
bash_completion script currently has to invoke hg three times. For
a large repository, the cost of starting up and loading all the
necessary context over and over is very high.
For instance, in mozilla-central:
time (export HGPLAIN=1; hg tags -q; hg bookmarks -q; hg branches) >/dev/null
0.446 sec
Compare with the debuglabelcomplete command that this commit adds:
time hg debuglabelcomplete >/dev/null
0.148 sec
This greatly helps responsiveness.
After this change, moving the active bookmark somewhere other than the
current changeset (i.e., with --rev) deactivates it. Previously it would
remain in .hg/bookmarks.current, which seems like a bug.
Allow a bookmark that points to the current changeset to be made the
active bookmark without requiring --force. Previously, this would've
aborted with:
abort: bookmark 'Z' already exists (use -f to force)
Allow 'hg bookmark MARK', with an existing bookmark MARK, to move the
bookmark forward to the current or specified revision, if the target
revision is a descendant of the revision the bookmark currently points
to. Prints a status message including the revision the bookmark was
formerly at:
$ hg bookmark Z
moving bookmark 'Z' forward from 663762316562
Test coverage is added.
Since re2 is enormously faster than Python's re module, this should
help performance, ceteris paribus. grep currently has other huge
performance problems that mask any gain :-(
We move the logic for generating the unformatted ReST source to the
help module, in order to eventually avoid calling commands.help_()
from hgweb.
No functionality change.
We create a new function commitstatus() in cmdutil that handles printing
the status message(s) after a commit. This will allow other commit-like
commands to use it, and in particular is step 2 towards removing
backout's call to commands.commit.
This is step 1 to remove backout's call to commands.commit. We don't use
the options again anywhere below except for backout's own purposes,
specifically choosing a merge tool, so we just write the commit options
in directly.
There's no way for addremove to show up in backout's opts dictionary. It
was being set manually because cmdutil.commit expected it to be there
(and would throw an exception if it wasn't). This was fixed waaaaaaay
back in:
changeset: 5829:e05e83ad9d2b
user: Kirill Smelkov <kirr@mns.spb.ru>
date: Thu Jan 10 12:07:18 2008 +0300
summary: cmdutil.commit: extract 'addremove' from opts carefully
Before this change, backout would explicitly set the options it passed
to commands.revert in order to fall thru most of its logic and call
cmdutil.revert. This change makes it clearer what backup is trying to
accomplish and makes it robust against changes to the revert command.
The checkexact() helper function was calling repo.rollback() from inside
an open transaction. In addition to being insane, this is unnecessary
because import will release the transaction on an exception.
It turns out that this has been broken since the feature was first
introduced, first released in v1.0:
changeset: 4263:3e8ce73e04cd
user: Brendan Cully <brendan@kublai.com>
date: Thu Mar 22 10:44:59 2007 -0700
files: mercurial/commands.py mercurial/patch.py
description:
Add import --exact.
When this option is set, import will apply the patch (which must
be generated by export) to the parents specified in the patch,
and check that the node produced by the patch matches the node
ID in the patch.
Before this change, 'hg summary' would not show the active bookmark
unless it pointed to the working directory parent. After this change, it
will show it in parentheses, like so:
parent: 18581:f0ff45fe6700 tip
summary: simplify handling of active bookmark
branch: default
bookmarks: [crew]
commit: (clean)
update: (current)
The dispatch code now enables filtering of "hidden" changesets globally. The
filter is installed before command and extension invocation. The `--hidden`
switch is now global and disables this filtering for any command.
Code in log dedicated to changeset exclusion is removed as this global filtering
has the same effect.
The phase command have some logic to report change made. We ensure this logic
run unfiltered.
With --force the command can change phase of a changeset for public to draft.
Such change can lead to obsolescence marker to apply again and the changeset to
be "hidden". If we do not run the logic unfiltered it could failed to fetch the
phase of a newly filtered changeset.
Obsolescence marker can represent this situation just fine. The old
version is marked as precursor of the new changeset. All its
descendants become "unstable".
If obsolescence is not enabled we keep the current behavior of
aborting. This new behavior only applies when obsolete is
enabled and is subject to future discussion and changes.
A type mismatch caused the search for the other head to fail. The code is
fragile, and instead it ended up using the 'first' bookmark head, but the
ordering is undefined and it could thus randomly use the wrong bookmarkhead
and fail with:
$ hg up -q -C e@diverged
$ hg merge
abort: merging with a working directory ancestor has no effect
Before this patch, enabling strict command processing (ui.strict=True)
meant that 'hg bookmark NAME', as referenced several places in the
documentation, would not work. This adds 'bookmark' as an explicit alias
to 'bookmarks'.
Starting with 049792af94d6, users are no longer able to update a
working copy to a branch named with a "bad" character (such as ':').
Prior to v2.4, it was possible to create branch names using "bad"
characters, so this breaks backwards compatibility.
Mercurial must allow users to update to existing branches with bad
names. However, it should continue to prevent the creation of new
branches with bad names.
A test was added to confirm that 'hg update' works as expected. The
test uses a bundled repo that was created with an earlier version of
Mercurial.
'*' causes the resulting RE to match 0 or more repetitions of the preceding RE:
>>> bool(re.search('.*', ''))
>>> True
This causes an infinite loop because currently we're only checking if there was
a match without looking at where we are in the searched string.
Successors set are an important part of obsolescence. It is necessary to detect
and solve divergence situation. This changeset add a core function to compute
them, a debug command to audit them and solid test on the concept.
Check function docstring for details about the concept.
This changes graft to explicitly track the progression of commits it
makes, and updates it's idea of the current node based on it's last
commit, rather than from the working copy parent. This should have no
effect on the value of current since we were reading the working copy
parent immediately after commiting to it.
The motivation for this change is that a subsequent patch will break
the current node and working copy relationship. Splitting this out
into a separate patch will make that one more readible.
This moves the logic for generating the commit metadata ahead of the
merge operation. The only purposae of this patch is to make
subsequent patches easier to read, and there should be no behavior
changes.
scmutil.checknewlabel takes a repo object as its first argument.
When the call to this function was added in 4d438984605c, the
first argument was mistakenly set to 'None'.
The bisect command does not have an option to limit itself only to
subdirectories, but it's possible to use revsets for the --skip option
for the same effect. Given the relative obscurity of revsets, it helps
to have this as another example for bisect.