Patchwork [2,of,4] debugdirstate: add option to drop or add files to dirstate

login
register
mail settings
Submitter Christian Delahousse
Date Nov. 12, 2015, 6:17 a.m.
Message ID <cb5481344592d2a38f1a.1447309076@dev4253.prn1.facebook.com>
Download mbox | patch
Permalink /patch/11366/
State Changes Requested
Headers show

Comments

Christian Delahousse - Nov. 12, 2015, 6:17 a.m.
# HG changeset patch
# User Christian Delahousse <cdelahousse@fb.com>
# Date 1446522845 28800
#      Mon Nov 02 19:54:05 2015 -0800
# Node ID cb5481344592d2a38f1a6724324542a3d2708ec0
# Parent  88237bdf95f715685488ba0260a27d6dd5dd5bb2
debugdirstate: add option to drop or add files to dirstate

Debugging the dirstate helps if you have options to add files for normal lookup
or drop them form the dirstate. This patch adds flags to the debugdirstate
command to do just that.
Yuya Nishihara - Nov. 13, 2015, 1:57 p.m.
On Wed, 11 Nov 2015 22:17:56 -0800, cdelahousse@fb.com wrote:
> # HG changeset patch
> # User Christian Delahousse <cdelahousse@fb.com>
> # Date 1446522845 28800
> #      Mon Nov 02 19:54:05 2015 -0800
> # Node ID cb5481344592d2a38f1a6724324542a3d2708ec0
> # Parent  88237bdf95f715685488ba0260a27d6dd5dd5bb2
> debugdirstate: add option to drop or add files to dirstate
> 
> Debugging the dirstate helps if you have options to add files for normal lookup
> or drop them form the dirstate. This patch adds flags to the debugdirstate
> command to do just that.
> 
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -3158,12 +3158,42 @@
>      finally:
>          wlock.release()
>  
> +def _moddirstate(repo, filestolookup=None, filestodrop=None):
> +    '''Manually add or drop a file to the dirstate'''
> +    wlock = repo.wlock()
> +    lock = repo.lock()
> +    try:
> +        tr = repo.transaction('dirstate')
> +        if filestolookup:
> +            for file in filestolookup:
> +                repo.dirstate.normallookup(file)
> +        else:
> +            for file in filestodrop:
> +                repo.dirstate.drop(file)
> +        repo.dirstate.write(tr)
> +        tr.close()
> +    finally:
> +        lock.release()
> +        wlock.release()

Not sure if we need a transaction (and repo.lock) just to modify dirstate.

> +
>  @command('debugdirstate|debugstate',
>      [('', 'nodates', None, _('do not display the saved mtime')),
> -    ('', 'datesort', None, _('sort by saved mtime'))],
> +    ('', 'datesort', None, _('sort by saved mtime')),
> +    ('', 'drop', [], _('drop file from dirstate'), _('FILE')),
> +    ('', 'normal-lookup', [], _('add file to dirstate'), _('FILE'))],
>      _('[OPTION]...'))
>  def debugstate(ui, repo, **opts):
> -    """show the contents of the current dirstate"""
> +    """show or modify the contents of the current dirstate"""
> +
> +    drop = opts.get('drop')
> +    nl = opts.get('normal_lookup')
> +
> +    if nl and drop:
> +        error.Abort('drop and normal-lookup are mutually exclusive')
> +
> +    if nl or drop:
> +        _moddirstate(repo, nl, drop)

As --normal-lookup and --drop are designed exclusive, we'd probably want to
do "hg debugdirstate --normal file1 file2 ...", i.e. bool **opts and *pats.

I want to call it --add (or --add-normal), but that would be a matter of taste.

