D8035: copy: add support for marking committed copies

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20153.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8035?vs=20086=20153

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8035/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8035

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  relnotes/next
  tests/test-copy.t
  tests/test-rename-after-merge.t
  tests/test-rename-rev.t
  tests/test-rename.t

CHANGE DETAILS

diff --git a/tests/test-rename.t b/tests/test-rename-rev.t
copy from tests/test-rename.t
copy to tests/test-rename-rev.t
--- a/tests/test-rename.t
+++ b/tests/test-rename-rev.t
@@ -6,693 +6,51 @@
   $ echo d1/b > d1/b
   $ echo d2/b > d2/b
   $ hg add d1/a d1/b d1/ba d1/d11/a1 d2/b
-  $ hg commit -m "1"
-
-rename a single file
-
-  $ hg rename d1/d11/a1 d2/c
-  $ hg --config ui.portablefilenames=abort rename d1/a d1/con.xml
-  abort: filename contains 'con', which is reserved on Windows: d1/con.xml
-  [255]
-  $ hg sum
-  parent: 0:9b4b6e7b2c26 tip
-   1
-  branch: default
-  commit: 1 renamed
-  update: (current)
-  phases: 1 draft
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
-
-rename a single file using absolute paths
-
-  $ hg rename `pwd`/d1/d11/a1 `pwd`/d2/c
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
+  $ hg commit -m "intial"
 
-rename --after a single file
 
-  $ mv d1/d11/a1 d2/c
-  $ hg rename --after d1/d11/a1 d2/c
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
-
-rename --after a single file when src and tgt already tracked
-
-  $ mv d1/d11/a1 d2/c
-  $ hg addrem -s 0
-  removing d1/d11/a1
-  adding d2/c
-  $ hg rename --after d1/d11/a1 d2/c
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
-
-rename --after a single file to a nonexistent target filename
-
-  $ hg rename --after d1/a dummy
-  d1/a: not recording move - dummy does not exist
-  [1]
-
-move a single file to an existing directory
+Test single file
 
-  $ hg rename d1/d11/a1 d2
-  $ hg status -C
-  A d2/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/a1
-
-move --after a single file to an existing directory
-
-  $ mv d1/d11/a1 d2
-  $ hg rename --after d1/d11/a1 d2
-  $ hg status -C
-  A d2/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/a1
-
-rename a file using a relative path
-
-  $ (cd d1/d11; hg rename ../../d2/b e)
-  $ hg status -C
-  A d1/d11/e
-d2/b
-  R d2/b
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d1/d11/e
-
-rename --after a file using a relative path
-
-  $ (cd d1/d11; mv ../../d2/b e; hg rename --after ../../d2/b e)
-  $ hg status -C
-  A d1/d11/e
-d2/b
-  R d2/b
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d1/d11/e
-
-rename directory d1 as d3
-
-  $ hg rename d1/ d3
-  moving d1/a to d3/a
-  moving d1/b to d3/b
-  moving d1/ba to d3/ba
-  moving d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d3/a
-d1/a
-  A d3/b
-d1/b
-  A d3/ba
-d1/ba
-  A d3/d11/a1
-d1/d11/a1
-  R d1/a
-  R d1/b
-  R d1/ba
-  R d1/d11/a1
-  $ hg update -C
-  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm -rf d3
-
-rename --after directory d1 as d3
-
-  $ mv d1 d3
-  $ hg rename --after d1 d3
-  moving d1/a to d3/a
-  moving d1/b to d3/b
-  moving d1/ba to d3/ba
-  moving d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d3/a
-d1/a
-  A d3/b
+# One recoded copy, one copy to record after commit
+  $ hg cp d1/b d1/c
+  $ cp d1/b d1/d
+  $ hg add d1/d
+  $ hg ci -m 'copy d1/b to d1/c and d1/d'
+  $ hg st -C --change .
+  A d1/c
 d1/b
-  A d3/ba
-d1/ba
-  A d3/d11/a1
-d1/d11/a1
-  R d1/a
-  R d1/b
-  R d1/ba
-  R d1/d11/a1
-  $ hg update -C
-  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm -rf d3
-
-move a directory using a relative path
-
-  $ (cd d2; mkdir d3; hg rename ../d1/d11 d3)
-  moving ../d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d2/d3/d11/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm -rf d2/d3
-
-move --after a directory using a relative path
-
-  $ (cd d2; mkdir d3; mv ../d1/d11 d3; hg rename --after ../d1/d11 d3)
-  moving ../d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d2/d3/d11/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files 

D8030: copy: add support for unmarking committed copies

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20149.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8030?vs=20082=20149

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8030/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8030

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  mercurial/context.py
  relnotes/next
  tests/test-completion.t
  tests/test-copy.t
  tests/test-rename-after-merge.t

CHANGE DETAILS

diff --git a/tests/test-rename-after-merge.t b/tests/test-rename-after-merge.t
--- a/tests/test-rename-after-merge.t
+++ b/tests/test-rename-after-merge.t
@@ -120,4 +120,10 @@
   $ hg log -r tip -C -v | grep copies
   copies:  b2 (b1)
 
+Test unmarking copies in merge commit
+
+  $ hg copy --forget -r . b2
+  abort: cannot unmark copy in merge commit
+  [255]
+
   $ cd ..
diff --git a/tests/test-copy.t b/tests/test-copy.t
--- a/tests/test-copy.t
+++ b/tests/test-copy.t
@@ -319,5 +319,56 @@
   A dir2/bar
   A dir2/foo
   ? dir2/untracked
+# Clean up for next test
+  $ hg forget dir2
+  removing dir2/bar
+  removing dir2/foo
+  $ rm -r dir2
+
+Test uncopy on committed copies
+
+# Commit some copies
+  $ hg cp bar baz
+  $ hg cp bar qux
+  $ hg ci -m copies
+  $ hg st -C --change .
+  A baz
+bar
+  A qux
+bar
+  $ base=$(hg log -r '.^' -T '{rev}')
+  $ hg log -G -T '{rev}:{node|short} {desc}\n' -r $base:
+  @  5:a612dc2edfda copies
+  |
+  o  4:4800b1f1f38e add dir/
+  |
+  ~
+# Add a dirty change on top to show that it's unaffected
+  $ echo dirty >> baz
+  $ hg st
+  M baz
+  $ cat baz
+  bleah
+  dirty
+  $ hg copy --forget -r . baz
+  saved backup bundle to 
$TESTTMP/part2/.hg/strip-backup/a612dc2edfda-e36b4448-uncopy.hg
+# The unwanted copy is no longer recorded, but the unrelated one is
+  $ hg st -C --change .
+  A baz
+  A qux
+bar
+# The old commit is gone and we have updated to the new commit
+  $ hg log -G -T '{rev}:{node|short} {desc}\n' -r $base:
+  @  5:c45090e5effe copies
+  |
+  o  4:4800b1f1f38e add dir/
+  |
+  ~
+# Working copy still has the uncommitted change
+  $ hg st
+  M baz
+  $ cat baz
+  bleah
+  dirty
 
   $ cd ..
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -257,7 +257,7 @@
   commit: addremove, close-branch, amend, secret, edit, force-close-branch, 
interactive, include, exclude, message, logfile, date, user, subrepos
   config: untrusted, edit, local, global, template
   continue: dry-run
-  copy: forget, after, force, include, exclude, dry-run
+  copy: forget, after, rev, force, include, exclude, dry-run
   debugancestor: 
   debugapplystreamclonebundle: 
   debugbuilddag: mergeable-file, overwritten-file, new-file
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -12,7 +12,8 @@
commits that are being merged, when there are conflicts. Also works
for conflicts caused by e.g. `hg graft`.
 
- * `hg copy --forget` can be used to unmark a file as copied.
+ * `hg copy --forget` can be used to unmark a file as copied. Use `hg
+   copy --forget -r REV` to unmark already committed copies.
 
 
 == New Experimental Features ==
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -2487,6 +2487,17 @@
 editor=editor,
 )
 
