Commit Graph

16040 Commits

Author SHA1 Message Date
Patrick Mezard
a2ea7bb50f graphlog: explicitely join multivalue parameters
This will let use override the "join" value (and/or) depending on the option
considered. The option revset arity is now deduced from the revset and the
option value type, to simplify opt2revset definition.
2012-02-22 12:30:15 +01:00
Patrick Mezard
0d86e86816 test-glog.t: use printrevset extension to trace rewritten revsets
Using "hg log -G --print-revset" prints the revset generated by graphlog and
exits. This helps debugging and writing shorter tests.

It has been suggested to handle these tests with doctests. I think the
extension approach is better because:
- It tests the actual parameter set passed to graphlog.revset(), not what we
  expect it to be. 'branch' and 'only-branch' are currently distinct options
  but nothing prevents fancyopts to grow a notion of option aliasing one day,
  where both options would be merged before reaching the command.
- It can be used as debug output interleaved with real log calls.

v2:
- Use a test extension instead of a global deprecated new option
2012-02-22 12:30:14 +01:00
Matt Mackall
8ddc445e67 status: fix format field thinko 2012-02-22 15:22:12 -06:00
Michal Sznajder
1c1007a5ed help: sort hgrc related "Sections" chapters alphabetically 2012-02-18 14:27:57 +01:00
Patrick Mezard
eacdef0369 doc: minor fixes to [graph] section documentation 2012-02-18 12:30:24 +01:00
Patrick Mezard
9737893642 hgweb: refactor graph customization javascript
- Avoid flipping lineWidth state around the edge() call, pass it to the
  function instead.
- Pass the line width and color appended to the other parameters instead of in
  a dictionary. The javascript code is simpler, no need to check for all
  containers existence, and the JSON output is smaller.
- Reindent setColor() comments and fix code spacing.
2012-01-22 19:35:26 +07:00
Patrick Mezard
23fea18b90 templates: move Graph.edge() implementation in mercurial.js
All implementation in graph.tmpl are the same. It can still be overriden if
necessary. There is no clear reason to keep it separated from mercurial.js.
2012-02-17 16:49:43 +01:00
Matt Mackall
4264cfcad0 formatter: convert status command 2012-02-20 16:42:51 -06:00
Matt Mackall
107150b868 ui: add formatter method 2012-02-20 16:42:48 -06:00
Matt Mackall
0acc5a5ce3 formatter: add basic formatters 2012-02-20 16:42:47 -06:00
Matt Mackall
feb580aa0d encoding: introduce utf8-b helpers 2012-02-20 16:42:45 -06:00
Matt Mackall
38994ac76a graphmod: add config cache
Before, we'd lookup the branch for every edge segment in the entire
graph: extremely expensive. This happened even when no per-branch
settings existed.

Now we define a revision -> config cache function that's LRU-cached
and is a no-op when no configuration exists. Still not terribly fast,
but hopefully only one real branch lookup per revision. This might
degenerate for wide graphs as the LRU is hard-coded to 20 elements.
2012-02-17 13:53:41 -06:00
Matt Mackall
6788faf119 graphmod: rewrite graph config validation
Our goal is not to strictly disallow _invalid_ input, simply disallow _hostile_ input.

Avoid using re
Avoid creating empty dicts when no branch parameters are recognized
2012-02-17 13:53:19 -06:00
Constantine Linnick
73bdfc9ad9 graph: in hgrc specify line color for main branch
You can specify color to visually distinguish main branch (trunk)
on hgweb's graph page. If color specified, all branch heads will share
same color. Settings format is branch_name.color = value, where color
is six hexadecimal digits e.g.:
[graph]
default.color = FF0000
2012-01-22 19:47:03 +07:00
Constantine Linnick
c28ce344f6 graph: in hgrc specify line width for main branch
You can specify width to visually distinguish main branch (trunk)
on hgweb's graph page. Settings format is branch_name.width = value,
where width in px e.g.:
[graph]
default.width = 3
2012-01-22 19:35:26 +07:00
Matt Mackall
ee1d294b90 merge with stable 2012-02-16 16:40:29 -06:00
Matt Mackall
6287da213f filemerge: remove some redundancy in decorators/docstrings 2012-02-16 15:58:51 -06:00
Patrick Mezard
20e5c736c0 patch: fuzz more aggressively to match patch(1) behaviour
The previous code was assuming a default context of 3 lines. When fuzzing, it
would take this value in account to reduce the amount of removed line from
hunks top or bottom. For instance, if a hunk has only 2 lines of bottom
context, fuzzing with fuzz=1 would do nothing and with fuzz=2 it would remove
one of those lines. A hunk with one line of bottom context could not be fuzzed
at all.  patch(1) has apparently no such restrictions and takes the fuzz level
at face value.

