Re: [PATCH 1 of 5] largefiles: remove unused 'rev' parameter from downloadlfiles()

2020-09-14 Thread Pulkit Goyal
On Sun, Sep 13, 2020 at 3:57 PM Yuya Nishihara  wrote:
>
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1599788837 -32400
> #  Fri Sep 11 10:47:17 2020 +0900
> # Node ID ff5371cc36edbe4bce8f0bb8514763ced1c8da6e
> # Parent  4668766a0dac96ceb1fa27e32890889a893d5695
> largefiles: remove unused 'rev' parameter from downloadlfiles()
>
> It's no longer used since 83ead8cb0ff2 "largefiles: implement pull
> --all-largefiles as a special case of --lfrev."

Queued the series, many thanks!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH STABLE] py3: fix formatting of LookupError for workingctx

2020-09-14 Thread Pulkit Goyal
On Sun, Sep 13, 2020 at 2:02 PM Yuya Nishihara  wrote:
>
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1599980363 -32400
> #  Sun Sep 13 15:59:23 2020 +0900
> # Branch stable
> # Node ID 63842da54dde663b9227ca4c5e7615649073303c
> # Parent  d4a83a7d132ace8e3cfe366d9ef56fb99f26ffab
> py3: fix formatting of LookupError for workingctx
>
> Spotted while writing broken tests for "hg grep -fr'wdir()'".
> basectx._fileinfo() raises ManifestLookupError(self._node, ..), but _node
> of the workingctx is None for historical reasons.

Queued for stable, many thanks!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: Failing To Find Directory

2020-09-14 Thread Raphaël Gomès

What does your config path for phabricator look like?

On 9/11/20 5:39 PM, Jake Mulhern wrote:

Hello,

I used Mercurial to make and submit a patch to Phabricator for Mozilla 
last week for the first time.  I began to make a patch this week for 
Mozilla again and continue to get this message whenever I type in any 
hg command in the terminal on my mac.


*** failed to import extension phabricator from 
~/usr/local/Cellar/mercurial/5.5/lib/python3.8/site-packages/hgext/phabricator.py: 
[Errno 2] No such file or directory: 
'/Users/jacobmulhern/usr/local/Cellar/mercurial/5.5/lib/python3.8/site-packages/hgext/phabricator.py'



I have been looking through files to see where it might have the wrong 
path for this but cannot seem to find it.  Any help would be 
appreciated in this so that I can fix my Mercurial setup and submit 
more patches!



Jake Mulhern


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


Re: [PATCH 2 of 2] tags: take lock while writing `tags2` cache

2020-09-14 Thread Pulkit Goyal
On Sat, Sep 12, 2020 at 8:31 AM Yuya Nishihara  wrote:
>
> On Fri, 11 Sep 2020 12:34:01 +0530, Pulkit Goyal wrote:
> > # HG changeset patch
> > # User Pulkit Goyal <7895pul...@gmail.com>
> > # Date 1599727895 -19800
> > #  Thu Sep 10 14:21:35 2020 +0530
> > # Node ID 3eae3d3a1b44b0fe10e00766e1113c50d48ed086
> > # Parent  3095d36efcaf9ce835249c9312e892b0d54aac78
> > # EXP-Topic tags-fix
> > tags: take lock while writing `tags2` cache
> >
> > Before this patch, we were not taking lock while writing the cache. This 
> > cache
> > is shared one and hence multiple writes can happen at same time. So let's 
> > take a
> > lock before writing it. We don't wait for lock because outdated cache is 
> > still
> > fine.
> >
> > diff --git a/mercurial/tags.py b/mercurial/tags.py
> > --- a/mercurial/tags.py
> > +++ b/mercurial/tags.py
> > @@ -514,38 +514,47 @@ def _getfnodes(ui, repo, nodes):
> >
> >  def _writetagcache(ui, repo, valid, cachetags):
> >  filename = _filename(repo)
> > +
> >  try:
> > -cachefile = repo.cachevfs(filename, b'w', atomictemp=True)
>
> Write race should be dealt with atomictemp. This wouldn't need a lock.

Missed it thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 5 of 5] merge: move initial handling of mergeactions near to later one

2020-09-14 Thread Pulkit Goyal
On Sat, Sep 12, 2020 at 8:31 AM Yuya Nishihara  wrote:
>
> On Fri, 11 Sep 2020 12:35:33 +0530, Pulkit Goyal wrote:
> > # HG changeset patch
> > # User Pulkit Goyal <7895pul...@gmail.com>
> > # Date 1599119729 -19800
> > #  Thu Sep 03 13:25:29 2020 +0530
> > # Node ID c48ee69a8c7202517cade973b3abe3715bfc3c5e
> > # Parent  8abe98dc3e3c020566d64ac3f3b802de2751d55f
> > # EXP-Topic merge-newnode
> > merge: move initial handling of mergeactions near to later one
> >
> > We build `mergeactions` in the beginning and use it in end. Let's build it 
> > just
> > before where it will be used. Helps making code much easier to understand.
>
> > -ms.add(fcl, fco, fca, f)
> > -if f1 != f and move:
> > -moves.append(f1)
> > -
> > -# remove renamed files after safely stored
> > -for f in moves:
> > -if wctx[f].lexists():
> > -repo.ui.debug(b"removing %s\n" % f)
> > -wctx[f].audit()
> > -wctx[f].remove()
>
> Needs more eyes. I have no expertise to say this remove() can be moved
> after batch gets.

I also was not sure, but all tests passes which made me confident :D
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 5] merge: show list of bids for each file in bid-merge in ui.note()

2020-09-14 Thread Pulkit Goyal
On Sat, Sep 12, 2020 at 8:31 AM Yuya Nishihara  wrote:
>
> On Fri, 11 Sep 2020 12:35:30 +0530, Pulkit Goyal wrote:
> > # HG changeset patch
> > # User Pulkit Goyal <7895pul...@gmail.com>
> > # Date 1598442653 -19800
> > #  Wed Aug 26 17:20:53 2020 +0530
> > # Node ID 76753724e6b5453d9540c73b1a1a6f11de818e46
> > # Parent  c196dc7f6cf18e32a8646ae7cd0b08014f8ffbdf
> > # EXP-Topic merge-newnode
> > merge: show list of bids for each file in bid-merge in ui.note()
> >
> > Earlier, we were showing the list of bids only when we were ambiguously 
> > picking.
> > However, the cases where we unambiguously picked a side may not always be
> > correct and need to be fixed.
> >
> > Having list of bids for all files will be helpful in debugging.
>
> Will experienced users can/have to understand the output? If it's just for
> debugging, I prefer not seeing it unless necessary.

It's for debugging purposes only. Right now, a lot of times the merge
code does not add an action for an ancestor. This leads to bid merge
doing the wrong thing.
This and showing number of ancestors in this debug output is meant to
track down such cases where `manifestmerge()` is missing adding action
for a file for some ancestors.
>
> >auction for merging merge bids
> > -   f1: picking 'get' action
> > -   f2: picking 'keep' action
> > +   f1:
> > + list of bids:
> > +   remote is newer -> g
> > +   versions differ -> m
> > + picking 'get' action
>
> Nit: if it's not a debug output, maybe it can be more readable by saying
> the action first.
>
>   f1: picking 'get' action
> list of bids:
>   ...
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 5] merge: show list of bids for each file in bid-merge in ui.note()

2020-09-14 Thread Yuya Nishihara
On Mon, 14 Sep 2020 13:44:37 +0530, Pulkit Goyal wrote:
> On Sat, Sep 12, 2020 at 8:31 AM Yuya Nishihara  wrote:
> >
> > On Fri, 11 Sep 2020 12:35:30 +0530, Pulkit Goyal wrote:
> > > # HG changeset patch
> > > # User Pulkit Goyal <7895pul...@gmail.com>
> > > # Date 1598442653 -19800
> > > #  Wed Aug 26 17:20:53 2020 +0530
> > > # Node ID 76753724e6b5453d9540c73b1a1a6f11de818e46
> > > # Parent  c196dc7f6cf18e32a8646ae7cd0b08014f8ffbdf
> > > # EXP-Topic merge-newnode
> > > merge: show list of bids for each file in bid-merge in ui.note()
> > >
> > > Earlier, we were showing the list of bids only when we were ambiguously 
> > > picking.
> > > However, the cases where we unambiguously picked a side may not always be
> > > correct and need to be fixed.
> > >
> > > Having list of bids for all files will be helpful in debugging.
> >
> > Will experienced users can/have to understand the output? If it's just for
> > debugging, I prefer not seeing it unless necessary.
> 
> It's for debugging purposes only. Right now, a lot of times the merge
> code does not add an action for an ancestor. This leads to bid merge
> doing the wrong thing.
> This and showing number of ancestors in this debug output is meant to
> track down such cases where `manifestmerge()` is missing adding action
> for a file for some ancestors.

Okay, then let's switch to ui.debug() and leave the ui.note() messages
unmodified.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH V2] merge: show list of bids for each file in bid-merge in ui.debug()

2020-09-14 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1598442653 -19800
#  Wed Aug 26 17:20:53 2020 +0530
# Node ID 7f605a79653a170cbf028192e1b2b5deb2f0d9b7
# Parent  d2b5a7659fff465286c7a1a451f0ebfe7118f251
# EXP-Topic merge-newnode
merge: show list of bids for each file in bid-merge in ui.debug()

Earlier, we were showing the list of bids only when we were ambiguously picking.
However, the cases where we unambiguously picked a side may not always be
correct and need to be fixed.

Having list of bids for all files will be helpful in debugging.

Differential Revision: https://phab.mercurial-scm.org/D8966

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -1157,6 +1157,10 @@ def calculateupdates(
 )
 mresult = mergeresult()
 for f, bids in sorted(fbids.items()):