+def tomemctx_for_amend(self, precursor):
+extra = precursor.extra().copy()
+extra[b'amend_source'] = precursor.hex()
+return self.tomemctx(
+text=precursor.description(),
+branch=precursor.branch(),
+extra=extra,
+date=precursor.date(),
+user=precursor.user(),
+)
+
 def isdirty(self, path):
 return path in self._cache
 
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2312,6 +2312,13 @@
 (b'', b'forget', None, _(b'unmark a file as copied')),
 (b'A', b'after', None, _(b'record a copy that has already occurred')),
 (
+b'r',
+b'rev',
+b'',
+_(b'unmark copies in the given revision'),
+_(b'REV'),
+),
+(
 b'f',
 b'force',
 None,
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1426,14 +1426,33 @@
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
 if forget:
-match = scmutil.match(wctx, pats, opts)
-
-current_copies = wctx.p1copies()
-current_copies.update(wctx.p2copies())
-
-for f in wctx.walk(match):
+rev = opts[b'rev']
+if rev:
+ctx = scmutil.revsingle(repo, rev)
+else:
+ctx = repo[None]
+if ctx.rev() is None:
+new_ctx = ctx
+else:
+if 

D8029: copy: add option to unmark file as copied

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20148.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8029?vs=20081=20148

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8029/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8029

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  relnotes/next
  tests/test-completion.t
  tests/test-copy.t

CHANGE DETAILS

diff --git a/tests/test-copy.t b/tests/test-copy.t
--- a/tests/test-copy.t
+++ b/tests/test-copy.t
@@ -262,5 +262,62 @@
   xyzzy: not overwriting - file exists
   ('hg copy --after' to record the copy)
   [1]
+  $ hg co -qC .
+  $ rm baz xyzzy
+
+
+Test unmarking copy of a single file
+
+# Set up by creating a copy
+  $ hg cp bar baz
+# Test uncopying a non-existent file
+  $ hg copy --forget non-existent
+  non-existent: $ENOENT$
+# Test uncopying an tracked but unrelated file
+  $ hg copy --forget foo
+  foo: not unmarking as copy - file is not marked as copied
+# Test uncopying a copy source
+  $ hg copy --forget bar
+  bar: not unmarking as copy - file is not marked as copied
+# baz should still be marked as a copy
+  $ hg st -C
+  A baz
+bar
+# Test the normal case
+  $ hg copy --forget baz
+  $ hg st -C
+  A baz
+# Test uncopy with matching an non-matching patterns
+  $ hg cp bar baz --after
+  $ hg copy --forget bar baz
+  bar: not unmarking as copy - file is not marked as copied
+  $ hg st -C
+  A baz
+# Test uncopy with no exact matches
+  $ hg cp bar baz --after
+  $ hg copy --forget .
+  $ hg st -C
+  A baz
+  $ hg forget baz
+  $ rm baz
+
+Test unmarking copy of a directory
+
+  $ mkdir dir
+  $ echo foo > dir/foo
+  $ echo bar > dir/bar
+  $ hg add dir
+  adding dir/bar
+  adding dir/foo
+  $ hg ci -m 'add dir/'
+  $ hg cp dir dir2
+  copying dir/bar to dir2/bar
+  copying dir/foo to dir2/foo
+  $ touch dir2/untracked
+  $ hg copy --forget dir2
+  $ hg st -C
+  A dir2/bar
+  A dir2/foo
+  ? dir2/untracked
 
   $ cd ..
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -257,7 +257,7 @@
   commit: addremove, close-branch, amend, secret, edit, force-close-branch, 
interactive, include, exclude, message, logfile, date, user, subrepos
   config: untrusted, edit, local, global, template
   continue: dry-run
-  copy: after, force, include, exclude, dry-run
+  copy: forget, after, force, include, exclude, dry-run
   debugancestor: 
   debugapplystreamclonebundle: 
   debugbuilddag: mergeable-file, overwritten-file, new-file
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -12,6 +12,8 @@
commits that are being merged, when there are conflicts. Also works
for conflicts caused by e.g. `hg graft`.
 
+ * `hg copy --forget` can be used to unmark a file as copied.
+
 
 == New Experimental Features ==
 
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2309,6 +2309,7 @@
 @command(
 b'copy|cp',
 [
+(b'', b'forget', None, _(b'unmark a file as copied')),
 (b'A', b'after', None, _(b'record a copy that has already occurred')),
 (
 b'f',
@@ -2333,8 +2334,11 @@
 exist in the working directory. If invoked with -A/--after, the
 operation is recorded, but no copying is performed.
 
-This command takes effect with the next commit. To undo a copy
-before that, see :hg:`revert`.
+To undo marking a file as copied, use --forget. With that option,
+both SOURCE and DEST are interpreted as destinations. The destination
+file(s) will be left in place (still tracked).
+
+This command takes effect with the next commit.
 
 Returns 0 on success, 1 if errors are encountered.
 """
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1410,18 +1410,39 @@
 
 
 def copy(ui, repo, pats, opts, rename=False):
+check_incompatible_arguments(opts, b'forget', [b'dry_run'])
+
 # called with the repo lock held
 #
 # hgsep => pathname that uses "/" to separate directories
 # ossep => pathname that uses os.sep to separate directories
 cwd = repo.getcwd()
 targets = {}
+forget = opts.get(b"forget")
 after = opts.get(b"after")
 dryrun = opts.get(b"dry_run")
 wctx = repo[None]
 
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
+if forget:
+match = scmutil.match(wctx, pats, opts)
+
+current_copies = wctx.p1copies()
+current_copies.update(wctx.p2copies())
+
+for f in wctx.walk(match):
+if f in current_copies:
+wctx[f].markcopied(None)
+elif match.exact(f):
+ui.warn(
+_(
+b'%s: not unmarking as copy - file is not marked as 
copied\n'
+)
+% 

D8033: copy: move argument validation a little earlier

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20152.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8033?vs=20085=20152

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8033/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8033

AFFECTED FILES
  mercurial/cmdutil.py

CHANGE DETAILS

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1477,6 +1477,13 @@
 
 return
 
+pats = scmutil.expandpats(pats)
+if not pats:
+raise error.Abort(_(b'no source or destination specified'))
+if len(pats) == 1:
+raise error.Abort(_(b'no destination specified'))
+dest = pats.pop()
+
 if opts.get(b'rev'):
 raise error.Abort(_("--rev is only supported with --forget"))
 
@@ -1715,12 +1722,6 @@
 res = lambda p: dest
 return res
 
-pats = scmutil.expandpats(pats)
-if not pats:
-raise error.Abort(_(b'no source or destination specified'))
-if len(pats) == 1:
-raise error.Abort(_(b'no destination specified'))
-dest = pats.pop()
 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
 if not destdirexists:
 if len(pats) > 1 or matchmod.patkind(pats[0]):



To: martinvonz, #hg-reviewers, marmoute
Cc: marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8031: copy: rewrite walkpat() to depend less on dirstate

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20150.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8031?vs=20083=20150

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8031/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8031

AFFECTED FILES
  mercurial/cmdutil.py

CHANGE DETAILS

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1422,6 +1422,7 @@
 after = opts.get(b"after")
 dryrun = opts.get(b"dry_run")
 wctx = repo[None]
+pctx = wctx.p1()
 
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
@@ -1481,27 +1482,29 @@
 
 def walkpat(pat):
 srcs = []
-if after:
-badstates = b'?'
-else:
-badstates = b'?r'
 m = scmutil.match(wctx, [pat], opts, globbed=True)
 for abs in wctx.walk(m):
-state = repo.dirstate[abs]
 rel = uipathfn(abs)
 exact = m.exact(abs)
-if state in badstates:
-if exact and state == b'?':
-ui.warn(_(b'%s: not copying - file is not managed\n') % 
rel)
-if exact and state == b'r':
-ui.warn(
-_(
-b'%s: not copying - file has been marked for'
-b' remove\n'
+if abs not in wctx:
+if abs in pctx:
+if not after:
+if exact:
+ui.warn(
+_(
+b'%s: not copying - file has been marked '
+b'for remove\n'
+)
+% rel
+)
+continue
+else:
+if exact:
+ui.warn(
+_(b'%s: not copying - file is not managed\n') % rel
 )
-% rel
-)
-continue
+continue
+
 # abs: hgsep
 # rel: ossep
 srcs.append((abs, rel, exact))



To: martinvonz, #hg-reviewers, marmoute
Cc: marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8032: copy: rename `wctx` to `ctx` since it will not necessarily be working copy

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20151.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8032?vs=20084=20151

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8032/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8032

AFFECTED FILES
  mercurial/cmdutil.py

CHANGE DETAILS

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1421,8 +1421,8 @@
 forget = opts.get(b"forget")
 after = opts.get(b"after")
 dryrun = opts.get(b"dry_run")
-wctx = repo[None]
-pctx = wctx.p1()
+ctx = repo[None]
+pctx = ctx.p1()
 
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
@@ -1482,11 +1482,11 @@
 
 def walkpat(pat):
 srcs = []
-m = scmutil.match(wctx, [pat], opts, globbed=True)
-for abs in wctx.walk(m):
+m = scmutil.match(ctx, [pat], opts, globbed=True)
+for abs in ctx.walk(m):
 rel = uipathfn(abs)
 exact = m.exact(abs)
-if abs not in wctx:
+if abs not in ctx:
 if abs in pctx:
 if not after:
 if exact:
@@ -1639,13 +1639,13 @@
 
 # fix up dirstate
 scmutil.dirstatecopy(
-ui, repo, wctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd
+ui, repo, ctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd
 )
 if rename and not dryrun:
 if not after and srcexists and not samefile:
 rmdir = repo.ui.configbool(b'experimental', b'removeemptydirs')
 repo.wvfs.unlinkpath(abssrc, rmdir=rmdir)
-wctx.forget([abssrc])
+ctx.forget([abssrc])
 
 # pat: ossep
 # dest ossep



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8109: context: use manifest.find() instead of two separate calls

2020-02-10 Thread durin42 (Augie Fackler)
Closed by commit rHG2e2cfc3bea0b: context: use manifest.find() instead of two 
separate calls (authored by durin42).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8109?vs=20143=20147

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8109/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8109

AFFECTED FILES
  mercurial/context.py

CHANGE DETAILS

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -267,7 +267,7 @@
 def _fileinfo(self, path):
 if '_manifest' in self.__dict__:
 try:
-return self._manifest[path], self._manifest.flags(path)
+return self._manifest.find(path)
 except KeyError:
 raise error.ManifestLookupError(
 self._node, path, _(b'not found in manifest')



To: durin42, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8106: tests: accept new bzr message about switching branches

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz added inline comments.

INLINE COMMENTS

> test-convert-bzr.t:229
>Tree is up to date at revision 1.
> -  Switched to branch: *repo/branch/ (glob)
> +  Switched to branch *repo/branch/ (glob)
>$ sleep 1

The added space before `*` here broke tests. I fixed up the queued commit 
myself.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8106/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8106

To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6734: git: RFC of a new extension to _directly_ operate on git repositories

2020-02-10 Thread durin42 (Augie Fackler)
durin42 added a comment.
durin42 planned changes to this revision.


  Planned changes:
  
  - Fix up writing files not at repo root
  - Code formatting
  
  Uploaded mainly so people don't despair. I'm much happier with the manifest 
implementation now, and I think we're close to having something that could be 
landed that others could contribute to. I don't have time to put all the polish 
into this that it would need, but would love to help out...

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6734/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6734

To: durin42, #hg-reviewers
Cc: sluongng, tom.prince, sheehan, rom1dep, JordiGH, hollisb, mjpieters, 
mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7914: rust-matchers: implement `visit_children_set` for `FileMatcher`

2020-02-10 Thread Raphaël Gomès
Closed by commit rHG54d185eb24b5: rust-matchers: implement `visit_children_set` 
for `FileMatcher` (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7914?vs=19388=20146

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7914/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7914

AFFECTED FILES
  rust/hg-core/src/matchers.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/matchers.rs b/rust/hg-core/src/matchers.rs
--- a/rust/hg-core/src/matchers.rs
+++ b/rust/hg-core/src/matchers.rs
@@ -10,7 +10,9 @@
 use crate::{utils::hg_path::HgPath, DirsMultiset, DirstateMapError};
 use std::collections::HashSet;
 use std::iter::FromIterator;
+use std::ops::Deref;
 
+#[derive(Debug, PartialEq)]
 pub enum VisitChildrenSet<'a> {
 /// Don't visit anything
 Empty,
@@ -163,12 +165,48 @@
 }
 fn visit_children_set(
 ,
-_directory: impl AsRef,
+directory: impl AsRef,
 ) -> VisitChildrenSet {
-// TODO implement once we have `status.traverse`
-// This is useless until unknown files are taken into account
-// Which will not need to happen before the `IncludeMatcher`.
-unimplemented!()
+if self.files.is_empty() || !self.dirs.contains() {
+return VisitChildrenSet::Empty;
+}
+let dirs_as_set = self.dirs.iter().map(|k| k.deref()).collect();
+
+let mut candidates: HashSet<> =
+self.files.union(_as_set).map(|k| *k).collect();
+candidates.remove(HgPath::new(b""));
+
+if !directory.as_ref().is_empty() {
+let directory = [directory.as_ref().as_bytes(), b"/"].concat();
+candidates = candidates
+.iter()
+.filter_map(|c| {
+if c.as_bytes().starts_with() {
+Some(HgPath::new(_bytes()[directory.len()..]))
+} else {
+None
+}
+})
+.collect();
+}
+
+// `self.dirs` includes all of the directories, recursively, so if
+// we're attempting to match 'foo/bar/baz.txt', it'll have '', 'foo',
+// 'foo/bar' in it. Thus we can safely ignore a candidate that has a
+// '/' in it, indicating it's for a subdir-of-a-subdir; the immediate
+// subdir will be in there without a slash.
+VisitChildrenSet::Set(
+candidates
+.iter()
+.filter_map(|c| {
+if c.bytes().all(|b| *b != b'/') {
+Some(*c)
+} else {
+None
+}
+})
+.collect(),
+)
 }
 fn matches_everything() -> bool {
 false
@@ -177,3 +215,107 @@
 true
 }
 }
+#[cfg(test)]
+mod tests {
+use super::*;
+use pretty_assertions::assert_eq;
+
+#[test]
+fn test_filematcher_visit_children_set() {
+// Visitchildrenset
+let files = vec![HgPath::new(b"dir/subdir/foo.txt")];
+let matcher = FileMatcher::new().unwrap();
+
+let mut set = HashSet::new();
+set.insert(HgPath::new(b"dir"));
+assert_eq!(
+matcher.visit_children_set(HgPath::new(b"")),
+VisitChildrenSet::Set(set)
+);
+
+let mut set = HashSet::new();
+set.insert(HgPath::new(b"subdir"));
+assert_eq!(
+matcher.visit_children_set(HgPath::new(b"dir")),
+VisitChildrenSet::Set(set)
+);
+
+let mut set = HashSet::new();
+set.insert(HgPath::new(b"foo.txt"));
+assert_eq!(
+matcher.visit_children_set(HgPath::new(b"dir/subdir")),
+VisitChildrenSet::Set(set)
+);
+
+assert_eq!(
+matcher.visit_children_set(HgPath::new(b"dir/subdir/x")),
+VisitChildrenSet::Empty
+);
+assert_eq!(
+matcher.visit_children_set(HgPath::new(b"dir/subdir/foo.txt")),
+VisitChildrenSet::Empty
+);
+assert_eq!(
+matcher.visit_children_set(HgPath::new(b"folder")),
+VisitChildrenSet::Empty
+);
+}
+
+#[test]
+fn test_filematcher_visit_children_set_files_and_dirs() {
+let files = vec![
+HgPath::new(b"rootfile.txt"),
+HgPath::new(b"a/file1.txt"),
+HgPath::new(b"a/b/file2.txt"),
+// No file in a/b/c
+HgPath::new(b"a/b/c/d/file4.txt"),
+];
+let matcher = FileMatcher::new().unwrap();
+
+let mut set = HashSet::new();
+set.insert(HgPath::new(b"a"));
+set.insert(HgPath::new(b"rootfile.txt"));
+assert_eq!(
+

D6734: git: RFC of a new extension to _directly_ operate on git repositories

2020-02-10 Thread durin42 (Augie Fackler)
durin42 edited the summary of this revision.
durin42 updated this revision to Diff 20144.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6734?vs=18757=20144

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6734/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6734

AFFECTED FILES
  hgext/git/__init__.py
  hgext/git/dirstate.py
  hgext/git/gitlog.py
  hgext/git/gitutil.py
  hgext/git/index.py
  hgext/git/manifest.py
  setup.py
  tests/test-git-interop.t

CHANGE DETAILS

diff --git a/tests/test-git-interop.t b/tests/test-git-interop.t
new file mode 100644
--- /dev/null
+++ b/tests/test-git-interop.t
@@ -0,0 +1,196 @@
+This test requires pygit2:
+  > $PYTHON -c 'import pygit2' || exit 80
+
+Setup:
+  > GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+  > GIT_AUTHOR_EMAIL='t...@example.org'; export GIT_AUTHOR_EMAIL
+  > GIT_AUTHOR_DATE="2007-01-01 00:00:00 +"; export GIT_AUTHOR_DATE
+  > GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+  > GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+  > GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+  > count=10
+  > gitcommit() {
+  >GIT_AUTHOR_DATE="2007-01-01 00:00:$count +";
+  >GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+  >git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+  >count=`expr $count + 1`
+  >  }
+
+  > echo "[extensions]" >> $HGRCPATH
+  > echo "git=" >> $HGRCPATH
+
+Make a new repo with git:
+  $ mkdir foo
+  $ cd foo
+  $ git init
+  Initialized empty Git repository in $TESTTMP/foo/.git/
+Ignore the .hg directory within git:
+  $ echo .hg >> .git/info/exclude
+  $ echo alpha > alpha
+  $ git add alpha
+  $ gitcommit -am 'Add alpha'
+  $ echo beta > beta
+  $ git add beta
+  $ gitcommit -am 'Add beta'
+  $ echo gamma > gamma
+  $ git status
+  On branch master
+  Untracked files:
+(use "git add ..." to include in what will be committed)
+   gamma
+  
+  nothing added to commit but untracked files present (use "git add" to track)
+
+Without creating the .hg, hg status fails:
+  $ hg status
+  abort: no repository found in '$TESTTMP/foo' (.hg not found)!
+  [255]
+But if you run hg init --git, it works:
+  $ hg init --git
+  $ hg id --traceback
+  3d9be8deba43 tip master
+  $ hg status
+  ? gamma
+Log works too:
+  $ hg log
+  changeset:   1:3d9be8deba43
+  bookmark:master
+  tag: tip
+  user:test 
+  date:Mon Jan 01 00:00:11 2007 +
+  summary: Add beta
+  
+  changeset:   0:c5864c9d16fb
+  user:test 
+  date:Mon Jan 01 00:00:10 2007 +
+  summary: Add alpha
+  
+
+
+and bookmarks:
+  $ hg bookmarks
+   * master1:3d9be8deba43
+
+diff even works transparently in both systems:
+  $ echo blah >> alpha
+  $ git diff
+  diff --git a/alpha b/alpha
+  index 4a58007..faed1b7 100644
+  --- a/alpha
+  +++ b/alpha
+  @@ -1* +1,2 @@ (glob)
+   alpha
+  +blah
+  $ hg diff --git
+  diff --git a/alpha b/alpha
+  --- a/alpha
+  +++ b/alpha
+  @@ -1,1 +1,2 @@
+   alpha
+  +blah
+
+Remove a file, it shows as such:
+  $ rm alpha
+  $ hg status
+  ! alpha
+  ? gamma
+
+Revert works:
+  $ hg revert alpha --traceback
+  $ hg status
+  ? gamma
+  $ git status
+  On branch master
+  Untracked files:
+(use "git add ..." to include in what will be committed)
+   gamma
+  
+  nothing added to commit but untracked files present (use "git add" to track)
+
+Add shows sanely in both:
+  $ hg add gamma
+  $ hg status
+  A gamma
+  $ hg files
+  alpha
+  beta
+  gamma
+  $ git ls-files
+  alpha
+  beta
+  gamma
+  $ git status
+  On branch master
+  Changes to be committed:
+(use "git restore --staged ..." to unstage)
+   new file:   gamma
+  
+
+forget does what it should as well:
+  $ hg forget gamma
+  $ hg status
+  ? gamma
+  $ git status
+  On branch master
+  Untracked files:
+(use "git add ..." to include in what will be committed)
+   gamma
+  
+  nothing added to commit but untracked files present (use "git add" to track)
+
+hg log FILE
+
+  $ echo a >> alpha
+  $ hg ci -m 'more alpha' --traceback
+  $ echo b >> beta
+  $ hg ci -m 'more beta'
+  $ echo a >> alpha
+  $ hg ci -m 'even more alpha'
+  $ hg log -G alpha
+  @  changeset:   4:bd975ddde71c
+  :  bookmark:master
+  :  tag: tip
+  :  user:test 
+  :  date:Thu Jan 01 00:00:00 1970 +
+  :  summary: even more alpha
+  :
+  o  changeset:   2:77f597222800
+  :  user:test 
+  :  date:Thu Jan 01 00:00:00 1970 +
+  :  summary: more alpha
+  :
+  o  changeset:   0:c5864c9d16fb
+ user:test 
+ date:Mon Jan 01 00:00:10 2007 +
+ summary: Add alpha
+  
+  $ hg log -G beta
+  o  changeset:   3:b40d4fed5e27
+  :  user:test 
+  :  date:Thu Jan 01 00:00:00 1970 +
+  :  summary: more beta
+  :
+  o  changeset:   1:3d9be8deba43
+  |  user:   

D8109: context: use manifest.find() instead of two separate calls

2020-02-10 Thread durin42 (Augie Fackler)
durin42 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  I noticed this while debugging an extension that's implementing the manifest
  interface. Always nice to save a function call.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D8109

AFFECTED FILES
  mercurial/context.py

CHANGE DETAILS

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -267,7 +267,7 @@
 def _fileinfo(self, path):
 if '_manifest' in self.__dict__:
 try:
-return self._manifest[path], self._manifest.flags(path)
+return self._manifest.find(path)
 except KeyError:
 raise error.ManifestLookupError(
 self._node, path, _(b'not found in manifest')



To: durin42, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8085: manifest: move matches method to be outside the interface

2020-02-10 Thread durin42 (Augie Fackler)
Closed by commit rHG0bf3b5e80d30: manifest: move matches method to be outside 
the interface (authored by durin42).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8085?vs=20101=20142

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8085/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8085

AFFECTED FILES
  mercurial/interfaces/repository.py
  mercurial/manifest.py
  tests/test-manifest.py

CHANGE DETAILS

diff --git a/tests/test-manifest.py b/tests/test-manifest.py
--- a/tests/test-manifest.py
+++ b/tests/test-manifest.py
@@ -171,7 +171,7 @@
 self.assertEqual(want, m[b'foo'])
 # make sure the suffix survives a copy
 match = matchmod.match(util.localpath(b'/repo'), b'', [b're:foo'])
-m2 = m.matches(match)
+m2 = m._matches(match)
 self.assertEqual(want, m2[b'foo'])
 self.assertEqual(1, len(m2))
 m2 = m.copy()
@@ -196,7 +196,7 @@
 
 match.matchfn = filt
 with self.assertRaises(AssertionError):
-m.matches(match)
+m._matches(match)
 
 def testRemoveItem(self):
 m = self.parsemanifest(A_SHORT_MANIFEST)
@@ -300,7 +300,7 @@
 m = self.parsemanifest(A_HUGE_MANIFEST)
 
 match = matchmod.exact([b'file1', b'file200', b'file300'])
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 w = (b'file1\0%sx\n' b'file200\0%sl\n' b'file300\0%s\n') % (
 HASH_2,
@@ -318,7 +318,7 @@
 match = matchmod.exact(
 [b'a/b/c/bar.txt', b'a/b/d/qux.py', b'readme.txt', b'nonexistent']
 )
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(
 [b'a/b/c/bar.txt', b'a/b/d/qux.py', b'readme.txt'], m2.keys()
@@ -332,7 +332,7 @@
 match = matchmod.match(
 util.localpath(b'/repo'), b'', [b'a/f'], default=b'relpath'
 )
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual([], m2.keys())
 
@@ -343,7 +343,7 @@
 
 flist = m.keys()[80:300]
 match = matchmod.exact(flist)
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(flist, m2.keys())
 
@@ -352,7 +352,7 @@
 m = self.parsemanifest(A_DEEPER_MANIFEST)
 
 match = matchmod.match(util.localpath(b'/repo'), b'', [b''])
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(m.keys(), m2.keys())
 
@@ -364,7 +364,7 @@
 match = matchmod.match(
 util.localpath(b'/repo'), b'', [b'a/b'], default=b'relpath'
 )
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(
 [
@@ -388,7 +388,7 @@
 m = self.parsemanifest(A_DEEPER_MANIFEST)
 
 match = matchmod.exact([b'a/b'])
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual([], m2.keys())
 
@@ -400,7 +400,7 @@
 match = matchmod.match(
 util.localpath(b'/repo'), b'a/b', [b'.'], default=b'relpath'
 )
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(
 [
@@ -423,7 +423,7 @@
 m = self.parsemanifest(A_DEEPER_MANIFEST)
 
 match = matchmod.match(util.localpath(b'/repo'), b'', [b'a/b/*/*.txt'])
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(
 [b'a/b/c/bar.txt', b'a/b/c/foo.txt', b'a/b/d/ten.txt'], m2.keys()
diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -545,7 +545,7 @@
 if not self.hasdir(fn):
 match.bad(fn, None)
 
-def matches(self, match):
+def _matches(self, match):
 '''generate a new manifest filtered by the match argument'''
 if match.always():
 return self.copy()
@@ -578,8 +578,8 @@
 string.
 '''
 if match:
-m1 = self.matches(match)
-m2 = m2.matches(match)
+m1 = self._matches(match)
+m2 = m2._matches(match)
 return m1.diff(m2, clean=clean)
 return self._lm.diff(m2._lm, clean)
 
@@ -1075,8 +1075,8 @@
 def filesnotin(self, m2, match=None):
 '''Set of files in this manifest that are not in the other'''
 if match and not match.always():
-m1 = self.matches(match)
-m2 = m2.matches(match)
+m1 = self._matches(match)
+m2 = m2._matches(match)
 return m1.filesnotin(m2)
 
 files = set()
@@ -1122,9 +1122,6 @@
 def walk(self, match):
 '''Generates matching file names.
 
-Equivalent to manifest.matches(match).iterkeys(), but without creating
-an 

D8107: tags: fix some type confusion exposed in python 3

2020-02-10 Thread durin42 (Augie Fackler)
Closed by commit rHGe80da7a63264: tags: fix some type confusion exposed in 
python 3 (authored by durin42).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8107?vs=20127=20140

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8107/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8107

AFFECTED FILES
  mercurial/debugcommands.py

CHANGE DETAILS

diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -3498,8 +3498,8 @@
 for r in repo:
 node = repo[r].node()
 tagsnode = cache.getfnode(node, computemissing=False)
-tagsnodedisplay = hex(tagsnode) if tagsnode else 'missing/invalid'
-ui.write(b'%s %s %s\n' % (r, hex(node), tagsnodedisplay))
+tagsnodedisplay = hex(tagsnode) if tagsnode else b'missing/invalid'
+ui.write(b'%d %s %s\n' % (r, hex(node), tagsnodedisplay))
 
 
 @command(



To: durin42, #hg-reviewers, pulkit
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8108: tags: use modern // operator for division

2020-02-10 Thread durin42 (Augie Fackler)
Closed by commit rHG8ec186c1ccfe: tags: use modern // operator for division 
(authored by durin42).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8108?vs=20128=20141

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8108/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8108

AFFECTED FILES
  mercurial/tags.py

CHANGE DETAILS

diff --git a/mercurial/tags.py b/mercurial/tags.py
--- a/mercurial/tags.py
+++ b/mercurial/tags.py
@@ -721,7 +721,7 @@
 self._dirtyoffset = None
 
 rawlentokeep = min(
-wantedlen, (rawlen / _fnodesrecsize) * _fnodesrecsize
+wantedlen, (rawlen // _fnodesrecsize) * _fnodesrecsize
 )
 if rawlen > rawlentokeep:
 # There's no easy way to truncate array instances. This seems



To: durin42, #hg-reviewers, pulkit
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7827: rebase: don't use rebased node as dirstate p2 (BC)

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHG9c9cfecd4600: rebase: dont use rebased node as 
dirstate p2 (BC) (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7827?vs=20097=20137

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7827/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7827

AFFECTED FILES
  hgext/rebase.py
  relnotes/next
  tests/test-rebase-abort.t
  tests/test-rebase-collapse.t
  tests/test-rebase-conflicts.t
  tests/test-rebase-interruptions.t
  tests/test-rebase-obsolete.t
  tests/test-rebase-parameters.t
  tests/test-rebase-transaction.t

CHANGE DETAILS

diff --git a/tests/test-rebase-transaction.t b/tests/test-rebase-transaction.t
--- a/tests/test-rebase-transaction.t
+++ b/tests/test-rebase-transaction.t
@@ -114,7 +114,7 @@
   |
   | @  4: Z
   | |
-  @ |  3: C
+  % |  3: C
   | |
   | o  2: Y
   | |
@@ -123,9 +123,9 @@
   o  0: A
   
   $ hg st
-  M C
   M conflict
   A B
+  A C
   ? conflict.orig
   $ echo resolved > conflict
   $ hg resolve -m
diff --git a/tests/test-rebase-parameters.t b/tests/test-rebase-parameters.t
--- a/tests/test-rebase-parameters.t
+++ b/tests/test-rebase-parameters.t
@@ -481,11 +481,9 @@
   $ hg summary
   parent: 1:56daeba07f4b 
c2
-  parent: 2:e4e3f3546619 tip
-   c2b
   branch: default
-  commit: 1 modified, 1 unresolved (merge)
-  update: (current)
+  commit: 1 unresolved (clean)
+  update: 1 new changesets, 2 branch heads (merge)
   phases: 3 draft
   rebase: 0 rebased, 1 remaining (rebase --continue)
 
diff --git a/tests/test-rebase-obsolete.t b/tests/test-rebase-obsolete.t
--- a/tests/test-rebase-obsolete.t
+++ b/tests/test-rebase-obsolete.t
@@ -1795,19 +1795,15 @@
   $ hg log -G
   @  2:b18e25de2cf5 D
   |
-  | @  1:2ec65233581b B (pruned using prune)
-  |/
   o  0:426bada5c675 A
   
   $ hg summary
   parent: 2:b18e25de2cf5 tip
D
-  parent: 1:2ec65233581b  (obsolete)
-   B
   branch: default
-  commit: 2 modified, 1 unknown, 1 unresolved (merge)
+  commit: 1 modified, 1 added, 1 unknown, 1 unresolved
   update: (current)
-  phases: 3 draft
+  phases: 2 draft
   rebase: 0 rebased, 2 remaining (rebase --continue)
 
   $ hg rebase --abort
diff --git a/tests/test-rebase-interruptions.t 
b/tests/test-rebase-interruptions.t
--- a/tests/test-rebase-interruptions.t
+++ b/tests/test-rebase-interruptions.t
@@ -294,7 +294,7 @@
   $ hg tglogp
   @  7: 401ccec5e39f secret 'C'
   |
-  | @  6: a0b2430ebfb8 secret 'F'
+  | o  6: a0b2430ebfb8 secret 'F'
   | |
   o |  5: 45396c49d53b public 'B'
   | |
@@ -345,7 +345,7 @@
   $ hg tglogp
   @  7: 401ccec5e39f secret 'C'
   |
-  | @  6: a0b2430ebfb8 secret 'F'
+  | o  6: a0b2430ebfb8 secret 'F'
   | |
   o |  5: 45396c49d53b public 'B'
   | |
@@ -395,7 +395,7 @@
   $ hg tglogp
   @  7: 401ccec5e39f secret 'C'
   |
-  | @  6: a0b2430ebfb8 secret 'F'
+  | o  6: a0b2430ebfb8 secret 'F'
   | |
   o |  5: 45396c49d53b public 'B'
   | |
diff --git a/tests/test-rebase-conflicts.t b/tests/test-rebase-conflicts.t
--- a/tests/test-rebase-conflicts.t
+++ b/tests/test-rebase-conflicts.t
@@ -456,15 +456,14 @@
   warning: conflicts while merging conflict! (edit, then use 'hg resolve 
--mark')
   unresolved conflicts (see hg resolve, then hg rebase --continue)
   [1]
-The current parents are not 7 and 8 even though that's what we're merging
   $ hg tglog
   @  8:draft 'E'
   |
-  | o  7:draft 'D'
+  | @  7:draft 'D'
   |/
   o  6:draft 'C'
   |
-  | @5:draft 'F'
+  | %5:draft 'F'
   | |\
   | | o  4:draft 'E'
   | | |
diff --git a/tests/test-rebase-collapse.t b/tests/test-rebase-collapse.t
--- a/tests/test-rebase-collapse.t
+++ b/tests/test-rebase-collapse.t
@@ -712,7 +712,7 @@
   |
   | @  2: 82b8abf9c185 'D'
   | |
-  @ |  1: f899f3910ce7 'B'
+  % |  1: f899f3910ce7 'B'
   |/
   o  0: 4a2df7238c3b 'A'
   
@@ -736,7 +736,7 @@
   unresolved conflicts (see hg resolve, then hg rebase --continue)
   [1]
   $ hg tglog
-  @  3: 63668d570d21 'C'
+  %  3: 63668d570d21 'C'
   |
   | @  2: 82b8abf9c185 'D'
   | |
diff --git a/tests/test-rebase-abort.t b/tests/test-rebase-abort.t
--- a/tests/test-rebase-abort.t
+++ b/tests/test-rebase-abort.t
@@ -236,7 +236,7 @@
   [1]
 
   $ hg tglog
-  @  4:draft 'C1'
+  %  4:draft 'C1'
   |
   o  3:draft 'B bis'
   |
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -21,6 +21,11 @@
 
 == Backwards Compatibility Changes ==
 
+ * When `hg rebase` pauses for merge conflict resolution, the working
+   copy will no longer have the rebased node as a second parent. You
+   can use the new `conflictparents()` revset for finding the other
+   parent during a conflict.
+
 
 == Internal API Changes ==
 
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -618,6 +618,7 @@
 repo,
 rev,
 p1,
+p2,
   

D8043: graphlog: use '%' for other context in merge conflict

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHG14d0e89520a2: graphlog: use % for other context 
in merge conflict (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8043?vs=20095=20135

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8043/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8043

AFFECTED FILES
  hgext/beautifygraph.py
  mercurial/hgweb/webutil.py
  mercurial/logcmdutil.py
  mercurial/templatekw.py
  relnotes/next
  tests/test-backout.t
  tests/test-graft-interrupted.t
  tests/test-rebase-collapse.t
  tests/test-strip.t
  tests/test-update-branches.t

CHANGE DETAILS

diff --git a/tests/test-update-branches.t b/tests/test-update-branches.t
--- a/tests/test-update-branches.t
+++ b/tests/test-update-branches.t
@@ -254,7 +254,7 @@
   |
   @  4:d047485b3896 0:60829823a42a  b1
   |
-  | o  3:6efa171f091b 1:0786582aa4b1
+  | %  3:6efa171f091b 1:0786582aa4b1
   | |
   | | o  2:bd10386d478c
   | |/
diff --git a/tests/test-strip.t b/tests/test-strip.t
--- a/tests/test-strip.t
+++ b/tests/test-strip.t
@@ -598,7 +598,7 @@
   |  date:Thu Jan 01 00:00:00 1970 +
   |  summary: b
   |
-  o  changeset:   0:9ab35a2d17cb
+  %  changeset:   0:9ab35a2d17cb
  user:test
  date:Thu Jan 01 00:00:00 1970 +
  summary: a
diff --git a/tests/test-rebase-collapse.t b/tests/test-rebase-collapse.t
--- a/tests/test-rebase-collapse.t
+++ b/tests/test-rebase-collapse.t
@@ -762,7 +762,7 @@
   abort: edit failed: false exited with status 1
   [255]
   $ hg tglog
-  o  3: 63668d570d21 'C'
+  %  3: 63668d570d21 'C'
   |
   | @  2: 82b8abf9c185 'D'
   | |
diff --git a/tests/test-graft-interrupted.t b/tests/test-graft-interrupted.t
--- a/tests/test-graft-interrupted.t
+++ b/tests/test-graft-interrupted.t
@@ -431,7 +431,7 @@
   $ hg log -GT "{rev}:{node|short} {desc}"
   @  6:6ec71c037d94 added x
   |
-  | o  5:36b793615f78 added foo to c
+  | %  5:36b793615f78 added foo to c
   | |
   | | o  4:863a25e1a9ea added x
   | |/
@@ -622,7 +622,7 @@
   $ hg log -GT "{rev}:{node|short} {desc}\n"
   @  4:2aa9ad1006ff B in file a
   |
-  | o  3:09e253b87e17 A in file a
+  | %  3:09e253b87e17 A in file a
   | |
   | o  2:d36c0562f908 c
   | |
@@ -669,7 +669,7 @@
   $ hg log -GT "{rev}:{node|short} {desc}\n"
   @  4:2aa9ad1006ff B in file a
   |
-  | o  3:09e253b87e17 A in file a
+  | %  3:09e253b87e17 A in file a
   | |
   | o  2:d36c0562f908 c
   | |
@@ -712,7 +712,7 @@
   $ hg log -GT "{rev}:{node|short} {desc}\n"
   @  4:2aa9ad1006ff B in file a
   |
-  | o  3:09e253b87e17 A in file a
+  | %  3:09e253b87e17 A in file a
   | |
   | o  2:d36c0562f908 c
   | |
diff --git a/tests/test-backout.t b/tests/test-backout.t
--- a/tests/test-backout.t
+++ b/tests/test-backout.t
@@ -103,7 +103,7 @@
   |  date:Thu Jan 01 00:00:02 1970 +
   |  summary: grapes
   |
-  o  changeset:   1:22cb4f70d813
+  %  changeset:   1:22cb4f70d813
   |  user:test
   |  date:Thu Jan 01 00:00:01 1970 +
   |  summary: chair
@@ -748,7 +748,7 @@
   |  date:Thu Jan 01 00:00:00 1970 +
   |  summary: capital three
   |
-  o  changeset:   0:a30dd8addae3
+  %  changeset:   0:a30dd8addae3
  user:test
  date:Thu Jan 01 00:00:00 1970 +
  summary: initial
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -3,7 +3,12 @@
  * `hg purge`/`hg clean` can now delete ignored files instead of
untracked files, with the new -i flag.
 
- * New `conflictlocal()` and `conflictother()` revsets returns the
+ * `hg log` now defaults to using an '%' symbol for commits involved
+in unresolved merge conflicts. That includes unresolved conflicts
+caused by e.g. `hg update --merge` and `hg graft`. '@' still takes
+precedence, so what used to be marked '@' still is.
+
+ * New `conflictlocal()` and `conflictother()` revsets return the
commits that are being merged, when there are conflicts. Also works
for conflicts caused by e.g. `hg graft`.
 
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -396,26 +396,38 @@
 return templateutil.compatfileslist(context, mapping, b'file', ctx.files())
 
 
-@templatekeyword(b'graphnode', requires={b'repo', b'ctx'})
+@templatekeyword(b'graphnode', requires={b'repo', b'ctx', b'cache'})
 def showgraphnode(context, mapping):
 """String. The character representing the changeset node in an ASCII
 revision graph."""
 repo = context.resource(mapping, b'repo')
 ctx = context.resource(mapping, b'ctx')
-return getgraphnode(repo, ctx)
+cache = context.resource(mapping, b'cache')
+return getgraphnode(repo, ctx, cache)
 
 
-def getgraphnode(repo, ctx):
-return getgraphnodecurrent(repo, ctx) or getgraphnodesymbol(ctx)
+def getgraphnode(repo, ctx, cache):

D7829: rebase: remove some now-unused parent arguments

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHGcd43cae79f25: rebase: remove some now-unused parent 
arguments (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7829?vs=20099=20139

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7829/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7829

AFFECTED FILES
  hgext/rebase.py

CHANGE DETAILS

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -506,7 +506,7 @@
 p.complete()
 ui.note(_(b'rebase merging completed\n'))
 
-def _concludenode(self, rev, p1, p2, editor, commitmsg=None):
+def _concludenode(self, rev, p1, editor, commitmsg=None):
 '''Commit the wd changes with parents p1 and p2.
 
 Reuse commit info from rev but also store useful information in extra.
@@ -530,8 +530,6 @@
 if self.inmemory:
 newnode = commitmemorynode(
 repo,
-p1,
-p2,
 wctx=self.wctx,
 extra=extra,
 commitmsg=commitmsg,
@@ -543,8 +541,6 @@
 else:
 newnode = commitnode(
 repo,
-p1,
-p2,
 extra=extra,
 commitmsg=commitmsg,
 editor=editor,
@@ -640,7 +636,7 @@
 editor = cmdutil.getcommiteditor(
 editform=editform, **pycompat.strkwargs(opts)
 )
-newnode = self._concludenode(rev, p1, p2, editor)
+newnode = self._concludenode(rev, p1, editor)
 else:
 # Skip commit if we are collapsing
 newnode = None
@@ -699,7 +695,7 @@
 
 self.wctx.setparents(repo[p1].node(), repo[self.external].node())
 newnode = self._concludenode(
-revtoreuse, p1, self.external, editor, commitmsg=commitmsg
+revtoreuse, p1, editor, commitmsg=commitmsg
 )
 
 if newnode is not None:
@@ -1421,7 +1417,7 @@
 )
 
 
-def commitmemorynode(repo, p1, p2, wctx, editor, extra, user, date, commitmsg):
+def commitmemorynode(repo, wctx, editor, extra, user, date, commitmsg):
 '''Commit the memory changes with parents p1 and p2.
 Return node of committed revision.'''
 # Replicates the empty check in ``repo.commit``.
@@ -1447,7 +1443,7 @@
 return commitres
 
 
-def commitnode(repo, p1, p2, editor, extra, user, date, commitmsg):
+def commitnode(repo, editor, extra, user, date, commitmsg):
 '''Commit the wd changes with parents p1 and p2.
 Return node of committed revision.'''
 dsguard = util.nullcontextmanager()



To: martinvonz, #hg-reviewers, durin42
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7828: rebase: remove some redundant setting of dirstate parents

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHG8082a77cc3a2: rebase: remove some redundant setting of 
dirstate parents (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7828?vs=20098=20138

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7828/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7828

AFFECTED FILES
  hgext/rebase.py

CHANGE DETAILS

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -697,6 +697,7 @@
 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
 revtoreuse = max(self.state)
 
+self.wctx.setparents(repo[p1].node(), repo[self.external].node())
 newnode = self._concludenode(
 revtoreuse, p1, self.external, editor, commitmsg=commitmsg
 )
@@ -1433,7 +1434,6 @@
 if b'branch' in extra:
 branch = extra[b'branch']
 
-wctx.setparents(repo[p1].node(), repo[p2].node())
 memctx = wctx.tomemctx(
 commitmsg,
 date=date,
@@ -1454,8 +1454,6 @@
 if not repo.ui.configbool(b'rebase', b'singletransaction'):
 dsguard = dirstateguard.dirstateguard(repo, b'rebase')
 with dsguard:
-repo.setparents(repo[p1].node(), repo[p2].node())
-
 # Commit might fail if unresolved files exist
 newnode = repo.commit(
 text=commitmsg, user=user, date=date, extra=extra, editor=editor



To: martinvonz, #hg-reviewers, durin42
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7826: rebase: stop relying on having two parents to resume rebase

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHGb42ce825308e: rebase: stop relying on having two parents to 
resume rebase (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7826?vs=20096=20136

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7826/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7826

AFFECTED FILES
  hgext/rebase.py

CHANGE DETAILS

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -178,6 +178,7 @@
 # --continue or --abort)), the original repo should be used so
 # visibility-dependent revsets are correct.
 self.prepared = False
+self.resume = False
 self._repo = repo
 
 self.ui = ui
@@ -367,6 +368,7 @@
 _checkobsrebase(self.repo, self.ui, obsoleteset, skippedset)
 
 def _prepareabortorcontinue(self, isabort, backup=True, suppwarns=False):
+self.resume = True
 try:
 self.restorestatus()
 self.collapsemsg = restorecollapsemsg(self.repo, isabort)
@@ -606,8 +608,9 @@
 self.skipped,
 self.obsoletenotrebased,
 )
-if not self.inmemory and len(repo[None].parents()) == 2:
+if self.resume and self.wctx.p1().rev() == p1:
 repo.ui.debug(b'resuming interrupted rebase\n')
+self.resume = False
 else:
 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
 with ui.configoverride(overrides, b'rebase'):



To: martinvonz, #hg-reviewers, durin42
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8041: revset: add a revset for parents in merge state

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHG8561ad49915d: revset: add a revset for parents in merge 
state (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8041?vs=20094=20133

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8041/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8041

AFFECTED FILES
  mercurial/revset.py
  relnotes/next
  tests/test-merge4.t

CHANGE DETAILS

diff --git a/tests/test-merge4.t b/tests/test-merge4.t
--- a/tests/test-merge4.t
+++ b/tests/test-merge4.t
@@ -23,3 +23,37 @@
   abort: cannot commit merge with missing files
   [255]
 
+
+Test conflict*() revsets
+
+# Bad usage
+  $ hg log -r 'conflictlocal(foo)'
+  hg: parse error: conflictlocal takes no arguments
+  [255]
+  $ hg log -r 'conflictother(foo)'
+  hg: parse error: conflictother takes no arguments
+  [255]
+  $ hg co -C .
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+# No merge parents when not merging
+  $ hg log -r 'conflictlocal() + conflictother()'
+# No merge parents when there is no conflict
+  $ hg merge 1
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg log -r 'conflictlocal() + conflictother()'
+  $ hg co -C .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo conflict > b
+  $ hg ci -Aqm 'conflicting change to b'
+  $ hg merge 1
+  merging b
+  warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to 
abandon
+  [1]
+# Shows merge parents when there is a conflict
+  $ hg log -r 'conflictlocal()' -T '{rev} {desc}\n'
+  3 conflicting change to b
+  $ hg log -r 'conflictother()' -T '{rev} {desc}\n'
+  1 commit #1
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -3,6 +3,11 @@
  * `hg purge`/`hg clean` can now delete ignored files instead of
untracked files, with the new -i flag.
 
+ * New `conflictlocal()` and `conflictother()` revsets returns the
+   commits that are being merged, when there are conflicts. Also works
+   for conflicts caused by e.g. `hg graft`.
+
+
 == New Experimental Features ==
 
 
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -769,6 +769,38 @@
 return subset
 
 
+@predicate(b'conflictlocal()', safe=True)
+def conflictlocal(repo, subset, x):
+"""The local side of the merge, if currently in an unresolved merge.
+
+"merge" here includes merge conflicts from e.g. 'hg rebase' or 'hg graft'.
+"""
+getargs(x, 0, 0, _(b"conflictlocal takes no arguments"))
+from . import merge
+
+mergestate = merge.mergestate.read(repo)
+if mergestate.active() and repo.changelog.hasnode(mergestate.local):
+return subset & {repo.changelog.rev(mergestate.local)}
+
+return baseset()
+
+
+@predicate(b'conflictother()', safe=True)
+def conflictother(repo, subset, x):
+"""The other side of the merge, if currently in an unresolved merge.
+
+"merge" here includes merge conflicts from e.g. 'hg rebase' or 'hg graft'.
+"""
+getargs(x, 0, 0, _(b"conflictother takes no arguments"))
+from . import merge
+
+mergestate = merge.mergestate.read(repo)
+if mergestate.active() and repo.changelog.hasnode(mergestate.other):
+return subset & {repo.changelog.rev(mergestate.other)}
+
+return baseset()
+
+
 @predicate(b'contains(pattern)', weight=100)
 def contains(repo, subset, x):
 """The revision's manifest contains a file matching pattern (but might not



To: martinvonz, #hg-reviewers, durin42
Cc: marmoute, yuja, pulkit, mjpieters, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8042: tests: add `hg log -G` output when there are merge conflicts

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHGab632e27f296: tests: add `hg log -G` output when there are 
merge conflicts (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8042?vs=19702=20134

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8042/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8042

AFFECTED FILES
  tests/test-backout.t
  tests/test-strip.t
  tests/test-update-branches.t

CHANGE DETAILS

diff --git a/tests/test-update-branches.t b/tests/test-update-branches.t
--- a/tests/test-update-branches.t
+++ b/tests/test-update-branches.t
@@ -249,6 +249,19 @@
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges
   [1]
+  $ hg log -G --template '{rev}:{node|short} {parents} {branches}\n'
+  o  5:ff252e8273df  b1
+  |
+  @  4:d047485b3896 0:60829823a42a  b1
+  |
+  | o  3:6efa171f091b 1:0786582aa4b1
+  | |
+  | | o  2:bd10386d478c
+  | |/
+  | o  1:0786582aa4b1
+  |/
+  o  0:60829823a42a
+  
   $ hg st
   M a
   ? a.orig
diff --git a/tests/test-strip.t b/tests/test-strip.t
--- a/tests/test-strip.t
+++ b/tests/test-strip.t
@@ -591,6 +591,18 @@
   phases: 2 draft
   mq: 3 unapplied
 
+  $ hg log --graph
+  @  changeset:   1:76dcf9fab855
+  |  tag: tip
+  |  user:test
+  |  date:Thu Jan 01 00:00:00 1970 +
+  |  summary: b
+  |
+  o  changeset:   0:9ab35a2d17cb
+ user:test
+ date:Thu Jan 01 00:00:00 1970 +
+ summary: a
+  
   $ echo c > b
   $ hg strip tip
   abort: uncommitted changes
diff --git a/tests/test-backout.t b/tests/test-backout.t
--- a/tests/test-backout.t
+++ b/tests/test-backout.t
@@ -86,6 +86,33 @@
   commit: 1 unresolved (clean)
   update: (current)
   phases: 5 draft
+  $ hg log -G
+  @  changeset:   4:ed7b793d
+  |  tag: tip
+  |  user:test
+  |  date:Thu Jan 01 00:00:05 1970 +
+  |  summary: ypples
+  |
+  o  changeset:   3:1c2161e97c0a
+  |  user:test
+  |  date:Thu Jan 01 00:00:04 1970 +
+  |  summary: Backed out changeset 22cb4f70d813
+  |
+  o  changeset:   2:a8c6e511cfee
+  |  user:test
+  |  date:Thu Jan 01 00:00:02 1970 +
+  |  summary: grapes
+  |
+  o  changeset:   1:22cb4f70d813
+  |  user:test
+  |  date:Thu Jan 01 00:00:01 1970 +
+  |  summary: chair
+  |
+  o  changeset:   0:a5cb2dde5805
+ user:test
+ date:Thu Jan 01 00:00:00 1970 +
+ summary: tomatoes
+  
 
 file that was removed is recreated
 (this also tests that editor is not invoked if the commit message is
@@ -709,6 +736,23 @@
   commit: 1 unresolved (clean)
   update: (current)
   phases: 3 draft
+  $ hg log -G
+  @  changeset:   2:b71750c4b0fd
+  |  tag: tip
+  |  user:test
+  |  date:Thu Jan 01 00:00:00 1970 +
+  |  summary: capital ten
+  |
+  o  changeset:   1:913609522437
+  |  user:test
+  |  date:Thu Jan 01 00:00:00 1970 +
+  |  summary: capital three
+  |
+  o  changeset:   0:a30dd8addae3
+ user:test
+ date:Thu Jan 01 00:00:00 1970 +
+ summary: initial
+  
   $ hg resolve --all --debug
   picked tool ':merge' for foo (binary False symlink False changedelete False)
   merging foo



To: martinvonz, #hg-reviewers, durin42
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7907: rebase: always be graft-like, not merge-like, also for merges

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHG77bb38be00ea: rebase: always be graft-like, not merge-like, 
also for merges (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7907?vs=20093=20131

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7907/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7907

AFFECTED FILES
  hgext/rebase.py
  tests/test-rebase-dest.t
  tests/test-rebase-newancestor.t

CHANGE DETAILS

diff --git a/tests/test-rebase-newancestor.t b/tests/test-rebase-newancestor.t
--- a/tests/test-rebase-newancestor.t
+++ b/tests/test-rebase-newancestor.t
@@ -68,11 +68,6 @@
 that is mixed up with the actual merge stuff and there is in general no way to
 separate them.
 
-Note: The dev branch contains _no_ changes to f-default. It might be unclear
-how rebasing of ancestor merges should be handled, but the current behavior
-with spurious prompts for conflicts in files that didn't change seems very
-wrong.
-
   $ hg init ancestor-merge
   $ cd ancestor-merge
 
@@ -133,16 +128,11 @@
   note: not rebasing 1:1d1a643d390e "dev: create branch", its destination 
already has all its changes
   rebasing 2:ec2c14fb2984 "dev: f-dev stuff"
   rebasing 4:4b019212aaf6 "dev: merge default"
-  file 'f-default' was deleted in local [dest] but was modified in other 
[source].
-  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
-  What do you want to do? c
+  note: not rebasing 4:4b019212aaf6 "dev: merge default", its destination 
already has all its changes
   rebasing 6:010ced67e558 "dev: merge default"
+  note: not rebasing 6:010ced67e558 "dev: merge default", its destination 
already has all its changes
   saved backup bundle to 
$TESTTMP/ancestor-merge/.hg/strip-backup/1d1a643d390e-4a6f6d17-rebase.hg
   $ hg tglog
-  o  6: de147e4f69cf 'dev: merge default'
-  |
-  o  5: eda7b7f46f5d 'dev: merge default'
-  |
   o  4: 3e075b1c0a40 'dev: f-dev stuff'
   |
   @  3: e08089805d82 'default: f-other stuff'
@@ -163,28 +153,8 @@
   > EOF
   rebasing 2:ec2c14fb2984 "dev: f-dev stuff"
   rebasing 4:4b019212aaf6 "dev: merge default"
-  file 'f-default' was deleted in local [dest] but was modified in other 
[source].
-  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
-  What do you want to do? c
-  rebasing 6:010ced67e558 "dev: merge default"
-  saved backup bundle to 
$TESTTMP/ancestor-merge-2/.hg/strip-backup/ec2c14fb2984-827d7a44-rebase.hg
-  $ hg tglog
-  o  7: de147e4f69cf 'dev: merge default'
-  |
-  o  6: eda7b7f46f5d 'dev: merge default'
-  |
-  o  5: 3e075b1c0a40 'dev: f-dev stuff'
-  |
-  o  4: e08089805d82 'default: f-other stuff'
-  |
-  o  3: 462860db70a1 'default: remove f-default'
-  |
-  o  2: f157ecfd2b6b 'default: f-default stuff'
-  |
-  | o  1: 1d1a643d390e 'dev: create branch' dev
-  |/
-  o  0: e90e8eb90b6f 'default: create f-default'
-  
+  abort: rebasing 4:4b019212aaf6 will include unwanted changes from 
1:1d1a643d390e
+  [255]
   $ cd ..
 
 
@@ -284,18 +254,7 @@
   rebasing 6:4c5f12f25ebe "merge rebase ancestors" (tip)
   resolving manifests
   removing other
-  note: merging f9daf77ffe76+ and 4c5f12f25ebe using bids from ancestors 
a60552eb93fb and f59da8fc0fcf
-  
-  calculating bids for ancestor a60552eb93fb
   resolving manifests
-  
-  calculating bids for ancestor f59da8fc0fcf
-  resolving manifests
-  
-  auction for merging merge bids
-   other: consensus for g
-  end of auction
-  
   getting other
   committing files:
   other
diff --git a/tests/test-rebase-dest.t b/tests/test-rebase-dest.t
--- a/tests/test-rebase-dest.t
+++ b/tests/test-rebase-dest.t
@@ -256,7 +256,7 @@
   > EOS
   rebasing 3:a4256619d830 "B" (B)
   rebasing 6:8e139e245220 "C" (C tip)
-  o8: 51e2ce92e06a C
+  o8: d7d1169e9b1c C
   |\
   | o7: 2ed0c8546285 B
   | |\
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -1678,22 +1678,6 @@
 elif p in state and state[p] > 0:
 np = state[p]
 
-# "bases" only record "special" merge bases that cannot be
-# calculated from changelog DAG (i.e. isancestor(p, np) is False).
-# For example:
-#
-#   B'   # rebase -s B -d D, when B was rebased to B'. dest for C
-#   | C  # is B', but merge base for C is B, instead of
-#   D |  # changelog.ancestor(C, B') == A. If changelog DAG and
-#   | B  # "state" edges are merged (so there will be an edge from
-#   |/   # B to B'), the merge base is still ancestor(C, B') in
-#   A# the merged graph.
-#
-# Also see https://bz.mercurial-scm.org/show_bug.cgi?id=1950#c8
-# which uses "virtual null merge" to explain this situation.
-if isancestor(p, 

D7824: tests: add test of rebase with conflict in merge commit

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHG7f7c8521e9bd: tests: add test of rebase with conflict in 
merge commit (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7824?vs=19859=20132

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7824/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7824

AFFECTED FILES
  tests/test-rebase-conflicts.t

CHANGE DETAILS

diff --git a/tests/test-rebase-conflicts.t b/tests/test-rebase-conflicts.t
--- a/tests/test-rebase-conflicts.t
+++ b/tests/test-rebase-conflicts.t
@@ -429,3 +429,73 @@
   |/
   o  0:draft 'A'
   
+
+Test where the conflict happens when rebasing a merge commit
+
+  $ cd $TESTTMP
+  $ hg init conflict-in-merge
+  $ cd conflict-in-merge
+  $ hg debugdrawdag <<'EOS'
+  > F # F/conflict = foo\n
+  > |\
+  > D E
+  > |/
+  > C B # B/conflict = bar\n
+  > |/
+  > A
+  > EOS
+
+  $ hg co F
+  5 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg rebase -d B
+  rebasing 2:dc0947a82db8 "C" (C)
+  rebasing 3:e7b3f00ed42e "D" (D)
+  rebasing 4:03ca77807e91 "E" (E)
+  rebasing 5:9a6b91dc2044 "F" (F tip)
+  merging conflict
+  warning: conflicts while merging conflict! (edit, then use 'hg resolve 
--mark')
+  unresolved conflicts (see hg resolve, then hg rebase --continue)
+  [1]
+The current parents are not 7 and 8 even though that's what we're merging
+  $ hg tglog
+  @  8:draft 'E'
+  |
+  | o  7:draft 'D'
+  |/
+  o  6:draft 'C'
+  |
+  | @5:draft 'F'
+  | |\
+  | | o  4:draft 'E'
+  | | |
+  | o |  3:draft 'D'
+  | |/
+  | o  2:draft 'C'
+  | |
+  o |  1:draft 'B'
+  |/
+  o  0:draft 'A'
+  
+  $ echo baz > conflict
+  $ hg resolve -m
+  (no more unresolved files)
+  continue: hg rebase --continue
+  $ hg rebase -c
+  already rebased 2:dc0947a82db8 "C" (C) as 0199610c343e
+  already rebased 3:e7b3f00ed42e "D" (D) as f0dd538aaa63
+  already rebased 4:03ca77807e91 "E" (E) as cbf25af8347d
+  rebasing 5:9a6b91dc2044 "F" (F)
+  saved backup bundle to 
$TESTTMP/conflict-in-merge/.hg/strip-backup/dc0947a82db8-ca7e7d5b-rebase.hg
+  $ hg tglog
+  @5:draft 'F'
+  |\
+  | o  4:draft 'E'
+  | |
+  o |  3:draft 'D'
+  |/
+  o  2:draft 'C'
+  |
+  o  1:draft 'B'
+  |
+  o  0:draft 'A'
+  



To: martinvonz, #hg-reviewers, durin42
Cc: pulkit, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8107: tags: fix some type confusion exposed in python 3

2020-02-10 Thread durin42 (Augie Fackler)
durin42 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  1. skip-blame just b-prefix and %-format cleanup, no meaningful change

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D8107

AFFECTED FILES
  mercurial/debugcommands.py

CHANGE DETAILS

diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -3498,8 +3498,8 @@
 for r in repo:
 node = repo[r].node()
 tagsnode = cache.getfnode(node, computemissing=False)
-tagsnodedisplay = hex(tagsnode) if tagsnode else 'missing/invalid'
-ui.write(b'%s %s %s\n' % (r, hex(node), tagsnodedisplay))
+tagsnodedisplay = hex(tagsnode) if tagsnode else b'missing/invalid'
+ui.write(b'%d %s %s\n' % (r, hex(node), tagsnodedisplay))
 
 
 @command(



To: durin42, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8106: tests: accept new bzr message about switching branches

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHG0ef6e90d52f8: tests: accept new bzr message about switching 
branches (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8106?vs=20088=20129

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8106/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8106

AFFECTED FILES
  tests/test-convert-bzr.t

CHANGE DETAILS

diff --git a/tests/test-convert-bzr.t b/tests/test-convert-bzr.t
--- a/tests/test-convert-bzr.t
+++ b/tests/test-convert-bzr.t
@@ -226,7 +226,7 @@
   Created tag trunk-tag.
   $ bzr switch -b branch
   Tree is up to date at revision 1.
-  Switched to branch: *repo/branch/ (glob)
+  Switched to branch *repo/branch/ (glob)
   $ sleep 1
   $ echo b > b
   $ bzr add -q b
@@ -235,7 +235,7 @@
   Created tag branch-tag.
   $ bzr switch --force ../repo/trunk
   Updated to revision 1.
-  Switched to branch: */repo/trunk/ (glob)
+  Switched to branch */repo/trunk/ (glob)
   $ sleep 1
   $ echo a >> a
   $ bzr ci -qm changea



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8105: tests: add workaround for bzr bug

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Closed by commit rHG815e9ca1078c: tests: add workaround for bzr bug (authored 
by martinvonz).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8105?vs=20087=20130

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8105/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8105

AFFECTED FILES
  tests/test-convert-bzr-directories.t

CHANGE DETAILS

diff --git a/tests/test-convert-bzr-directories.t 
b/tests/test-convert-bzr-directories.t
--- a/tests/test-convert-bzr-directories.t
+++ b/tests/test-convert-bzr-directories.t
@@ -2,6 +2,9 @@
 
   $ . "$TESTDIR/bzr-definitions"
 
+Work around https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=944379
+  $ mkdir -p "${HOME}/.config/breezy"
+
 empty directory
 
   $ mkdir test-empty



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8108: tags: use modern // operator for division

2020-02-10 Thread durin42 (Augie Fackler)
durin42 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Fixes a test on Python 3.
  
  1. skip-blame only correcting a division operator, not a substantive change

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D8108

AFFECTED FILES
  mercurial/tags.py

CHANGE DETAILS

diff --git a/mercurial/tags.py b/mercurial/tags.py
--- a/mercurial/tags.py
+++ b/mercurial/tags.py
@@ -721,7 +721,7 @@
 self._dirtyoffset = None
 
 rawlentokeep = min(
-wantedlen, (rawlen / _fnodesrecsize) * _fnodesrecsize
+wantedlen, (rawlen // _fnodesrecsize) * _fnodesrecsize
 )
 if rawlen > rawlentokeep:
 # There's no easy way to truncate array instances. This seems



To: durin42, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7888: nodemap: track the maximum revision tracked in the nodemap

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHGe41a164db7a9: nodemap: track the maximum revision tracked 
in the nodemap (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7888?vs=19900=20121

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7888/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7888

AFFECTED FILES
  mercurial/debugcommands.py
  mercurial/pure/parsers.py
  mercurial/revlog.py
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -14,8 +14,9 @@
   $ hg debugbuilddag .+5000
   $ hg debugnodemap --metadata
   uid:  (glob)
+  tip-rev: 5000
   $ f --size .hg/store/00changelog.n
-  .hg/store/00changelog.n: size=18
+  .hg/store/00changelog.n: size=26
   $ f --sha256 .hg/store/00changelog-*.nd
   .hg/store/00changelog-.nd: 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7 (glob)
   $ hg debugnodemap --dump-new | f --sha256 --size
@@ -51,8 +52,9 @@
   $ hg ci -m 'foo'
   $ hg debugnodemap --metadata
   uid:  (glob)
+  tip-rev: 5001
   $ f --size .hg/store/00changelog.n
-  .hg/store/00changelog.n: size=18
+  .hg/store/00changelog.n: size=26
 
 (The pure code use the debug code that perform incremental update, the C code 
reencode from scratch)
 
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -36,9 +36,11 @@
 if version != ONDISK_VERSION:
 return None
 offset += S_VERSION.size
-(uid_size,) = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
+headers = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
+uid_size, tip_rev = headers
 offset += S_HEADER.size
 docket = NodeMapDocket(pdata[offset : offset + uid_size])
+docket.tip_rev = tip_rev
 
 filename = _rawdata_filepath(revlog, docket)
 return docket, revlog.opener.tryread(filename)
@@ -94,6 +96,7 @@
 # store vfs
 with revlog.opener(datafile, b'w') as fd:
 fd.write(data)
+target_docket.tip_rev = revlog.tiprev()
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
 with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp:
@@ -142,7 +145,7 @@
 ONDISK_VERSION = 0
 
 S_VERSION = struct.Struct(">B")
-S_HEADER = struct.Struct(">B")
+S_HEADER = struct.Struct(">BQ")
 
 ID_SIZE = 8
 
@@ -164,15 +167,19 @@
 if uid is None:
 uid = _make_uid()
 self.uid = uid
+self.tip_rev = None
 
 def copy(self):
-return NodeMapDocket(uid=self.uid)
+new = NodeMapDocket(uid=self.uid)
+new.tip_rev = self.tip_rev
+return new
 
 def serialize(self):
 """return serialized bytes for a docket using the passed uid"""
 data = []
 data.append(S_VERSION.pack(ONDISK_VERSION))
-data.append(S_HEADER.pack(len(self.uid)))
+headers = (len(self.uid), self.tip_rev)
+data.append(S_HEADER.pack(*headers))
 data.append(self.uid)
 return b''.join(data)
 
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -639,7 +639,7 @@
 if use_nodemap:
 nodemap_data = nodemaputil.persisted_data(self)
 if nodemap_data is not None:
-index.update_nodemap_data(nodemap_data[1])
+index.update_nodemap_data(*nodemap_data)
 except (ValueError, IndexError):
 raise error.RevlogError(
 _(b"index %s is corrupted") % self.indexfile
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -170,15 +170,15 @@
 self._nm_root = self._nm_max_idx = self._nm_rev = None
 return data
 
-def update_nodemap_data(self, nm_data):
-"""provide full blokc of persisted binary data for a nodemap
+def update_nodemap_data(self, docket, nm_data):
+"""provide full block of persisted binary data for a nodemap
 
 The data are expected to come from disk. See `nodemap_data_all` for a
 produceur of such data."""
 if nm_data is not None:
 self._nm_root, self._nm_max_idx = nodemaputil.parse_data(nm_data)
 if self._nm_root:
-self._nm_rev = len(self) - 1
+self._nm_rev = docket.tip_rev
 else:
 self._nm_root = self._nm_max_idx = self._nm_rev = None
 
diff --git a/mercurial/debugcommands.py 

D7892: nodemap: never read more than the expected data amount

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHGc7eebdb15139: nodemap: never read more than the expected 
data amount (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7892?vs=19904=20125

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7892/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7892

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -45,7 +45,12 @@
 docket.data_unused = data_unused
 
 filename = _rawdata_filepath(revlog, docket)
-return docket, revlog.opener.tryread(filename)
+data = revlog.opener.tryread(filename)
+if len(data) < data_length:
+return None
+elif len(data) > data_length:
+data = data[:data_length]
+return docket, data
 
 
 def setup_persistent_nodemap(tr, revlog):



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7893: nodemap: update the index with the newly written data (when appropriate)

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG6ecc34b31137: nodemap: update the index with the newly 
written data (when appropriate) (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7893?vs=19905=20126

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7893/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7893

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -100,6 +100,8 @@
 with revlog.opener(datafile, b'r+') as fd:
 fd.seek(target_docket.data_length)
 fd.write(data)
+fd.seek(0)
+new_data = fd.read(target_docket.data_length + len(data))
 target_docket.data_length += len(data)
 target_docket.data_unused += data_changed_count
 
@@ -113,6 +115,7 @@
 data = persistent_data(revlog.index)
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
+new_data = data
 with revlog.opener(datafile, b'w') as fd:
 fd.write(data)
 target_docket.data_length = len(data)
@@ -122,6 +125,9 @@
 with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp:
 fp.write(target_docket.serialize())
 revlog._nodemap_docket = target_docket
+if util.safehasattr(revlog.index, "update_nodemap_data"):
+revlog.index.update_nodemap_data(target_docket, new_data)
+
 # EXP-TODO: if the transaction abort, we should remove the new data and
 # reinstall the old one.
 



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7890: nodemap: double check the source docket when doing incremental update

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG1d2b37def017: nodemap: double check the source docket when 
doing incremental update (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7890?vs=19902=20123

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7890/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7890

AFFECTED FILES
  mercurial/pure/parsers.py
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -77,18 +77,27 @@
 can_incremental = util.safehasattr(revlog.index, 
"nodemap_data_incremental")
 ondisk_docket = revlog._nodemap_docket
 
+data = None
 # first attemp an incremental update of the data
 if can_incremental and ondisk_docket is not None:
 target_docket = revlog._nodemap_docket.copy()
-data_changed_count, data = revlog.index.nodemap_data_incremental()
-datafile = _rawdata_filepath(revlog, target_docket)
-# EXP-TODO: if this is a cache, this should use a cache vfs, not a
-# store vfs
-with revlog.opener(datafile, b'a') as fd:
-fd.write(data)
-target_docket.data_length += len(data)
-target_docket.data_unused += data_changed_count
-else:
+(
+src_docket,
+data_changed_count,
+data,
+) = revlog.index.nodemap_data_incremental()
+if src_docket != target_docket:
+data = None
+else:
+datafile = _rawdata_filepath(revlog, target_docket)
+# EXP-TODO: if this is a cache, this should use a cache vfs, not a
+# store vfs
+with revlog.opener(datafile, b'a') as fd:
+fd.write(data)
+target_docket.data_length += len(data)
+target_docket.data_unused += data_changed_count
+
+if data is None:
 # otherwise fallback to a full new export
 target_docket = NodeMapDocket()
 datafile = _rawdata_filepath(revlog, target_docket)
@@ -182,6 +191,20 @@
 new.data_unused = self.data_unused
 return new
 
+def __cmp__(self, other):
+if self.uid < other.uid:
+return -1
+if self.uid > other.uid:
+return 1
+elif self.data_length < other.data_length:
+return -1
+elif self.data_length > other.data_length:
+return 1
+return 0
+
+def __eq__(self, other):
+return self.uid == other.uid and self.data_length == other.data_length
+
 def serialize(self):
 """return serialized bytes for a docket using the passed uid"""
 data = []
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -164,11 +164,13 @@
 """
 if self._nm_root is None:
 return None
+docket = self._nm_docket
 changed, data = nodemaputil.update_persistent_data(
-self, self._nm_root, self._nm_max_idx, self._nm_rev
+self, self._nm_root, self._nm_max_idx, self._nm_docket.tip_rev
 )
-self._nm_root = self._nm_max_idx = self._nm_rev = None
-return changed, data
+
+self._nm_root = self._nm_max_idx = self._nm_docket = None
+return docket, changed, data
 
 def update_nodemap_data(self, docket, nm_data):
 """provide full block of persisted binary data for a nodemap
@@ -178,9 +180,9 @@
 if nm_data is not None:
 self._nm_root, self._nm_max_idx = nodemaputil.parse_data(nm_data)
 if self._nm_root:
-self._nm_rev = docket.tip_rev
+self._nm_docket = docket
 else:
-self._nm_root = self._nm_max_idx = self._nm_rev = None
+self._nm_root = self._nm_max_idx = self._nm_docket = None
 
 
 class InlinedIndexObject(BaseIndexObject):



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7891: nodemap: write new data from the expected current data length

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG2ea6a67ff502: nodemap: write new data from the expected 
current data length (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7891?vs=19903=20124

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7891/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7891

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -92,7 +92,8 @@
 datafile = _rawdata_filepath(revlog, target_docket)
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
-with revlog.opener(datafile, b'a') as fd:
+with revlog.opener(datafile, b'r+') as fd:
+fd.seek(target_docket.data_length)
 fd.write(data)
 target_docket.data_length += len(data)
 target_docket.data_unused += data_changed_count



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7889: nodemap: track the total and unused amount of data in the rawdata file

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG8374b69aef75: nodemap: track the total and unused amount of 
data in the rawdata file (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7889?vs=19901=20122

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7889/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7889

AFFECTED FILES
  mercurial/debugcommands.py
  mercurial/pure/parsers.py
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -15,8 +15,10 @@
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5000
+  data-length: 122880
+  data-unused: 0
   $ f --size .hg/store/00changelog.n
-  .hg/store/00changelog.n: size=26
+  .hg/store/00changelog.n: size=42
   $ f --sha256 .hg/store/00changelog-*.nd
   .hg/store/00changelog-.nd: 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7 (glob)
   $ hg debugnodemap --dump-new | f --sha256 --size
@@ -50,11 +52,22 @@
   $ echo foo > foo
   $ hg add foo
   $ hg ci -m 'foo'
+
+#if pure
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5001
+  data-length: 123072
+  data-unused: 192
+#else
+  $ hg debugnodemap --metadata
+  uid:  (glob)
+  tip-rev: 5001
+  data-length: 122880
+  data-unused: 0
+#endif
   $ f --size .hg/store/00changelog.n
-  .hg/store/00changelog.n: size=26
+  .hg/store/00changelog.n: size=42
 
 (The pure code use the debug code that perform incremental update, the C code 
reencode from scratch)
 
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -37,10 +37,12 @@
 return None
 offset += S_VERSION.size
 headers = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
-uid_size, tip_rev = headers
+uid_size, tip_rev, data_length, data_unused = headers
 offset += S_HEADER.size
 docket = NodeMapDocket(pdata[offset : offset + uid_size])
 docket.tip_rev = tip_rev
+docket.data_length = data_length
+docket.data_unused = data_unused
 
 filename = _rawdata_filepath(revlog, docket)
 return docket, revlog.opener.tryread(filename)
@@ -78,12 +80,14 @@
 # first attemp an incremental update of the data
 if can_incremental and ondisk_docket is not None:
 target_docket = revlog._nodemap_docket.copy()
-data = revlog.index.nodemap_data_incremental()
+data_changed_count, data = revlog.index.nodemap_data_incremental()
 datafile = _rawdata_filepath(revlog, target_docket)
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
 with revlog.opener(datafile, b'a') as fd:
 fd.write(data)
+target_docket.data_length += len(data)
+target_docket.data_unused += data_changed_count
 else:
 # otherwise fallback to a full new export
 target_docket = NodeMapDocket()
@@ -96,6 +100,7 @@
 # store vfs
 with revlog.opener(datafile, b'w') as fd:
 fd.write(data)
+target_docket.data_length = len(data)
 target_docket.tip_rev = revlog.tiprev()
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
@@ -143,9 +148,8 @@
 
 # version 0 is experimental, no BC garantee, do no use outside of tests.
 ONDISK_VERSION = 0
-
 S_VERSION = struct.Struct(">B")
-S_HEADER = struct.Struct(">BQ")
+S_HEADER = struct.Struct(">BQQQ")
 
 ID_SIZE = 8
 
@@ -168,17 +172,26 @@
 uid = _make_uid()
 self.uid = uid
 self.tip_rev = None
+self.data_length = None
+self.data_unused = 0
 
 def copy(self):
 new = NodeMapDocket(uid=self.uid)
 new.tip_rev = self.tip_rev
+new.data_length = self.data_length
+new.data_unused = self.data_unused
 return new
 
 def serialize(self):
 """return serialized bytes for a docket using the passed uid"""
 data = []
 data.append(S_VERSION.pack(ONDISK_VERSION))
-headers = (len(self.uid), self.tip_rev)
+headers = (
+len(self.uid),
+self.tip_rev,
+self.data_length,
+self.data_unused,
+)
 data.append(S_HEADER.pack(*headers))
 data.append(self.uid)
 return b''.join(data)
@@ -236,8 +249,11 @@
 def update_persistent_data(index, root, max_idx, last_rev):
 """return the incremental update for persistent nodemap from a given index
 """
-trie = _update_trie(index, root, last_rev)
-return _persist_trie(trie, existing_idx=max_idx)

D7887: nodemap: add a flag to dump the details of the docket

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG6614b301ea58: nodemap: add a flag to dump the details of 
the docket (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7887?vs=19899=20120

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7887/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7887

AFFECTED FILES
  mercurial/debugcommands.py
  tests/test-completion.t
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -12,6 +12,8 @@
   > persistent-nodemap=yes
   > EOF
   $ hg debugbuilddag .+5000
+  $ hg debugnodemap --metadata
+  uid:  (glob)
   $ f --size .hg/store/00changelog.n
   .hg/store/00changelog.n: size=18
   $ f --sha256 .hg/store/00changelog-*.nd
@@ -47,6 +49,8 @@
   $ echo foo > foo
   $ hg add foo
   $ hg ci -m 'foo'
+  $ hg debugnodemap --metadata
+  uid:  (glob)
   $ f --size .hg/store/00changelog.n
   .hg/store/00changelog.n: size=18
 
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -291,7 +291,7 @@
   debugmanifestfulltextcache: clear, add
   debugmergestate: 
   debugnamecomplete: 
-  debugnodemap: dump-new, dump-disk, check
+  debugnodemap: dump-new, dump-disk, check, metadata
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, 
user, template
   debugp1copies: rev
   debugp2copies: rev
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2100,6 +2100,12 @@
 False,
 _(b'check that the data on disk data are correct.'),
 ),
+(
+b'',
+b'metadata',
+False,
+_(b'display the on disk meta data for the nodemap'),
+),
 ],
 )
 def debugnodemap(ui, repo, **opts):
@@ -2124,6 +2130,13 @@
 if nm_data is not None:
 docket, data = nm_data
 return nodemap.check_data(ui, cl.index, data)
+elif opts['metadata']:
+unfi = repo.unfiltered()
+cl = unfi.changelog
+nm_data = nodemap.persisted_data(cl)
+if nm_data is not None:
+docket, data = nm_data
+ui.write((b"uid: %s\n") % docket.uid)
 
 
 @command(



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7885: nodemap: keep track of the docket for loaded data

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG76a96e3a2bbb: nodemap: keep track of the docket for loaded 
data (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7885?vs=19897=20118

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7885/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7885

AFFECTED FILES
  mercurial/debugcommands.py
  mercurial/revlog.py
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -41,7 +41,7 @@
 docket = NodeMapDocket(pdata[offset : offset + uid_size])
 
 filename = _rawdata_filepath(revlog, docket)
-return revlog.opener.tryread(filename)
+return docket, revlog.opener.tryread(filename)
 
 
 def setup_persistent_nodemap(tr, revlog):
@@ -93,6 +93,7 @@
 # store vfs
 with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp:
 fp.write(target_docket.serialize())
+revlog._nodemap_docket = target_docket
 # EXP-TODO: if the transaction abort, we should remove the new data and
 # reinstall the old one.
 
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -455,6 +455,7 @@
 self._maxchainlen = None
 self._deltabothparents = True
 self.index = None
+self._nodemap_docket = None
 # Mapping of partial identifiers to full nodes.
 self._pcache = {}
 # Mapping of revision integer to full node.
@@ -544,6 +545,9 @@
 indexdata = b''
 self._initempty = True
 try:
+nodemap_data = nodemaputil.persisted_data(self)
+if nodemap_data is not None:
+self._nodemap_docket = nodemap_data[0]
 with self._indexfp() as f:
 if (
 mmapindexthreshold is not None
@@ -635,7 +639,7 @@
 if use_nodemap:
 nodemap_data = nodemaputil.persisted_data(self)
 if nodemap_data is not None:
-index.update_nodemap_data(nodemap_data)
+index.update_nodemap_data(nodemap_data[1])
 except (ValueError, IndexError):
 raise error.RevlogError(
 _(b"index %s is corrupted") % self.indexfile
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2113,13 +2113,17 @@
 elif opts['dump_disk']:
 unfi = repo.unfiltered()
 cl = unfi.changelog
-data = nodemap.persisted_data(cl)
-ui.write(data)
+nm_data = nodemap.persisted_data(cl)
+if nm_data is not None:
+docket, data = nm_data
+ui.write(data)
 elif opts['check']:
 unfi = repo.unfiltered()
 cl = unfi.changelog
-data = nodemap.persisted_data(cl)
-return nodemap.check_data(ui, cl.index, data)
+nm_data = nodemap.persisted_data(cl)
+if nm_data is not None:
+docket, data = nm_data
+return nodemap.check_data(ui, cl.index, data)
 
 
 @command(



To: marmoute, indygreg, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7886: nodemap: introduce append-only incremental update of the persisten data

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG50ad851efd9b: nodemap: introduce append-only incremental 
update of the persistent data (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7886?vs=19898=20119

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7886/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7886

AFFECTED FILES
  mercurial/pure/parsers.py
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -49,8 +49,19 @@
   $ hg ci -m 'foo'
   $ f --size .hg/store/00changelog.n
   .hg/store/00changelog.n: size=18
+
+(The pure code use the debug code that perform incremental update, the C code 
reencode from scratch)
+
+#if pure
+  $ f --sha256 .hg/store/00changelog-*.nd --size
+  .hg/store/00changelog-.nd: size=123072, 
sha256=136472751566c8198ff09e306a7d2f9bd18bd32298d614752b73da4d6df23340 (glob)
+
+#else
   $ f --sha256 .hg/store/00changelog-*.nd --size
   .hg/store/00changelog-.nd: size=122880, 
sha256=bfafebd751c4f6d116a76a37a1dee2a251747affe7efbcc4f4842ccc746d4db9 (glob)
+
+#endif
+
   $ hg debugnodemap --check
   revision in index:   5002
   revision in nodemap: 5002
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -69,12 +69,41 @@
 if revlog.nodemap_file is None:
 msg = "calling persist nodemap on a revlog without the feature enableb"
 raise error.ProgrammingError(msg)
-if util.safehasattr(revlog.index, "nodemap_data_all"):
-data = revlog.index.nodemap_data_all()
+
+can_incremental = util.safehasattr(revlog.index, 
"nodemap_data_incremental")
+ondisk_docket = revlog._nodemap_docket
+
+# first attemp an incremental update of the data
+if can_incremental and ondisk_docket is not None:
+target_docket = revlog._nodemap_docket.copy()
+data = revlog.index.nodemap_data_incremental()
+datafile = _rawdata_filepath(revlog, target_docket)
+# EXP-TODO: if this is a cache, this should use a cache vfs, not a
+# store vfs
+with revlog.opener(datafile, b'a') as fd:
+fd.write(data)
 else:
-data = persistent_data(revlog.index)
-target_docket = NodeMapDocket()
-datafile = _rawdata_filepath(revlog, target_docket)
+# otherwise fallback to a full new export
+target_docket = NodeMapDocket()
+datafile = _rawdata_filepath(revlog, target_docket)
+if util.safehasattr(revlog.index, "nodemap_data_all"):
+data = revlog.index.nodemap_data_all()
+else:
+data = persistent_data(revlog.index)
+# EXP-TODO: if this is a cache, this should use a cache vfs, not a
+# store vfs
+with revlog.opener(datafile, b'w') as fd:
+fd.write(data)
+# EXP-TODO: if this is a cache, this should use a cache vfs, not a
+# store vfs
+with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp:
+fp.write(target_docket.serialize())
+revlog._nodemap_docket = target_docket
+# EXP-TODO: if the transaction abort, we should remove the new data and
+# reinstall the old one.
+
+# search for old index file in all cases, some older process might have
+# left one behind.
 olds = _other_rawdata_filepath(revlog, target_docket)
 if olds:
 realvfs = getattr(revlog, '_realopener', revlog.opener)
@@ -85,17 +114,6 @@
 
 callback_id = b"revlog-cleanup-nodemap-%s" % revlog.nodemap_file
 tr.addpostclose(callback_id, cleanup)
-# EXP-TODO: if this is a cache, this should use a cache vfs, not a
-# store vfs
-with revlog.opener(datafile, b'w') as fd:
-fd.write(data)
-# EXP-TODO: if this is a cache, this should use a cache vfs, not a
-# store vfs
-with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp:
-fp.write(target_docket.serialize())
-revlog._nodemap_docket = target_docket
-# EXP-TODO: if the transaction abort, we should remove the new data and
-# reinstall the old one.
 
 
 ### Nodemap docket file
@@ -208,6 +226,13 @@
 return _persist_trie(trie)
 
 
+def update_persistent_data(index, root, max_idx, last_rev):
+"""return the incremental update for persistent nodemap from a given index
+"""
+trie = _update_trie(index, root, last_rev)
+return _persist_trie(trie, existing_idx=max_idx)
+
+
 S_BLOCK = struct.Struct(">" + ("l" * 16))
 
 NO_ENTRY = -1
@@ -260,6 +285,14 @@
 return root
 
 
+def _update_trie(index, root, last_rev):
+"""consume"""
+

D7845: nodemap: add basic checking of the on disk nodemap content

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG20e125cdd719: nodemap: add basic checking of the on disk 
nodemap content (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7845?vs=19893=20113

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7845/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7845

AFFECTED FILES
  mercurial/debugcommands.py
  mercurial/revlogutils/nodemap.py
  tests/test-completion.t
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -36,6 +36,9 @@
   00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
   00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
   00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+  $ hg debugnodemap --check
+  revision in index:   5001
+  revision in nodemap: 5001
 
 add a new commit
 
@@ -48,3 +51,6 @@
   .hg/store/00changelog.n: size=18
   $ f --sha256 .hg/store/00changelog-*.nd --size
   .hg/store/00changelog-.nd: size=122880, 
sha256=bfafebd751c4f6d116a76a37a1dee2a251747affe7efbcc4f4842ccc746d4db9 (glob)
+  $ hg debugnodemap --check
+  revision in index:   5002
+  revision in nodemap: 5002
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -291,7 +291,7 @@
   debugmanifestfulltextcache: clear, add
   debugmergestate: 
   debugnamecomplete: 
-  debugnodemap: dump-new, dump-disk
+  debugnodemap: dump-new, dump-disk, check
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, 
user, template
   debugp1copies: rev
   debugp2copies: rev
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -337,3 +337,37 @@
 else:
 b[idx] = _transform_rev(v)
 return block
+
+
+# debug utility
+
+
+def check_data(ui, index, data):
+"""verify that the provided nodemap data are valid for the given idex"""
+ret = 0
+ui.status((b"revision in index:   %d\n") % len(index))
+root = parse_data(data)
+all_revs = set(_all_revisions(root))
+ui.status((b"revision in nodemap: %d\n") % len(all_revs))
+for r in range(len(index)):
+if r not in all_revs:
+msg = b"  revision missing from nodemap: %d\n" % r
+ui.write_err(msg)
+ret = 1
+else:
+all_revs.remove(r)
+if all_revs:
+for r in sorted(all_revs):
+msg = b"  extra revision in  nodemap: %d\n" % r
+ui.write_err(msg)
+ret = 1
+return ret
+
+
+def _all_revisions(root):
+"""return all revisions stored in a Trie"""
+for block in _walk_trie(root):
+for v in block:
+if v is None or isinstance(v, Block):
+continue
+yield v
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2094,6 +2094,12 @@
 _(b'write a (new) persistent binary nodemap on stdin'),
 ),
 (b'', b'dump-disk', False, _(b'dump on-disk data on stdin')),
+(
+b'',
+b'check',
+False,
+_(b'check that the data on disk data are correct.'),
+),
 ],
 )
 def debugnodemap(ui, repo, **opts):
@@ -2109,6 +2115,11 @@
 cl = unfi.changelog
 data = nodemap.persisted_data(cl)
 ui.write(data)
+elif opts['check']:
+unfi = repo.unfiltered()
+cl = unfi.changelog
+data = nodemap.persisted_data(cl)
+return nodemap.check_data(ui, cl.index, data)
 
 
 @command(



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7840: nodemap: add a (python) index class for persistent nodemap testing

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG6f9e8e142cea: nodemap: add a (python) index class for 
persistent nodemap testing (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7840?vs=20017=20108

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7840/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7840

AFFECTED FILES
  mercurial/configitems.py
  mercurial/localrepo.py
  mercurial/pure/parsers.py
  mercurial/revlog.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -8,6 +8,8 @@
   $ cat << EOF >> .hg/hgrc
   > [experimental]
   > exp-persistent-nodemap=yes
+  > [devel]
+  > persistent-nodemap=yes
   > EOF
   $ hg debugbuilddag .+5000
   $ f --size .hg/store/00changelog.n
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -352,6 +352,21 @@
 return p
 
 
+NodemapRevlogIO = None
+
+if util.safehasattr(parsers, 'parse_index_devel_nodemap'):
+
+class NodemapRevlogIO(revlogio):
+"""A debug oriented IO class that return a PersistentNodeMapIndexObject
+
+The PersistentNodeMapIndexObject object is meant to test the 
persistent nodemap feature.
+"""
+
+def parseindex(self, data, inline):
+index, cache = parsers.parse_index_devel_nodemap(data, inline)
+return index, cache
+
+
 class rustrevlogio(revlogio):
 def parseindex(self, data, inline):
 index, cache = super(rustrevlogio, self).parseindex(data, inline)
@@ -596,9 +611,17 @@
 
 self._storedeltachains = True
 
+devel_nodemap = (
+self.nodemap_file
+and opts.get(b'devel-force-nodemap', False)
+and NodemapRevlogIO is not None
+)
+
 self._io = revlogio()
 if self.version == REVLOGV0:
 self._io = revlogoldio()
+elif devel_nodemap:
+self._io = NodemapRevlogIO()
 elif rustrevlog is not None and self.opener.options.get(b'rust.index'):
 self._io = rustrevlogio()
 try:
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -141,6 +141,15 @@
 self._extra = self._extra[: i - self._lgt]
 
 
+class PersistentNodeMapIndexObject(IndexObject):
+"""a Debug oriented class to test persistent nodemap
+
+We need a simple python object to test API and higher level behavior. See
+the Rust implementation for  more serious usage. This should be used only
+through the dedicated `devel.persistent-nodemap` config.
+"""
+
+
 class InlinedIndexObject(BaseIndexObject):
 def __init__(self, data, inline=0):
 self._data = data
@@ -188,6 +197,12 @@
 return InlinedIndexObject(data, inline), (0, data)
 
 
+def parse_index_devel_nodemap(data, inline):
+"""like parse_index2, but alway return a PersistentNodeMapIndexObject
+"""
+return PersistentNodeMapIndexObject(data), None
+
+
 def parse_dirstate(dmap, copymap, st):
 parents = [st[:20], st[20:40]]
 # dereference fields so they will be local in loop
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -934,6 +934,8 @@
 options[b'rust.index'] = True
 if ui.configbool(b'experimental', b'exp-persistent-nodemap'):
 options[b'exp-persistent-nodemap'] = True
+if ui.configbool(b'devel', b'persistent-nodemap'):
+options[b'devel-force-nodemap'] = True
 
 return options
 
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -406,6 +406,9 @@
 b'devel', b'legacy.exchange', default=list,
 )
 coreconfigitem(
+b'devel', b'persistent-nodemap', default=False,
+)
+coreconfigitem(
 b'devel', b'servercafile', default=b'',
 )
 coreconfigitem(



To: marmoute, indygreg, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7847: nodemap: provide the on disk data to indexes who support it

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG671f9479af0e: nodemap: provide the on disk data to indexes 
who support it (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7847?vs=19763=20115

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7847/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7847

AFFECTED FILES
  mercurial/pure/parsers.py
  mercurial/revlog.py

CHANGE DETAILS

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -626,6 +626,16 @@
 self._io = rustrevlogio()
 try:
 d = self._io.parseindex(indexdata, self._inline)
+index, _chunkcache = d
+use_nodemap = (
+not self._inline
+and self.nodemap_file is not None
+and util.safehasattr(index, 'update_nodemap_data')
+)
+if use_nodemap:
+nodemap_data = nodemaputil.persisted_data(self)
+if nodemap_data is not None:
+index.update_nodemap_data(nodemap_data)
 except (ValueError, IndexError):
 raise error.RevlogError(
 _(b"index %s is corrupted") % self.indexfile
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -156,6 +156,14 @@
 index."""
 return nodemaputil.persistent_data(self)
 
+def update_nodemap_data(self, nm_data):
+"""provide full blokc of persisted binary data for a nodemap
+
+The data are expected to come from disk. See `nodemap_data_all` for a
+produceur of such data."""
+if nm_data is not None:
+nodemaputil.parse_data(nm_data)
+
 
 class InlinedIndexObject(BaseIndexObject):
 def __init__(self, data, inline=0):



To: marmoute, indygreg, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7884: nodemap: introduce an explicit class/object for the docket

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG72c15641c8b4: nodemap: introduce an explicit class/object 
for the docket (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7884?vs=19896=20117

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7884/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7884

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -36,11 +36,11 @@
 if version != ONDISK_VERSION:
 return None
 offset += S_VERSION.size
-(uuid_size,) = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
+(uid_size,) = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
 offset += S_HEADER.size
-uid = pdata[offset : offset + uuid_size]
+docket = NodeMapDocket(pdata[offset : offset + uid_size])
 
-filename = _rawdata_filepath(revlog, uid)
+filename = _rawdata_filepath(revlog, docket)
 return revlog.opener.tryread(filename)
 
 
@@ -73,9 +73,9 @@
 data = revlog.index.nodemap_data_all()
 else:
 data = persistent_data(revlog.index)
-uid = _make_uid()
-datafile = _rawdata_filepath(revlog, uid)
-olds = _other_rawdata_filepath(revlog, uid)
+target_docket = NodeMapDocket()
+datafile = _rawdata_filepath(revlog, target_docket)
+olds = _other_rawdata_filepath(revlog, target_docket)
 if olds:
 realvfs = getattr(revlog, '_realopener', revlog.opener)
 
@@ -92,7 +92,7 @@
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
 with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp:
-fp.write(_serialize_docket(uid))
+fp.write(target_docket.serialize())
 # EXP-TODO: if the transaction abort, we should remove the new data and
 # reinstall the old one.
 
@@ -135,25 +135,39 @@
 return nodemod.hex(os.urandom(ID_SIZE))
 
 
-def _serialize_docket(uid):
-"""return serialized bytes for a docket using the passed uid"""
-data = []
-data.append(S_VERSION.pack(ONDISK_VERSION))
-data.append(S_HEADER.pack(len(uid)))
-data.append(uid)
-return b''.join(data)
+class NodeMapDocket(object):
+"""metadata associated with persistent nodemap data
+
+The persistent data may come from disk or be on their way to disk.
+"""
+
+def __init__(self, uid=None):
+if uid is None:
+uid = _make_uid()
+self.uid = uid
+
+def copy(self):
+return NodeMapDocket(uid=self.uid)
+
+def serialize(self):
+"""return serialized bytes for a docket using the passed uid"""
+data = []
+data.append(S_VERSION.pack(ONDISK_VERSION))
+data.append(S_HEADER.pack(len(self.uid)))
+data.append(self.uid)
+return b''.join(data)
 
 
-def _rawdata_filepath(revlog, uid):
+def _rawdata_filepath(revlog, docket):
 """The (vfs relative) nodemap's rawdata file for a given uid"""
 prefix = revlog.nodemap_file[:-2]
-return b"%s-%s.nd" % (prefix, uid)
+return b"%s-%s.nd" % (prefix, docket.uid)
 
 
-def _other_rawdata_filepath(revlog, uid):
+def _other_rawdata_filepath(revlog, docket):
 prefix = revlog.nodemap_file[:-2]
 pattern = re.compile(b"(^|/)%s-[0-9a-f]+\.nd$" % prefix)
-new_file_path = _rawdata_filepath(revlog, uid)
+new_file_path = _rawdata_filepath(revlog, docket)
 new_file_name = revlog.opener.basename(new_file_path)
 dirpath = revlog.opener.dirname(new_file_path)
 others = []



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7883: nodemap: keep track of the ondisk id of nodemap blocks

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHGf0862ee1a31e: nodemap: keep track of the ondisk id of 
nodemap blocks (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7883?vs=19895=20116

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7883/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7883

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -221,6 +221,11 @@
 
 contains up to 16 entry indexed from 0 to 15"""
 
+def __init__(self):
+super(Block, self).__init__()
+# If this block exist on disk, here is its ID
+self.ondisk_id = None
+
 def __iter__(self):
 return iter(self.get(i) for i in range(16))
 
@@ -323,8 +328,8 @@
 new_blocks = []
 for i in range(0, len(data), S_BLOCK.size):
 block = Block()
-ondisk_id = len(block_map)
-block_map[ondisk_id] = block
+block.ondisk_id = len(block_map)
+block_map[block.ondisk_id] = block
 block_data = data[i : i + S_BLOCK.size]
 values = S_BLOCK.unpack(block_data)
 new_blocks.append((block, values))



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7846: nodemap: all check that revision and nodes match in the nodemap

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHGd58206b70199: nodemap: all check that revision and nodes 
match in the nodemap (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7846?vs=19894=20114

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7846/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7846

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -356,6 +356,19 @@
 ret = 1
 else:
 all_revs.remove(r)
+nm_rev = _find_node(root, nodemod.hex(index[r][7]))
+if nm_rev is None:
+msg = b"  revision node does not match any entries: %d\n" % r
+ui.write_err(msg)
+ret = 1
+elif nm_rev != r:
+msg = (
+b"  revision node does not match the expected revision: "
+b"%d != %d\n" % (r, nm_rev)
+)
+ui.write_err(msg)
+ret = 1
+
 if all_revs:
 for r in sorted(all_revs):
 msg = b"  extra revision in  nodemap: %d\n" % r
@@ -371,3 +384,11 @@
 if v is None or isinstance(v, Block):
 continue
 yield v
+
+
+def _find_node(block, node):
+"""find the revision associated with a given node"""
+entry = block.get(_to_int(node[0:1]))
+if isinstance(entry, dict):
+return _find_node(entry, node[1:])
+return entry



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7835: nodemap: write nodemap data on disk

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG5962fd0d1045: nodemap: write nodemap data on disk (authored 
by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7835?vs=20016=20103

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7835/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7835

AFFECTED FILES
  mercurial/changelog.py
  mercurial/configitems.py
  mercurial/localrepo.py
  mercurial/revlog.py
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -5,8 +5,14 @@
 
   $ hg init test-repo
   $ cd test-repo
+  $ cat << EOF >> .hg/hgrc
+  > [experimental]
+  > exp-persistent-nodemap=yes
+  > EOF
   $ hg debugbuilddag .+5000
-  $ hg debugnodemap --dump | f --sha256 --bytes=256 --hexdump --size
+  $ hg debugnodemap --dump | f --sha256 --size
+  size=122880, 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
+  $ f --sha256 --bytes=256 --hexdump --size < .hg/store/00changelog.n
   size=122880, 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
   : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
   0010: ff ff ff ff ff ff ff ff ff ff fa c2 ff ff ff ff ||
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -22,6 +22,39 @@
 raise error.RevlogError(b'unknown node: %s' % x)
 
 
+def setup_persistent_nodemap(tr, revlog):
+"""Install whatever is needed transaction side to persist a nodemap on disk
+
+(only actually persist the nodemap if this is relevant for this revlog)
+"""
+if revlog.nodemap_file is None:
+return  # we do not use persistent_nodemap on this revlog
+callback_id = b"revlog-persistent-nodemap-%s" % revlog.nodemap_file
+if tr.hasfinalize(callback_id):
+return  # no need to register again
+tr.addfinalize(callback_id, lambda tr: _persist_nodemap(tr, revlog))
+
+
+def _persist_nodemap(tr, revlog):
+"""Write nodemap data on disk for a given revlog
+"""
+if getattr(revlog, 'filteredrevs', ()):
+raise error.ProgrammingError(
+"cannot persist nodemap of a filtered changelog"
+)
+if revlog.nodemap_file is None:
+msg = "calling persist nodemap on a revlog without the feature enableb"
+raise error.ProgrammingError(msg)
+data = persistent_data(revlog.index)
+# EXP-TODO: if this is a cache, this should use a cache vfs, not a
+# store vfs
+with revlog.opener(revlog.nodemap_file, b'w') as f:
+f.write(data)
+# EXP-TODO: if the transaction abort, we should remove the new data and
+# reinstall the old one. (This will be simpler when the file format get a
+# bit more advanced)
+
+
 ### Nodemap Trie
 #
 # This is a simple reference implementation to compute and persist a nodemap
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -407,6 +407,7 @@
 mmaplargeindex=False,
 censorable=False,
 upperboundcomp=None,
+persistentnodemap=False,
 ):
 """
 create a revlog object
@@ -418,6 +419,10 @@
 self.upperboundcomp = upperboundcomp
 self.indexfile = indexfile
 self.datafile = datafile or (indexfile[:-2] + b".d")
+self.nodemap_file = None
+if persistentnodemap:
+self.nodemap_file = indexfile[:-2] + b".n"
+
 self.opener = opener
 #  When True, indexfile is opened with checkambig=True at writing, to
 #  avoid file stat ambiguity.
@@ -2286,6 +2291,7 @@
 ifh.write(data[0])
 ifh.write(data[1])
 self._enforceinlinesize(transaction, ifh)
+nodemaputil.setup_persistent_nodemap(transaction, self)
 
 def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None):
 """
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -932,6 +932,8 @@
 
 if ui.configbool(b'experimental', b'rust.index'):
 options[b'rust.index'] = True
+if ui.configbool(b'experimental', b'exp-persistent-nodemap'):
+options[b'exp-persistent-nodemap'] = True
 
 return options
 
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -660,6 +660,9 @@
 b'experimental', b'rust.index', default=False,
 )
 coreconfigitem(
+b'experimental', b'exp-persistent-nodemap', default=False,
+)
+coreconfigitem(
 b'experimental', 

D7844: nodemap: code to parse the persistent binary nodemap data

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG78721bbdb2ab: nodemap: code to parse the persistent binary 
nodemap data (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7844?vs=19892=20112

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7844/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7844

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -310,3 +310,30 @@
 return block_map[id(item)]
 else:
 return _transform_rev(item)
+
+
+def parse_data(data):
+"""parse parse nodemap data into a nodemap Trie"""
+if (len(data) % S_BLOCK.size) != 0:
+msg = "nodemap data size is not a multiple of block size (%d): %d"
+raise error.Abort(msg % (S_BLOCK.size, len(data)))
+if not data:
+return Block()
+block_map = {}
+new_blocks = []
+for i in range(0, len(data), S_BLOCK.size):
+block = Block()
+ondisk_id = len(block_map)
+block_map[ondisk_id] = block
+block_data = data[i : i + S_BLOCK.size]
+values = S_BLOCK.unpack(block_data)
+new_blocks.append((block, values))
+for b, values in new_blocks:
+for idx, v in enumerate(values):
+if v == NO_ENTRY:
+continue
+elif v >= 0:
+b[idx] = block_map[v]
+else:
+b[idx] = _transform_rev(v)
+return block



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7843: nodemap: move the iteratio inside the Block object

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG55b12f2593c1: nodemap: move the iteratio inside the Block 
object (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D7843?vs=19891=20111#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7843?vs=19891=20111

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7843/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7843

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -221,6 +221,9 @@
 
 contains up to 16 entry indexed from 0 to 15"""
 
+def __iter__(self):
+return iter(self.get(i) for i in range(16))
+
 
 def _build_trie(index):
 """build a nodemap trie
@@ -295,7 +298,7 @@
 Children block are assumed to be already persisted and present in
 block_map.
 """
-data = tuple(_to_value(block_node.get(i), block_map) for i in range(16))
+data = tuple(_to_value(v, block_map) for v in block_node)
 return S_BLOCK.pack(*data)
 
 



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7842: nodemap: use an explicit "Block" object in the reference implementation

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG7762a295fd4d: nodemap: use an explicit Block 
object in the reference implementation (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D7842?vs=19890=20110#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7842?vs=19890=20110

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7842/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7842

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -216,6 +216,12 @@
 return int(hex_digit, 16)
 
 
+class Block(dict):
+"""represent a block of the Trie
+
+contains up to 16 entry indexed from 0 to 15"""
+
+
 def _build_trie(index):
 """build a nodemap trie
 
@@ -224,7 +230,7 @@
 Each block is a dictionary with keys in `[0, 15]`. Values are either
 another block or a revision number.
 """
-root = {}
+root = Block()
 for rev in range(len(index)):
 hex = nodemod.hex(index[rev][7])
 _insert_into_block(index, 0, root, rev, hex)
@@ -253,7 +259,7 @@
 # vertices to fit both entry.
 other_hex = nodemod.hex(index[entry][7])
 other_rev = entry
-new = {}
+new = Block()
 block[hex_digit] = new
 _insert_into_block(index, level + 1, new, other_rev, other_hex)
 _insert_into_block(index, level + 1, new, current_rev, current_hex)



To: marmoute, #hg-reviewers
Cc: durin42, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7841: nodemap: add a optional `nodemap_add_full` method on indexes

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG7f4f7ef3133e: nodemap: add a optional `nodemap_add_full` 
method on indexes (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7841?vs=19889=20109

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7841/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7841

AFFECTED FILES
  mercurial/pure/parsers.py
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -15,7 +15,7 @@
 from .. import (
 error,
 node as nodemod,
-pycompat,
+util,
 )
 
 
@@ -69,7 +69,10 @@
 if revlog.nodemap_file is None:
 msg = "calling persist nodemap on a revlog without the feature enableb"
 raise error.ProgrammingError(msg)
-data = persistent_data(revlog.index)
+if util.safehasattr(revlog.index, "nodemap_data_all"):
+data = revlog.index.nodemap_data_all()
+else:
+data = persistent_data(revlog.index)
 uid = _make_uid()
 datafile = _rawdata_filepath(revlog, uid)
 olds = _other_rawdata_filepath(revlog, uid)
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -149,6 +149,13 @@
 through the dedicated `devel.persistent-nodemap` config.
 """
 
+def nodemap_data_all(self):
+"""Return bytes containing a full serialization of a nodemap
+
+The nodemap should be valid for the full set of revisions in the
+index."""
+return nodemaputil.persistent_data(self)
+
 
 class InlinedIndexObject(BaseIndexObject):
 def __init__(self, data, inline=0):



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7834: nodemap: have some python code writing a nodemap in persistent binary form

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHGc577bb4a04d4: nodemap: have some python code writing a 
nodemap in persistent binary form (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7834?vs=20015=20102

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7834/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7834

AFFECTED FILES
  mercurial/debugcommands.py
  mercurial/revlogutils/nodemap.py
  tests/test-completion.t
  tests/test-help.t
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
new file mode 100644
--- /dev/null
+++ b/tests/test-persistent-nodemap.t
@@ -0,0 +1,26 @@
+===
+Test the persistent on-disk nodemap
+===
+
+
+  $ hg init test-repo
+  $ cd test-repo
+  $ hg debugbuilddag .+5000
+  $ hg debugnodemap --dump | f --sha256 --bytes=256 --hexdump --size
+  size=122880, 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
+  : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+  0010: ff ff ff ff ff ff ff ff ff ff fa c2 ff ff ff ff ||
+  0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+  0030: ff ff ff ff ff ff ed b3 ff ff ff ff ff ff ff ff ||
+  0040: ff ff ff ff ff ff ee 34 00 00 00 00 ff ff ff ff |...4|
+  0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+  0060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+  0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+  0080: ff ff ff ff ff ff f8 50 ff ff ff ff ff ff ff ff |...P|
+  0090: ff ff ff ff ff ff ff ff ff ff ec c7 ff ff ff ff ||
+  00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+  00b0: ff ff ff ff ff ff fa be ff ff f2 fc ff ff ff ff ||
+  00c0: ff ff ff ff ff ff ef ea ff ff ff ff ff ff f9 17 ||
+  00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+  00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+  00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -1024,6 +1024,7 @@
  print merge state
debugnamecomplete
  complete "names" - tags, open branch names, bookmark names
+   debugnodemap  write and inspect on disk nodemap
debugobsolete
  create arbitrary obsolete marker
debugoptADV   (no help text available)
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -107,6 +107,7 @@
   debugmanifestfulltextcache
   debugmergestate
   debugnamecomplete
+  debugnodemap
   debugobsolete
   debugp1copies
   debugp2copies
@@ -290,6 +291,7 @@
   debugmanifestfulltextcache: clear, add
   debugmergestate: 
   debugnamecomplete: 
+  debugnodemap: dump
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, 
user, template
   debugp1copies: rev
   debugp2copies: rev
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -7,9 +7,156 @@
 # GNU General Public License version 2 or any later version.
 
 from __future__ import absolute_import
-from .. import error
+
+import struct
+
+from .. import (
+error,
+node as nodemod,
+pycompat,
+)
 
 
 class NodeMap(dict):
 def __missing__(self, x):
 raise error.RevlogError(b'unknown node: %s' % x)
+
+
+### Nodemap Trie
+#
+# This is a simple reference implementation to compute and persist a nodemap
+# trie. This reference implementation is write only. The python version of this
+# is not expected to be actually used, since it wont provide performance
+# improvement over existing non-persistent C implementation.
+#
+# The nodemap is persisted as Trie using 4bits-address/16-entries block. each
+# revision can be adressed using its node shortest prefix.
+#
+# The trie is stored as a sequence of block. Each block contains 16 entries
+# (signed 64bit integer, big endian). Each entry can be one of the following:
+#
+#  * value >=  0 -> index of sub-block
+#  * value == -1 -> no value
+#  * value <  -1 -> a revision value: rev = -(value+10)
+#
+# The implementation focus on simplicity, not on performance. A Rust
+# implementation should provide a efficient version of the same binary
+# persistence. This reference python implementation is never meant to be
+# extensively use in production.
+
+
+def persistent_data(index):
+"""return the persistent binary form for a nodemap 

D7839: nodemap: delete older raw data file when creating a new ones

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG563dfdfd01a4: nodemap: delete older raw data file when 
creating a new ones (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7839?vs=19887=20107

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7839/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7839

AFFECTED FILES
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -12,6 +12,8 @@
   $ hg debugbuilddag .+5000
   $ f --size .hg/store/00changelog.n
   .hg/store/00changelog.n: size=18
+  $ f --sha256 .hg/store/00changelog-*.nd
+  .hg/store/00changelog-.nd: 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7 (glob)
   $ hg debugnodemap --dump-new | f --sha256 --size
   size=122880, 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
   $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
@@ -32,3 +34,15 @@
   00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
   00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
   00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+
+add a new commit
+
+  $ hg up
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo foo > foo
+  $ hg add foo
+  $ hg ci -m 'foo'
+  $ f --size .hg/store/00changelog.n
+  .hg/store/00changelog.n: size=18
+  $ f --sha256 .hg/store/00changelog-*.nd --size
+  .hg/store/00changelog-.nd: size=122880, 
sha256=bfafebd751c4f6d116a76a37a1dee2a251747affe7efbcc4f4842ccc746d4db9 (glob)
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -9,6 +9,7 @@
 from __future__ import absolute_import
 
 import os
+import re
 import struct
 
 from .. import (
@@ -71,6 +72,16 @@
 data = persistent_data(revlog.index)
 uid = _make_uid()
 datafile = _rawdata_filepath(revlog, uid)
+olds = _other_rawdata_filepath(revlog, uid)
+if olds:
+realvfs = getattr(revlog, '_realopener', revlog.opener)
+
+def cleanup(tr):
+for oldfile in olds:
+realvfs.tryunlink(oldfile)
+
+callback_id = b"revlog-cleanup-nodemap-%s" % revlog.nodemap_file
+tr.addpostclose(callback_id, cleanup)
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
 with revlog.opener(datafile, b'w') as fd:
@@ -136,6 +147,19 @@
 return b"%s-%s.nd" % (prefix, uid)
 
 
+def _other_rawdata_filepath(revlog, uid):
+prefix = revlog.nodemap_file[:-2]
+pattern = re.compile(b"(^|/)%s-[0-9a-f]+\.nd$" % prefix)
+new_file_path = _rawdata_filepath(revlog, uid)
+new_file_name = revlog.opener.basename(new_file_path)
+dirpath = revlog.opener.dirname(new_file_path)
+others = []
+for f in revlog.opener.listdir(dirpath):
+if pattern.match(f) and f != new_file_name:
+others.append(f)
+return others
+
+
 ### Nodemap Trie
 #
 # This is a simple reference implementation to compute and persist a nodemap



To: marmoute, #hg-reviewers
Cc: martinvonz, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7836: nodemap: add a function to read the data from disk

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG6c07480d6659: nodemap: add a function to read the data from 
disk (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7836?vs=19884=20104

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7836/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7836

AFFECTED FILES
  mercurial/debugcommands.py
  mercurial/revlogutils/nodemap.py
  tests/test-completion.t
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -10,9 +10,9 @@
   > exp-persistent-nodemap=yes
   > EOF
   $ hg debugbuilddag .+5000
-  $ hg debugnodemap --dump | f --sha256 --size
+  $ hg debugnodemap --dump-new | f --sha256 --size
   size=122880, 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
-  $ f --sha256 --bytes=256 --hexdump --size < .hg/store/00changelog.n
+  $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
   size=122880, 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
   : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
   0010: ff ff ff ff ff ff ff ff ff ff fa c2 ff ff ff ff ||
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -291,7 +291,7 @@
   debugmanifestfulltextcache: clear, add
   debugmergestate: 
   debugnamecomplete: 
-  debugnodemap: dump
+  debugnodemap: dump-new, dump-disk
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, 
user, template
   debugp1copies: rev
   debugp2copies: rev
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -22,6 +22,13 @@
 raise error.RevlogError(b'unknown node: %s' % x)
 
 
+def persisted_data(revlog):
+"""read the nodemap for a revlog from disk"""
+if revlog.nodemap_file is None:
+return None
+return revlog.opener.tryread(revlog.nodemap_file)
+
+
 def setup_persistent_nodemap(tr, revlog):
 """Install whatever is needed transaction side to persist a nodemap on disk
 
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2086,16 +2086,29 @@
 
 @command(
 b'debugnodemap',
-[(b'', b'dump', False, _(b'write persistent binary nodemap on stdin'))],
+[
+(
+b'',
+b'dump-new',
+False,
+_(b'write a (new) persistent binary nodemap on stdin'),
+),
+(b'', b'dump-disk', False, _(b'dump on-disk data on stdin')),
+],
 )
 def debugnodemap(ui, repo, **opts):
 """write and inspect on disk nodemap
 """
-if opts['dump']:
+if opts['dump_new']:
 unfi = repo.unfiltered()
 cl = unfi.changelog
 data = nodemap.persistent_data(cl.index)
 ui.write(data)
+elif opts['dump_disk']:
+unfi = repo.unfiltered()
+cl = unfi.changelog
+data = nodemap.persisted_data(cl)
+ui.write(data)
 
 
 @command(



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7838: nodemap: use an intermediate "docket" file to carry small metadata

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG2b72c4ff8ed1: nodemap: use an intermediate 
docket file to carry small metadata (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7838?vs=19886=20106

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7838/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7838

AFFECTED FILES
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -10,6 +10,8 @@
   > exp-persistent-nodemap=yes
   > EOF
   $ hg debugbuilddag .+5000
+  $ f --size .hg/store/00changelog.n
+  .hg/store/00changelog.n: size=18
   $ hg debugnodemap --dump-new | f --sha256 --size
   size=122880, 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
   $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -8,6 +8,7 @@
 
 from __future__ import absolute_import
 
+import os
 import struct
 
 from .. import (
@@ -26,7 +27,20 @@
 """read the nodemap for a revlog from disk"""
 if revlog.nodemap_file is None:
 return None
-return revlog.opener.tryread(revlog.nodemap_file)
+pdata = revlog.opener.tryread(revlog.nodemap_file)
+if not pdata:
+return None
+offset = 0
+(version,) = S_VERSION.unpack(pdata[offset : offset + S_VERSION.size])
+if version != ONDISK_VERSION:
+return None
+offset += S_VERSION.size
+(uuid_size,) = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
+offset += S_HEADER.size
+uid = pdata[offset : offset + uuid_size]
+
+filename = _rawdata_filepath(revlog, uid)
+return revlog.opener.tryread(filename)
 
 
 def setup_persistent_nodemap(tr, revlog):
@@ -55,13 +69,71 @@
 msg = "calling persist nodemap on a revlog without the feature enableb"
 raise error.ProgrammingError(msg)
 data = persistent_data(revlog.index)
+uid = _make_uid()
+datafile = _rawdata_filepath(revlog, uid)
+# EXP-TODO: if this is a cache, this should use a cache vfs, not a
+# store vfs
+with revlog.opener(datafile, b'w') as fd:
+fd.write(data)
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
-with revlog.opener(revlog.nodemap_file, b'w') as f:
-f.write(data)
+with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp:
+fp.write(_serialize_docket(uid))
 # EXP-TODO: if the transaction abort, we should remove the new data and
-# reinstall the old one. (This will be simpler when the file format get a
-# bit more advanced)
+# reinstall the old one.
+
+
+### Nodemap docket file
+#
+# The nodemap data are stored on disk using 2 files:
+#
+# * a raw data files containing a persistent nodemap
+#   (see `Nodemap Trie` section)
+#
+# * a small "docket" file containing medatadata
+#
+# While the nodemap data can be multiple tens of megabytes, the "docket" is
+# small, it is easy to update it automatically or to duplicated its content
+# during a transaction.
+#
+# Multiple raw data can exist at the same time (The currently valid one and a
+# new one beind used by an in progress transaction). To accomodate this, the
+# filename hosting the raw data has a variable parts. The exact filename is
+# specified inside the "docket" file.
+#
+# The docket file contains information to find, qualify and validate the raw
+# data. Its content is currently very light, but it will expand as the on disk
+# nodemap gains the necessary features to be used in production.
+
+# version 0 is experimental, no BC garantee, do no use outside of tests.
+ONDISK_VERSION = 0
+
+S_VERSION = struct.Struct(">B")
+S_HEADER = struct.Struct(">B")
+
+ID_SIZE = 8
+
+
+def _make_uid():
+"""return a new unique identifier.
+
+The identifier is random and composed of ascii characters."""
+return nodemod.hex(os.urandom(ID_SIZE))
+
+
+def _serialize_docket(uid):
+"""return serialized bytes for a docket using the passed uid"""
+data = []
+data.append(S_VERSION.pack(ONDISK_VERSION))
+data.append(S_HEADER.pack(len(uid)))
+data.append(uid)
+return b''.join(data)
+
+
+def _rawdata_filepath(revlog, uid):
+"""The (vfs relative) nodemap's rawdata file for a given uid"""
+prefix = revlog.nodemap_file[:-2]
+return b"%s-%s.nd" % (prefix, uid)
 
 
 ### Nodemap Trie



To: marmoute, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org

D7837: nodemap: only use persistent nodemap for non-inlined revlog

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHGdaad3aace942: nodemap: only use persistent nodemap for 
non-inlined revlog (authored by marmoute).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7837?vs=19885=20105

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7837/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7837

AFFECTED FILES
  mercurial/revlog.py
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -34,6 +34,8 @@
 
 (only actually persist the nodemap if this is relevant for this revlog)
 """
+if revlog._inline:
+return  # inlined revlog are too small for this to be relevant
 if revlog.nodemap_file is None:
 return  # we do not use persistent_nodemap on this revlog
 callback_id = b"revlog-persistent-nodemap-%s" % revlog.nodemap_file
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -1965,6 +1965,7 @@
 # manager
 
 tr.replace(self.indexfile, trindex * self._io.size)
+nodemaputil.setup_persistent_nodemap(tr, self)
 self._chunkclear()
 
 def _nodeduplicatecallback(self, transaction, node):



To: marmoute, indygreg, #hg-reviewers, martinvonz
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7894: nodemap: introduce an option to use mmap to read the nodemap mapping

2020-02-10 Thread durin42 (Augie Fackler)
This revision now requires changes to proceed.
durin42 added a comment.
durin42 requested changes to this revision.


  In D7894#120247 , @marmoute 
wrote:
  
  > More throughful benchmarking has arrived.
  > This is a large win all over the board. The win for the larger repository 
very significant.
  >
  >   + 3.9e-05  7.1e-05 1.82  
internal.index.no_lookup.track_time('mercurial-2018-08-01', 'zlib', 'default', 
True, True, True, True, False) 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
  
  [...]
  
  >   
  
  I literally have no idea what this wall of text is trying to tell me. Some 
column headers would be a baseline to making this readable, structuring it as a 
table somehow would be even better, and for actual archaeology it would have 
been put in some summarized form in the commit message.
  
  I've reviewed up to here and I'm basically happy, but I'll hold this one 
until the commit message has at least some useful summary of where we're going 
performance wise.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7894/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7894

To: marmoute, #hg-reviewers, durin42
Cc: durin42, gracinet, martinvonz, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7842: nodemap: use an explicit "Block" object in the reference implementation

2020-02-10 Thread durin42 (Augie Fackler)
durin42 added inline comments.

INLINE COMMENTS

> nodemap.py:224
> +
> +pass
> +

nit: you could have omitted this superfluous pass statement

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7842/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7842

To: marmoute, #hg-reviewers
Cc: durin42, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8085: manifest: move matches method to be outside the interface

2020-02-10 Thread durin42 (Augie Fackler)
durin42 updated this revision to Diff 20101.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8085?vs=19928=20101

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8085/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8085

AFFECTED FILES
  mercurial/interfaces/repository.py
  mercurial/manifest.py
  tests/test-manifest.py

CHANGE DETAILS

diff --git a/tests/test-manifest.py b/tests/test-manifest.py
--- a/tests/test-manifest.py
+++ b/tests/test-manifest.py
@@ -171,7 +171,7 @@
 self.assertEqual(want, m[b'foo'])
 # make sure the suffix survives a copy
 match = matchmod.match(util.localpath(b'/repo'), b'', [b're:foo'])
-m2 = m.matches(match)
+m2 = m._matches(match)
 self.assertEqual(want, m2[b'foo'])
 self.assertEqual(1, len(m2))
 m2 = m.copy()
@@ -196,7 +196,7 @@
 
 match.matchfn = filt
 with self.assertRaises(AssertionError):
-m.matches(match)
+m._matches(match)
 
 def testRemoveItem(self):
 m = self.parsemanifest(A_SHORT_MANIFEST)
@@ -300,7 +300,7 @@
 m = self.parsemanifest(A_HUGE_MANIFEST)
 
 match = matchmod.exact([b'file1', b'file200', b'file300'])
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 w = (b'file1\0%sx\n' b'file200\0%sl\n' b'file300\0%s\n') % (
 HASH_2,
@@ -318,7 +318,7 @@
 match = matchmod.exact(
 [b'a/b/c/bar.txt', b'a/b/d/qux.py', b'readme.txt', b'nonexistent']
 )
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(
 [b'a/b/c/bar.txt', b'a/b/d/qux.py', b'readme.txt'], m2.keys()
@@ -332,7 +332,7 @@
 match = matchmod.match(
 util.localpath(b'/repo'), b'', [b'a/f'], default=b'relpath'
 )
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual([], m2.keys())
 
@@ -343,7 +343,7 @@
 
 flist = m.keys()[80:300]
 match = matchmod.exact(flist)
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(flist, m2.keys())
 
@@ -352,7 +352,7 @@
 m = self.parsemanifest(A_DEEPER_MANIFEST)
 
 match = matchmod.match(util.localpath(b'/repo'), b'', [b''])
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(m.keys(), m2.keys())
 
@@ -364,7 +364,7 @@
 match = matchmod.match(
 util.localpath(b'/repo'), b'', [b'a/b'], default=b'relpath'
 )
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(
 [
@@ -388,7 +388,7 @@
 m = self.parsemanifest(A_DEEPER_MANIFEST)
 
 match = matchmod.exact([b'a/b'])
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual([], m2.keys())
 
@@ -400,7 +400,7 @@
 match = matchmod.match(
 util.localpath(b'/repo'), b'a/b', [b'.'], default=b'relpath'
 )
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(
 [
@@ -423,7 +423,7 @@
 m = self.parsemanifest(A_DEEPER_MANIFEST)
 
 match = matchmod.match(util.localpath(b'/repo'), b'', [b'a/b/*/*.txt'])
-m2 = m.matches(match)
+m2 = m._matches(match)
 
 self.assertEqual(
 [b'a/b/c/bar.txt', b'a/b/c/foo.txt', b'a/b/d/ten.txt'], m2.keys()
diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -545,7 +545,7 @@
 if not self.hasdir(fn):
 match.bad(fn, None)
 
-def matches(self, match):
+def _matches(self, match):
 '''generate a new manifest filtered by the match argument'''
 if match.always():
 return self.copy()
@@ -578,8 +578,8 @@
 string.
 '''
 if match:
-m1 = self.matches(match)
-m2 = m2.matches(match)
+m1 = self._matches(match)
+m2 = m2._matches(match)
 return m1.diff(m2, clean=clean)
 return self._lm.diff(m2._lm, clean)
 
@@ -1075,8 +1075,8 @@
 def filesnotin(self, m2, match=None):
 '''Set of files in this manifest that are not in the other'''
 if match and not match.always():
-m1 = self.matches(match)
-m2 = m2.matches(match)
+m1 = self._matches(match)
+m2 = m2._matches(match)
 return m1.filesnotin(m2)
 
 files = set()
@@ -1122,9 +1122,6 @@
 def walk(self, match):
 '''Generates matching file names.
 
-Equivalent to manifest.matches(match).iterkeys(), but without creating
-an entirely new manifest.
-
 It also reports nonexistent files by marking them bad with match.bad().
 '''
 if match.always():
@@ -1167,16 +1164,16 @@
 for f in 

D7922: rust-matchers: add function to generate a regex matcher function

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
This revision now requires changes to proceed.
martinvonz added inline comments.
martinvonz requested changes to this revision.

INLINE COMMENTS

> matchers.rs:224
> +
> +const MAX_RE_SIZE: usize = 2;
> +

Hmm, I don't like to replicate this into Rust. I argued for a long time with 
Boris over a year ago that we should see if we can remove it from Python. He 
said they (Octobus, I think) would look into that if I would just queue the 
workaround for the time being. Could you see if you can simplify the Python 
code first instead?

See https://patchwork.mercurial-scm.org/patch/36755/ for discussion.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7922/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7922

To: Alphare, #hg-reviewers, pulkit, martinvonz
Cc: martinvonz, durin42, kevincox, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8104: cleanup: re-run black on the codebase

2020-02-10 Thread durin42 (Augie Fackler)
Closed by commit rHGa0ec05d93c8e: cleanup: re-run black on the codebase 
(authored by durin42).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8104?vs=20067=20100

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8104/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8104

AFFECTED FILES
  mercurial/branchmap.py
  mercurial/changegroup.py
  mercurial/cmdutil.py
  mercurial/commands.py
  mercurial/debugcommands.py
  mercurial/discovery.py
  mercurial/dispatch.py
  mercurial/help.py
  mercurial/posix.py
  mercurial/tags.py

CHANGE DETAILS

diff --git a/mercurial/tags.py b/mercurial/tags.py
--- a/mercurial/tags.py
+++ b/mercurial/tags.py
@@ -720,7 +720,9 @@
 
 self._dirtyoffset = None
 
-rawlentokeep = min(wantedlen, (rawlen / _fnodesrecsize) * 
_fnodesrecsize)
+rawlentokeep = min(
+wantedlen, (rawlen / _fnodesrecsize) * _fnodesrecsize
+)
 if rawlen > rawlentokeep:
 # There's no easy way to truncate array instances. This seems
 # slightly less evil than copying a potentially large array slice.
diff --git a/mercurial/posix.py b/mercurial/posix.py
--- a/mercurial/posix.py
+++ b/mercurial/posix.py
@@ -324,9 +324,8 @@
 open(fullpath, b'w').close()
 except IOError as inst:
 if (
-inst[0]  # pytype: disable=unsupported-operands
-== errno.EACCES
-):
+inst[0] == errno.EACCES
+):  # pytype: disable=unsupported-operands
 # If we can't write to cachedir, just pretend
 # that the fs is readonly and by association
 # that the fs won't support symlinks. This
diff --git a/mercurial/help.py b/mercurial/help.py
--- a/mercurial/help.py
+++ b/mercurial/help.py
@@ -152,6 +152,7 @@
 doc = b''.join(rst)
 return doc
 
+
 def parsedefaultmarker(text):
 """given a text 'abc (DEFAULT: def.ghi)',
 returns (b'abc', (b'def', b'ghi')). Otherwise return None"""
@@ -159,9 +160,10 @@
 marker = b' (DEFAULT: '
 pos = text.find(marker)
 if pos >= 0:
-item = text[pos + len(marker):-1]
+item = text[pos + len(marker) : -1]
 return text[:pos], item.split(b'.', 2)
 
+
 def optrst(header, options, verbose, ui):
 data = []
 multioccur = False
@@ -734,7 +736,9 @@
 
 if ui.verbose:
 rst.append(
-optrst(_(b"global options"), commands.globalopts, ui.verbose, 
ui)
+optrst(
+_(b"global options"), commands.globalopts, ui.verbose, ui
+)
 )
 
 if not ui.verbose:
@@ -874,7 +878,9 @@
 elif ui.verbose:
 rst.append(
 b'\n%s\n'
-% optrst(_(b"global options"), commands.globalopts, 
ui.verbose, ui)
+% optrst(
+_(b"global options"), commands.globalopts, ui.verbose, ui
+)
 )
 if name == b'shortlist':
 rst.append(
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -624,7 +624,7 @@
 except error.AmbiguousCommand:
 self.badalias = _(
 b"alias '%s' resolves to ambiguous command '%s'"
-) % (self.name, cmd)
+) % (self.name, cmd,)
 
 def _populatehelp(self, ui, name, cmd, fn, defaulthelp=None):
 # confine strings to be passed to i18n.gettext()
diff --git a/mercurial/discovery.py b/mercurial/discovery.py
--- a/mercurial/discovery.py
+++ b/mercurial/discovery.py
@@ -448,7 +448,7 @@
 if branch not in (b'default', None):
 errormsg = _(
 b"push creates new remote head %s on branch '%s'!"
-) % (short(dhs[0]), branch)
+) % (short(dhs[0]), branch,)
 elif repo[dhs[0]].bookmarks():
 errormsg = _(
 b"push creates new remote head %s "
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -3429,6 +3429,7 @@
 ui.write(node2str(node))
 ui.write(b'\n')
 
+
 @command(b'debugtagscache', [])
 def debugtagscache(ui, repo):
 """display the contents of .hg/cache/hgtagsfnodes1"""
@@ -3439,6 +3440,7 @@
 tagsnodedisplay = hex(tagsnode) if tagsnode else 'missing/invalid'
 ui.write(b'%s %s %s\n' % (r, hex(node), tagsnodedisplay))
 
+
 @command(
 b'debugtemplate',
 [
diff --git a/mercurial/commands.py 

D7960: httpconnection: allow `httpsendfile` subclasses to suppress the progressbar

2020-02-10 Thread durin42 (Augie Fackler)
durin42 added a comment.


  In D7960#120242 , @mharbison72 
wrote:
  
  > I forgot to reply to this last week- I was concerned when the subsequent 
part of the stack went in without suppressing the per file progress bars here, 
that the displayed progress bar would be bouncing around randomly.  But it 
wasn't- it was ever increasing like only the main bar was being changed.  Any 
ideas why that would be?
  
  Progress bars have some stickiness and won't show brief sub-topics. It's all 
pretty configurable, but I think the default is we don't show a nested topic if 
it exists for less than 2 seconds of ticks of the upper level progress bar.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7960/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7960

To: mharbison72, #hg-reviewers
Cc: durin42, marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7827: rebase: don't use rebased node as dirstate p2 (BC)

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20097.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7827?vs=19871=20097

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7827/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7827

AFFECTED FILES
  hgext/rebase.py
  relnotes/next
  tests/test-rebase-abort.t
  tests/test-rebase-collapse.t
  tests/test-rebase-conflicts.t
  tests/test-rebase-interruptions.t
  tests/test-rebase-obsolete.t
  tests/test-rebase-parameters.t
  tests/test-rebase-transaction.t

CHANGE DETAILS

diff --git a/tests/test-rebase-transaction.t b/tests/test-rebase-transaction.t
--- a/tests/test-rebase-transaction.t
+++ b/tests/test-rebase-transaction.t
@@ -114,7 +114,7 @@
   |
   | @  4: Z
   | |
-  @ |  3: C
+  % |  3: C
   | |
   | o  2: Y
   | |
@@ -123,9 +123,9 @@
   o  0: A
   
   $ hg st
-  M C
   M conflict
   A B
+  A C
   ? conflict.orig
   $ echo resolved > conflict
   $ hg resolve -m
diff --git a/tests/test-rebase-parameters.t b/tests/test-rebase-parameters.t
--- a/tests/test-rebase-parameters.t
+++ b/tests/test-rebase-parameters.t
@@ -481,11 +481,9 @@
   $ hg summary
   parent: 1:56daeba07f4b 
c2
-  parent: 2:e4e3f3546619 tip
-   c2b
   branch: default
-  commit: 1 modified, 1 unresolved (merge)
-  update: (current)
+  commit: 1 unresolved (clean)
+  update: 1 new changesets, 2 branch heads (merge)
   phases: 3 draft
   rebase: 0 rebased, 1 remaining (rebase --continue)
 
diff --git a/tests/test-rebase-obsolete.t b/tests/test-rebase-obsolete.t
--- a/tests/test-rebase-obsolete.t
+++ b/tests/test-rebase-obsolete.t
@@ -1795,19 +1795,15 @@
   $ hg log -G
   @  2:b18e25de2cf5 D
   |
-  | @  1:2ec65233581b B (pruned using prune)
-  |/
   o  0:426bada5c675 A
   
   $ hg summary
   parent: 2:b18e25de2cf5 tip
D
-  parent: 1:2ec65233581b  (obsolete)
-   B
   branch: default
-  commit: 2 modified, 1 unknown, 1 unresolved (merge)
+  commit: 1 modified, 1 added, 1 unknown, 1 unresolved
   update: (current)
-  phases: 3 draft
+  phases: 2 draft
   rebase: 0 rebased, 2 remaining (rebase --continue)
 
   $ hg rebase --abort
diff --git a/tests/test-rebase-interruptions.t 
b/tests/test-rebase-interruptions.t
--- a/tests/test-rebase-interruptions.t
+++ b/tests/test-rebase-interruptions.t
@@ -294,7 +294,7 @@
   $ hg tglogp
   @  7: 401ccec5e39f secret 'C'
   |
-  | @  6: a0b2430ebfb8 secret 'F'
+  | o  6: a0b2430ebfb8 secret 'F'
   | |
   o |  5: 45396c49d53b public 'B'
   | |
@@ -345,7 +345,7 @@
   $ hg tglogp
   @  7: 401ccec5e39f secret 'C'
   |
-  | @  6: a0b2430ebfb8 secret 'F'
+  | o  6: a0b2430ebfb8 secret 'F'
   | |
   o |  5: 45396c49d53b public 'B'
   | |
@@ -395,7 +395,7 @@
   $ hg tglogp
   @  7: 401ccec5e39f secret 'C'
   |
-  | @  6: a0b2430ebfb8 secret 'F'
+  | o  6: a0b2430ebfb8 secret 'F'
   | |
   o |  5: 45396c49d53b public 'B'
   | |
diff --git a/tests/test-rebase-conflicts.t b/tests/test-rebase-conflicts.t
--- a/tests/test-rebase-conflicts.t
+++ b/tests/test-rebase-conflicts.t
@@ -456,15 +456,14 @@
   warning: conflicts while merging conflict! (edit, then use 'hg resolve 
--mark')
   unresolved conflicts (see hg resolve, then hg rebase --continue)
   [1]
-The current parents are not 7 and 8 even though that's what we're merging
   $ hg tglog
   @  8:draft 'E'
   |
-  | o  7:draft 'D'
+  | @  7:draft 'D'
   |/
   o  6:draft 'C'
   |
-  | @5:draft 'F'
+  | %5:draft 'F'
   | |\
   | | o  4:draft 'E'
   | | |
diff --git a/tests/test-rebase-collapse.t b/tests/test-rebase-collapse.t
--- a/tests/test-rebase-collapse.t
+++ b/tests/test-rebase-collapse.t
@@ -712,7 +712,7 @@
   |
   | @  2: 82b8abf9c185 'D'
   | |
-  @ |  1: f899f3910ce7 'B'
+  % |  1: f899f3910ce7 'B'
   |/
   o  0: 4a2df7238c3b 'A'
   
@@ -736,7 +736,7 @@
   unresolved conflicts (see hg resolve, then hg rebase --continue)
   [1]
   $ hg tglog
-  @  3: 63668d570d21 'C'
+  %  3: 63668d570d21 'C'
   |
   | @  2: 82b8abf9c185 'D'
   | |
diff --git a/tests/test-rebase-abort.t b/tests/test-rebase-abort.t
--- a/tests/test-rebase-abort.t
+++ b/tests/test-rebase-abort.t
@@ -236,7 +236,7 @@
   [1]
 
   $ hg tglog
-  @  4:draft 'C1'
+  %  4:draft 'C1'
   |
   o  3:draft 'B bis'
   |
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -21,6 +21,11 @@
 
 == Backwards Compatibility Changes ==
 
+ * When `hg rebase` pauses for merge conflict resolution, the working
+   copy will no longer have the rebased node as a second parent. You
+   can use the new `conflictparents()` revset for finding the other
+   parent during a conflict.
+
 
 == Internal API Changes ==
 
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -618,6 +618,7 @@
 repo,
 rev,
 p1,
+p2,
 base,
 self.collapsef,
 dest,
@@ -642,10 +643,6 @@
  

D8043: graphlog: use '%' for other context in merge conflict

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
Herald added a subscriber: mjpieters.
martinvonz updated this revision to Diff 20095.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8043?vs=19870=20095

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8043/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8043

AFFECTED FILES
  hgext/beautifygraph.py
  mercurial/hgweb/webutil.py
  mercurial/logcmdutil.py
  mercurial/templatekw.py
  relnotes/next
  tests/test-backout.t
  tests/test-graft-interrupted.t
  tests/test-rebase-collapse.t
  tests/test-strip.t
  tests/test-update-branches.t

CHANGE DETAILS

diff --git a/tests/test-update-branches.t b/tests/test-update-branches.t
--- a/tests/test-update-branches.t
+++ b/tests/test-update-branches.t
@@ -254,7 +254,7 @@
   |
   @  4:d047485b3896 0:60829823a42a  b1
   |
-  | o  3:6efa171f091b 1:0786582aa4b1
+  | %  3:6efa171f091b 1:0786582aa4b1
   | |
   | | o  2:bd10386d478c
   | |/
diff --git a/tests/test-strip.t b/tests/test-strip.t
--- a/tests/test-strip.t
+++ b/tests/test-strip.t
@@ -598,7 +598,7 @@
   |  date:Thu Jan 01 00:00:00 1970 +
   |  summary: b
   |
-  o  changeset:   0:9ab35a2d17cb
+  %  changeset:   0:9ab35a2d17cb
  user:test
  date:Thu Jan 01 00:00:00 1970 +
  summary: a
diff --git a/tests/test-rebase-collapse.t b/tests/test-rebase-collapse.t
--- a/tests/test-rebase-collapse.t
+++ b/tests/test-rebase-collapse.t
@@ -762,7 +762,7 @@
   abort: edit failed: false exited with status 1
   [255]
   $ hg tglog
-  o  3: 63668d570d21 'C'
+  %  3: 63668d570d21 'C'
   |
   | @  2: 82b8abf9c185 'D'
   | |
diff --git a/tests/test-graft-interrupted.t b/tests/test-graft-interrupted.t
--- a/tests/test-graft-interrupted.t
+++ b/tests/test-graft-interrupted.t
@@ -431,7 +431,7 @@
   $ hg log -GT "{rev}:{node|short} {desc}"
   @  6:6ec71c037d94 added x
   |
-  | o  5:36b793615f78 added foo to c
+  | %  5:36b793615f78 added foo to c
   | |
   | | o  4:863a25e1a9ea added x
   | |/
@@ -622,7 +622,7 @@
   $ hg log -GT "{rev}:{node|short} {desc}\n"
   @  4:2aa9ad1006ff B in file a
   |
-  | o  3:09e253b87e17 A in file a
+  | %  3:09e253b87e17 A in file a
   | |
   | o  2:d36c0562f908 c
   | |
@@ -669,7 +669,7 @@
   $ hg log -GT "{rev}:{node|short} {desc}\n"
   @  4:2aa9ad1006ff B in file a
   |
-  | o  3:09e253b87e17 A in file a
+  | %  3:09e253b87e17 A in file a
   | |
   | o  2:d36c0562f908 c
   | |
@@ -712,7 +712,7 @@
   $ hg log -GT "{rev}:{node|short} {desc}\n"
   @  4:2aa9ad1006ff B in file a
   |
-  | o  3:09e253b87e17 A in file a
+  | %  3:09e253b87e17 A in file a
   | |
   | o  2:d36c0562f908 c
   | |
diff --git a/tests/test-backout.t b/tests/test-backout.t
--- a/tests/test-backout.t
+++ b/tests/test-backout.t
@@ -103,7 +103,7 @@
   |  date:Thu Jan 01 00:00:02 1970 +
   |  summary: grapes
   |
-  o  changeset:   1:22cb4f70d813
+  %  changeset:   1:22cb4f70d813
   |  user:test
   |  date:Thu Jan 01 00:00:01 1970 +
   |  summary: chair
@@ -748,7 +748,7 @@
   |  date:Thu Jan 01 00:00:00 1970 +
   |  summary: capital three
   |
-  o  changeset:   0:a30dd8addae3
+  %  changeset:   0:a30dd8addae3
  user:test
  date:Thu Jan 01 00:00:00 1970 +
  summary: initial
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -3,7 +3,12 @@
  * `hg purge`/`hg clean` can now delete ignored files instead of
untracked files, with the new -i flag.
 
- * New `conflictlocal()` and `conflictother()` revsets returns the
+ * `hg log` now defaults to using an '%' symbol for commits involved
+in unresolved merge conflicts. That includes unresolved conflicts
+caused by e.g. `hg update --merge` and `hg graft`. '@' still takes
+precedence, so what used to be marked '@' still is.
+
+ * New `conflictlocal()` and `conflictother()` revsets return the
commits that are being merged, when there are conflicts. Also works
for conflicts caused by e.g. `hg graft`.
 
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -396,26 +396,38 @@
 return templateutil.compatfileslist(context, mapping, b'file', ctx.files())
 
 
-@templatekeyword(b'graphnode', requires={b'repo', b'ctx'})
+@templatekeyword(b'graphnode', requires={b'repo', b'ctx', b'cache'})
 def showgraphnode(context, mapping):
 """String. The character representing the changeset node in an ASCII
 revision graph."""
 repo = context.resource(mapping, b'repo')
 ctx = context.resource(mapping, b'ctx')
-return getgraphnode(repo, ctx)
+cache = context.resource(mapping, b'cache')
+return getgraphnode(repo, ctx, cache)
 
 
-def getgraphnode(repo, ctx):
-return getgraphnodecurrent(repo, ctx) or getgraphnodesymbol(ctx)
+def getgraphnode(repo, ctx, cache):
+return getgraphnodecurrent(repo, ctx, cache) or getgraphnodesymbol(ctx)
 
 

D7829: rebase: remove some now-unused parent arguments

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20099.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7829?vs=19863=20099

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7829/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7829

AFFECTED FILES
  hgext/rebase.py

CHANGE DETAILS

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -506,7 +506,7 @@
 p.complete()
 ui.note(_(b'rebase merging completed\n'))
 
-def _concludenode(self, rev, p1, p2, editor, commitmsg=None):
+def _concludenode(self, rev, p1, editor, commitmsg=None):
 '''Commit the wd changes with parents p1 and p2.
 
 Reuse commit info from rev but also store useful information in extra.
@@ -530,8 +530,6 @@
 if self.inmemory:
 newnode = commitmemorynode(
 repo,
-p1,
-p2,
 wctx=self.wctx,
 extra=extra,
 commitmsg=commitmsg,
@@ -543,8 +541,6 @@
 else:
 newnode = commitnode(
 repo,
-p1,
-p2,
 extra=extra,
 commitmsg=commitmsg,
 editor=editor,
@@ -640,7 +636,7 @@
 editor = cmdutil.getcommiteditor(
 editform=editform, **pycompat.strkwargs(opts)
 )
-newnode = self._concludenode(rev, p1, p2, editor)
+newnode = self._concludenode(rev, p1, editor)
 else:
 # Skip commit if we are collapsing
 newnode = None
@@ -699,7 +695,7 @@
 
 self.wctx.setparents(repo[p1].node(), repo[self.external].node())
 newnode = self._concludenode(
-revtoreuse, p1, self.external, editor, commitmsg=commitmsg
+revtoreuse, p1, editor, commitmsg=commitmsg
 )
 
 if newnode is not None:
@@ -1421,7 +1417,7 @@
 )
 
 
-def commitmemorynode(repo, p1, p2, wctx, editor, extra, user, date, commitmsg):
+def commitmemorynode(repo, wctx, editor, extra, user, date, commitmsg):
 '''Commit the memory changes with parents p1 and p2.
 Return node of committed revision.'''
 # Replicates the empty check in ``repo.commit``.
@@ -1447,7 +1443,7 @@
 return commitres
 
 
-def commitnode(repo, p1, p2, editor, extra, user, date, commitmsg):
+def commitnode(repo, editor, extra, user, date, commitmsg):
 '''Commit the wd changes with parents p1 and p2.
 Return node of committed revision.'''
 dsguard = util.nullcontextmanager()



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7828: rebase: remove some redundant setting of dirstate parents

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20098.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7828?vs=19862=20098

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7828/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7828

AFFECTED FILES
  hgext/rebase.py

CHANGE DETAILS

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -697,6 +697,7 @@
 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
 revtoreuse = max(self.state)
 
+self.wctx.setparents(repo[p1].node(), repo[self.external].node())
 newnode = self._concludenode(
 revtoreuse, p1, self.external, editor, commitmsg=commitmsg
 )
@@ -1433,7 +1434,6 @@
 if b'branch' in extra:
 branch = extra[b'branch']
 
-wctx.setparents(repo[p1].node(), repo[p2].node())
 memctx = wctx.tomemctx(
 commitmsg,
 date=date,
@@ -1454,8 +1454,6 @@
 if not repo.ui.configbool(b'rebase', b'singletransaction'):
 dsguard = dirstateguard.dirstateguard(repo, b'rebase')
 with dsguard:
-repo.setparents(repo[p1].node(), repo[p2].node())
-
 # Commit might fail if unresolved files exist
 newnode = repo.commit(
 text=commitmsg, user=user, date=date, extra=extra, editor=editor



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8041: revset: add a revset for parents in merge state

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20094.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8041?vs=19869=20094

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8041/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8041

AFFECTED FILES
  mercurial/revset.py
  relnotes/next
  tests/test-merge4.t

CHANGE DETAILS

diff --git a/tests/test-merge4.t b/tests/test-merge4.t
--- a/tests/test-merge4.t
+++ b/tests/test-merge4.t
@@ -23,3 +23,37 @@
   abort: cannot commit merge with missing files
   [255]
 
+
+Test conflict*() revsets
+
+# Bad usage
+  $ hg log -r 'conflictlocal(foo)'
+  hg: parse error: conflictlocal takes no arguments
+  [255]
+  $ hg log -r 'conflictother(foo)'
+  hg: parse error: conflictother takes no arguments
+  [255]
+  $ hg co -C .
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+# No merge parents when not merging
+  $ hg log -r 'conflictlocal() + conflictother()'
+# No merge parents when there is no conflict
+  $ hg merge 1
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg log -r 'conflictlocal() + conflictother()'
+  $ hg co -C .
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo conflict > b
+  $ hg ci -Aqm 'conflicting change to b'
+  $ hg merge 1
+  merging b
+  warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to 
abandon
+  [1]
+# Shows merge parents when there is a conflict
+  $ hg log -r 'conflictlocal()' -T '{rev} {desc}\n'
+  3 conflicting change to b
+  $ hg log -r 'conflictother()' -T '{rev} {desc}\n'
+  1 commit #1
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -3,6 +3,11 @@
  * `hg purge`/`hg clean` can now delete ignored files instead of
untracked files, with the new -i flag.
 
+ * New `conflictlocal()` and `conflictother()` revsets returns the
+   commits that are being merged, when there are conflicts. Also works
+   for conflicts caused by e.g. `hg graft`.
+
+
 == New Experimental Features ==
 
 
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -769,6 +769,38 @@
 return subset
 
 
+@predicate(b'conflictlocal()', safe=True)
+def conflictlocal(repo, subset, x):
+"""The local side of the merge, if currently in an unresolved merge.
+
+"merge" here includes merge conflicts from e.g. 'hg rebase' or 'hg graft'.
+"""
+getargs(x, 0, 0, _(b"conflictlocal takes no arguments"))
+from . import merge
+
+mergestate = merge.mergestate.read(repo)
+if mergestate.active() and repo.changelog.hasnode(mergestate.local):
+return subset & {repo.changelog.rev(mergestate.local)}
+
+return baseset()
+
+
+@predicate(b'conflictother()', safe=True)
+def conflictother(repo, subset, x):
+"""The other side of the merge, if currently in an unresolved merge.
+
+"merge" here includes merge conflicts from e.g. 'hg rebase' or 'hg graft'.
+"""
+getargs(x, 0, 0, _(b"conflictother takes no arguments"))
+from . import merge
+
+mergestate = merge.mergestate.read(repo)
+if mergestate.active() and repo.changelog.hasnode(mergestate.other):
+return subset & {repo.changelog.rev(mergestate.other)}
+
+return baseset()
+
+
 @predicate(b'contains(pattern)', weight=100)
 def contains(repo, subset, x):
 """The revision's manifest contains a file matching pattern (but might not



To: martinvonz, #hg-reviewers
Cc: marmoute, yuja, pulkit, mjpieters, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7907: rebase: always be graft-like, not merge-like, also for merges

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20093.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7907?vs=19858=20093

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7907/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7907

AFFECTED FILES
  hgext/rebase.py
  tests/test-rebase-dest.t
  tests/test-rebase-newancestor.t

CHANGE DETAILS

diff --git a/tests/test-rebase-newancestor.t b/tests/test-rebase-newancestor.t
--- a/tests/test-rebase-newancestor.t
+++ b/tests/test-rebase-newancestor.t
@@ -68,11 +68,6 @@
 that is mixed up with the actual merge stuff and there is in general no way to
 separate them.
 
-Note: The dev branch contains _no_ changes to f-default. It might be unclear
-how rebasing of ancestor merges should be handled, but the current behavior
-with spurious prompts for conflicts in files that didn't change seems very
-wrong.
-
   $ hg init ancestor-merge
   $ cd ancestor-merge
 
@@ -133,16 +128,11 @@
   note: not rebasing 1:1d1a643d390e "dev: create branch", its destination 
already has all its changes
   rebasing 2:ec2c14fb2984 "dev: f-dev stuff"
   rebasing 4:4b019212aaf6 "dev: merge default"
-  file 'f-default' was deleted in local [dest] but was modified in other 
[source].
-  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
-  What do you want to do? c
+  note: not rebasing 4:4b019212aaf6 "dev: merge default", its destination 
already has all its changes
   rebasing 6:010ced67e558 "dev: merge default"
+  note: not rebasing 6:010ced67e558 "dev: merge default", its destination 
already has all its changes
   saved backup bundle to 
$TESTTMP/ancestor-merge/.hg/strip-backup/1d1a643d390e-4a6f6d17-rebase.hg
   $ hg tglog
-  o  6: de147e4f69cf 'dev: merge default'
-  |
-  o  5: eda7b7f46f5d 'dev: merge default'
-  |
   o  4: 3e075b1c0a40 'dev: f-dev stuff'
   |
   @  3: e08089805d82 'default: f-other stuff'
@@ -163,28 +153,8 @@
   > EOF
   rebasing 2:ec2c14fb2984 "dev: f-dev stuff"
   rebasing 4:4b019212aaf6 "dev: merge default"
-  file 'f-default' was deleted in local [dest] but was modified in other 
[source].
-  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
-  What do you want to do? c
-  rebasing 6:010ced67e558 "dev: merge default"
-  saved backup bundle to 
$TESTTMP/ancestor-merge-2/.hg/strip-backup/ec2c14fb2984-827d7a44-rebase.hg
-  $ hg tglog
-  o  7: de147e4f69cf 'dev: merge default'
-  |
-  o  6: eda7b7f46f5d 'dev: merge default'
-  |
-  o  5: 3e075b1c0a40 'dev: f-dev stuff'
-  |
-  o  4: e08089805d82 'default: f-other stuff'
-  |
-  o  3: 462860db70a1 'default: remove f-default'
-  |
-  o  2: f157ecfd2b6b 'default: f-default stuff'
-  |
-  | o  1: 1d1a643d390e 'dev: create branch' dev
-  |/
-  o  0: e90e8eb90b6f 'default: create f-default'
-  
+  abort: rebasing 4:4b019212aaf6 will include unwanted changes from 
1:1d1a643d390e
+  [255]
   $ cd ..
 
 
@@ -284,18 +254,7 @@
   rebasing 6:4c5f12f25ebe "merge rebase ancestors" (tip)
   resolving manifests
   removing other
-  note: merging f9daf77ffe76+ and 4c5f12f25ebe using bids from ancestors 
a60552eb93fb and f59da8fc0fcf
-  
-  calculating bids for ancestor a60552eb93fb
   resolving manifests
-  
-  calculating bids for ancestor f59da8fc0fcf
-  resolving manifests
-  
-  auction for merging merge bids
-   other: consensus for g
-  end of auction
-  
   getting other
   committing files:
   other
diff --git a/tests/test-rebase-dest.t b/tests/test-rebase-dest.t
--- a/tests/test-rebase-dest.t
+++ b/tests/test-rebase-dest.t
@@ -256,7 +256,7 @@
   > EOS
   rebasing 3:a4256619d830 "B" (B)
   rebasing 6:8e139e245220 "C" (C tip)
-  o8: 51e2ce92e06a C
+  o8: d7d1169e9b1c C
   |\
   | o7: 2ed0c8546285 B
   | |\
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -1678,22 +1678,6 @@
 elif p in state and state[p] > 0:
 np = state[p]
 
-# "bases" only record "special" merge bases that cannot be
-# calculated from changelog DAG (i.e. isancestor(p, np) is False).
-# For example:
-#
-#   B'   # rebase -s B -d D, when B was rebased to B'. dest for C
-#   | C  # is B', but merge base for C is B, instead of
-#   D |  # changelog.ancestor(C, B') == A. If changelog DAG and
-#   | B  # "state" edges are merged (so there will be an edge from
-#   |/   # B to B'), the merge base is still ancestor(C, B') in
-#   A# the merged graph.
-#
-# Also see https://bz.mercurial-scm.org/show_bug.cgi?id=1950#c8
-# which uses "virtual null merge" to explain this situation.
-if isancestor(p, np):
-bases[i] = nullrev
-
 # If one parent becomes an ancestor of the other, drop the ancestor
 for j, x in enumerate(newps[:i]):
 if x == nullrev:
@@ -1754,10 

D7826: rebase: stop relying on having two parents to resume rebase

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20096.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7826?vs=19860=20096

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7826/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7826

AFFECTED FILES
  hgext/rebase.py

CHANGE DETAILS

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -178,6 +178,7 @@
 # --continue or --abort)), the original repo should be used so
 # visibility-dependent revsets are correct.
 self.prepared = False
+self.resume = False
 self._repo = repo
 
 self.ui = ui
@@ -367,6 +368,7 @@
 _checkobsrebase(self.repo, self.ui, obsoleteset, skippedset)
 
 def _prepareabortorcontinue(self, isabort, backup=True, suppwarns=False):
+self.resume = True
 try:
 self.restorestatus()
 self.collapsemsg = restorecollapsemsg(self.repo, isabort)
@@ -606,8 +608,9 @@
 self.skipped,
 self.obsoletenotrebased,
 )
-if not self.inmemory and len(repo[None].parents()) == 2:
+if self.resume and self.wctx.p1().rev() == p1:
 repo.ui.debug(b'resuming interrupted rebase\n')
+self.resume = False
 else:
 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
 with ui.configoverride(overrides, b'rebase'):



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7894: nodemap: introduce an option to use mmap to read the nodemap mapping

2020-02-10 Thread marmoute (Pierre-Yves David)
marmoute added a comment.


  More throughful benchmarking has arrived.
  
  This is a large win all over the board. The win for the larger repository 
very significant.
  
+ 3.9e-05  7.1e-05 1.82  
internal.index.no_lookup.track_time('mercurial-2018-08-01', 'zlib', 'default', 
True, True, True, True, False) 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
+ 3.8e-057e-05 1.84  
internal.index.no_lookup.track_time('mercurial-2018-08-01', 'zlib', 'default', 
True, True, True, True, True) 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
+ 3.7e-057e-05 1.89  
internal.index.no_lookup.track_time('mercurial-2018-08-01', 'zstd', 'default', 
True, True, True, True, True) 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.002178 0.000111 0.05  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, False, '(-10:) + :9') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
+ 6.4e-05  9.8e-05 1.53  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, False, '-10:') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.000561  7.9e-05 0.14  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, False, '0') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.003858 0.000108 0.03  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, False, ':9 + (-10:)') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.003848   0.0001 0.03  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, False, ':9') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
+ 6.3e-05  7.8e-05 1.24  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, False, 'tip') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.002184  0.00011 0.05  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, True, '(-10:) + :9') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
+ 6.6e-05  9.9e-05 1.50  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, True, '-10:') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.0005678e-05 0.14  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, True, '0') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
- 0.00386 0.000106 0.03  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, True, ':9 + (-10:)') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.003892  9.9e-05 0.03  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, True, ':9') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
+ 6.2e-05  7.7e-05 1.24  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zlib', 
'default', True, True, True, True, True, 'tip') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.002187 0.000108 0.05  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zstd', 
'default', True, True, True, True, True, '(-10:) + :9') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
+ 6.5e-05  9.7e-05 1.49  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zstd', 
'default', True, True, True, True, True, '-10:') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.000561  7.9e-05 0.14  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zstd', 
'default', True, True, True, True, True, '0') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.003846  0.00011 0.03  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zstd', 
'default', True, True, True, True, True, ':9 + (-10:)') 
[citrea/virtualenv-py2.7-pyyaml-HGMODULEPOLICYrust+c-HGWITHRUSTEXTcpython]
-0.003854  9.9e-05 0.03  
internal.index.small_lookup.track_time('mercurial-2018-08-01', 'zstd', 

D7960: httpconnection: allow `httpsendfile` subclasses to suppress the progressbar

2020-02-10 Thread mharbison72 (Matt Harbison)
mharbison72 added a comment.


  I forgot to reply to this last week- I was concerned when the subsequent part 
of the stack went in without suppressing the per file progress bars here, that 
the displayed progress bar would be bouncing around randomly.  But it wasn't- 
it was ever increasing like only the main bar was being changed.  Any ideas why 
that would be?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7960/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7960

To: mharbison72, #hg-reviewers
Cc: durin42, marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8106: tests: accept new bzr message about switching branches

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  The new version apparently prints "Switched to branch at " instead of
  "Switched to branch: ".

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D8106

AFFECTED FILES
  tests/test-convert-bzr.t

CHANGE DETAILS

diff --git a/tests/test-convert-bzr.t b/tests/test-convert-bzr.t
--- a/tests/test-convert-bzr.t
+++ b/tests/test-convert-bzr.t
@@ -226,7 +226,7 @@
   Created tag trunk-tag.
   $ bzr switch -b branch
   Tree is up to date at revision 1.
-  Switched to branch: *repo/branch/ (glob)
+  Switched to branch *repo/branch/ (glob)
   $ sleep 1
   $ echo b > b
   $ bzr add -q b
@@ -235,7 +235,7 @@
   Created tag branch-tag.
   $ bzr switch --force ../repo/trunk
   Updated to revision 1.
-  Switched to branch: */repo/trunk/ (glob)
+  Switched to branch */repo/trunk/ (glob)
   $ sleep 1
   $ echo a >> a
   $ bzr ci -qm changea



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8105: tests: add workaround for bzr bug

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This started failing for me today. I guess my bzr was upgraded.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D8105

AFFECTED FILES
  tests/test-convert-bzr-directories.t

CHANGE DETAILS

diff --git a/tests/test-convert-bzr-directories.t 
b/tests/test-convert-bzr-directories.t
--- a/tests/test-convert-bzr-directories.t
+++ b/tests/test-convert-bzr-directories.t
@@ -2,6 +2,9 @@
 
   $ . "$TESTDIR/bzr-definitions"
 
+Work around https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=944379
+  $ mkdir -p "${HOME}/.config/breezy"
+
 empty directory
 
   $ mkdir test-empty



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


mercurial@44292: 8 new changesets

2020-02-10 Thread Mercurial Commits
8 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/63d84c18247a
changeset:   44285:63d84c18247a
parent:  44284:e786d69c665d
parent:  44256:74172a234dd3
user:Pulkit Goyal <7895pul...@gmail.com>
date:Sat Feb 08 03:13:45 2020 +0530
summary: merge with stable

https://www.mercurial-scm.org/repo/hg/rev/bbecb6d80aa7
changeset:   44286:bbecb6d80aa7
user:Augie Fackler 
date:Wed Feb 05 16:58:50 2020 -0500
summary: manifest: rewrite filesnotin to not make superfluous manifest 
copies

https://www.mercurial-scm.org/repo/hg/rev/e76d98546bd2
changeset:   44287:e76d98546bd2
user:Augie Fackler 
date:Wed Feb 05 17:12:39 2020 -0500
summary: merge: use manifestdict.walk() instead of manifestdict.matches()

https://www.mercurial-scm.org/repo/hg/rev/cd8f248fead4
changeset:   44288:cd8f248fead4
user:Matt Harbison 
date:Thu Jan 30 19:50:43 2020 -0500
summary: pyoxidizer: use `legacy_windows_stdio` on Windows

https://www.mercurial-scm.org/repo/hg/rev/9f8eddd2723f
changeset:   44289:9f8eddd2723f
user:Valentin Gatien-Baron 
date:Sat Feb 08 10:22:47 2020 -0500
summary: purge: add -i flag to delete ignored files instead of untracked 
files

https://www.mercurial-scm.org/repo/hg/rev/d8b53385b1bc
changeset:   44290:d8b53385b1bc
user:Valentin Gatien-Baron 
date:Fri Feb 07 13:54:09 2020 -0500
summary: tags: add a debug command to display .hg/cache/hgtagsfnodes1

https://www.mercurial-scm.org/repo/hg/rev/89d44cfcdeeb
changeset:   44291:89d44cfcdeeb
user:Valentin Gatien-Baron 
date:Fri Feb 07 15:55:26 2020 -0500
summary: tags: show how hg behaves if a tags cache entry is truncated

https://www.mercurial-scm.org/repo/hg/rev/f5a7cf0adb12
changeset:   44292:f5a7cf0adb12
bookmark:@
tag: tip
user:Valentin Gatien-Baron 
date:Fri Feb 07 16:01:32 2020 -0500
summary: tags: behave better if a tags cache entry is partially written

-- 
Repository URL: https://www.mercurial-scm.org/repo/hg
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7871: rust-utils: add util for canonical path

2020-02-10 Thread Raphaël Gomès
Alphare added inline comments.

INLINE COMMENTS

> martinvonz wrote in files.rs:366
> Can the test method be annotated so it's only run on unix?

Yes, but I think we need to have a more general chat about this subject. A 
non-negligible number of `hg-core`'s features do not work under non-UNIX 
systems. Our module policy system does not have the fine-grained control needed 
to map for a more complexe set of `features` (in Cargo terms). I think the more 
reasonable option right now is to have a compilation failure. Maybe we should 
have a big gated `compile_error!` at the top of `lib.rs` to inform users that 
there is work to be done to be cross-platform?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7871/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7871

To: Alphare, #hg-reviewers, kevincox, martinvonz
Cc: martinvonz, durin42, kevincox, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8035: copy: add support for marking committed copies

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20086.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8035?vs=20073=20086

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8035/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8035

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  relnotes/next
  tests/test-copy.t
  tests/test-rename-after-merge.t
  tests/test-rename-rev.t
  tests/test-rename.t

CHANGE DETAILS

diff --git a/tests/test-rename.t b/tests/test-rename-rev.t
copy from tests/test-rename.t
copy to tests/test-rename-rev.t
--- a/tests/test-rename.t
+++ b/tests/test-rename-rev.t
@@ -6,693 +6,51 @@
   $ echo d1/b > d1/b
   $ echo d2/b > d2/b
   $ hg add d1/a d1/b d1/ba d1/d11/a1 d2/b
-  $ hg commit -m "1"
-
-rename a single file
-
-  $ hg rename d1/d11/a1 d2/c
-  $ hg --config ui.portablefilenames=abort rename d1/a d1/con.xml
-  abort: filename contains 'con', which is reserved on Windows: d1/con.xml
-  [255]
-  $ hg sum
-  parent: 0:9b4b6e7b2c26 tip
-   1
-  branch: default
-  commit: 1 renamed
-  update: (current)
-  phases: 1 draft
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
-
-rename a single file using absolute paths
-
-  $ hg rename `pwd`/d1/d11/a1 `pwd`/d2/c
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
+  $ hg commit -m "intial"
 
-rename --after a single file
 
-  $ mv d1/d11/a1 d2/c
-  $ hg rename --after d1/d11/a1 d2/c
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
-
-rename --after a single file when src and tgt already tracked
-
-  $ mv d1/d11/a1 d2/c
-  $ hg addrem -s 0
-  removing d1/d11/a1
-  adding d2/c
-  $ hg rename --after d1/d11/a1 d2/c
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
-
-rename --after a single file to a nonexistent target filename
-
-  $ hg rename --after d1/a dummy
-  d1/a: not recording move - dummy does not exist
-  [1]
-
-move a single file to an existing directory
+Test single file
 
-  $ hg rename d1/d11/a1 d2
-  $ hg status -C
-  A d2/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/a1
-
-move --after a single file to an existing directory
-
-  $ mv d1/d11/a1 d2
-  $ hg rename --after d1/d11/a1 d2
-  $ hg status -C
-  A d2/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/a1
-
-rename a file using a relative path
-
-  $ (cd d1/d11; hg rename ../../d2/b e)
-  $ hg status -C
-  A d1/d11/e
-d2/b
-  R d2/b
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d1/d11/e
-
-rename --after a file using a relative path
-
-  $ (cd d1/d11; mv ../../d2/b e; hg rename --after ../../d2/b e)
-  $ hg status -C
-  A d1/d11/e
-d2/b
-  R d2/b
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d1/d11/e
-
-rename directory d1 as d3
-
-  $ hg rename d1/ d3
-  moving d1/a to d3/a
-  moving d1/b to d3/b
-  moving d1/ba to d3/ba
-  moving d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d3/a
-d1/a
-  A d3/b
-d1/b
-  A d3/ba
-d1/ba
-  A d3/d11/a1
-d1/d11/a1
-  R d1/a
-  R d1/b
-  R d1/ba
-  R d1/d11/a1
-  $ hg update -C
-  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm -rf d3
-
-rename --after directory d1 as d3
-
-  $ mv d1 d3
-  $ hg rename --after d1 d3
-  moving d1/a to d3/a
-  moving d1/b to d3/b
-  moving d1/ba to d3/ba
-  moving d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d3/a
-d1/a
-  A d3/b
+# One recoded copy, one copy to record after commit
+  $ hg cp d1/b d1/c
+  $ cp d1/b d1/d
+  $ hg add d1/d
+  $ hg ci -m 'copy d1/b to d1/c and d1/d'
+  $ hg st -C --change .
+  A d1/c
 d1/b
-  A d3/ba
-d1/ba
-  A d3/d11/a1
-d1/d11/a1
-  R d1/a
-  R d1/b
-  R d1/ba
-  R d1/d11/a1
-  $ hg update -C
-  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm -rf d3
-
-move a directory using a relative path
-
-  $ (cd d2; mkdir d3; hg rename ../d1/d11 d3)
-  moving ../d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d2/d3/d11/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm -rf d2/d3
-
-move --after a directory using a relative path
-
-  $ (cd d2; mkdir d3; mv ../d1/d11 d3; hg rename --after ../d1/d11 d3)
-  moving ../d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d2/d3/d11/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files 

D8030: copy: add support for unmarking committed copies

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20082.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8030?vs=20069=20082

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8030/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8030

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  mercurial/context.py
  relnotes/next
  tests/test-completion.t
  tests/test-copy.t
  tests/test-rename-after-merge.t

CHANGE DETAILS

diff --git a/tests/test-rename-after-merge.t b/tests/test-rename-after-merge.t
--- a/tests/test-rename-after-merge.t
+++ b/tests/test-rename-after-merge.t
@@ -120,4 +120,10 @@
   $ hg log -r tip -C -v | grep copies
   copies:  b2 (b1)
 
+Test unmarking copies in merge commit
+
+  $ hg copy --forget -r . b2
+  abort: cannot unmark copy in merge commit
+  [255]
+
   $ cd ..
diff --git a/tests/test-copy.t b/tests/test-copy.t
--- a/tests/test-copy.t
+++ b/tests/test-copy.t
@@ -319,5 +319,56 @@
   A dir2/bar
   A dir2/foo
   ? dir2/untracked
+# Clean up for next test
+  $ hg forget dir2
+  removing dir2/bar
+  removing dir2/foo
+  $ rm -r dir2
+
+Test uncopy on committed copies
+
+# Commit some copies
+  $ hg cp bar baz
+  $ hg cp bar qux
+  $ hg ci -m copies
+  $ hg st -C --change .
+  A baz
+bar
+  A qux
+bar
+  $ base=$(hg log -r '.^' -T '{rev}')
+  $ hg log -G -T '{rev}:{node|short} {desc}\n' -r $base:
+  @  5:a612dc2edfda copies
+  |
+  o  4:4800b1f1f38e add dir/
+  |
+  ~
+# Add a dirty change on top to show that it's unaffected
+  $ echo dirty >> baz
+  $ hg st
+  M baz
+  $ cat baz
+  bleah
+  dirty
+  $ hg copy --forget -r . baz
+  saved backup bundle to 
$TESTTMP/part2/.hg/strip-backup/a612dc2edfda-e36b4448-uncopy.hg
+# The unwanted copy is no longer recorded, but the unrelated one is
+  $ hg st -C --change .
+  A baz
+  A qux
+bar
+# The old commit is gone and we have updated to the new commit
+  $ hg log -G -T '{rev}:{node|short} {desc}\n' -r $base:
+  @  5:c45090e5effe copies
+  |
+  o  4:4800b1f1f38e add dir/
+  |
+  ~
+# Working copy still has the uncommitted change
+  $ hg st
+  M baz
+  $ cat baz
+  bleah
+  dirty
 
   $ cd ..
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -256,7 +256,7 @@
   commit: addremove, close-branch, amend, secret, edit, force-close-branch, 
interactive, include, exclude, message, logfile, date, user, subrepos
   config: untrusted, edit, local, global, template
   continue: dry-run
-  copy: forget, after, force, include, exclude, dry-run
+  copy: forget, after, rev, force, include, exclude, dry-run
   debugancestor: 
   debugapplystreamclonebundle: 
   debugbuilddag: mergeable-file, overwritten-file, new-file
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -3,7 +3,8 @@
  * `hg purge`/`hg clean` can now delete ignored files instead of
untracked files, with the new -i flag.
 
- * `hg copy --forget` can be used to unmark a file as copied.
+ * `hg copy --forget` can be used to unmark a file as copied. Use `hg
+   copy --forget -r REV` to unmark already committed copies.
 
 
 == New Experimental Features ==
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -2487,6 +2487,17 @@
 editor=editor,
 )
 
+def tomemctx_for_amend(self, precursor):
+extra = precursor.extra().copy()
+extra[b'amend_source'] = precursor.hex()
+return self.tomemctx(
+text=precursor.description(),
+branch=precursor.branch(),
+extra=extra,
+date=precursor.date(),
+user=precursor.user(),
+)
+
 def isdirty(self, path):
 return path in self._cache
 
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2312,6 +2312,13 @@
 (b'', b'forget', None, _(b'unmark a file as copied')),
 (b'A', b'after', None, _(b'record a copy that has already occurred')),
 (
+b'r',
+b'rev',
+b'',
+_(b'unmark copies in the given revision'),
+_(b'REV'),
+),
+(
 b'f',
 b'force',
 None,
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1419,14 +1419,33 @@
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
 if forget:
-match = scmutil.match(wctx, pats, opts)
-
-current_copies = wctx.p1copies()
-current_copies.update(wctx.p2copies())
-
-for f in wctx.walk(match):
+rev = opts[b'rev']
+if rev:
+ctx = scmutil.revsingle(repo, rev)
+else:
+ctx = repo[None]
+if ctx.rev() is None:
+new_ctx = ctx
+else:
+if len(ctx.parents()) > 1:
+   

D8029: copy: add option to unmark file as copied

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20081.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8029?vs=20068=20081

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8029/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8029

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  relnotes/next
  tests/test-completion.t
  tests/test-copy.t

CHANGE DETAILS

diff --git a/tests/test-copy.t b/tests/test-copy.t
--- a/tests/test-copy.t
+++ b/tests/test-copy.t
@@ -262,5 +262,62 @@
   xyzzy: not overwriting - file exists
   ('hg copy --after' to record the copy)
   [1]
+  $ hg co -qC .
+  $ rm baz xyzzy
+
+
+Test unmarking copy of a single file
+
+# Set up by creating a copy
+  $ hg cp bar baz
+# Test uncopying a non-existent file
+  $ hg copy --forget non-existent
+  non-existent: $ENOENT$
+# Test uncopying an tracked but unrelated file
+  $ hg copy --forget foo
+  foo: not unmarking as copy - file is not marked as copied
+# Test uncopying a copy source
+  $ hg copy --forget bar
+  bar: not unmarking as copy - file is not marked as copied
+# baz should still be marked as a copy
+  $ hg st -C
+  A baz
+bar
+# Test the normal case
+  $ hg copy --forget baz
+  $ hg st -C
+  A baz
+# Test uncopy with matching an non-matching patterns
+  $ hg cp bar baz --after
+  $ hg copy --forget bar baz
+  bar: not unmarking as copy - file is not marked as copied
+  $ hg st -C
+  A baz
+# Test uncopy with no exact matches
+  $ hg cp bar baz --after
+  $ hg copy --forget .
+  $ hg st -C
+  A baz
+  $ hg forget baz
+  $ rm baz
+
+Test unmarking copy of a directory
+
+  $ mkdir dir
+  $ echo foo > dir/foo
+  $ echo bar > dir/bar
+  $ hg add dir
+  adding dir/bar
+  adding dir/foo
+  $ hg ci -m 'add dir/'
+  $ hg cp dir dir2
+  copying dir/bar to dir2/bar
+  copying dir/foo to dir2/foo
+  $ touch dir2/untracked
+  $ hg copy --forget dir2
+  $ hg st -C
+  A dir2/bar
+  A dir2/foo
+  ? dir2/untracked
 
   $ cd ..
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -256,7 +256,7 @@
   commit: addremove, close-branch, amend, secret, edit, force-close-branch, 
interactive, include, exclude, message, logfile, date, user, subrepos
   config: untrusted, edit, local, global, template
   continue: dry-run
-  copy: after, force, include, exclude, dry-run
+  copy: forget, after, force, include, exclude, dry-run
   debugancestor: 
   debugapplystreamclonebundle: 
   debugbuilddag: mergeable-file, overwritten-file, new-file
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -3,6 +3,9 @@
  * `hg purge`/`hg clean` can now delete ignored files instead of
untracked files, with the new -i flag.
 
+ * `hg copy --forget` can be used to unmark a file as copied.
+
+
 == New Experimental Features ==
 
 
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2309,6 +2309,7 @@
 @command(
 b'copy|cp',
 [
+(b'', b'forget', None, _(b'unmark a file as copied')),
 (b'A', b'after', None, _(b'record a copy that has already occurred')),
 (
 b'f',
@@ -2333,8 +2334,11 @@
 exist in the working directory. If invoked with -A/--after, the
 operation is recorded, but no copying is performed.
 
-This command takes effect with the next commit. To undo a copy
-before that, see :hg:`revert`.
+To undo marking a file as copied, use --forget. With that option,
+both SOURCE and DEST are interpreted as destinations. The destination
+file(s) will be left in place (still tracked).
+
+This command takes effect with the next commit.
 
 Returns 0 on success, 1 if errors are encountered.
 """
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1403,18 +1403,39 @@
 
 
 def copy(ui, repo, pats, opts, rename=False):
+check_incompatible_arguments(opts, b'forget', [b'dry_run'])
+
 # called with the repo lock held
 #
 # hgsep => pathname that uses "/" to separate directories
 # ossep => pathname that uses os.sep to separate directories
 cwd = repo.getcwd()
 targets = {}
+forget = opts.get(b"forget")
 after = opts.get(b"after")
 dryrun = opts.get(b"dry_run")
 wctx = repo[None]
 
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
+if forget:
+match = scmutil.match(wctx, pats, opts)
+
+current_copies = wctx.p1copies()
+current_copies.update(wctx.p2copies())
+
+for f in wctx.walk(match):
+if f in current_copies:
+wctx[f].markcopied(None)
+elif match.exact(f):
+ui.warn(
+_(
+b'%s: not unmarking as copy - file is not marked as 
copied\n'
+)
+% uipathfn(f)
+ 

D8033: copy: move argument validation a little earlier

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20085.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8033?vs=20072=20085

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8033/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8033

AFFECTED FILES
  mercurial/cmdutil.py

CHANGE DETAILS

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1470,6 +1470,13 @@
 
 return
 
+pats = scmutil.expandpats(pats)
+if not pats:
+raise error.Abort(_(b'no source or destination specified'))
+if len(pats) == 1:
+raise error.Abort(_(b'no destination specified'))
+dest = pats.pop()
+
 if opts.get(b'rev'):
 raise error.Abort(_("--rev is only supported with --forget"))
 
@@ -1708,12 +1715,6 @@
 res = lambda p: dest
 return res
 
-pats = scmutil.expandpats(pats)
-if not pats:
-raise error.Abort(_(b'no source or destination specified'))
-if len(pats) == 1:
-raise error.Abort(_(b'no destination specified'))
-dest = pats.pop()
 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
 if not destdirexists:
 if len(pats) > 1 or matchmod.patkind(pats[0]):



To: martinvonz, #hg-reviewers, marmoute
Cc: marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8032: copy: rename `wctx` to `ctx` since it will not necessarily be working copy

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20084.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8032?vs=20071=20084

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8032/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8032

AFFECTED FILES
  mercurial/cmdutil.py

CHANGE DETAILS

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1414,8 +1414,8 @@
 forget = opts.get(b"forget")
 after = opts.get(b"after")
 dryrun = opts.get(b"dry_run")
-wctx = repo[None]
-pctx = wctx.p1()
+ctx = repo[None]
+pctx = ctx.p1()
 
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
@@ -1475,11 +1475,11 @@
 
 def walkpat(pat):
 srcs = []
-m = scmutil.match(wctx, [pat], opts, globbed=True)
-for abs in wctx.walk(m):
+m = scmutil.match(ctx, [pat], opts, globbed=True)
+for abs in ctx.walk(m):
 rel = uipathfn(abs)
 exact = m.exact(abs)
-if abs not in wctx:
+if abs not in ctx:
 if abs in pctx:
 if not after:
 if exact:
@@ -1632,13 +1632,13 @@
 
 # fix up dirstate
 scmutil.dirstatecopy(
-ui, repo, wctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd
+ui, repo, ctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd
 )
 if rename and not dryrun:
 if not after and srcexists and not samefile:
 rmdir = repo.ui.configbool(b'experimental', b'removeemptydirs')
 repo.wvfs.unlinkpath(abssrc, rmdir=rmdir)
-wctx.forget([abssrc])
+ctx.forget([abssrc])
 
 # pat: ossep
 # dest ossep



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7910: rust-re2: add wrapper for calling Re2 from Rust

2020-02-10 Thread Raphaël Gomès
Closed by commit rHGcdf3e49a0572: rust-re2: add wrapper for calling Re2 from 
Rust (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7910?vs=20040=20080

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7910/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7910

AFFECTED FILES
  rust/Cargo.lock
  rust/hg-core/Cargo.toml
  rust/hg-core/build.rs
  rust/hg-core/src/lib.rs
  rust/hg-core/src/re2/mod.rs
  rust/hg-core/src/re2/re2.rs
  rust/hg-core/src/re2/rust_re2.cpp
  rust/hg-cpython/Cargo.toml
  setup.py

CHANGE DETAILS

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -1351,10 +1351,19 @@
 env['HOME'] = pwd.getpwuid(os.getuid()).pw_dir
 
 cargocmd = ['cargo', 'rustc', '-vv', '--release']
+
+feature_flags = []
+
 if sys.version_info[0] == 3 and self.py3_features is not None:
-cargocmd.extend(
-('--features', self.py3_features, '--no-default-features')
-)
+feature_flags.append(self.py3_features)
+cargocmd.append('--no-default-features')
+
+rust_features = env.get("HG_RUST_FEATURES")
+if rust_features:
+feature_flags.append(rust_features)
+
+cargocmd.extend(('--features', " ".join(feature_flags)))
+
 cargocmd.append('--')
 if sys.platform == 'darwin':
 cargocmd.extend(
diff --git a/rust/hg-cpython/Cargo.toml b/rust/hg-cpython/Cargo.toml
--- a/rust/hg-cpython/Cargo.toml
+++ b/rust/hg-cpython/Cargo.toml
@@ -10,6 +10,7 @@
 
 [features]
 default = ["python27"]
+with-re2 = ["hg-core/with-re2"]
 
 # Features to build an extension module:
 python27 = ["cpython/python27-sys", "cpython/extension-module-2-7"]
@@ -21,7 +22,7 @@
 python3-bin = ["cpython/python3-sys"]
 
 [dependencies]
-hg-core = { path = "../hg-core" }
+hg-core = { path = "../hg-core"}
 libc = '*'
 
 [dependencies.cpython]
diff --git a/rust/hg-core/src/re2/rust_re2.cpp 
b/rust/hg-core/src/re2/rust_re2.cpp
new file mode 100644
--- /dev/null
+++ b/rust/hg-core/src/re2/rust_re2.cpp
@@ -0,0 +1,49 @@
+/*
+rust_re2.cpp
+
+C ABI export of Re2's C++ interface for Rust FFI.
+
+Copyright 2020 Valentin Gatien-Baron
+
+This software may be used and distributed according to the terms of the
+GNU General Public License version 2 or any later version.
+*/
+
+#include 
+using namespace re2;
+
+extern "C" {
+   RE2* rust_re2_create(const char* data, size_t len) {
+   RE2::Options o;
+   o.set_encoding(RE2::Options::Encoding::EncodingLatin1);
+   o.set_log_errors(false);
+   o.set_max_mem(5000);
+
+   return new RE2(StringPiece(data, len), o);
+   }
+
+   void rust_re2_destroy(RE2* re) {
+   delete re;
+   }
+
+   bool rust_re2_ok(RE2* re) {
+   return re->ok();
+   }
+
+   void rust_re2_error(RE2* re, const char** outdata, size_t* outlen) {
+   const std::string& e = re->error();
+   *outdata = e.data();
+   *outlen = e.length();
+   }
+
+   bool rust_re2_match(RE2* re, char* data, size_t len, int ianchor) {
+   const StringPiece sp = StringPiece(data, len);
+
+   RE2::Anchor anchor =
+   ianchor == 0 ? RE2::Anchor::UNANCHORED :
+   (ianchor == 1 ? RE2::Anchor::ANCHOR_START :
+RE2::Anchor::ANCHOR_BOTH);
+
+   return re->Match(sp, 0, len, anchor, NULL, 0);
+   }
+}
diff --git a/rust/hg-core/src/re2/re2.rs b/rust/hg-core/src/re2/re2.rs
new file mode 100644
--- /dev/null
+++ b/rust/hg-core/src/re2/re2.rs
@@ -0,0 +1,66 @@
+/*
+re2.rs
+
+Rust FFI bindings to Re2.
+
+Copyright 2020 Valentin Gatien-Baron
+
+This software may be used and distributed according to the terms of the
+GNU General Public License version 2 or any later version.
+*/
+use libc::{c_int, c_void};
+
+type Re2Ptr = *const c_void;
+
+pub struct Re2(Re2Ptr);
+
+/// `re2.h` says:
+/// "An "RE2" object is safe for concurrent use by multiple threads."
+unsafe impl Sync for Re2 {}
+
+/// These bind to the C ABI in `rust_re2.cpp`.
+extern "C" {
+fn rust_re2_create(data: *const u8, len: usize) -> Re2Ptr;
+fn rust_re2_destroy(re2: Re2Ptr);
+fn rust_re2_ok(re2: Re2Ptr) -> bool;
+fn rust_re2_error(
+re2: Re2Ptr,
+outdata: *mut *const u8,
+outlen: *mut usize,
+) -> bool;
+fn rust_re2_match(
+re2: Re2Ptr,
+data: *const u8,
+len: usize,
+anchor: c_int,
+) -> bool;
+}
+
+impl Re2 {
+pub fn new(pattern: &[u8]) -> Result {
+unsafe {
+let re2 = rust_re2_create(pattern.as_ptr(), pattern.len());
+if rust_re2_ok(re2) {
+

D8031: copy: rewrite walkpat() to depend less on dirstate

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20083.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8031?vs=20070=20083

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8031/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8031

AFFECTED FILES
  mercurial/cmdutil.py

CHANGE DETAILS

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1415,6 +1415,7 @@
 after = opts.get(b"after")
 dryrun = opts.get(b"dry_run")
 wctx = repo[None]
+pctx = wctx.p1()
 
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
@@ -1474,27 +1475,29 @@
 
 def walkpat(pat):
 srcs = []
-if after:
-badstates = b'?'
-else:
-badstates = b'?r'
 m = scmutil.match(wctx, [pat], opts, globbed=True)
 for abs in wctx.walk(m):
-state = repo.dirstate[abs]
 rel = uipathfn(abs)
 exact = m.exact(abs)
-if state in badstates:
-if exact and state == b'?':
-ui.warn(_(b'%s: not copying - file is not managed\n') % 
rel)
-if exact and state == b'r':
-ui.warn(
-_(
-b'%s: not copying - file has been marked for'
-b' remove\n'
+if abs not in wctx:
+if abs in pctx:
+if not after:
+if exact:
+ui.warn(
+_(
+b'%s: not copying - file has been marked '
+b'for remove\n'
+)
+% rel
+)
+continue
+else:
+if exact:
+ui.warn(
+_(b'%s: not copying - file is not managed\n') % rel
 )
-% rel
-)
-continue
+continue
+
 # abs: hgsep
 # rel: ossep
 srcs.append((abs, rel, exact))



To: martinvonz, #hg-reviewers, marmoute
Cc: marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7909: rust-filepatterns: add support for `include` and `subinclude` patterns

2020-02-10 Thread Raphaël Gomès
Closed by commit rHGd1fb8bdf3384: rust-filepatterns: add support for `include` 
and `subinclude` patterns (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7909?vs=20039=20079

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7909/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7909

AFFECTED FILES
  rust/hg-core/src/filepatterns.rs
  rust/hg-core/src/lib.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -121,6 +121,9 @@
 UnsupportedSyntaxInFile(String, String, usize),
 TooLong(usize),
 IO(std::io::Error),
+/// Needed a pattern that can be turned into a regex but got one that can't
+/// This should only happen through programmer error.
+NonRegexPattern(IgnorePattern),
 }
 
 impl ToString for PatternError {
@@ -140,6 +143,9 @@
 }
 PatternError::IO(e) => e.to_string(),
 PatternError::Path(e) => e.to_string(),
+PatternError::NonRegexPattern(pattern) => {
+format!("'{:?}' cannot be turned into a regex", pattern)
+}
 }
 }
 }
diff --git a/rust/hg-core/src/filepatterns.rs b/rust/hg-core/src/filepatterns.rs
--- a/rust/hg-core/src/filepatterns.rs
+++ b/rust/hg-core/src/filepatterns.rs
@@ -7,11 +7,19 @@
 
 //! Handling of Mercurial-specific patterns.
 
-use crate::{utils::SliceExt, FastHashMap, PatternError};
+use crate::{
+utils::{
+files::{canonical_path, get_bytes_from_path, get_path_from_bytes},
+hg_path::{path_to_hg_path_buf, HgPathBuf, HgPathError},
+SliceExt,
+},
+FastHashMap, PatternError,
+};
 use lazy_static::lazy_static;
 use regex::bytes::{NoExpand, Regex};
 use std::fs::File;
 use std::io::Read;
+use std::ops::Deref;
 use std::path::{Path, PathBuf};
 use std::vec::Vec;
 
@@ -53,6 +61,10 @@
 /// A path relative to repository root, which is matched non-recursively
 /// (will not match subdirectories)
 RootFiles,
+/// A file of patterns to read and include
+Include,
+/// A file of patterns to match against files under the same directory
+SubInclude,
 }
 
 /// Transforms a glob pattern into a regex
@@ -145,6 +157,8 @@
 b"relre:" => Ok(PatternSyntax::RelRegexp),
 b"glob:" => Ok(PatternSyntax::Glob),
 b"rootglob:" => Ok(PatternSyntax::RootGlob),
+b"include:" => Ok(PatternSyntax::Include),
+b"subinclude:" => Ok(PatternSyntax::SubInclude),
 _ => Err(PatternError::UnsupportedSyntax(
 String::from_utf8_lossy(kind).to_string(),
 )),
@@ -198,6 +212,7 @@
 PatternSyntax::Glob | PatternSyntax::RootGlob => {
 [glob_to_re(pattern).as_slice(), GLOB_SUFFIX].concat()
 }
+PatternSyntax::Include | PatternSyntax::SubInclude => unreachable!(),
 }
 }
 
@@ -259,6 +274,9 @@
 | PatternSyntax::Path
 | PatternSyntax::RelGlob
 | PatternSyntax::RootFiles => normalize_path_bytes(),
+PatternSyntax::Include | PatternSyntax::SubInclude => {
+return Err(PatternError::NonRegexPattern(entry.clone()))
+}
 _ => pattern.to_owned(),
 };
 if *syntax == PatternSyntax::RootGlob
@@ -422,6 +440,110 @@
 
 pub type PatternResult = Result;
 
+/// Wrapper for `read_pattern_file` that also recursively expands `include:`
+/// patterns.
+///
+/// `subinclude:` is not treated as a special pattern here: unraveling them
+/// needs to occur in the "ignore" phase.
+pub fn get_patterns_from_file(
+pattern_file: impl AsRef,
+root_dir: impl AsRef,
+) -> PatternResult<(Vec, Vec)> {
+let (patterns, mut warnings) = read_pattern_file(_file, true)?;
+let patterns = patterns
+.into_iter()
+.flat_map(|entry| -> PatternResult<_> {
+let IgnorePattern {
+syntax,
+pattern,
+source: _,
+} = 
+Ok(match syntax {
+PatternSyntax::Include => {
+let inner_include =
+root_dir.as_ref().join(get_path_from_bytes());
+let (inner_pats, inner_warnings) = get_patterns_from_file(
+_include,
+root_dir.as_ref(),
+)?;
+warnings.extend(inner_warnings);
+inner_pats
+}
+_ => vec![entry],
+})
+})
+.flatten()
+.collect();
+
+Ok((patterns, warnings))
+}
+
+/// Holds all the information needed to handle a `subinclude:` pattern.
+pub struct SubInclude {
+/// Will be used for repository (hg) paths that start with this prefix.
+/// It is relative to the 

D7908: rust-filepatterns: improve API and robustness for pattern files parsing

2020-02-10 Thread Raphaël Gomès
Closed by commit rHG725d79b48e07: rust-filepatterns: improve API and robustness 
for pattern files parsing (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7908?vs=20038=20078

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7908/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7908

AFFECTED FILES
  rust/hg-core/src/filepatterns.rs
  rust/hg-core/src/lib.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -25,7 +25,8 @@
 
 use crate::utils::hg_path::{HgPathBuf, HgPathError};
 pub use filepatterns::{
-build_single_regex, read_pattern_file, PatternSyntax, PatternTuple,
+parse_pattern_syntax, read_pattern_file, IgnorePattern,
+PatternFileWarning, PatternSyntax,
 };
 use std::collections::HashMap;
 use twox_hash::RandomXxHashBuilder64;
@@ -115,18 +116,31 @@
 
 #[derive(Debug)]
 pub enum PatternError {
+Path(HgPathError),
 UnsupportedSyntax(String),
+UnsupportedSyntaxInFile(String, String, usize),
+TooLong(usize),
+IO(std::io::Error),
 }
 
-#[derive(Debug)]
-pub enum PatternFileError {
-IO(std::io::Error),
-Pattern(PatternError, LineNumber),
-}
-
-impl From for PatternFileError {
-fn from(e: std::io::Error) -> Self {
-PatternFileError::IO(e)
+impl ToString for PatternError {
+fn to_string() -> String {
+match self {
+PatternError::UnsupportedSyntax(syntax) => {
+format!("Unsupported syntax {}", syntax)
+}
+PatternError::UnsupportedSyntaxInFile(syntax, file_path, line) => {
+format!(
+"{}:{}: unsupported syntax {}",
+file_path, line, syntax
+)
+}
+PatternError::TooLong(size) => {
+format!("matcher pattern is too long ({} bytes)", size)
+}
+PatternError::IO(e) => e.to_string(),
+PatternError::Path(e) => e.to_string(),
+}
 }
 }
 
@@ -141,3 +155,15 @@
 DirstateError::IO(e)
 }
 }
+
+impl From for PatternError {
+fn from(e: std::io::Error) -> Self {
+PatternError::IO(e)
+}
+}
+
+impl From for PatternError {
+fn from(e: HgPathError) -> Self {
+PatternError::Path(e)
+}
+}
diff --git a/rust/hg-core/src/filepatterns.rs b/rust/hg-core/src/filepatterns.rs
--- a/rust/hg-core/src/filepatterns.rs
+++ b/rust/hg-core/src/filepatterns.rs
@@ -7,9 +7,7 @@
 
 //! Handling of Mercurial-specific patterns.
 
-use crate::{
-utils::SliceExt, FastHashMap, LineNumber, PatternError, PatternFileError,
-};
+use crate::{utils::SliceExt, FastHashMap, PatternError};
 use lazy_static::lazy_static;
 use regex::bytes::{NoExpand, Regex};
 use std::fs::File;
@@ -32,18 +30,28 @@
 const GLOB_REPLACEMENTS: &[(&[u8], &[u8])] =
 &[(b"*/", b"(?:.*/)?"), (b"*", b".*"), (b"", b"[^/]*")];
 
+/// Appended to the regexp of globs
+const GLOB_SUFFIX: &[u8; 7] = b"(?:/|$)";
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub enum PatternSyntax {
+/// A regular expression
 Regexp,
 /// Glob that matches at the front of the path
 RootGlob,
 /// Glob that matches at any suffix of the path (still anchored at
 /// slashes)
 Glob,
+/// a path relative to repository root, which is matched recursively
 Path,
+/// A path relative to cwd
 RelPath,
+/// an unrooted glob (*.rs matches Rust files in all dirs)
 RelGlob,
+/// A regexp that needn't match the start of a name
 RelRegexp,
+/// A path relative to repository root, which is matched non-recursively
+/// (will not match subdirectories)
 RootFiles,
 }
 
@@ -125,16 +133,18 @@
 .collect()
 }
 
-fn parse_pattern_syntax(kind: &[u8]) -> Result {
+pub fn parse_pattern_syntax(
+kind: &[u8],
+) -> Result {
 match kind {
-b"re" => Ok(PatternSyntax::Regexp),
-b"path" => Ok(PatternSyntax::Path),
-b"relpath" => Ok(PatternSyntax::RelPath),
-b"rootfilesin" => Ok(PatternSyntax::RootFiles),
-b"relglob" => Ok(PatternSyntax::RelGlob),
-b"relre" => Ok(PatternSyntax::RelRegexp),
-b"glob" => Ok(PatternSyntax::Glob),
-b"rootglob" => Ok(PatternSyntax::RootGlob),
+b"re:" => Ok(PatternSyntax::Regexp),
+b"path:" => Ok(PatternSyntax::Path),
+b"relpath:" => Ok(PatternSyntax::RelPath),
+b"rootfilesin:" => Ok(PatternSyntax::RootFiles),
+b"relglob:" => Ok(PatternSyntax::RelGlob),
+b"relre:" => Ok(PatternSyntax::RelRegexp),
+b"glob:" => Ok(PatternSyntax::Glob),
+b"rootglob:" => Ok(PatternSyntax::RootGlob),
 _ => Err(PatternError::UnsupportedSyntax(
 

D7871: rust-utils: add util for canonical path

2020-02-10 Thread Raphaël Gomès
Closed by commit rHGecf816b17825: rust-utils: add util for canonical path 
(authored by Alphare).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7871?vs=20057=20077

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7871/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7871

AFFECTED FILES
  rust/Cargo.lock
  rust/hg-core/Cargo.toml
  rust/hg-core/src/utils/files.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/utils/files.rs b/rust/hg-core/src/utils/files.rs
--- a/rust/hg-core/src/utils/files.rs
+++ b/rust/hg-core/src/utils/files.rs
@@ -9,13 +9,18 @@
 
 //! Functions for fiddling with files.
 
-use crate::utils::hg_path::{HgPath, HgPathBuf};
-
-use crate::utils::replace_slice;
+use crate::utils::{
+hg_path::{path_to_hg_path_buf, HgPath, HgPathBuf, HgPathError},
+path_auditor::PathAuditor,
+replace_slice,
+};
 use lazy_static::lazy_static;
+use same_file::is_same_file;
+use std::borrow::ToOwned;
 use std::fs::Metadata;
 use std::iter::FusedIterator;
-use std::path::Path;
+use std::ops::Deref;
+use std::path::{Path, PathBuf};
 
 pub fn get_path_from_bytes(bytes: &[u8]) ->  {
 let os_str;
@@ -189,9 +194,66 @@
 }
 }
 
+/// Returns the canonical path of `name`, given `cwd` and `root`
+pub fn canonical_path(
+root: impl AsRef,
+cwd: impl AsRef,
+name: impl AsRef,
+) -> Result {
+// TODO add missing normalization for other platforms
+let root = root.as_ref();
+let cwd = cwd.as_ref();
+let name = name.as_ref();
+
+let name = if !name.is_absolute() {
+root.join().join()
+} else {
+name.to_owned()
+};
+let mut auditor = PathAuditor::new();
+if name != root && name.starts_with() {
+let name = name.strip_prefix().unwrap();
+auditor.audit_path(path_to_hg_path_buf(name)?)?;
+return Ok(name.to_owned());
+} else if name == root {
+return Ok("".into());
+} else {
+// Determine whether `name' is in the hierarchy at or beneath `root',
+// by iterating name=name.parent() until it returns `None` (can't
+// check name == '/', because that doesn't work on windows).
+let mut name = name.deref();
+let original_name = name.to_owned();
+loop {
+let same = is_same_file(, ).unwrap_or(false);
+if same {
+if name == original_name {
+// `name` was actually the same as root (maybe a symlink)
+return Ok("".into());
+}
+// `name` is a symlink to root, so `original_name` is under 
+// root
+let rel_path = original_name.strip_prefix().unwrap();
+auditor.audit_path(path_to_hg_path_buf(_path)?)?;
+return Ok(rel_path.to_owned());
+}
+name = match name.parent() {
+None => break,
+Some(p) => p,
+};
+}
+// TODO hint to the user about using --cwd
+// Bubble up the responsibility to Python for now
+Err(HgPathError::NotUnderRoot {
+path: original_name.to_owned(),
+root: root.to_owned(),
+})
+}
+}
+
 #[cfg(test)]
 mod tests {
 use super::*;
+use pretty_assertions::assert_eq;
 
 #[test]
 fn find_dirs_some() {
@@ -235,4 +297,88 @@
 assert_eq!(dirs.next(), None);
 assert_eq!(dirs.next(), None);
 }
+
+#[test]
+fn test_canonical_path() {
+let root = Path::new("/repo");
+let cwd = Path::new("/dir");
+let name = Path::new("filename");
+assert_eq!(
+canonical_path(root, cwd, name),
+Err(HgPathError::NotUnderRoot {
+path: PathBuf::from("/dir/filename"),
+root: root.to_path_buf()
+})
+);
+
+let root = Path::new("/repo");
+let cwd = Path::new("/");
+let name = Path::new("filename");
+assert_eq!(
+canonical_path(root, cwd, name),
+Err(HgPathError::NotUnderRoot {
+path: PathBuf::from("/filename"),
+root: root.to_path_buf()
+})
+);
+
+let root = Path::new("/repo");
+let cwd = Path::new("/");
+let name = Path::new("repo/filename");
+assert_eq!(
+canonical_path(root, cwd, name),
+Ok(PathBuf::from("filename"))
+);
+
+let root = Path::new("/repo");
+let cwd = Path::new("/repo");
+let name = Path::new("filename");
+assert_eq!(
+canonical_path(root, cwd, name),
+Ok(PathBuf::from("filename"))
+);
+
+let root = Path::new("/repo");
+let cwd = Path::new("/repo/subdir");
+let name = Path::new("filename");
+assert_eq!(
+canonical_path(root, cwd, 

D7966: remotefilelog: only prefetch history in linkrevfixup

2020-02-10 Thread pulkit (Pulkit Goyal)
Closed by commit rHG6f1e6e8ed85a: remotefilelog: only prefetch history in 
linkrevfixup (authored by pulkit).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Revision".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7966?vs=19500=20076

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7966/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7966

AFFECTED FILES
  hgext/remotefilelog/remotefilectx.py

CHANGE DETAILS

diff --git a/hgext/remotefilelog/remotefilectx.py 
b/hgext/remotefilelog/remotefilectx.py
--- a/hgext/remotefilelog/remotefilectx.py
+++ b/hgext/remotefilelog/remotefilectx.py
@@ -325,7 +325,9 @@
 logmsg = b''
 start = time.time()
 try:
-repo.fileservice.prefetch([(path, hex(fnode))], force=True)
+repo.fileservice.prefetch(
+[(path, hex(fnode))], force=True, fetchdata=False
+)
 
 # Now that we've downloaded a new blob from the server,
 # we need to rebuild the ancestor map to recompute the



To: pulkit, #hg-reviewers, marmoute, durin42
Cc: durin42, marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7871: rust-utils: add util for canonical path

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
This revision is now accepted and ready to land.
martinvonz added inline comments.
martinvonz accepted this revision.

INLINE COMMENTS

> files.rs:366
> +// TODO make portable
> +std::os::unix::fs::symlink(, _of_repo).unwrap();
> +

Can the test method be annotated so it's only run on unix?

REPOSITORY
  rHG Mercurial

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7871/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7871

To: Alphare, #hg-reviewers, kevincox, martinvonz
Cc: martinvonz, durin42, kevincox, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8103: test: simplify test-amend.t to avoid race condition

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHG5f55b5c35630: test: simplify test-amend.t to avoid race 
condition (authored by marmoute).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8103?vs=20036=20075

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8103/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8103

AFFECTED FILES
  tests/test-amend.t

CHANGE DETAILS

diff --git a/tests/test-amend.t b/tests/test-amend.t
--- a/tests/test-amend.t
+++ b/tests/test-amend.t
@@ -485,14 +485,14 @@
   $ echo r0 > foo; hg commit -qAm "r0"
   $ echo alpha > foo; hg commit -qm "alpha"
   $ echo beta >> foo
-  $ cat > $TESTTMP/sleepy_editor.sh < $TESTTMP/touchy_editor.sh < sleep 1
+  > echo delta >> $TESTTMP/modify-during-amend/foo
+  > sleep 1
   > echo hi > "\$1"
-  > sleep 3
+  > sleep 1
   > EOF
-  $ HGEDITOR="sh $TESTTMP/sleepy_editor.sh" hg commit --amend &
-  $ sleep 1
-  $ echo delta >> foo
-  $ sleep 3
+  $ HGEDITOR="sh $TESTTMP/touchy_editor.sh" hg commit --amend
   $ if (hg diff -c . | grep 'delta' >/dev/null) || [ -n "$(hg status)" ]; then
   >   echo "OK."
   > else



To: marmoute, #hg-reviewers, pulkit
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8102: remotefilelog-test: glob some flacky output line (issue6083)

2020-02-10 Thread marmoute (Pierre-Yves David)
Closed by commit rHGee0959e7d435: remotefilelog-test: glob some flaky output 
line (issue6083) (authored by marmoute).
This revision was automatically updated to reflect the committed changes.

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D8102?vs=20035=20074#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8102?vs=20035=20074

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8102/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8102

AFFECTED FILES
  tests/test-remotefilelog-bgprefetch.t

CHANGE DETAILS

diff --git a/tests/test-remotefilelog-bgprefetch.t 
b/tests/test-remotefilelog-bgprefetch.t
--- a/tests/test-remotefilelog-bgprefetch.t
+++ b/tests/test-remotefilelog-bgprefetch.t
@@ -178,8 +178,11 @@
   $ clearcache
   $ find $CACHEDIR -type f | sort
   $ echo b > b
+.. The following output line about files fetches is globed because it is
+.. flaky, the core the test is checked when checking the cache dir, so
+.. hopefully this flakyness is not hiding any actual bug.
   $ hg commit -qAm b
-  * files fetched over 1 fetches - (* misses, 0.00% hit ratio) over *s (glob)
+  * files fetched over 1 fetches - (* misses, 0.00% hit ratio) over *s (glob) 
(?)
   $ hg bookmark temporary
   $ find $CACHEDIR -type f | sort
   
$TESTTMP/hgcache/master/packs/8f1443d44e57fec96f72fb2412e01d2818767ef2.histidx
@@ -222,10 +225,19 @@
   (leaving bookmark temporary)
   $ clearcache
   $ find $CACHEDIR -type f | sort
+.. The following output line about files fetches is globed because it is
+.. flaky, the core the test is checked when checking the cache dir, so
+.. hopefully this flakyness is not hiding any actual bug.
   $ hg rebase -s temporary -d foo
   rebasing 3:d9cf06e3b5b6 "b" (temporary tip)
   saved backup bundle to 
$TESTTMP/shallow/.hg/strip-backup/d9cf06e3b5b6-e5c3dc63-rebase.hg
-  3 files fetched over 1 fetches - (3 misses, 0.00% hit ratio) over *s (glob)
+  ? files fetched over ? fetches - (? misses, 0.00% hit ratio) over *s (glob)
+  $ find $CACHEDIR -type f | sort
+  
$TESTTMP/hgcache/master/packs/8f1443d44e57fec96f72fb2412e01d2818767ef2.histidx
+  
$TESTTMP/hgcache/master/packs/8f1443d44e57fec96f72fb2412e01d2818767ef2.histpack
+  
$TESTTMP/hgcache/master/packs/f4d50848e0b465e9bfd2875f213044c06cfd7407.dataidx
+  
$TESTTMP/hgcache/master/packs/f4d50848e0b465e9bfd2875f213044c06cfd7407.datapack
+  $TESTTMP/hgcache/repos
 
 # Ensure that file 'y' was prefetched - it was not part of the rebase 
operation and therefore
 # could only be downloaded by the background prefetch



To: marmoute, #hg-reviewers, pulkit
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8029: copy: add option to unmark file as copied

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  In D8029#119818 , @martinvonz 
wrote:
  
  > In D8029#119813 , @marmoute 
wrote:
  >
  >> I am still not convinced by the command name.
  >>
  >> In D8029#118464 , @martinvonz 
wrote:
  >>
  >>> In D8029#118463 , @marmoute 
wrote:
  >>>
   Coudl we use a flag for to `hg copy` for that ? something like `hg copy 
--forget`
  >>>
  >>> Why would you prefer that? Discoverability?
  >>
  >> Discoverability, avoiding command creep, interface clarify, avoiding 
interface of similar command drifting appart from each other. The two command 
really deal with the same data in the same way. Having them one would
  >>
  >>> An argument against it is that the commands take different flags and 
arguments (for example, `hg uncopy` takes only the destination, no source).
  >>
  >> I don't think it is a big deal `hg copy source dest`, `hg copy --forget 
dest` seems clear enough to me.
  >> One of the thing that bother me is that `hg uncopy` is not reverse of `hg 
copy`, it is the reverse `hg copy --after` I expect it can be a source of 
confusion. using `--after` better map the behavior of the function, that is 
closer to `hg forget` as you point out in your changeset description.
  >
  > You're saying you want the user to say `hg copy --forget --after dest` to 
unmark it as copied?
  
  Since both you and @durin42 wanted `hg copy --forget`, I've updated the 
series to do it that way. I decided not to require `hg --after` since 
`--forget` could be interpreted to mean both "forget the copy" and "forget the 
file" (i.e. untrack but don't remove) at the same time. That's convenient :)
  
  Note that the synopsis of the command is now not quite correct because `hg 
copy --forget` doesn't have `SOURCE... DEST` but `DEST...`. timeless suggested 
adding multiple synopsis lines à la `man cp`, but our help system decided not 
to respect my newline. So I just gave up on it. I described it in the help text 
instead.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8029/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8029

To: martinvonz, #hg-reviewers, durin42, marmoute
Cc: pulkit, durin42, marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8035: copy: add support for marking committed copies

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20073.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8035?vs=19727=20073

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8035/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8035

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  relnotes/next
  tests/test-copy.t
  tests/test-rename-after-merge.t
  tests/test-rename-rev.t
  tests/test-rename.t

CHANGE DETAILS

diff --git a/tests/test-rename.t b/tests/test-rename-rev.t
copy from tests/test-rename.t
copy to tests/test-rename-rev.t
--- a/tests/test-rename.t
+++ b/tests/test-rename-rev.t
@@ -6,693 +6,51 @@
   $ echo d1/b > d1/b
   $ echo d2/b > d2/b
   $ hg add d1/a d1/b d1/ba d1/d11/a1 d2/b
-  $ hg commit -m "1"
-
-rename a single file
-
-  $ hg rename d1/d11/a1 d2/c
-  $ hg --config ui.portablefilenames=abort rename d1/a d1/con.xml
-  abort: filename contains 'con', which is reserved on Windows: d1/con.xml
-  [255]
-  $ hg sum
-  parent: 0:9b4b6e7b2c26 tip
-   1
-  branch: default
-  commit: 1 renamed
-  update: (current)
-  phases: 1 draft
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
-
-rename a single file using absolute paths
-
-  $ hg rename `pwd`/d1/d11/a1 `pwd`/d2/c
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
+  $ hg commit -m "intial"
 
-rename --after a single file
 
-  $ mv d1/d11/a1 d2/c
-  $ hg rename --after d1/d11/a1 d2/c
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
-
-rename --after a single file when src and tgt already tracked
-
-  $ mv d1/d11/a1 d2/c
-  $ hg addrem -s 0
-  removing d1/d11/a1
-  adding d2/c
-  $ hg rename --after d1/d11/a1 d2/c
-  $ hg status -C
-  A d2/c
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/c
-
-rename --after a single file to a nonexistent target filename
-
-  $ hg rename --after d1/a dummy
-  d1/a: not recording move - dummy does not exist
-  [1]
-
-move a single file to an existing directory
+Test single file
 
-  $ hg rename d1/d11/a1 d2
-  $ hg status -C
-  A d2/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/a1
-
-move --after a single file to an existing directory
-
-  $ mv d1/d11/a1 d2
-  $ hg rename --after d1/d11/a1 d2
-  $ hg status -C
-  A d2/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d2/a1
-
-rename a file using a relative path
-
-  $ (cd d1/d11; hg rename ../../d2/b e)
-  $ hg status -C
-  A d1/d11/e
-d2/b
-  R d2/b
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d1/d11/e
-
-rename --after a file using a relative path
-
-  $ (cd d1/d11; mv ../../d2/b e; hg rename --after ../../d2/b e)
-  $ hg status -C
-  A d1/d11/e
-d2/b
-  R d2/b
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm d1/d11/e
-
-rename directory d1 as d3
-
-  $ hg rename d1/ d3
-  moving d1/a to d3/a
-  moving d1/b to d3/b
-  moving d1/ba to d3/ba
-  moving d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d3/a
-d1/a
-  A d3/b
-d1/b
-  A d3/ba
-d1/ba
-  A d3/d11/a1
-d1/d11/a1
-  R d1/a
-  R d1/b
-  R d1/ba
-  R d1/d11/a1
-  $ hg update -C
-  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm -rf d3
-
-rename --after directory d1 as d3
-
-  $ mv d1 d3
-  $ hg rename --after d1 d3
-  moving d1/a to d3/a
-  moving d1/b to d3/b
-  moving d1/ba to d3/ba
-  moving d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d3/a
-d1/a
-  A d3/b
+# One recoded copy, one copy to record after commit
+  $ hg cp d1/b d1/c
+  $ cp d1/b d1/d
+  $ hg add d1/d
+  $ hg ci -m 'copy d1/b to d1/c and d1/d'
+  $ hg st -C --change .
+  A d1/c
 d1/b
-  A d3/ba
-d1/ba
-  A d3/d11/a1
-d1/d11/a1
-  R d1/a
-  R d1/b
-  R d1/ba
-  R d1/d11/a1
-  $ hg update -C
-  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm -rf d3
-
-move a directory using a relative path
-
-  $ (cd d2; mkdir d3; hg rename ../d1/d11 d3)
-  moving ../d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d2/d3/d11/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ rm -rf d2/d3
-
-move --after a directory using a relative path
-
-  $ (cd d2; mkdir d3; mv ../d1/d11 d3; hg rename --after ../d1/d11 d3)
-  moving ../d1/d11/a1 to d3/d11/a1
-  $ hg status -C
-  A d2/d3/d11/a1
-d1/d11/a1
-  R d1/d11/a1
-  $ hg update -C
-  1 files 

D8030: copy: add support for unmarking committed copies

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz edited the summary of this revision.
martinvonz retitled this revision from "uncopy: add support for unmarking 
committed copies" to "copy: add support for unmarking committed copies".
martinvonz marked 3 inline comments as done.
martinvonz updated this revision to Diff 20069.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8030?vs=19726=20069

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8030/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8030

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  mercurial/context.py
  relnotes/next
  tests/test-completion.t
  tests/test-copy.t
  tests/test-rename-after-merge.t

CHANGE DETAILS

diff --git a/tests/test-rename-after-merge.t b/tests/test-rename-after-merge.t
--- a/tests/test-rename-after-merge.t
+++ b/tests/test-rename-after-merge.t
@@ -120,4 +120,10 @@
   $ hg log -r tip -C -v | grep copies
   copies:  b2 (b1)
 
+Test unmarking copies in merge commit
+
+  $ hg copy --forget -r . b2
+  abort: cannot unmark copy in merge commit
+  [255]
+
   $ cd ..
diff --git a/tests/test-copy.t b/tests/test-copy.t
--- a/tests/test-copy.t
+++ b/tests/test-copy.t
@@ -319,5 +319,56 @@
   A dir2/bar
   A dir2/foo
   ? dir2/untracked
+# Clean up for next test
+  $ hg forget dir2
+  removing dir2/bar
+  removing dir2/foo
+  $ rm -r dir2
+
+Test uncopy on committed copies
+
+# Commit some copies
+  $ hg cp bar baz
+  $ hg cp bar qux
+  $ hg ci -m copies
+  $ hg st -C --change .
+  A baz
+bar
+  A qux
+bar
+  $ base=$(hg log -r '.^' -T '{rev}')
+  $ hg log -G -T '{rev}:{node|short} {desc}\n' -r $base:
+  @  5:a612dc2edfda copies
+  |
+  o  4:4800b1f1f38e add dir/
+  |
+  ~
+# Add a dirty change on top to show that it's unaffected
+  $ echo dirty >> baz
+  $ hg st
+  M baz
+  $ cat baz
+  bleah
+  dirty
+  $ hg copy --forget -r . baz
+  saved backup bundle to 
$TESTTMP/part2/.hg/strip-backup/a612dc2edfda-e36b4448-uncopy.hg
+# The unwanted copy is no longer recorded, but the unrelated one is
+  $ hg st -C --change .
+  A baz
+  A qux
+bar
+# The old commit is gone and we have updated to the new commit
+  $ hg log -G -T '{rev}:{node|short} {desc}\n' -r $base:
+  @  5:c45090e5effe copies
+  |
+  o  4:4800b1f1f38e add dir/
+  |
+  ~
+# Working copy still has the uncommitted change
+  $ hg st
+  M baz
+  $ cat baz
+  bleah
+  dirty
 
   $ cd ..
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -255,7 +255,7 @@
   commit: addremove, close-branch, amend, secret, edit, force-close-branch, 
interactive, include, exclude, message, logfile, date, user, subrepos
   config: untrusted, edit, local, global, template
   continue: dry-run
-  copy: forget, after, force, include, exclude, dry-run
+  copy: forget, after, rev, force, include, exclude, dry-run
   debugancestor: 
   debugapplystreamclonebundle: 
   debugbuilddag: mergeable-file, overwritten-file, new-file
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -1,6 +1,7 @@
 == New Features ==
 
- * `hg copy --forget` can be used to unmark a file as copied.
+ * `hg copy --forget` can be used to unmark a file as copied. Use `hg
+   copy --forget -r REV` to unmark already committed copies.
 
 
 == New Experimental Features ==
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -2487,6 +2487,17 @@
 editor=editor,
 )
 
+def tomemctx_for_amend(self, precursor):
+extra = precursor.extra().copy()
+extra[b'amend_source'] = precursor.hex()
+return self.tomemctx(
+text=precursor.description(),
+branch=precursor.branch(),
+extra=extra,
+date=precursor.date(),
+user=precursor.user(),
+)
+
 def isdirty(self, path):
 return path in self._cache
 
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2312,6 +2312,13 @@
 (b'', b'forget', None, _(b'unmark a file as copied')),
 (b'A', b'after', None, _(b'record a copy that has already occurred')),
 (
+b'r',
+b'rev',
+b'',
+_(b'unmark copies in the given revision'),
+_(b'REV'),
+),
+(
 b'f',
 b'force',
 None,
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1419,14 +1419,33 @@
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
 if forget:
-match = scmutil.match(wctx, pats, opts)
-
-current_copies = wctx.p1copies()
-current_copies.update(wctx.p2copies())
-
-for f in wctx.walk(match):
+rev = opts[b'rev']
+if rev:
+ctx = scmutil.revsingle(repo, rev)
+

D8029: copy: add option to unmark file as copied

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz edited the summary of this revision.
martinvonz retitled this revision from "uncopy: add new `hg uncopy` command" to 
"copy: add option to unmark file as copied".
martinvonz updated this revision to Diff 20068.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8029?vs=19725=20068

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8029/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8029

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  relnotes/next
  tests/test-completion.t
  tests/test-copy.t

CHANGE DETAILS

diff --git a/tests/test-copy.t b/tests/test-copy.t
--- a/tests/test-copy.t
+++ b/tests/test-copy.t
@@ -262,5 +262,62 @@
   xyzzy: not overwriting - file exists
   ('hg copy --after' to record the copy)
   [1]
+  $ hg co -qC .
+  $ rm baz xyzzy
+
+
+Test unmarking copy of a single file
+
+# Set up by creating a copy
+  $ hg cp bar baz
+# Test uncopying a non-existent file
+  $ hg copy --forget non-existent
+  non-existent: $ENOENT$
+# Test uncopying an tracked but unrelated file
+  $ hg copy --forget foo
+  foo: not unmarking as copy - file is not marked as copied
+# Test uncopying a copy source
+  $ hg copy --forget bar
+  bar: not unmarking as copy - file is not marked as copied
+# baz should still be marked as a copy
+  $ hg st -C
+  A baz
+bar
+# Test the normal case
+  $ hg copy --forget baz
+  $ hg st -C
+  A baz
+# Test uncopy with matching an non-matching patterns
+  $ hg cp bar baz --after
+  $ hg copy --forget bar baz
+  bar: not unmarking as copy - file is not marked as copied
+  $ hg st -C
+  A baz
+# Test uncopy with no exact matches
+  $ hg cp bar baz --after
+  $ hg copy --forget .
+  $ hg st -C
+  A baz
+  $ hg forget baz
+  $ rm baz
+
+Test unmarking copy of a directory
+
+  $ mkdir dir
+  $ echo foo > dir/foo
+  $ echo bar > dir/bar
+  $ hg add dir
+  adding dir/bar
+  adding dir/foo
+  $ hg ci -m 'add dir/'
+  $ hg cp dir dir2
+  copying dir/bar to dir2/bar
+  copying dir/foo to dir2/foo
+  $ touch dir2/untracked
+  $ hg copy --forget dir2
+  $ hg st -C
+  A dir2/bar
+  A dir2/foo
+  ? dir2/untracked
 
   $ cd ..
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -255,7 +255,7 @@
   commit: addremove, close-branch, amend, secret, edit, force-close-branch, 
interactive, include, exclude, message, logfile, date, user, subrepos
   config: untrusted, edit, local, global, template
   continue: dry-run
-  copy: after, force, include, exclude, dry-run
+  copy: forget, after, force, include, exclude, dry-run
   debugancestor: 
   debugapplystreamclonebundle: 
   debugbuilddag: mergeable-file, overwritten-file, new-file
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -1,5 +1,7 @@
 == New Features ==
 
+ * `hg copy --forget` can be used to unmark a file as copied.
+
 
 == New Experimental Features ==
 
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2309,6 +2309,7 @@
 @command(
 b'copy|cp',
 [
+(b'', b'forget', None, _(b'unmark a file as copied')),
 (b'A', b'after', None, _(b'record a copy that has already occurred')),
 (
 b'f',
@@ -2333,8 +2334,11 @@
 exist in the working directory. If invoked with -A/--after, the
 operation is recorded, but no copying is performed.
 
-This command takes effect with the next commit. To undo a copy
-before that, see :hg:`revert`.
+To undo marking a file as copied, use --forget. With that option,
+both SOURCE and DEST are interpreted as destinations. The destination
+file(s) will be left in place (still tracked).
+
+This command takes effect with the next commit.
 
 Returns 0 on success, 1 if errors are encountered.
 """
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1403,18 +1403,39 @@
 
 
 def copy(ui, repo, pats, opts, rename=False):
+check_incompatible_arguments(opts, b'forget', [b'dry_run'])
+
 # called with the repo lock held
 #
 # hgsep => pathname that uses "/" to separate directories
 # ossep => pathname that uses os.sep to separate directories
 cwd = repo.getcwd()
 targets = {}
+forget = opts.get(b"forget")
 after = opts.get(b"after")
 dryrun = opts.get(b"dry_run")
 wctx = repo[None]
 
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
+if forget:
+match = scmutil.match(wctx, pats, opts)
+
+current_copies = wctx.p1copies()
+current_copies.update(wctx.p2copies())
+
+for f in wctx.walk(match):
+if f in current_copies:
+wctx[f].markcopied(None)
+elif match.exact(f):
+ui.warn(
+_(
+b'%s: not unmarking as copy - file is not 

D8033: copy: move argument validation a little earlier

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20072.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8033?vs=19696=20072

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8033/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8033

AFFECTED FILES
  mercurial/cmdutil.py

CHANGE DETAILS

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1470,6 +1470,13 @@
 
 return
 
+pats = scmutil.expandpats(pats)
+if not pats:
+raise error.Abort(_(b'no source or destination specified'))
+if len(pats) == 1:
+raise error.Abort(_(b'no destination specified'))
+dest = pats.pop()
+
 if opts.get(b'rev'):
 raise error.Abort(_("--rev is only supported with --forget"))
 
@@ -1708,12 +1715,6 @@
 res = lambda p: dest
 return res
 
-pats = scmutil.expandpats(pats)
-if not pats:
-raise error.Abort(_(b'no source or destination specified'))
-if len(pats) == 1:
-raise error.Abort(_(b'no destination specified'))
-dest = pats.pop()
 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
 if not destdirexists:
 if len(pats) > 1 or matchmod.patkind(pats[0]):



To: martinvonz, #hg-reviewers, marmoute
Cc: marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8031: copy: rewrite walkpat() to depend less on dirstate

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20070.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8031?vs=19694=20070

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8031/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8031

AFFECTED FILES
  mercurial/cmdutil.py

CHANGE DETAILS

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1415,6 +1415,7 @@
 after = opts.get(b"after")
 dryrun = opts.get(b"dry_run")
 wctx = repo[None]
+pctx = wctx.p1()
 
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
@@ -1474,27 +1475,29 @@
 
 def walkpat(pat):
 srcs = []
-if after:
-badstates = b'?'
-else:
-badstates = b'?r'
 m = scmutil.match(wctx, [pat], opts, globbed=True)
 for abs in wctx.walk(m):
-state = repo.dirstate[abs]
 rel = uipathfn(abs)
 exact = m.exact(abs)
-if state in badstates:
-if exact and state == b'?':
-ui.warn(_(b'%s: not copying - file is not managed\n') % 
rel)
-if exact and state == b'r':
-ui.warn(
-_(
-b'%s: not copying - file has been marked for'
-b' remove\n'
+if abs not in wctx:
+if abs in pctx:
+if not after:
+if exact:
+ui.warn(
+_(
+b'%s: not copying - file has been marked '
+b'for remove\n'
+)
+% rel
+)
+continue
+else:
+if exact:
+ui.warn(
+_(b'%s: not copying - file is not managed\n') % rel
 )
-% rel
-)
-continue
+continue
+
 # abs: hgsep
 # rel: ossep
 srcs.append((abs, rel, exact))



To: martinvonz, #hg-reviewers, marmoute
Cc: marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8032: copy: rename `wctx` to `ctx` since it will not necessarily be working copy

2020-02-10 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 20071.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8032?vs=19695=20071

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8032/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8032

AFFECTED FILES
  mercurial/cmdutil.py

CHANGE DETAILS

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1414,8 +1414,8 @@
 forget = opts.get(b"forget")
 after = opts.get(b"after")
 dryrun = opts.get(b"dry_run")
-wctx = repo[None]
-pctx = wctx.p1()
+ctx = repo[None]
+pctx = ctx.p1()
 
 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
 
@@ -1475,11 +1475,11 @@
 
 def walkpat(pat):
 srcs = []
-m = scmutil.match(wctx, [pat], opts, globbed=True)
-for abs in wctx.walk(m):
+m = scmutil.match(ctx, [pat], opts, globbed=True)
+for abs in ctx.walk(m):
 rel = uipathfn(abs)
 exact = m.exact(abs)
-if abs not in wctx:
+if abs not in ctx:
 if abs in pctx:
 if not after:
 if exact:
@@ -1632,13 +1632,13 @@
 
 # fix up dirstate
 scmutil.dirstatecopy(
-ui, repo, wctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd
+ui, repo, ctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd
 )
 if rename and not dryrun:
 if not after and srcexists and not samefile:
 rmdir = repo.ui.configbool(b'experimental', b'removeemptydirs')
 repo.wvfs.unlinkpath(abssrc, rmdir=rmdir)
-wctx.forget([abssrc])
+ctx.forget([abssrc])
 
 # pat: ossep
 # dest ossep



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8104: cleanup: re-run black on the codebase

2020-02-10 Thread durin42 (Augie Fackler)
durin42 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Looks like a few patches have landed without having been blackened. I
  strongly suspect I should write a patch for baymax that blackens
  things on the way in...
  
  1. skip-blame automatic formatting

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D8104

AFFECTED FILES
  mercurial/branchmap.py
  mercurial/changegroup.py
  mercurial/cmdutil.py
  mercurial/commands.py
  mercurial/debugcommands.py
  mercurial/discovery.py
  mercurial/dispatch.py
  mercurial/help.py
  mercurial/posix.py
  mercurial/tags.py

CHANGE DETAILS

diff --git a/mercurial/tags.py b/mercurial/tags.py
--- a/mercurial/tags.py
+++ b/mercurial/tags.py
@@ -720,7 +720,9 @@
 
 self._dirtyoffset = None
 
-rawlentokeep = min(wantedlen, (rawlen / _fnodesrecsize) * 
_fnodesrecsize)
+rawlentokeep = min(
+wantedlen, (rawlen / _fnodesrecsize) * _fnodesrecsize
+)
 if rawlen > rawlentokeep:
 # There's no easy way to truncate array instances. This seems
 # slightly less evil than copying a potentially large array slice.
diff --git a/mercurial/posix.py b/mercurial/posix.py
--- a/mercurial/posix.py
+++ b/mercurial/posix.py
@@ -324,9 +324,8 @@
 open(fullpath, b'w').close()
 except IOError as inst:
 if (
-inst[0]  # pytype: disable=unsupported-operands
-== errno.EACCES
-):
+inst[0] == errno.EACCES
+):  # pytype: disable=unsupported-operands
 # If we can't write to cachedir, just pretend
 # that the fs is readonly and by association
 # that the fs won't support symlinks. This
diff --git a/mercurial/help.py b/mercurial/help.py
--- a/mercurial/help.py
+++ b/mercurial/help.py
@@ -152,6 +152,7 @@
 doc = b''.join(rst)
 return doc
 
+
 def parsedefaultmarker(text):
 """given a text 'abc (DEFAULT: def.ghi)',
 returns (b'abc', (b'def', b'ghi')). Otherwise return None"""
@@ -159,9 +160,10 @@
 marker = b' (DEFAULT: '
 pos = text.find(marker)
 if pos >= 0:
-item = text[pos + len(marker):-1]
+item = text[pos + len(marker) : -1]
 return text[:pos], item.split(b'.', 2)
 
+
 def optrst(header, options, verbose, ui):
 data = []
 multioccur = False
@@ -734,7 +736,9 @@
 
 if ui.verbose:
 rst.append(
-optrst(_(b"global options"), commands.globalopts, ui.verbose, 
ui)
+optrst(
+_(b"global options"), commands.globalopts, ui.verbose, ui
+)
 )
 
 if not ui.verbose:
@@ -874,7 +878,9 @@
 elif ui.verbose:
 rst.append(
 b'\n%s\n'
-% optrst(_(b"global options"), commands.globalopts, 
ui.verbose, ui)
+% optrst(
+_(b"global options"), commands.globalopts, ui.verbose, ui
+)
 )
 if name == b'shortlist':
 rst.append(
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -624,7 +624,7 @@
 except error.AmbiguousCommand:
 self.badalias = _(
 b"alias '%s' resolves to ambiguous command '%s'"
-) % (self.name, cmd)
+) % (self.name, cmd,)
 
 def _populatehelp(self, ui, name, cmd, fn, defaulthelp=None):
 # confine strings to be passed to i18n.gettext()
diff --git a/mercurial/discovery.py b/mercurial/discovery.py
--- a/mercurial/discovery.py
+++ b/mercurial/discovery.py
@@ -448,7 +448,7 @@
 if branch not in (b'default', None):
 errormsg = _(
 b"push creates new remote head %s on branch '%s'!"
-) % (short(dhs[0]), branch)
+) % (short(dhs[0]), branch,)
 elif repo[dhs[0]].bookmarks():
 errormsg = _(
 b"push creates new remote head %s "
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -3429,6 +3429,7 @@
 ui.write(node2str(node))
 ui.write(b'\n')
 
+
 @command(b'debugtagscache', [])
 def debugtagscache(ui, repo):
 """display the contents of .hg/cache/hgtagsfnodes1"""
@@ -3439,6 +3440,7 @@
 tagsnodedisplay = hex(tagsnode) if tagsnode else 'missing/invalid'
 ui.write(b'%s %s %s\n' % (r, hex(node), tagsnodedisplay))
 
+
 @command(
 b'debugtemplate',
 [
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ 

D8101: help: when possible, indicate flags implied by tweakdefaults

2020-02-10 Thread valentin.gatienbaron (Valentin Gatien-Baron)
Closed by commit rHG5830efce522b: help: when possible, indicate flags implied 
by tweakdefaults (authored by valentin.gatienbaron).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8101?vs=20034=20064

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8101/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8101

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py

CHANGE DETAILS

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -6646,7 +6646,7 @@
 (b'i', b'ignored', None, _(b'show only ignored files')),
 (b'n', b'no-status', None, _(b'hide status prefix')),
 (b't', b'terse', _NOTTERSE, _(b'show the terse output 
(EXPERIMENTAL)')),
-(b'C', b'copies', None, _(b'show source of copied files')),
+(b'C', b'copies', None, _(b'show source of copied files (DEFAULT: 
ui.statuscopies)')),
 (
 b'0',
 b'print0',
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -209,7 +209,7 @@
 b'p',
 b'show-function',
 None,
-_(b'show which function each change is in'),
+_(b'show which function each change is in (DEFAULT: 
diff.showfunc)'),
 ),
 (b'', b'reverse', None, _(b'produce a diff that undoes the changes')),
 ]



To: valentin.gatienbaron, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8100: help: add a mechanism to change flags' help depending on config

2020-02-10 Thread valentin.gatienbaron (Valentin Gatien-Baron)
Closed by commit rHG142d2a4cb69a: help: add a mechanism to change flags 
help depending on config (authored by valentin.gatienbaron).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8100?vs=20033=20063

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8100/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8100

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/help.py
  tests/test-help.t

CHANGE DETAILS

diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -788,6 +788,12 @@
   (use 'hg help extensions' for information on enabling extensions)
   [255]
 
+Checking that help adapts based on the config:
+
+  $ hg help diff --config ui.tweakdefaults=true | egrep -e '^ *(-g|config)'
+   -g --[no-]gituse git extended diff format (default: on from
+config)
+
 Make sure that we don't run afoul of the help system thinking that
 this is a section and erroring out weirdly.
 
diff --git a/mercurial/help.py b/mercurial/help.py
--- a/mercurial/help.py
+++ b/mercurial/help.py
@@ -152,8 +152,17 @@
 doc = b''.join(rst)
 return doc
 
+def parsedefaultmarker(text):
+"""given a text 'abc (DEFAULT: def.ghi)',
+returns (b'abc', (b'def', b'ghi')). Otherwise return None"""
+if text[-1:] == b')':
+marker = b' (DEFAULT: '
+pos = text.find(marker)
+if pos >= 0:
+item = text[pos + len(marker):-1]
+return text[:pos], item.split(b'.', 2)
 
-def optrst(header, options, verbose):
+def optrst(header, options, verbose, ui):
 data = []
 multioccur = False
 for option in options:
@@ -165,7 +174,14 @@
 
 if not verbose and any(w in desc for w in _exclkeywords):
 continue
-
+defaultstrsuffix = b''
+if default is None:
+parseresult = parsedefaultmarker(desc)
+if parseresult is not None:
+(desc, (section, name)) = parseresult
+if ui.configbool(section, name):
+default = True
+defaultstrsuffix = _(b' from config')
 so = b''
 if shortopt:
 so = b'-' + shortopt
@@ -183,7 +199,7 @@
 defaultstr = pycompat.bytestr(default)
 if default is True:
 defaultstr = _(b"on")
-desc += _(b" (default: %s)") % defaultstr
+desc += _(b" (default: %s)") % (defaultstr + defaultstrsuffix)
 
 if isinstance(default, list):
 lo += b" %s [+]" % optlabel
@@ -714,11 +730,11 @@
 
 # options
 if not ui.quiet and entry[1]:
-rst.append(optrst(_(b"options"), entry[1], ui.verbose))
+rst.append(optrst(_(b"options"), entry[1], ui.verbose, ui))
 
 if ui.verbose:
 rst.append(
-optrst(_(b"global options"), commands.globalopts, ui.verbose)
+optrst(_(b"global options"), commands.globalopts, ui.verbose, 
ui)
 )
 
 if not ui.verbose:
@@ -858,7 +874,7 @@
 elif ui.verbose:
 rst.append(
 b'\n%s\n'
-% optrst(_(b"global options"), commands.globalopts, ui.verbose)
+% optrst(_(b"global options"), commands.globalopts, 
ui.verbose, ui)
 )
 if name == b'shortlist':
 rst.append(
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -170,7 +170,7 @@
 
 diffopts = [
 (b'a', b'text', None, _(b'treat all files as text')),
-(b'g', b'git', None, _(b'use git extended diff format')),
+(b'g', b'git', None, _(b'use git extended diff format (DEFAULT: 
diff.git)')),
 (b'', b'binary', None, _(b'generate binary diffs in git mode (default)')),
 (b'', b'nodates', None, _(b'omit dates from diff headers')),
 ]



To: valentin.gatienbaron, #hg-reviewers, durin42
Cc: durin42, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8049: rust-dirstatemap: add `NonNormalEntries` class

2020-02-10 Thread Raphaël Gomès
Closed by commit rHGcf1f8660e568: rust-dirstatemap: add `NonNormalEntries` 
class (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8049?vs=20061=20065

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8049/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8049

AFFECTED FILES
  mercurial/dirstate.py
  rust/hg-cpython/src/dirstate.rs
  rust/hg-cpython/src/dirstate/dirstate_map.rs
  rust/hg-cpython/src/dirstate/non_normal_entries.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/dirstate/non_normal_entries.rs 
b/rust/hg-cpython/src/dirstate/non_normal_entries.rs
new file mode 100644
--- /dev/null
+++ b/rust/hg-cpython/src/dirstate/non_normal_entries.rs
@@ -0,0 +1,52 @@
+// non_normal_other_parent_entries.rs
+//
+// Copyright 2020 Raphaël Gomès 
+//
+// This software may be used and distributed according to the terms of the
+// GNU General Public License version 2 or any later version.
+
+use cpython::{
+exc::NotImplementedError, CompareOp, ObjectProtocol, PyErr, PyList,
+PyObject, PyResult, PyString, Python, PythonObject, ToPyObject,
+};
+
+use crate::dirstate::DirstateMap;
+
+py_class!(pub class NonNormalEntries |py| {
+data dmap: DirstateMap;
+
+def __contains__(, key: PyObject) -> PyResult {
+self.dmap(py).non_normal_entries_contains(py, key)
+}
+def remove(, key: PyObject) -> PyResult {
+self.dmap(py).non_normal_entries_remove(py, key)
+}
+def union(, other: PyObject) -> PyResult {
+self.dmap(py).non_normal_entries_union(py, other)
+}
+def __richcmp__(, other: PyObject, op: CompareOp) -> PyResult {
+match op {
+CompareOp::Eq => self.is_equal_to(py, other),
+CompareOp::Ne => Ok(!self.is_equal_to(py, other)?),
+_ => Err(PyErr::new::(py, ""))
+}
+}
+def __repr__() -> PyResult {
+self.dmap(py).non_normal_entries_display(py)
+}
+});
+
+impl NonNormalEntries {
+pub fn from_inner(py: Python, dm: DirstateMap) -> PyResult {
+Self::create_instance(py, dm)
+}
+
+fn is_equal_to(, py: Python, other: PyObject) -> PyResult {
+for item in other.iter(py)? {
+if !self.dmap(py).non_normal_entries_contains(py, item?)? {
+return Ok(false);
+}
+}
+Ok(true)
+}
+}
diff --git a/rust/hg-cpython/src/dirstate/dirstate_map.rs 
b/rust/hg-cpython/src/dirstate/dirstate_map.rs
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs
+++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs
@@ -13,12 +13,14 @@
 use std::time::Duration;
 
 use cpython::{
-exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject,
-PyResult, PyTuple, Python, PythonObject, ToPyObject, UnsafePyLeaked,
+exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList,
+PyObject, PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject,
+UnsafePyLeaked,
 };
 
 use crate::{
 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
+dirstate::non_normal_entries::NonNormalEntries,
 dirstate::{dirs_multiset::Dirs, make_dirstate_tuple},
 };
 use hg::{
@@ -164,32 +166,86 @@
 Ok(py.None())
 }
 
-// TODO share the reference
-def nonnormalentries() -> PyResult {
-let (non_normal, other_parent) =
-self.inner(py).borrow().non_normal_other_parent_entries();
+def other_parent_entries() -> PyResult {
+let mut inner_shared = self.inner(py).borrow_mut();
+let (_, other_parent) =
+inner_shared.get_non_normal_other_parent_entries();
 
 let locals = PyDict::new(py);
 locals.set_item(
 py,
-"non_normal",
-non_normal
-.iter()
-.map(|v| PyBytes::new(py, v.as_ref()))
-.collect::>()
-.to_py_object(py),
-)?;
-locals.set_item(
-py,
 "other_parent",
-other_parent
+other_parent.as_ref()
+.unwrap()
 .iter()
 .map(|v| PyBytes::new(py, v.as_ref()))
 .collect::>()
 .to_py_object(py),
 )?;
 
-py.eval("set(non_normal), set(other_parent)", None, Some())
+py.eval("set(other_parent)", None, Some())
+}
+
+def non_normal_entries() -> PyResult {
+NonNormalEntries::from_inner(py, self.clone_ref(py))
+}
+
+def non_normal_entries_contains(, key: PyObject) -> PyResult {
+let key = key.extract::(py)?;
+Ok(self
+.inner(py)
+.borrow_mut()
+.get_non_normal_other_parent_entries().0
+.as_ref()
+.unwrap()
+

D7960: httpconnection: allow `httpsendfile` subclasses to suppress the progressbar

2020-02-10 Thread mharbison72 (Matt Harbison)
Closed by commit rHG0e8b28fb751b: httpconnection: allow `httpsendfile` 
subclasses to suppress the progressbar (authored by mharbison72).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7960?vs=19494=20066

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7960/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7960

AFFECTED FILES
  mercurial/httpconnection.py

CHANGE DETAILS

diff --git a/mercurial/httpconnection.py b/mercurial/httpconnection.py
--- a/mercurial/httpconnection.py
+++ b/mercurial/httpconnection.py
@@ -39,12 +39,15 @@
 self.write = self._data.write
 self.length = os.fstat(self._data.fileno()).st_size
 self._pos = 0
+self._progress = self._makeprogress()
+
+def _makeprogress(self):
 # We pass double the max for total because we currently have
 # to send the bundle twice in the case of a server that
 # requires authentication. Since we can't know until we try
 # once whether authentication will be required, just lie to
 # the user and maybe the push succeeds suddenly at 50%.
-self._progress = ui.makeprogress(
+return self.ui.makeprogress(
 _(b'sending'), unit=_(b'kb'), total=(self.length // 1024 * 2)
 )
 



To: mharbison72, #hg-reviewers
Cc: durin42, marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D8099: lfs: use str for the open() mode when opening a blob for py3

2020-02-10 Thread mharbison72 (Matt Harbison)
Closed by commit rHG234001d22ba6: lfs: use str for the open() mode when opening 
a blob for py3 (authored by mharbison72).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8099?vs=20032=20062

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8099/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8099

AFFECTED FILES
  hgext/lfs/blobstore.py

CHANGE DETAILS

diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py
--- a/hgext/lfs/blobstore.py
+++ b/hgext/lfs/blobstore.py
@@ -128,7 +128,7 @@
 def open(self, oid):
 """Open a read-only file descriptor to the named blob, in either the
 usercache or the local store."""
-return open(self.path(oid), b'rb')
+return open(self.path(oid), 'rb')
 
 def path(self, oid):
 """Build the path for the given blob ``oid``.



To: mharbison72, #hg-reviewers, pulkit, durin42
Cc: durin42, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7966: remotefilelog: only prefetch history in linkrevfixup

2020-02-10 Thread durin42 (Augie Fackler)
This revision now requires changes to proceed.
durin42 added a comment.
durin42 requested changes to this revision.


  Terrible damage:
  
cd tests && python run-tests.py  test-remotefilelog-linknodes.t
running 1 tests using 1 parallel processes

--- .../tests/test-remotefilelog-linknodes.t
+++ .../hgtest/tests/test-remotefilelog-linknodes.t.err
@@ -173,7 +173,6 @@
   32e6611f6149 xx2-fake-rebased public x
   0632994590a8 xx public x
   b292c1e3311f x public x
-  1 files fetched over 1 fetches - (1 misses, 0.00% hit ratio) over *s 
(glob)

 # But not after that
   $ hg log -f x -T '{node|short} {desc} {phase} {files}\n'
@@ -184,11 +183,5 @@

 # Check the contents of the remote blob for correct linknode
   $ hg debugremotefilelog 
$CACHEDIR/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/d4a3ed9310e5bd9887e3bf779da5077efab28216
-  size: 6 bytes
-  path: 
$TESTTMP/hgcache/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/d4a3ed9310e5bd9887e3bf779da5077efab28216
-  key: d4a3ed9310e5
-
-  node =>   p1p2  linknode copyfrom
-  d4a3ed9310e5 => aee31534993a    32e6611f6149
-  aee31534993a => 1406e7411862    0632994590a8
-  1406e7411862 =>     b292c1e3311f
+  abort: $ENOENT$: 
'$TESTTMP/hgcache/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/d4a3ed9310e5bd9887e3bf779da5077efab28216'
+  [255]

ERROR: test-remotefilelog-linknodes.t output changed

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7966/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7966

To: pulkit, #hg-reviewers, marmoute, durin42
Cc: durin42, marmoute, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


  1   2   >