- test-import.t: fuzz/offset changes at the beginning of file are explained by
  the new fuzzing behaviour and match patch(1) ones. Patching locations are
  different but those of my patch(1) do not make a lot of sense right now
  (patched output are the same)

- test-import-bypass.t: more agressive fuzzing makes a patching supposed to
  fail because of context, succeed. Change the diff to avoid this.

- test-mq-merge.t: more agressive fuzzing would allow the merged patch to apply
  with fuzz, but fortunately we disallow this behaviour. The new output is
  kept.

I have not enough experience with patch(1) fuzzing to know whether aligning our
implementation on it is a good or bad idea. Until now, it has been the
implementation reference. For instance, "qpush" tolerates fuzz (test-mq-merge.t
runs the special case of pushing merge revisions where fuzzing is forbidden).
2012-02-13 17:22:35 +01:00
Patrick Mezard
39da9af001 patch: fix fuzzing of hunks without previous lines (issue3264)
When applying hunks such as:

  @@ -2,1 +2,2 @@
   context
  +change

fuzzing would empty the "old" block and make patchfile.apply() traceback.
Instead, we apply the new block at specified location without testing.

The "bottom hunk" test was removed as patch(1) has no problem applying hunk
with no context in the middle of a file.
2012-02-13 16:47:31 +01:00
Patrick Mezard
1be0e99fa3 patch: make hunk.fuzzit() compute the fuzzed start locations
- It moves hunks processing weirdness where it belongs
- It helps reusing said weirdness whenever fuzzit() is called, like during the
  actual hunk fuzzing.
2012-02-13 13:51:38 +01:00
Patrick Mezard
e783da0202 patch: fuzz old and new lines at the same time
In theory, the fuzzed offsets for old and new lines should be exactly the same
as they are based on hunk parsing. Make it true in practice.
2012-02-13 13:21:00 +01:00
Patrick Mezard
3141b1aa35 mq: make qimport --push push all imported patches (issue3130)
Only the first imported one was pushed.
2012-02-14 14:31:40 +01:00
Patrick Mezard
d410481c55 convert: tolerate spaces between splicemap parent ids (issue3203)
Splicemap lines are documented in hg help convert like:

  key parent1, parent2

but parsed like:

  key, parents = line.strip().rsplit(' ', 1)
  parents = parents.replace(',', ' ').split()

The rsplit() call was introduced to handle spaces in keys for the generic
mapfile format. Spaces can appear in svn identifiers since they contain path
components. This logic makes less sense with splicemap since svn identifiers
can also appear on the right side, even if it is a bit less likely. Given the
parsing is theorically broken, I would rather follow what is documented already
and is correct in the main case where all identifiers are hg hashes. Also,
using svn identifiers in a splicemap sounds difficult as they are not easily
accessible.
2012-02-15 11:21:24 +01:00
Idan Kamara
e771a65076 test-commandserver: flush stdout 2012-02-16 01:23:45 +02:00
Idan Kamara
1e4d0cc218 localrepo: clear _filecache on rollback (issue3261)
Files are being replaced by rollback but the corresponding data in localrepo
isn't actually updated for things like bookmarks, phases, etc. Then when
rollback is done, the cache is updated thinking it has the most up-to-date
data, where in fact it is still pre-rollback.

We clear _filecache to force everything to be recreated.
2012-02-16 01:21:34 +02:00
Idan Kamara
f729c0ef8a scmutil: update cached copy when filecached attribute is assigned (issue3263)
When assigning a new object to filecached properties, the cached object that
was kept in the _filecache map was still holding the old object.

By implementing __set__, we track these changes too and update the cached
copy as well.
2012-02-15 20:02:35 +02:00
Idan Kamara
351bf40844 cmdserver: invalidate the dirstate when running commands (issue3271)
The dirstate is invalidated separately outside of invalidate() which is
already being called (other callers of invalidate() seems to suggest the
separation is there for a reason).
2012-02-15 23:44:10 +02:00
Idan Kamara
11836c52b3 localrepo: reset _phasesdirty flag after writing 2012-02-15 23:49:15 +02:00
Patrick Mezard
a7eea871c8 import: handle git renames and --similarity (issue3187)
There is no reason to discard copy sources from the set of files considered by
addremove(). It was done to handle the case where a first patch would create
'a' and a second one would move 'a' to 'b'. If these patches were applied with
--no-commit, 'a' would first be marked as added, then unlinked and dropped from
the dirstate but still passed to addremove(). A better fix is thus to exclude
removed files which ends being dropped from the dirstate instead of removed.