+repo.ui.debug(_(b" list of bids for %s:\n") % f)
+for m, l in sorted(bids.items()):
+for _f, args, msg in l:
+repo.ui.debug(b'   %s -> %s\n' % (msg, m))
 # bids is a mapping from action method to list af actions
 # Consensus?
 if len(bids) == 1:  # all bids are the same kind of method
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -150,7 +150,13 @@ Redo merge with merge.preferancestor="*"
f2: remote unchanged -> k
   
   auction for merging merge bids (2 ancestors)
+   list of bids for f1:
+ remote is newer -> g
+ versions differ -> m
f1: picking 'get' action
+   list of bids for f2:
+ remote unchanged -> k
+ versions differ -> m
f2: picking 'keep' action
   end of auction
   
@@ -193,7 +199,13 @@ The other way around:
f2: remote is newer -> g
   
   auction for merging merge bids (2 ancestors)
+   list of bids for f1:
+ remote unchanged -> k
+ versions differ -> m
f1: picking 'keep' action
+   list of bids for f2:
+ remote is newer -> g
+ versions differ -> m
f2: picking 'get' action
   end of auction
   
@@ -258,7 +270,13 @@ Verify how the output looks and and how 
f2: remote unchanged -> k
   
   auction for merging merge bids (2 ancestors)
+   list of bids for f1:
+ remote is newer -> g
+ versions differ -> m
f1: picking 'get' action
+   list of bids for f2:
+ remote unchanged -> k
+ versions differ -> m
f2: picking 'keep' action
   end of auction
   
@@ -431,8 +449,15 @@ Verify that the old context ancestor wor
d2/b: remote created -> g
   
   auction for merging merge bids (2 ancestors)
+   list of bids for d1/a:
+ other deleted -> r
d1/a: consensus for r
+   list of bids for d1/b:
+ other deleted -> r
d1/b: consensus for r
+   list of bids for d2/b:
+ remote created -> g
+ remote created -> g
d2/b: consensus for g
   end of auction
   
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 8] tests: add criss cross merging tests whose behavior need to be fixed

2020-09-14 Thread Pulkit Goyal
# HG changeset patch
# User Pierre-Yves David 
# Date 1592566066 -7200
#  Fri Jun 19 13:27:46 2020 +0200
# Node ID eab095687e7b655011a26001dc83c802ab474ceb
# Parent  6df7dc3e9c3578587c96f244b685d284d114f732
# EXP-Topic merge-newnode
tests: add criss cross merging tests whose behavior need to be fixed

Merging two changesets can mark a file as removed post merge. However, in some
cases, a user might not want to remove that file and they revert the removal
back and commit the merge. All this works perfectly well.

However, when we do criss-cross merges with such merge where user explicitly
choose to revert the removal with one where another user choose the removal,
we does not get any conflict.

The intent here is conflicting and merge should result in conflicts. One user
merged and want to keep the file while other user merged and want to remove the
file. Merging those merges should result in conflicts.

This patch adds test cases for these cases.

Differential Revision: https://phab.mercurial-scm.org/D8939

diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -469,3 +469,225 @@ Verify that the old context ancestor wor
   getting d2/b
   1 files updated, 0 files merged, 2 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