Regards,
Pierre-Yves David - Nov. 14, 2015, 1:08 a.m.
On 11/13/2015 05:57 AM, Yuya Nishihara wrote:
> On Wed, 11 Nov 2015 22:17:56 -0800, cdelahousse@fb.com wrote:
>> # HG changeset patch
>> # User Christian Delahousse <cdelahousse@fb.com>
>> # Date 1446522845 28800
>> #      Mon Nov 02 19:54:05 2015 -0800
>> # Node ID cb5481344592d2a38f1a6724324542a3d2708ec0
>> # Parent  88237bdf95f715685488ba0260a27d6dd5dd5bb2
>> debugdirstate: add option to drop or add files to dirstate
>>
>> Debugging the dirstate helps if you have options to add files for normal lookup
>> or drop them form the dirstate. This patch adds flags to the debugdirstate
>> command to do just that.
>>
>> diff --git a/mercurial/commands.py b/mercurial/commands.py
>> --- a/mercurial/commands.py
>> +++ b/mercurial/commands.py
>> @@ -3158,12 +3158,42 @@
>>       finally:
>>           wlock.release()
>>
>> +def _moddirstate(repo, filestolookup=None, filestodrop=None):
>> +    '''Manually add or drop a file to the dirstate'''
>> +    wlock = repo.wlock()
>> +    lock = repo.lock()
>> +    try:
>> +        tr = repo.transaction('dirstate')
>> +        if filestolookup:
>> +            for file in filestolookup:
>> +                repo.dirstate.normallookup(file)
>> +        else:
>> +            for file in filestodrop:
>> +                repo.dirstate.drop(file)
>> +        repo.dirstate.write(tr)
>> +        tr.close()
>> +    finally:
>> +        lock.release()
>> +        wlock.release()
>
> Not sure if we need a transaction (and repo.lock) just to modify dirstate.

We do not to create a transaction for dirstate. We need to pass the 
current transaction if it exist that is all.

We only need repo.wlock. the repo.lock will be taken but third party 
code creating the transaction if one exists.

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3158,12 +3158,42 @@ 
     finally:
         wlock.release()
 
+def _moddirstate(repo, filestolookup=None, filestodrop=None):
+    '''Manually add or drop a file to the dirstate'''
+    wlock = repo.wlock()
+    lock = repo.lock()
+    try:
+        tr = repo.transaction('dirstate')
+        if filestolookup:
+            for file in filestolookup:
+                repo.dirstate.normallookup(file)
+        else:
+            for file in filestodrop:
+                repo.dirstate.drop(file)
+        repo.dirstate.write(tr)
+        tr.close()
+    finally:
+        lock.release()
+        wlock.release()
+
 @command('debugdirstate|debugstate',
     [('', 'nodates', None, _('do not display the saved mtime')),
-    ('', 'datesort', None, _('sort by saved mtime'))],
+    ('', 'datesort', None, _('sort by saved mtime')),
+    ('', 'drop', [], _('drop file from dirstate'), _('FILE')),
+    ('', 'normal-lookup', [], _('add file to dirstate'), _('FILE'))],
     _('[OPTION]...'))
 def debugstate(ui, repo, **opts):
-    """show the contents of the current dirstate"""
+    """show or modify the contents of the current dirstate"""
+
+    drop = opts.get('drop')
+    nl = opts.get('normal_lookup')
+
+    if nl and drop:
+        error.Abort('drop and normal-lookup are mutually exclusive')
+
+    if nl or drop:
+        _moddirstate(repo, nl, drop)
+        return
 
     nodates = opts.get('nodates')
     datesort = opts.get('datesort')
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -243,7 +243,7 @@ 
   debugdag: tags, branches, dots, spaces
   debugdata: changelog, manifest, dir
   debugdate: extended
-  debugdirstate: nodates, datesort
+  debugdirstate: nodates, datesort, drop, normal-lookup
   debugdiscovery: old, nonheads, ssh, remotecmd, insecure
   debugextensions: template
   debugfileset: rev
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -800,7 +800,7 @@ 
    debugdata     dump the contents of a data file revision
    debugdate     parse and display a date
    debugdirstate
-                 show the contents of the current dirstate
+                 show or modify the contents of the current dirstate
    debugdiscovery
                  runs the changeset discovery protocol in isolation
    debugextensions
diff --git a/tests/test-rebuildstate.t b/tests/test-rebuildstate.t
--- a/tests/test-rebuildstate.t
+++ b/tests/test-rebuildstate.t
@@ -20,6 +20,15 @@ 
   n 644         -1 set                 bar
   n 644         -1 set                 foo
 
+  $ hg debugstate --normal-lookup file1 --normal-lookup file2
+  $ hg debugstate --drop bar
+  $ hg debugstate --nodates
+  n   0         -1 unset               file1
+  n   0         -1 unset               file2
+  n 644         -1 set                 foo
+
+  $ hg debugrebuildstate
+
 status
 
   $ hg st -A