Reported by Jason Harris <jason@jasonfharris.com>
2012-02-16 13:03:42 +01:00
Patrick Mezard
48bbc97548 context: make workingctx.forget() really warn about untracked files 2012-02-16 12:56:48 +01:00
FUJIWARA Katsunori
c3838f8d3f largefiles: check whether specified patterns are related to largefiles strictly
current 'lfiles_repo.status()' implementation examines whether
specified patterns are related to largefiles in working directory (not
to STANDIN) or not by NOT-EMPTY-NESS of below list:

    [f for f in match.files() if f in lfdirstate]

but it can not be assumed that all in 'match.files()' are file itself
exactly, because user may only specify part of path to match whole
under subdirectories recursively.

above examination will mis-recognize such pattern as 'not related to
largefiles', and executes normal 'status()' procedure. so, 'hg status'
shows '?'(unknown) status for largefiles in working directory unexpectedly.

this patch examines relation of pattern to largefiles by applying
'match()' on each entries in lfdirstate and checking wheter there is
no matched entry.

it may increase cost of examination, because it causes of full scan of
entries in lfdirstate.

so this patch uses normal for-loop instead of list comprehensions, to
decrease cost when matching is found.
2012-02-15 23:01:09 +09:00
FUJIWARA Katsunori
4629df01c9 filemerge: create detail of internal merge tools from documentation string
this patch introduces 'internaltoolsmarker' which creates detail of
each internal merge tools from documentation string for 'hg help merge-tools'.
2012-02-12 21:38:12 +09:00
FUJIWARA Katsunori
030b0e3bf3 filemerge: refactoring of 'filemerge()'
current 'filemerge.filemerge()' implementation is verfy complicated.

    - it is not easy to add new internal merge tools
      (only by patching on 'filemerge()', or replacing it completely)

    - cleanup of temporary files is unsatisfactory
      ('internal:dump' does not, in fact)

this is patch for refactoring of 'filemerge()' to isolate each
internal merge tool implementations from 'filemerge()', and clean up
common part in it.
2012-02-12 21:38:12 +09:00
Na'Tosha Bard
8640514f70 largefiles: optimize update speed by only updating changed largefiles
Historically, during 'hg update', every largefile in the working copy was
hashed (which is a very expensive operation on big files) and any
largefiles that did not have a hash that matched their standin were
updated.

This patch optimizes 'hg update' by keeping track of what standins have
changed between the old and new revisions, and only updating the largefiles
that have changed.  This saves a lot of time by avoiding the unecessary
calculation of a list of sha1 hashes for big files.

With this patch, the time 'hg update' takes to complete is a function of
how many largefiles need to be updated and what their size is.

Performance tests on a repository with about 80 largefiles ranging from
a few MB to about 97 MB are shown below.  The tests show how long it takes
to run 'hg update' with no changes actually being updated.

Mercurial 2.1 release:

$ time hg update
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
getting changed largefiles
0 largefiles updated, 0 removed

real    0m10.045s
user    0m9.367s
sys    0m0.674s

With this patch:

$ time hg update
0 files updated, 0 files merged, 0 files removed, 0 files unresolved

real    0m0.965s
user    0m0.845s
sys    0m0.115s

The same repsoitory, without the largefiles extension enabled:

$ time hg update
0 files updated, 0 files merged, 0 files removed, 0 files unresolved

real    0m0.799s
user    0m0.684s
sys    0m0.111s

So before the patch, 'hg update' with no changes was approximately 9.25s
slower with largefiles enabled.  With this patch, it is approximately 0.165s
slower.
2012-02-13 18:37:07 +01:00
Matt Mackall
bd7d3adcb4 merge with stable 2012-02-10 17:09:23 -06:00
Matt Mackall
3ec4361714 log: remove caching of all visited revisions (issue3253)
Not only does this eat all available memory for some users, it's slower.
2012-02-10 16:52:32 -06:00
Matt Mackall
31ad230c52 pull: backout change to return code
This bit a number of people.
2012-02-10 16:09:30 -06:00
Patrick Mezard
4fbe13b66c convert: use splicemap entries when sorting revisions (issue1748)
When sorting revisions before converting them, we have to edit the revision
graph using splicemap entries. Otherwise, a spliced revision may be converted
before its synthetic parents. Invalid splicemap revisions are now detected
before starting the conversion.
2012-02-10 22:34:13 +01:00
Patrick Mezard
a92c89fcd0 convert: turn splicemap into a simple dictionary
Parsing the splicemap as a mapfile was a pain because map does not let us
override its parsing code and splicemap entries are not key/values. Besides we
had no need for mapfiles extra features. Just parse the splicemap and return a
dictionary.
2012-02-10 22:25:49 +01:00
Na'Tosha Bard
8564a2aba3 largefiles: only cache largefiles in new heads
This fixes a serious performance regression in largefiles introduced in
Mercurial 2.1.  Caching new largefiles on pull is necessary, because
otherwise largefiles will be missing (and unable to be downloaded) when
the user tries to merge or rebase a new head with an old one.  But this
is an expensive operation and should only be done for heads that are new
from the pull, rather than on all heads in the repository.
2012-02-10 14:46:09 +01:00
Patrick Mezard
165a91747d debugrevspec: mention --verbose to print the parsed tree 2012-02-10 13:50:13 +01:00
Matt Mackall
0d314915f7 merge with stable 2012-02-10 13:47:57 -06:00
Patrick Mezard
431fc934f5 convert/bzr: ignore nested repos when listing branches (issue3254)
Reported by A.S. Budden <abudden@gmail.com>
2012-02-08 17:45:10 +01:00
Patrick Mezard
e1749878c6 phase: when phase cannot be reduced, hint at --force and return 1 (BC)
Before, trying to change the phase of a "public" node to "draft" would result
in:

  $ hg phase --draft .
  no phases changed
  [0]