+
+
+Check that removal reversion does not go unotified
+==
+
+On a merge, a file can be removed and user can revert that removal. This means
+user has made an explicit choice of keeping the file or reverting the removal
+even though the merge algo wanted to remove it.
+Based on this, when we do criss cross merges, merge algorithm should not again
+choose to remove the file as in one of the merges, user made an explicit choice
+to revert the removal.
+Following test cases demonstrate how merge algo does not take in account
+explicit choices made by users to revert the removal and on criss-cross merging
+removes the file again.
+
+"Simple" case where the filenode changes
+
+
+  $ cd ..
+  $ hg init criss-cross-merge-reversal-with-update
+  $ cd criss-cross-merge-reversal-with-update
+  $ echo the-file > the-file
+  $ echo other-file > other-file
+  $ hg add the-file other-file
+  $ hg ci -m 'root-commit'
+  $ echo foo >> the-file
+  $ echo bar >> other-file
+  $ hg ci -m 'updating-both-file'
+  $ hg up 'desc("root-commit")'
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg rm the-file
+  $ hg ci -m 'delete-the-file'
+  created new head
+  $ hg log -G -T '{node|short} {desc}\n'
+  @  7801bc9b9899 delete-the-file
+  |
+  | o  9b610631ab29 updating-both-file
+  |/
+  o  955800955977 root-commit
+  
+
+Do all the merge combination (from the deleted or the update side × keeping 
and deleting the file
+
+  $ hg update 'desc("delete-the-file")'
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge 'desc("updating-both-file")' -t :local
+  1 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merge-deleting-the-file-from-deleted"
+  $ hg manifest
+  other-file
+
+  $ hg update 'desc("updating-both-file")'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge 'desc("delete-the-file")' -t :other
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merge-deleting-the-file-from-updated"
+  created new head
+  $ hg manifest
+  other-file
+
+  $ hg update 'desc("delete-the-file")'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge 'desc("updating-both-file")' -t :other
+  1 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merge-keeping-the-file-from-deleted"
+  created new head
+  $ hg manifest
+  other-file
+  the-file
+
+  $ hg update 'desc("updating-both-file")'
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge 'desc("delete-the-file")' -t :local
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merge-keeping-the-file-from-updated"
+  created new head
+  $ hg manifest
+  other-file
+  the-file
+
+There the resulting merge together (leading to criss cross situation). Check
+the conflict is properly detected.
+
+(merging two deletion together → no conflict)
+
+  $ hg update --clean 'desc("merge-deleting-the-file-from-deleted")'
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge  'desc("merge-deleting-the-file-from-updated")'
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ ls -1
+  other-file
+
+(merging a deletion with 

[PATCH 2 of 8] mergeresult: introduce dedicated tuple for no-op actions

2020-09-14 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1600071699 -19800
#  Mon Sep 14 13:51:39 2020 +0530
# Node ID cfabb1ccdf7a2cb67bb2819f798bad53c6aac977
# Parent  eab095687e7b655011a26001dc83c802ab474ceb
# EXP-Topic merge-newnode
mergeresult: introduce dedicated tuple for no-op actions

This will help us in adding more no-op actions in next patch while keeping the
code cleaner.

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -523,7 +523,6 @@ def _filternarrowactions(narrowmatch, br
 narrowed.
 """
 # TODO: handle with nonconflicttypes
-nooptypes = {mergestatemod.ACTION_KEEP}
 nonconflicttypes = {
 mergestatemod.ACTION_ADD,
 mergestatemod.ACTION_ADD_MODIFIED,
@@ -541,7 +540,7 @@ def _filternarrowactions(narrowmatch, br
 pass
 elif not branchmerge:
 mresult.removefile(f)  # just updating, ignore changes outside 
clone
-elif action[0] in nooptypes:
+elif action[0] in mergeresult.NO_OP_ACTIONS:
 mresult.removefile(f)  # merge does not affect file
 elif action[0] in nonconflicttypes:
 raise error.Abort(
@@ -564,6 +563,8 @@ class mergeresult(object):
 It has information about what actions need to be performed on dirstate
 mapping of divergent renames and other such cases. '''
 
+NO_OP_ACTIONS = (mergestatemod.ACTION_KEEP,)
+
 def __init__(self):
 """
 filemapping: dict of filename as keys and action related info as values
@@ -711,12 +712,12 @@ class mergeresult(object):
 a
 not in (
 mergestatemod.ACTION_GET,
-mergestatemod.ACTION_KEEP,
 mergestatemod.ACTION_EXEC,
 mergestatemod.ACTION_REMOVE,
 mergestatemod.ACTION_PATH_CONFLICT_RESOLVE,
 )
 and self._actionmapping[a]
+and a not in self.NO_OP_ACTIONS
 ):
 return True
 
@@ -1376,7 +1377,7 @@ def applyupdates(
 # mergestate so that it can be reused on commit
 ms.addcommitinfo(f, op)
 
-numupdates = mresult.len() - mresult.len((mergestatemod.ACTION_KEEP,))
+numupdates = mresult.len() - mresult.len(mergeresult.NO_OP_ACTIONS)
 progress = repo.ui.makeprogress(
 _(b'updating'), unit=_(b'files'), total=numupdates
 )
diff --git a/mercurial/sparse.py b/mercurial/sparse.py
--- a/mercurial/sparse.py
+++ b/mercurial/sparse.py
@@ -399,7 +399,7 @@ def filterupdatesactions(repo, wctx, mct
 temporaryfiles.append(file)
 prunedactions[file] = action
 elif branchmerge:
-if type != mergestatemod.ACTION_KEEP:
+if type not in mergemod.mergeresult.NO_OP_ACTIONS:
 temporaryfiles.append(file)
 prunedactions[file] = action
 elif type == mergestatemod.ACTION_FORGET:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 8] merge: add `ACTION_KEEP_ABSENT` to represent files we want to keep absent

2020-09-14 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1598960306 -19800
#  Tue Sep 01 17:08:26 2020 +0530
# Node ID 2c58747e0a1ebe17b6bf1f4f393da2be57bce63a
# Parent  cfabb1ccdf7a2cb67bb2819f798bad53c6aac977
# EXP-Topic merge-newnode
merge: add `ACTION_KEEP_ABSENT` to represent files we want to keep absent

There are files which were deleted/not present in working copy parent but were
present on other side of merge. On merge, we might decide to keep them deleted.
We want to track such cases more closely, rather all kind of cases which results
from some kind of merging logic.

We do have `ACTION_KEEP` but having a dedicated action for the absent case is
more cleaner.

Initially I named the action as `ACTION_KEEP_DELETED` but later realized that
file can be not-present because of other reasons than deletion like rename,
hence decided to use more generic name `ACTION_KEEP_ABSENT`.

Differential Revision: https://phab.mercurial-scm.org/D8974

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -563,7 +563,10 @@ class mergeresult(object):
 It has information about what actions need to be performed on dirstate
 mapping of divergent renames and other such cases. '''
 
-NO_OP_ACTIONS = (mergestatemod.ACTION_KEEP,)
+NO_OP_ACTIONS = (
+mergestatemod.ACTION_KEEP,
+mergestatemod.ACTION_KEEP_ABSENT,
+)
 
 def __init__(self):
 """
@@ -1175,6 +1178,11 @@ def calculateupdates(
 repo.ui.note(_(b" %s: picking 'keep' action\n") % f)
 mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP][0])
 continue
+# If keep absent is an option, just do that
+if mergestatemod.ACTION_KEEP_ABSENT in bids:
+repo.ui.note(_(b" %s: picking 'keep absent' action\n") % f)
+mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP_ABSENT][0])
+continue
 # If there are gets and they all agree [how could they not?], do 
it.
 if mergestatemod.ACTION_GET in bids:
 ga0 = bids[mergestatemod.ACTION_GET][0]
@@ -1486,6 +1494,11 @@ def applyupdates(
 ):
 repo.ui.debug(b" %s: %s -> k\n" % (f, msg))
 # no progress
+for f, args, msg in mresult.getactions(
+(mergestatemod.ACTION_KEEP_ABSENT,), sort=True
+):
+repo.ui.debug(b" %s: %s -> ka\n" % (f, msg))
+# no progress
 
 # directory rename, move local
 for f, args, msg in mresult.getactions(
diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py
--- a/mercurial/mergestate.py
+++ b/mercurial/mergestate.py
@@ -120,6 +120,10 @@ ACTION_MERGE = b'm'
 ACTION_LOCAL_DIR_RENAME_GET = b'dg'
 ACTION_DIR_RENAME_MOVE_LOCAL = b'dm'
 ACTION_KEEP = b'k'
+# the file was absent on local side before merge and we should
+# keep it absent (absent means file not present, it can be a result
+# of file deletion, rename etc.)
+ACTION_KEEP_ABSENT = b'ka'
 ACTION_EXEC = b'e'
 ACTION_CREATED_MERGE = b'cm'
 
@@ -837,6 +841,10 @@ def recordupdates(repo, actions, branchm
 for f, args, msg in actions.get(ACTION_KEEP, []):
 pass
 
+# keep deleted
+for f, args, msg in actions.get(ACTION_KEEP_ABSENT, []):
+pass
+
 # get
 for f, args, msg in actions.get(ACTION_GET, []):
 if branchmerge:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 8] merge: store ACTION_KEEP_ABSENT when we are keeping the file absent locally

2020-09-14 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1598262609 -19800
#  Mon Aug 24 15:20:09 2020 +0530
# Node ID 8c918c4872a151ba17e744c6a7a4610fef8f16b3
# Parent  2c58747e0a1ebe17b6bf1f4f393da2be57bce63a
# EXP-Topic merge-newnode
merge: store ACTION_KEEP_ABSENT when we are keeping the file absent locally

If a file is not present on the local side, and it's unchanged between other
merge parent and ancestor, we don't use any action, neither we had a if-else
branch for that condition. This leads to bid-merge missing that there is a
such action possible which can be performed.

As test changes demonstrate, we now choose the locally deleted side instead
of choosing the remote one consistently. This is also wrong behavior which is
resulted because of missing possible action. It will be fixed in next patch.

This whole logic is not acurrate as we should prompt user on what to do
when this kind of criss-cross merge is in play.

Differential Revision: https://phab.mercurial-scm.org/D8940

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -1023,6 +1023,13 @@ def manifestmerge(
 (None, f, f, False, pa.node()),
 b'prompt deleted/changed',
 )
+else:
+mresult.addfile(
+f,
+mergestatemod.ACTION_KEEP_ABSENT,
+None,
+b'local not present, remote unchanged',
+)
 
 if repo.ui.configbool(b'experimental', b'merge.checkpathconflicts'):
 # If we are merging, look for path conflicts.
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -572,28 +572,26 @@ BROKEN: this should result in conflict
   $ hg update --clean 'desc("merge-deleting-the-file-from-deleted")'
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge  'desc("merge-keeping-the-file-from-deleted")'
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ ls -1
   other-file
-  the-file
 
 (merging a deletion with keeping → conflict)
 BROKEN: this should result in conflict
 
   $ hg update --clean 'desc("merge-deleting-the-file-from-deleted")'
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge  'desc("merge-keeping-the-file-from-updated")'
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ ls -1
   other-file
-  the-file
 
 (merging two deletion together → no conflict)
 
   $ hg update --clean 'desc("merge-deleting-the-file-from-updated")'
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge  'desc("merge-deleting-the-file-from-deleted")'
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
@@ -606,23 +604,21 @@ BROKEN: this should result in conflict
   $ hg update --clean 'desc("merge-deleting-the-file-from-updated")'
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge  'desc("merge-keeping-the-file-from-deleted")'
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ ls -1
   other-file
-  the-file
 
 (merging a deletion with keeping → conflict)
 BROKEN: this should result in conflict
 
   $ hg update --clean 'desc("merge-deleting-the-file-from-updated")'
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge  'desc("merge-keeping-the-file-from-updated")'
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ ls -1
   other-file
-  the-file
 
 (merging two "keeping" together → no conflict)
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 8] merge: add missing ACTION_KEEP when both remote and ancestor are not present

2020-09-14 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1598269948 -19800
#  Mon Aug 24 17:22:28 2020 +0530
# Node ID 9be2d61f80be6059bcdc890bfb889d0a9670dbda
# Parent  8c918c4872a151ba17e744c6a7a4610fef8f16b3
# EXP-Topic merge-newnode
merge: add missing ACTION_KEEP when both remote and ancestor are not present

Previous patch may lead to confusion that the related criss-cross merge is
consistent when done from any of the parents. However this is not true and we
were missing setting an ACTION_KEEP.

This patch now exposes that bid-merge favors ACTION_KEEP always and the result
of merge is different when started from different parents.

This change also effects a test case above where bid merge was wrongly picking
`r` because it was missing keep related information from one of the ancestor.

After this test, we are back in a state in the criss-cross merge tests where the
result depends on which parent we are merging from.

Differential Revision: https://phab.mercurial-scm.org/D8941

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -932,6 +932,14 @@ def manifestmerge(
 mresult.addfile(
 f, mergestatemod.ACTION_REMOVE, None, b'other deleted',
 )
+else:  # file not in ancestor, not in remote
+mresult.addfile(
+f,
+mergestatemod.ACTION_KEEP,
+None,
+b'ancestor missing, remote missing',
+)
+
 elif n2:  # file exists only on remote side
 if f in copied1:
 pass  # we'll deal with it on m1 side
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -431,6 +431,8 @@ Verify that the old context ancestor wor
   resolving manifests
branchmerge: True, force: False, partial: False
ancestor: 11b5b303e36c, local: c0ef19750a22+, remote: 6ca01f7342b9
+   d1/a: ancestor missing, remote missing -> k
+   d1/b: ancestor missing, remote missing -> k
d2/b: remote created -> g
   
   calculating bids for ancestor 154e6000f54e
@@ -450,24 +452,24 @@ Verify that the old context ancestor wor
   
   auction for merging merge bids (2 ancestors)
list of bids for d1/a:
+ ancestor missing, remote missing -> k
  other deleted -> r
-   d1/a: consensus for r
+   d1/a: picking 'keep' action
list of bids for d1/b:
+ ancestor missing, remote missing -> k
  other deleted -> r
-   d1/b: consensus for r
+   d1/b: picking 'keep' action
list of bids for d2/b:
  remote created -> g
  remote created -> g
d2/b: consensus for g
   end of auction
   
-   d1/a: other deleted -> r
-  removing d1/a
-   d1/b: other deleted -> r
-  removing d1/b
d2/b: remote created -> g
   getting d2/b
-  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
+   d1/a: ancestor missing, remote missing -> k
+   d1/b: ancestor missing, remote missing -> k
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
 
 
@@ -649,15 +651,16 @@ BROKEN: this should result in conflict
   $ hg update --clean 'desc("merge-keeping-the-file-from-updated")'
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge  'desc("merge-deleting-the-file-from-updated")'
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ ls -1
   other-file
+  the-file
 
 (merging two "keeping" together → no conflict)
 
   $ hg update --clean 'desc("merge-keeping-the-file-from-deleted")'
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge  'desc("merge-keeping-the-file-from-updated")'
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
@@ -683,7 +686,8 @@ BROKEN: this should result in conflict
   $ hg update --clean 'desc("merge-keeping-the-file-from-deleted")'
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge  'desc("merge-deleting-the-file-from-updated")'
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ ls -1
   other-file
+  the-file
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 8] merge: update commitinfo from all mergeresults during bid merge

2020-09-14 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1598440043 -19800
#  Wed Aug 26 16:37:23 2020 +0530
# Node ID 21f520670eb08917eeb5fcf11c75cc1dfb242530
# Parent  9be2d61f80be6059bcdc890bfb889d0a9670dbda
# EXP-Topic merge-newnode
merge: update commitinfo from all mergeresults during bid merge

During bid merge, it's not clear which commitinfo should be stored and which one
should not. This depends on which side the bid merge chooses for a file. For
this we will need to refactor bid merge code and commitinfo handling.

For now, we just blindly updates info since we hardly have any users of
commitinfo and this will help us in testing and clearing out further path.

Differential Revision: https://phab.mercurial-scm.org/D8965

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -1130,6 +1130,7 @@ def calculateupdates(
 # mapping of following form:
 # {ACTION_X : [info, ..], ACTION_Y : [info, ..]}
 fbids = {}
+mresult = mergeresult()
 diverge, renamedelete = None, None
 for ancestor in ancestors:
 repo.ui.note(_(b'\ncalculating bids for ancestor %s\n') % ancestor)
@@ -1156,6 +1157,12 @@ def calculateupdates(
 ):
 renamedelete = mresult1.renamedelete
 
+# blindly update final mergeresult commitinfo with what we get
+# from mergeresult object for each ancestor
+# TODO: some commitinfo depends on what bid merge choose and hence
+# we will need to make commitinfo also depend on bid merge logic
+mresult._commitinfo.update(mresult1._commitinfo)
+
 for f, a in mresult1.filemap(sort=True):
 m, args, msg = a
 repo.ui.debug(b' %s: %s -> %s\n' % (f, msg, m))
@@ -1174,7 +1181,6 @@ def calculateupdates(
 _(b'\nauction for merging merge bids (%d ancestors)\n')
 % len(ancestors)
 )
-mresult = mergeresult()
 for f, bids in sorted(fbids.items()):
 repo.ui.debug(_(b" list of bids for %s:\n") % f)
 for m, l in sorted(bids.items()):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 8] merge: check for dir rename dest before adding ACTION_KEEP

2020-09-14 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1599034669 -19800
#  Wed Sep 02 13:47:49 2020 +0530
# Node ID a6378fd3a90effdd150f94f4da8266687276e0e4
# Parent  21f520670eb08917eeb5fcf11c75cc1dfb242530
# EXP-Topic merge-newnode
merge: check for dir rename dest before adding ACTION_KEEP

A previous patch in the series blindly uses `ACTION_KEEP` if the file is not
present on both remote and ancestor. This was wrong.

We tries to detect directory renames and in some graft cases, it can be possible
that file is not present on both sides but is created in rename destination of
other directory which exists on remote. In such cases, we need to merge the
rename source from remote with rename dest from local.

This patch makes sure we checks for such rename cases before falling back to
`ACTION_KEEP`.

Also, we moved the adding of action for the destination file while processing
the destination file which makes things much simpler as an action for file will
only be added while processing it. And we added a `ACTION_KEEP_ABSENT` for the
rename source because otherwise an action for that was missing.

Differential Revision: https://phab.mercurial-scm.org/D8977

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -933,12 +933,41 @@ def manifestmerge(
 f, mergestatemod.ACTION_REMOVE, None, b'other deleted',
 )
 else:  # file not in ancestor, not in remote
-mresult.addfile(
-f,
-mergestatemod.ACTION_KEEP,
-None,
-b'ancestor missing, remote missing',
-)
+rename_found = False
+for source, dest in branch_copies1.dirmove.items():
+if f.startswith(dest):
+# this directory in which this file is created
+# is moved from somewhere else
+# we should check if the source file exists on
+# remote side
+sf = source + f[len(dest) :]
+if sf in m2:
+rename_found = True
+if m2[sf] == ma[sf]:
+mresult.addfile(
+f,
+mergestatemod.ACTION_KEEP,
+None,
+b'file is rename dest and rename source'
+b' did not change',
+)
+else:
+mresult.addfile(
+f,
+mergestatemod.ACTION_MERGE,
+(f, sf, sf, False, pa.node()),
+b'local directory rename - respect move '
+b'from %s' % sf,
+)
+break
+
+if not rename_found:
+mresult.addfile(
+f,
+mergestatemod.ACTION_KEEP,
+None,
+b'ancestor missing, remote missing',
+)
 
 elif n2:  # file exists only on remote side
 if f in copied1:
@@ -1010,12 +1039,16 @@ def manifestmerge(
 df = branch_copies1.dirmove[d] + f[len(d) :]
 break
 if df is not None and df in m1:
+# this file is not present in local however its a source
+# of rename for another file. keep this file not
+# present in local. Action for rename dest is written
+# while processing it
 mresult.addfile(
-df,
-mergestatemod.ACTION_MERGE,
-(df, f, f, False, pa.node()),
-b'local directory rename - respect move '
-b'from %s' % f,
+f,
+mergestatemod.ACTION_KEEP_ABSENT,
+None,
+b'remote directory is rename source - respect move '
+b'to %s' % df,
 )
 elif acceptremote:
 mresult.addfile(
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 8] mergestate: introduce a new ACTION_KEEP_NEW

2020-09-14 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1599650359 -19800
#  Wed Sep 09 16:49:19 2020 +0530
# Node ID d5e63af55451c06b706484f1ba5ee589bfc8f26c
# Parent  a6378fd3a90effdd150f94f4da8266687276e0e4
# EXP-Topic merge-newnode
mergestate: introduce a new ACTION_KEEP_NEW

`ACTION_KEEP` is overloaded and it's hard to figure out how we end up with this
KEEP, what was the state of things.

In a previous patch, we introduced `ACTION_KEEP_ABSENT` which represents files
which are kept absent in the working directory.

There is another special case where we keep the file when it's not present on
both ancestor and remote side. We introduce a dedicated action for that.

The goal is to use these information to make bid merge smarter.

Differential Revision: https://phab.mercurial-scm.org/D9002

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -566,6 +566,7 @@ class mergeresult(object):
 NO_OP_ACTIONS = (
 mergestatemod.ACTION_KEEP,
 mergestatemod.ACTION_KEEP_ABSENT,
+mergestatemod.ACTION_KEEP_NEW,
 )
 
 def __init__(self):
@@ -964,7 +965,7 @@ def manifestmerge(
 if not rename_found:
 mresult.addfile(
 f,
-mergestatemod.ACTION_KEEP,
+mergestatemod.ACTION_KEEP_NEW,
 None,
 b'ancestor missing, remote missing',
 )
@@ -1237,6 +1238,11 @@ def calculateupdates(
 repo.ui.note(_(b" %s: picking 'keep absent' action\n") % f)
 mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP_ABSENT][0])
 continue
+# If keep new is an option, let's just do that
+if mergestatemod.ACTION_KEEP_NEW in bids:
+repo.ui.note(_(b" %s: picking 'keep new' action\n") % f)
+mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP_NEW][0])
+continue
 # If there are gets and they all agree [how could they not?], do 
it.
 if mergestatemod.ACTION_GET in bids:
 ga0 = bids[mergestatemod.ACTION_GET][0]
@@ -1543,15 +1549,9 @@ def applyupdates(
 progress.increment(item=f)
 
 # keep (noop, just log it)
-for f, args, msg in mresult.getactions(
-(mergestatemod.ACTION_KEEP,), sort=True
-):
-repo.ui.debug(b" %s: %s -> k\n" % (f, msg))
-# no progress
-for f, args, msg in mresult.getactions(
-(mergestatemod.ACTION_KEEP_ABSENT,), sort=True
-):
-repo.ui.debug(b" %s: %s -> ka\n" % (f, msg))
+for a in mergeresult.NO_OP_ACTIONS:
+for f, args, msg in mresult.getactions((a,), sort=True):
+repo.ui.debug(b" %s: %s -> %s\n" % (f, msg, a))
 # no progress
 
 # directory rename, move local
diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py
--- a/mercurial/mergestate.py
+++ b/mercurial/mergestate.py
@@ -124,6 +124,9 @@ ACTION_KEEP = b'k'
 # keep it absent (absent means file not present, it can be a result
 # of file deletion, rename etc.)
 ACTION_KEEP_ABSENT = b'ka'
+# the file is absent on the ancestor and remote side of the merge
+# hence this file is new and we should keep it
+ACTION_KEEP_NEW = b'kn'
 ACTION_EXEC = b'e'
 ACTION_CREATED_MERGE = b'cm'
 
@@ -845,6 +848,10 @@ def recordupdates(repo, actions, branchm
 for f, args, msg in actions.get(ACTION_KEEP_ABSENT, []):
 pass
 
+# keep new
+for f, args, msg in actions.get(ACTION_KEEP_NEW, []):
+pass
+
 # get
 for f, args, msg in actions.get(ACTION_GET, []):
 if branchmerge:
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -431,8 +431,8 @@ Verify that the old context ancestor wor
   resolving manifests
branchmerge: True, force: False, partial: False
ancestor: 11b5b303e36c, local: c0ef19750a22+, remote: 6ca01f7342b9
-   d1/a: ancestor missing, remote missing -> k
-   d1/b: ancestor missing, remote missing -> k
+   d1/a: ancestor missing, remote missing -> kn
+   d1/b: ancestor missing, remote missing -> kn
d2/b: remote created -> g
   
   calculating bids for ancestor 154e6000f54e
@@ -452,13 +452,13 @@ Verify that the old context ancestor wor
   
   auction for merging merge bids (2 ancestors)
list of bids for d1/a:
- ancestor missing, remote missing -> k
+ ancestor missing, remote missing -> kn
  other deleted -> r
-   d1/a: picking 'keep' action
+   d1/a: picking 'keep new' action
list of bids for d1/b:
- ancestor missing, remote missing -> k
+ ancestor missing, remote missing -> kn
  other deleted -> r
-   d1/b: picking 'keep' action
+   d1/b: picking 'keep new' action
list of bids for d2/b:
  remote created -> g
  remote created -> g
@@ -467,8 +467,8 @@ Verify that the old co

Re: [PATCH V2] merge: show list of bids for each file in bid-merge in ui.debug()

2020-09-14 Thread Yuya Nishihara
On Mon, 14 Sep 2020 16:42:06 +0530, Pulkit Goyal wrote:
> # HG changeset patch
> # User Pulkit Goyal <7895pul...@gmail.com>
> # Date 1598442653 -19800
> #  Wed Aug 26 17:20:53 2020 +0530
> # Node ID 7f605a79653a170cbf028192e1b2b5deb2f0d9b7
> # Parent  d2b5a7659fff465286c7a1a451f0ebfe7118f251
> # EXP-Topic merge-newnode
> merge: show list of bids for each file in bid-merge in ui.debug()

> diff --git a/mercurial/merge.py b/mercurial/merge.py
> --- a/mercurial/merge.py
> +++ b/mercurial/merge.py
> @@ -1157,6 +1157,10 @@ def calculateupdates(
>  )
>  mresult = mergeresult()
>  for f, bids in sorted(fbids.items()):
> +repo.ui.debug(_(b" list of bids for %s:\n") % f)

no _() for debug prints.

> +for m, l in sorted(bids.items()):
> +for _f, args, msg in l:
> +repo.ui.debug(b'   %s -> %s\n' % (msg, m))

Nit: this loop can be gated by ui.debugflag.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH V3] merge: show list of bids for each file in bid-merge in ui.debug()

2020-09-14 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1598442653 -19800
#  Wed Aug 26 17:20:53 2020 +0530
# Node ID be084d2cbcd0681bf9654a39331502a3b1689142
# Parent  d2b5a7659fff465286c7a1a451f0ebfe7118f251
# EXP-Topic merge-newnode
merge: show list of bids for each file in bid-merge in ui.debug()

Earlier, we were showing the list of bids only when we were ambiguously picking.
However, the cases where we unambiguously picked a side may not always be
correct and need to be fixed.

Having list of bids for all files will be helpful in debugging.

Differential Revision: https://phab.mercurial-scm.org/D8966

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -1157,6 +1157,11 @@ def calculateupdates(
 )
 mresult = mergeresult()
 for f, bids in sorted(fbids.items()):
+if repo.ui.debugflag:
+repo.ui.debug(b" list of bids for %s:\n" % f)
+for m, l in sorted(bids.items()):
+for _f, args, msg in l:
+repo.ui.debug(b'   %s -> %s\n' % (msg, m))
 # bids is a mapping from action method to list af actions
 # Consensus?
 if len(bids) == 1:  # all bids are the same kind of method
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -150,7 +150,13 @@ Redo merge with merge.preferancestor="*"
f2: remote unchanged -> k
   
   auction for merging merge bids (2 ancestors)
+   list of bids for f1:
+ remote is newer -> g
+ versions differ -> m
f1: picking 'get' action
+   list of bids for f2:
+ remote unchanged -> k
+ versions differ -> m
f2: picking 'keep' action
   end of auction
   
@@ -193,7 +199,13 @@ The other way around:
f2: remote is newer -> g
   
   auction for merging merge bids (2 ancestors)
+   list of bids for f1:
+ remote unchanged -> k
+ versions differ -> m
f1: picking 'keep' action
+   list of bids for f2:
+ remote is newer -> g
+ versions differ -> m
f2: picking 'get' action
   end of auction
   
@@ -258,7 +270,13 @@ Verify how the output looks and and how 
f2: remote unchanged -> k
   
   auction for merging merge bids (2 ancestors)
+   list of bids for f1:
+ remote is newer -> g
+ versions differ -> m
f1: picking 'get' action
+   list of bids for f2:
+ remote unchanged -> k
+ versions differ -> m
f2: picking 'keep' action
   end of auction
   
@@ -431,8 +449,15 @@ Verify that the old context ancestor wor
d2/b: remote created -> g
   
   auction for merging merge bids (2 ancestors)
+   list of bids for d1/a:
+ other deleted -> r
d1/a: consensus for r
+   list of bids for d1/b:
+ other deleted -> r
d1/b: consensus for r
+   list of bids for d2/b:
+ remote created -> g
+ remote created -> g
d2/b: consensus for g
   end of auction
   
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 3] log: reorganize if-else and for loop in logcmdutil._makematcher()

2020-09-14 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1599804538 -32400
#  Fri Sep 11 15:08:58 2020 +0900
# Node ID 306c09f80dd9659aa9f0eebe1baa328afa3b7977
# Parent  4532e7ebde4d9eb5011b78fb537879bcc67b30c4
log: reorganize if-else and for loop in logcmdutil._makematcher()

The test conditions are branchy depending on --follow and --rev options,
so it should be better to switch first by --follow --rev.

Note that revs is not empty so "if follow and startctxs" can be replaced
with "if follow and opts.get(b'rev')".

diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -691,39 +691,47 @@ def _makematcher(repo, revs, pats, opts)
 slowpath = match.anypats() or (not match.always() and opts.get(b'removed'))
 if not slowpath:
 follow = opts.get(b'follow') or opts.get(b'follow_first')
-startctxs = []
 if follow and opts.get(b'rev'):
 startctxs = [repo[r] for r in revs]
-for f in match.files():
-if follow and startctxs:
+for f in match.files():
 # No idea if the path was a directory at that revision, so
 # take the slow path.
 if any(f not in c for c in startctxs):
 slowpath = True
 continue
-elif follow and f not in wctx:
-# If the file exists, it may be a directory, so let it
-# take the slow path.
-if os.path.exists(repo.wjoin(f)):
-slowpath = True
-continue
-else:
-raise error.Abort(
-_(
-b'cannot follow file not in parent '
-b'revision: "%s"'
-)
-% f
-)
-filelog = repo.file(f)
-if not filelog:
-# A zero count may be a directory or deleted file, so
-# try to find matching entries on the slow path.
-if follow:
+filelog = repo.file(f)
+if not filelog:
 raise error.Abort(
 _(b'cannot follow nonexistent file: "%s"') % f
 )
-slowpath = True
+elif follow:
+for f in match.files():
+if f not in wctx:
+# If the file exists, it may be a directory, so let it
+# take the slow path.
+if os.path.exists(repo.wjoin(f)):
+slowpath = True
+continue
+else:
+raise error.Abort(
+_(
+b'cannot follow file not in parent '
+b'revision: "%s"'
+)
+% f
+)
+filelog = repo.file(f)
+if not filelog:
+raise error.Abort(
+_(b'cannot follow nonexistent file: "%s"') % f
+)
+else:
+for f in match.files():
+filelog = repo.file(f)
+if not filelog:
+# A zero count may be a directory or deleted file, so
+# try to find matching entries on the slow path.
+slowpath = True
 
 # We decided to fall back to the slowpath because at least one
 # of the paths was not a file. Check to see if at least one of them
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -2308,6 +2308,20 @@ follow files from wdir
   $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat notfound
   notfound: $ENOENT$
 
+follow added/removed files from wdir parent
+
+  $ hg log -T '{rev}\n' -f d1/f2
+  abort: cannot follow nonexistent file: "d1/f2"
+  [255]
+
+  $ hg log -T '{rev}\n' -f f1-copy
+  abort: cannot follow nonexistent file: "f1-copy"
+  [255]
+
+  $ hg log -T '{rev}\n' -f .d6/f1
+  abort: cannot follow file not in parent revision: ".d6/f1"
+  [255]
+
   $ hg revert -aqC
 
 Check that adding an arbitrary name shows up in log automatically
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 3] log: fix -fr'wdir()' PATH to follow newly added file

2020-09-14 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1599804815 -32400
#  Fri Sep 11 15:13:35 2020 +0900
# Node ID 21487b54666e457374fa669ffe3005f3840353c6
# Parent  306c09f80dd9659aa9f0eebe1baa328afa3b7977
log: fix -fr'wdir()' PATH to follow newly added file

Testing filelog doesn't make sense in this case because the file existence
is tested against the specified changectxs. If the filelog is empty and
if startctxs != [wctx], 'f not in c' should be triggered.

diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -698,12 +698,7 @@ def _makematcher(repo, revs, pats, opts)
 # take the slow path.
 if any(f not in c for c in startctxs):
 slowpath = True
-continue
-filelog = repo.file(f)
-if not filelog:
-raise error.Abort(
-_(b'cannot follow nonexistent file: "%s"') % f
-)
+break
 elif follow:
 for f in match.files():
 if f not in wctx:
@@ -722,6 +717,8 @@ def _makematcher(repo, revs, pats, opts)
 )
 filelog = repo.file(f)
 if not filelog:
+# A file exists in wdir but not in history, which means
+# the file isn't committed yet.
 raise error.Abort(
 _(b'cannot follow nonexistent file: "%s"') % f
 )
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -2295,15 +2295,21 @@ follow files from wdir
1 files changed, 1 insertions(+), 0 deletions(-)
   
 
- BROKEN: added file should exist in wdir
   $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat d1/f2
-  abort: cannot follow nonexistent file: "d1/f2"
-  [255]
+  == 2147483647 ==
+   d1/f2 |  1 +
+   1 files changed, 1 insertions(+), 0 deletions(-)
+  
 
- BROKEN: copied file should exist in wdir
   $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat f1-copy
-  abort: cannot follow nonexistent file: "f1-copy"
-  [255]
+  == 2147483647 ==
+   f1-copy |  1 +
+   1 files changed, 1 insertions(+), 0 deletions(-)
+  
+  == 0 ==
+   d1/f1 |  1 +
+   1 files changed, 1 insertions(+), 0 deletions(-)
+  
 
   $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat notfound
   notfound: $ENOENT$
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 3] log: make -frREV PATH detect missing files before falling back to slow path

2020-09-14 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1599863027 -32400
#  Sat Sep 12 07:23:47 2020 +0900
# Node ID 78f4530ec2ed09dce0146ab2dfb6f42b323abe76
# Parent  21487b54666e457374fa669ffe3005f3840353c6
log: make -frREV PATH detect missing files before falling back to slow path

If -rREV isn't specified, "log --follow" would abort on nonexistent paths.
Let's implement this behavior for "-frREV" case as we have ctx.hasdir() now.
Otherwise "log -frREV PATH" would silently fall back to slow path and files
wouldn't be followed across renames.

The loop is quadratic (as before), but the size of the startctxs and
match.files() should be small in general.

Some tests are marked as BROKEN since file renames aren't tracked in the
slow path. This is a known limitation of the current history traversal
function.

diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -692,13 +692,27 @@ def _makematcher(repo, revs, pats, opts)
 if not slowpath:
 follow = opts.get(b'follow') or opts.get(b'follow_first')
 if follow and opts.get(b'rev'):
+# There may be the case that a path doesn't exist in some (but
+# not all) of the specified start revisions, but let's consider
+# the path is valid. Missing files will be warned by the matcher.
 startctxs = [repo[r] for r in revs]
 for f in match.files():
-# No idea if the path was a directory at that revision, so
-# take the slow path.
-if any(f not in c for c in startctxs):
-slowpath = True
-break
+found = False
+for c in startctxs:
+if f in c:
+found = True
+elif c.hasdir(f):
+# If a directory exists in any of the start revisions,
+# take the slow path.
+found = slowpath = True
+if not found:
+raise error.Abort(
+_(
+b'cannot follow file not in any of the specified '
+b'revisions: "%s"'
+)
+% f
+)
 elif follow:
 for f in match.files():
 if f not in wctx:
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -504,14 +504,50 @@ follow files from the specified revision
   0 (false !)
 
 follow files from the specified revisions with missing patterns
-(BROKEN: should follow copies from e@4)
 
   $ hg log -T '{rev}\n' -fr4 e x
-  4
-  2 (false !)
+  abort: cannot follow file not in any of the specified revisions: "x"
+  [255]
+
+follow files from the specified revisions with directory patterns
+(BROKEN: should follow copies from dir/b@2)
+
+  $ hg log -T '{rev}\n' -fr2 dir/b dir
+  2
   1 (false !)
   0 (false !)
 
+follow files from multiple revisions, but the pattern is missing in
+one of the specified revisions
+
+  $ hg log -T '{rev}\n' -fr'2+4' dir/b e
+  e: no such file in rev f8954cd4dc1f
+  dir/b: no such file in rev 7e4639b4691b
+  4
+  2
+  1
+  0
+
+follow files from multiple revisions, and the pattern matches a file in
+one revision but matches a directory in another:
+(BROKEN: should follow copies from dir/b@2 and dir/b/g@5)
+(BROKEN: the revision 4 should not be included since dir/b/g@5 is unchanged)
+
+  $ mkdir -p dir/b
+  $ hg mv g dir/b
+  $ hg ci -m 'make dir/b a directory'
+
+  $ hg log -T '{rev}\n' -fr'2+5' dir/b
+  5
+  4
+  3 (false !)
+  2
+  1 (false !)
+  0 (false !)
+
+  $ hg --config extensions.strip= strip -r. --no-backup
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
 follow files from the specified revisions across copies with -p/--patch
 
   $ hg log -T '== rev: {rev},{file_copies % " {source}->{name}"} ==\n' -fpr 4 
e g
@@ -2312,7 +2348,15 @@ follow files from wdir
   
 
   $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat notfound
-  notfound: $ENOENT$
+  abort: cannot follow file not in any of the specified revisions: "notfound"
+  [255]
+
+follow files from wdir and non-wdir revision:
+
+  $ hg log -T '{rev}\n' -fr'wdir()+.' f1-copy
+  f1-copy: no such file in rev 65624cd9070a
+  2147483647
+  0
 
 follow added/removed files from wdir parent
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D9019: procutil: avoid using os.fork() to implement runbgcommand

2020-09-14 Thread valentin.gatienbaron (Valentin Gatien-Baron)
valentin.gatienbaron created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  NB: this only works with py3. I'm hoping that maybe it won't be
  necessary to support py2 in a couple of months?
  
  We ran into the following deadlock:
  
  - some command creates an ssh peer, then raises without explicitly closing 
the peer (hg id + extension in our case)
  
  - dispatch catches the exception, calls ui.log('commandfinish', ..) (the 
sshpeer is still not closed), which calls logtoprocess, which calls 
procutil.runbgcommand.
  
  - in the child of runbgcommand's fork(), between the fork and the exec, the 
opening of file descriptors triggers a gc which runs the destructor for 
sshpeer, which waits on ssh's stderr being closed, which never happens since 
ssh's stderr is held open by the parent of the fork where said destructor 
hasn't run
  
  I don't know if there's more subtlety to it, because even though the
  problem is determistic, it is very fragile, so I didn't manage to
  reduce it.
  
  I can imagine three ways of tackling this problem:
  
  1. don't run any python between fork and exec in runbgcommand
  2. make the finalizer harmless after the fork
  3. close the peer without relying on gc behavior
  
  3 wouldn't help with calls to logtoprocess in the middle of commands.
  So this commit implements 1, and the next commit will do 2 for
  robustness (it might help with the forks from worker.py in hg pull
  -u).
  
  Performance wise: at low memory usage, it's an improvement. At higher
  memory usage, it's about 2x faster than before when ensurestart=True,
  but 2x slower when ensurestart=False. Not sure if that matters. The
  reason for that last bit is that the subprocess.Popen always waits for
  the execve to finish, and at high memory usage, execve is slow because
  it deallocates the large page table. Numbers and script:
  
 before after
mem=1.0GB, ensurestart=True  52.1ms 26.0ms
mem=1.0GB, ensurestart=False 14.7ms 26.0ms
mem=0.5GB, ensurestart=True  23.2ms 11.2ms
mem=0.5GB, ensurestart=False  6.2ms 11.3ms
mem=0.2GB, ensurestart=True  15.7ms 7.4ms
mem=0.2GB, ensurestart=False  4.3ms 8.1ms
mem=0.0GB, ensurestart=True   2.3ms 0.7ms
mem=0.0GB, ensurestart=False  0.8ms 0.8ms

import time
for memsize in [1_000_000_000, 500_000_000, 250_000_000, 0]:
mem = 'a' * memsize
for ensurestart in [True, False]:
now = time.time()
n = 100
for i in range(n):
procutil.runbgcommand([b'true'], {}, 
ensurestart=ensurestart)
after = time.time()
ms = (after - now) / float(n) * 1000
print(f'mem={memsize / 1e9:.1f}GB, ensurestart={ensurestart} -> 
{ms:.1f}ms')

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  mercurial/utils/procutil.py

CHANGE DETAILS

diff --git a/mercurial/utils/procutil.py b/mercurial/utils/procutil.py
--- a/mercurial/utils/procutil.py
+++ b/mercurial/utils/procutil.py
@@ -676,83 +676,53 @@
 # calls gui() while we're calling fork().
 gui()
 
-# double-fork to completely detach from the parent process
-# based on http://code.activestate.com/recipes/278731
+if shell:
+script = cmd
+else:
+if isinstance(cmd, bytes):
+cmd = [cmd]
+script = b' '.join(shellquote(x) for x in cmd)
 if record_wait is None:
-pid = os.fork()
-if pid:
-if not ensurestart:
-# Even though we're not waiting on the child process,
-# we still must call waitpid() on it at some point so
-# it's not a zombie/defunct. This is especially relevant 
for
-# chg since the parent process won't die anytime soon.
-# We use a thread to make the overhead tiny.
-def _do_wait():
-os.waitpid(pid, 0)
+# double-fork to completely detach from the parent process
+script = b'( %s ) &' % script
+start_new_session = True
+else:
+start_new_session = False
+ensurestart = True
 
-t = threading.Thread(target=_do_wait)
-t.daemon = True
-t.start()
-return
-# Parent process
-(_pid, status) = os.waitpid(pid, 0)
-if os.WIFEXITED(status):
-returncode = os.WEXITSTATUS(status)
-else:
-returncode = -(os.WTERMSIG(status))
-if returncode != 0:
-# The child process's return code is 0 on success, an errno
- 

D9020: sshpeer: avoid having a destructor that can block forks forever

2020-09-14 Thread valentin.gatienbaron (Valentin Gatien-Baron)
valentin.gatienbaron created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This is solution 2. that was described in the previous commit.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  mercurial/sshpeer.py

CHANGE DETAILS

diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py
--- a/mercurial/sshpeer.py
+++ b/mercurial/sshpeer.py
@@ -7,6 +7,7 @@
 
 from __future__ import absolute_import
 
+import os
 import re
 import uuid
 
@@ -145,7 +146,7 @@
 return self._main.flush()
 
 
-def _cleanuppipes(ui, pipei, pipeo, pipee):
+def _cleanuppipes(ui, pipei, pipeo, pipee, origpid):
 """Clean up pipes used by an SSH connection."""
 if pipeo:
 pipeo.close()
@@ -153,12 +154,15 @@
 pipei.close()
 
 if pipee:
-# Try to read from the err descriptor until EOF.
-try:
-for l in pipee:
-ui.status(_(b'remote: '), l)
-except (IOError, ValueError):
-pass
+if origpid == os.getpid():
+# Try to read from the err descriptor until EOF. But if we
+# "leak" an ssh peer in a fork, just close without
+# reading.
+try:
+for l in pipee:
+ui.status(_(b'remote: '), l)
+except (IOError, ValueError):
+pass
 
 pipee.close()
 
@@ -411,6 +415,7 @@
 self._pipeo = stdin
 self._pipei = stdout
 self._pipee = stderr
+self._origpid = os.getpid() # recorded to detect calls to fork()
 self._caps = caps
 self._autoreadstderr = autoreadstderr
 
@@ -454,7 +459,8 @@
 raise exception
 
 def _cleanup(self):
-_cleanuppipes(self.ui, self._pipei, self._pipeo, self._pipee)
+_cleanuppipes(self.ui, self._pipei, self._pipeo, self._pipee,
+  self._origpid)
 
 __del__ = _cleanup
 
@@ -605,10 +611,11 @@
 servers and clients via non-standard means, which can be useful for
 testing.
 """
+origgpid = os.getpid()
 try:
 protoname, caps = _performhandshake(ui, stdin, stdout, stderr)
 except Exception:
-_cleanuppipes(ui, stdout, stdin, stderr)
+_cleanuppipes(ui, stdout, stdin, stderr, origgpid)
 raise
 
 if protoname == wireprototypes.SSHV1:
@@ -634,7 +641,7 @@
 autoreadstderr=autoreadstderr,
 )
 else:
-_cleanuppipes(ui, stdout, stdin, stderr)
+_cleanuppipes(ui, stdout, stdin, stderr, origgpid)
 raise error.RepoError(
 _(b'unknown version of SSH protocol: %s') % protoname
 )



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


D9021: fsmonitor: increase the threshold before we recommend it, when using rust

2020-09-14 Thread valentin.gatienbaron (Valentin Gatien-Baron)
valentin.gatienbaron created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  50k files works just fine with the rust status, and it's annoying to
  get told "consider using fsmonitor" when we have another solution to
  the status speed.
  
  400k files was not chosen in any rigorous way. I know 200k files is
  fine. Twice as many files should still be fine.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  hgext/fsmonitor/__init__.py
  mercurial/configitems.py
  mercurial/merge.py
  tests/test-clone.t

CHANGE DETAILS

diff --git a/tests/test-clone.t b/tests/test-clone.t
--- a/tests/test-clone.t
+++ b/tests/test-clone.t
@@ -1241,6 +1241,7 @@
   $ cat >> $HGRCPATH << EOF
   > [fsmonitor]
   > warn_update_file_count = 2
+  > warn_update_file_count_rust = 2
   > EOF
 
 We should see a warning about no fsmonitor on supported platforms
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -1693,6 +1693,15 @@
 fsmonitorthreshold = repo.ui.configint(
 b'fsmonitor', b'warn_update_file_count'
 )
+# avoid cycle dirstate -> sparse -> merge -> dirstate
+from . import dirstate
+
+if dirstate.rustmod is not None:
+# When using rust status, fsmonitor becomes necessary at higher sizes
+fsmonitorthreshold = repo.ui.configint(
+b'fsmonitor', b'warn_update_file_count_rust',
+)
+
 try:
 # avoid cycle: extensions -> cmdutil -> merge
 from . import extensions
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -793,6 +793,9 @@
 b'fsmonitor', b'warn_update_file_count', default=5,
 )
 coreconfigitem(
+b'fsmonitor', b'warn_update_file_count_rust', default=40,
+)
+coreconfigitem(
 b'help', br'hidden-command\..*', default=False, generic=True,
 )
 coreconfigitem(
diff --git a/hgext/fsmonitor/__init__.py b/hgext/fsmonitor/__init__.py
--- a/hgext/fsmonitor/__init__.py
+++ b/hgext/fsmonitor/__init__.py
@@ -73,6 +73,8 @@
 
 [fsmonitor]
 warn_update_file_count = (integer)
+# or when mercurial is built with rust support
+warn_update_file_count_rust = (integer)
 
 If ``warn_when_unused`` is set and fsmonitor isn't enabled, a warning will
 be printed during working directory updates if this many files will be



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


mercurial@45416: 2 new changesets (2 on stable)

2020-09-14 Thread Mercurial Commits
2 new changesets (2 on stable) in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/81b4e7c866ec
changeset:   45415:81b4e7c866ec
branch:  stable
parent:  45412:aaeccdb6e654
user:Augie Fackler 
date:Wed Sep 09 14:48:55 2020 -0400
summary: hgdemandimport: bypass demandimport for _ast module (issue6407)

https://www.mercurial-scm.org/repo/hg/rev/4ebc5f325bed
changeset:   45416:4ebc5f325bed
branch:  stable
tag: tip
user:Yuya Nishihara 
date:Fri Sep 11 14:41:05 2020 +0900
summary: log: fix crash and bad filematcher lookup by -fr'wdir()' PATH

-- 
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


mercurial@45430: 14 new changesets

2020-09-14 Thread Mercurial Commits
14 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/c8695439d7e3
changeset:   45417:c8695439d7e3
parent:  45414:66a10bd1b8db
user:Augie Fackler 
date:Mon Sep 07 16:13:10 2020 -0400
summary: git: actually copy treemanifest instances in .copy() (issue6398)

https://www.mercurial-scm.org/repo/hg/rev/4111954cf86d
changeset:   45418:4111954cf86d
user:Augie Fackler 
date:Mon Sep 07 16:25:16 2020 -0400
summary: localrepo: use functools.wraps() in unfilteredmethod decorator

https://www.mercurial-scm.org/repo/hg/rev/6739ef7c5fcf
changeset:   45419:6739ef7c5fcf
user:Augie Fackler 
date:Mon Sep 07 16:27:12 2020 -0400
summary: git: correctly handle "nothing changed" commits

https://www.mercurial-scm.org/repo/hg/rev/c67529569643
changeset:   45420:c67529569643
user:Augie Fackler 
date:Mon Sep 07 17:12:29 2020 -0400
summary: git: fix up dirstate use of index

https://www.mercurial-scm.org/repo/hg/rev/0c6b2cc9a7bb
changeset:   45421:0c6b2cc9a7bb
user:Augie Fackler 
date:Mon Sep 07 17:13:45 2020 -0400
summary: git: make dirstate status() respect matcher

https://www.mercurial-scm.org/repo/hg/rev/601e3658216d
changeset:   45422:601e3658216d
user:Augie Fackler 
date:Mon Sep 07 17:14:59 2020 -0400
summary: git: make dirstate actually support listclean parameter

https://www.mercurial-scm.org/repo/hg/rev/d4cf80341589
changeset:   45423:d4cf80341589
user:Augie Fackler 
date:Mon Sep 07 17:16:16 2020 -0400
summary: git: fix index handling of removed files during commit (issue6398)

https://www.mercurial-scm.org/repo/hg/rev/0a57ef4b3bdb
changeset:   45424:0a57ef4b3bdb
user:Matt Harbison 
date:Mon Aug 24 12:43:53 2020 -0400
summary: rewriteutil: extract evolve code used to replace obsolete hashes 
in commits

https://www.mercurial-scm.org/repo/hg/rev/f7e293e0475f
changeset:   45425:f7e293e0475f
user:Matt Harbison 
date:Mon Aug 24 18:44:15 2020 -0400
summary: rewriteutil: also consider pending obsoletes when updating hashes 
in messages

https://www.mercurial-scm.org/repo/hg/rev/1a5d3e555c70
changeset:   45426:1a5d3e555c70
user:Matt Harbison 
date:Mon Aug 24 18:51:25 2020 -0400
summary: phabricator: update the hashes in commit messages as they get 
submitted

https://www.mercurial-scm.org/repo/hg/rev/78861610ded8
changeset:   45427:78861610ded8
user:Matt Harbison 
date:Tue Aug 25 23:18:42 2020 -0400
summary: rewriteutil: relax the sha1 hash references to handle future hash 
types

https://www.mercurial-scm.org/repo/hg/rev/9b9071fabcd3
changeset:   45428:9b9071fabcd3
user:Yuya Nishihara 
date:Wed Sep 09 11:51:51 2020 +0900
summary: revset: remove indirect indexing of status tuple

https://www.mercurial-scm.org/repo/hg/rev/9c8d2cf7f591
changeset:   45429:9c8d2cf7f591
user:Yuya Nishihara 
date:Tue Sep 08 21:38:10 2020 +0900
summary: test-grep: document that trivially moved lines might not be 
detected

https://www.mercurial-scm.org/repo/hg/rev/e47385ef4e17
changeset:   45430:e47385ef4e17
bookmark:@
tag: tip
user:Yuya Nishihara 
date:Wed Sep 09 11:41:18 2020 +0900
summary: grep: fix hash(linestate) to not include linenum

-- 
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


mercurial@45458: 28 new changesets

2020-09-14 Thread Mercurial Commits
28 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/7a57ced7de87
changeset:   45431:7a57ced7de87
user:Pulkit Goyal <7895pul...@gmail.com>
date:Thu Sep 10 17:03:38 2020 +0530
summary: git: remove unrequired assignment of listignored and listunknown

https://www.mercurial-scm.org/repo/hg/rev/f52b0297acc8
changeset:   45432:f52b0297acc8
user:Pulkit Goyal <7895pul...@gmail.com>
date:Thu Sep 03 14:14:40 2020 +0530
summary: commit: fix a wrong argument name in documentation

https://www.mercurial-scm.org/repo/hg/rev/324ad3e7ef41
changeset:   45433:324ad3e7ef41
user:Pulkit Goyal <7895pul...@gmail.com>
date:Tue Sep 08 18:46:01 2020 +0530
summary: localrepo: warn if we are writing to cache without a lock

https://www.mercurial-scm.org/repo/hg/rev/5523e3e1bc71
changeset:   45434:5523e3e1bc71
user:Pulkit Goyal <7895pul...@gmail.com>
date:Thu Sep 10 13:37:35 2020 +0530
summary: statichttprepo: use LockUnavailable() instead of Abort() for lock 
(API)

https://www.mercurial-scm.org/repo/hg/rev/64de86fd0984
changeset:   45435:64de86fd0984
user:Pulkit Goyal <7895pul...@gmail.com>
date:Tue Sep 08 19:36:40 2020 +0530
summary: tags: take lock instead of wlock before writing hgtagsfnodes1 cache

https://www.mercurial-scm.org/repo/hg/rev/1b3197047f5c
changeset:   45436:1b3197047f5c
user:Raphaël Gomès 
date:Thu Jul 30 16:55:44 2020 +0200
summary: rhg: make output of `files` relative to the current directory and 
the root

https://www.mercurial-scm.org/repo/hg/rev/e339693addc0
changeset:   45437:e339693addc0
user:Antoine Cezar 
date:Mon Aug 03 11:55:59 2020 +0200
summary: rhg: add harness tests for rhg files

https://www.mercurial-scm.org/repo/hg/rev/ed95ccc94333
changeset:   45438:ed95ccc94333
user:Antoine Cezar 
date:Tue Aug 04 16:11:23 2020 +0200
summary: rhg: pass `ui` to `Command` `run`

https://www.mercurial-scm.org/repo/hg/rev/fbc373b7cbc3
changeset:   45439:fbc373b7cbc3
user:Antoine Cezar 
date:Thu Aug 13 16:36:42 2020 +0200
summary: rhg: fix `clippy` warnings

https://www.mercurial-scm.org/repo/hg/rev/a6a000ab135b
changeset:   45440:a6a000ab135b
user:Antoine Cezar 
date:Mon Aug 17 16:55:43 2020 +0200
summary: rhg: print error message when argument parsing fails

https://www.mercurial-scm.org/repo/hg/rev/3d9f1dfc52c2
changeset:   45441:3d9f1dfc52c2
user:Antoine Cezar 
date:Mon Aug 17 10:59:30 2020 +0200
summary: hg-core: fix some `clippy` warnings

https://www.mercurial-scm.org/repo/hg/rev/c6e332a451d0
changeset:   45442:c6e332a451d0
user:Sushil khanchi 
date:Fri Sep 11 13:04:05 2020 +0530
summary: py3: fix bytes and str mixup in run-tests

https://www.mercurial-scm.org/repo/hg/rev/037e88d453fa
changeset:   45443:037e88d453fa
user:Pulkit Goyal <7895pul...@gmail.com>
date:Thu Sep 03 14:14:04 2020 +0530
summary: commit: pass mergestate into _filecommit() instead of re-reading it

https://www.mercurial-scm.org/repo/hg/rev/f6c67bb4ca03
changeset:   45444:f6c67bb4ca03
user:Pulkit Goyal <7895pul...@gmail.com>
date:Thu Sep 10 16:51:40 2020 +0530
summary: tests: update lockdelay.py to handle the `wait` argument

https://www.mercurial-scm.org/repo/hg/rev/766797f23f77
changeset:   45445:766797f23f77
user:Pulkit Goyal <7895pul...@gmail.com>
date:Mon Aug 24 18:59:19 2020 +0530
summary: debugmergestate: show extras for files which are not in mergestate

https://www.mercurial-scm.org/repo/hg/rev/00e4e97c6bc8
changeset:   45446:00e4e97c6bc8
user:Pulkit Goyal <7895pul...@gmail.com>
date:Thu Sep 03 14:45:16 2020 +0530
summary: debugmergestate: sort extras before printing

https://www.mercurial-scm.org/repo/hg/rev/e7c8a5030a90
changeset:   45447:e7c8a5030a90
user:Pulkit Goyal <7895pul...@gmail.com>
date:Wed Aug 26 17:24:22 2020 +0530
summary: merge: show number of ancestors in bid merge debug notes

https://www.mercurial-scm.org/repo/hg/rev/85b03b1e4715
changeset:   45448:85b03b1e4715
user:Martin von Zweigbergk 
date:Thu Sep 10 13:12:34 2020 -0700
summary: graphlog: use '%' only if there are *unresolved* conflicts

https://www.mercurial-scm.org/repo/hg/rev/814c7430f828
changeset:   45449:814c7430f828
user:Martin von Zweigbergk 
date:Fri Sep 11 09:55:08 2020 -0700
summary: tests: make emacs test less strict

https://www.mercurial-scm.org/repo/hg/rev/47d10ade5bc4
changeset:   45450:47d10ade5bc4
user:Martin von Zweigbergk 
date:Fri Sep 11 09:35:49 2020 -0700
summary: histedit: cache description line

https://www.mercurial-scm.org/repo/hg/rev/e53a3d0ef416
changeset:   45451:e53a3d0ef416
user:Martin von Zweigbergk 
date:Thu Sep 10 22:00:00 2020 -0700
summary: templater: fix reading of templates in frozen bina

[PATCH 2 of 2] copy-tracing: test case where a merge reverted a file deletion

2020-09-14 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1592540106 -7200
#  Fri Jun 19 06:15:06 2020 +0200
# Node ID f6a7035cc13565b4314e30ab89d4ec5f94bab55b
# Parent  67fed36f1a0658931cf68a2ac772b70b79c40f6f
# EXP-Topic copies-and-merge
# Available At https://foss.heptapod.net/octobus/mercurial-devel/
#  hg pull https://foss.heptapod.net/octobus/mercurial-devel/ -r 
f6a7035cc135
copy-tracing: test case where a merge reverted a file deletion

This case is currently broken for commit centric copy tracing. So we add an
official case for it with a note about it being broken.

Fixing it will requires multiples change in code related to merge, commit and
copy tracing, so we introduce it beforehand for simplicity.

Also, I have been sitting on this test for 3 months so I would rather have it
upstream.

diff --git a/tests/test-copies-chain-merge.t b/tests/test-copies-chain-merge.t
--- a/tests/test-copies-chain-merge.t
+++ b/tests/test-copies-chain-merge.t
@@ -926,3 +926,71 @@ BROKEN: 'a' should be the the source of 
   A d
   $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mCGm-0")'
   $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mGCm-0")'
+
+
+Comparing with merge restoring an untouched deleted file
+
+
+Merge:
+- one removing a file (d)
+- one leaving the file untouched
+- the merge actively restore the file to the same content.
+
+In this case, the file keep on living after the merge. So we should not drop 
its
+copy tracing chain.
+
+  $ hg up 'desc("c-1")'
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge 'desc("b-1")'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg revert --rev 'desc("b-1")' d
+  $ hg ci -m "mCB-revert-m-0"
+  created new head
+
+  $ hg up 'desc("b-1")'
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge 'desc("c-1")'
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg revert --rev 'desc("b-1")' d
+  $ hg ci -m "mBC-revert-m-0"
+  created new head
+
+  $ hg log -G --rev '::(desc("mCB-revert-m")+desc("mBC-revert-m"))'
+  @33 mBC-revert-m-0
+  |\
+  +---o  32 mCB-revert-m-0
+  | |/
+  | o  6 c-1 delete d
+  | |
+  o |  5 b-1: b update
+  |/
+  o  2 i-2: c -move-> d
+  |
+  o  1 i-1: a -move-> c
+  |
+  o  0 i-0 initial commit: a b h
+  
+
+BROKEN: 'a' should be the the source of 'd' in the changeset centric algorithm 
too
+
+  $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCB-revert-m-0")'
+  M b
+  A d
+a (filelog !)
+  R a
+  $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBC-revert-m-0")'
+  M b
+  A d
+a (filelog !)
+  R a
+  $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCB-revert-m-0")'
+  M b
+  A d
+  $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBC-revert-m-0")'
+  M b
+  A d
+  $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCB-revert-m-0")'
+  $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBC-revert-m-0")'
+

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


[PATCH 1 of 2] copy-tracing: test case where we go across a changed/deleted merge

2020-09-14 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1592539488 -7200
#  Fri Jun 19 06:04:48 2020 +0200
# Node ID 67fed36f1a0658931cf68a2ac772b70b79c40f6f
# Parent  e7c8a5030a90d99640beb51623ab5dec996c1e20
# EXP-Topic copies-and-merge
# Available At https://foss.heptapod.net/octobus/mercurial-devel/
#  hg pull https://foss.heptapod.net/octobus/mercurial-devel/ -r 
67fed36f1a06
copy-tracing: test case where we go across a changed/deleted merge

This case is currently broken in the commit centric case. So we add an official
case for it with a note about it being broken.

Fixing it will requires multiples change in code related to merge, commit and
copy tracing, so we introduce it beforehand for simplicity.

Also, I have been sitting on this test for 3 months so I would rather have it
upstream.

diff --git a/tests/test-copies-chain-merge.t b/tests/test-copies-chain-merge.t
--- a/tests/test-copies-chain-merge.t
+++ b/tests/test-copies-chain-merge.t
@@ -853,3 +853,76 @@ Note:
   |
   o  0 i-0 initial commit: a b h
   
+
+
+Comparing with merging with a deletion (and keeping the file)
+-
+
+Merge:
+- one removing a file (d)
+- one updating that file
+- the merge keep the modified version of the file (canceling the delete)
+
+In this case, the file keep on living after the merge. So we should not drop 
its
+copy tracing chain.
+
+  $ hg up 'desc("c-1")'
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge 'desc("g-1")'
+  file 'd' was deleted in local [working copy] but was modified in other 
[merge rev].
+  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
+  What do you want to do? u
+  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]
+  $ hg resolve -t :other d
+  (no more unresolved files)
+  $ hg ci -m "mCGm-0"
+  created new head
+
+  $ hg up 'desc("g-1")'
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge 'desc("c-1")'
+  file 'd' was deleted in other [merge rev] but was modified in local [working 
copy].
+  You can use (c)hanged version, (d)elete, or leave (u)nresolved.
+  What do you want to do? u
+  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]
+  $ hg resolve -t :local d
+  (no more unresolved files)
+  $ hg ci -m "mGCm-0"
+  created new head
+
+  $ hg log -G --rev '::(desc("mCGm")+desc("mGCm"))'
+  @31 mGCm-0
+  |\
+  +---o  30 mCGm-0
+  | |/
+  | o  25 g-1: update d
+  | |
+  o |  6 c-1 delete d
+  |/
+  o  2 i-2: c -move-> d
+  |
+  o  1 i-1: a -move-> c
+  |
+  o  0 i-0 initial commit: a b h
+  
+
+BROKEN: 'a' should be the the source of 'd' in the changeset centric algorithm 
too
+
+  $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCGm-0")'
+  A d
+a (filelog !)
+  R a
+  $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGCm-0")'
+  A d
+a (filelog !)
+  R a
+  $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCGm-0")'
+  A d
+  $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mGCm-0")'
+  A d
+  $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mCGm-0")'
+  $ hg status --copies --rev 'desc("g-1")' --rev 'desc("mGCm-0")'

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