With this patch:

  $ hg phase --draft .
  cannot move 1 changesets to a more permissive phase, use --force
  no phases changed
  [1]

On partial failures, the exit status is now 1 instead of 0 and the number of
changed nodes is displayed while it was only with --verbose. It seems useful to
tell the user that despite the apparent failure, something changed.

  $ hg phase --draft '5 or 7'
  cannot move 1 changesets to a more permissive phase, use --force
  phase changed for 1 changesets
  [1]
2012-02-08 20:00:52 +01:00
Patrick Mezard
231c7be7bb revset: fix alias substitution recursion (issue3240)
The revset aliases expansion worked like:

  expr = "some revset"
  for alias in aliases:
      expr = alias.process(expr)

where "process" was replacing the alias with its *unexpanded* substitution,
recursively. So it only worked when aliases were applied in proper dependency
order.

This patch rewrites the expansion process so all aliases are expanded
recursively at every tree level, after parent alias rewriting and variable
expansion.
2012-02-09 21:03:07 +01:00
Matt Mackall
1b38343e48 update: just merge unknown file collisions
The unknown file collision rule was introduced as an extension of the
"should be clean when merging" rule. Unfortunately, it got applied to
the normal update path, which should be happy to merge local changes.

This patch gives us merges for unknown file collisions on update,
while preserving abort for merge and update -c.
2012-02-09 17:54:47 -06:00
Matt Mackall
e3a172f2f0 merge: don't use unknown()
This removes use of unknown files for building the synthetic working
directory manifest used by manifestmerge. Instead, we adopt the
strategy used by _checkunknown.

Side-effect: unknown files are no longer moved by remote directory
renames, and now are left alone like ignored files.
2012-02-09 17:04:17 -06:00
Matt Mackall
f454042775 merge: refactor unknown file conflict checking
Previously, we would do a full working directory walk including
unknown files to perform a merge. In many cases, this was painful
because unknown files greatly outnumbered tracked files and generally
had no useful effect on the merge.

Here we instead wait until we find a file in the destination that's
not tracked locally and detect if it exists and is not ignored. This
is usually cheaper but can be -more- expensive in the case where we're
adding a huge number of files. On the other hand, the cost of statting
the new files should be dwarfed by the cost of eventually writing
them.

In this version, case collisions are detected implicitly by
os.path.exists and wctx[f] lookup.
2012-02-09 16:50:19 -06:00
Matt Mackall
1ceb79342c update: use normal update path with --check (issue2450)
This avoids clobbering unknown files on update by not using overwrite mode.
2012-02-09 13:16:20 -06:00
Patrick Mezard
7b9cb90b98 mq: restore _branchtags() fast path (issue3223)
Since c06eb45e85a7, mq saves the nodeid of the first applied patch to
cache/branchheads, which breaks the optimized cache handling introduced in
1808e27e1362. The problem is the revision being committed is appended to
mqrepo.applied after the commit succeeds, which means mqrepo._branchtags()
performs a regular update and write the first applied patch to the branch
cache.

One solution is to set a context variable _committingpatch on the mqrepo while
it is committing a patch and to take it in account when deciding to fast-path
mqrepo._branchtags(). Not really elegant but it works.

The changes to test-mq-caches.t reverse changes introduced by c06eb45e85a7. The
cache should not have been updated with mq records.

The changes to test-keyword.t are indirectly caused by c06eb45e85a7.

Reported and analyzed by Yuya Nishihara <yuya@tcha.org>

Notes:
- qpush still makes a slow path _branchtags() call when checking heads. Maybe
  this can be optimized.
- be careful when merging this patch in default as secretcommit() was renamed
  newcommit() right after the end of the code freeze.
2012-02-07 18:47:16 +01:00