Patchwork [3,of,3,STABLE,V2] revert: look for copies information for all local modifications

login
register
mail settings
Submitter Pierre-Yves David
Date Nov. 27, 2014, 1:16 a.m.
Message ID <e655cc8ea56eb08a4f1a.1417051015@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/6880/
State Accepted
Headers show

Comments

Pierre-Yves David - Nov. 27, 2014, 1:16 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1416973254 28800
#      Tue Nov 25 19:40:54 2014 -0800
# Branch stable
# Node ID e655cc8ea56eb08a4f1af813b3b00364385b7daa
# Parent  6c8af433ac6e7ec4870d05db82a6671620329240
revert: look for copies information for all local modifications

Renaming a file over an existing one marks the file as modified. So we
track rename source in modified file too.
Martin von Zweigbergk - Nov. 27, 2014, 4:01 a.m.
This series looks good to me. Thanks.

PS. I haven't forgotten about generating test cases for this.

On Wed Nov 26 2014 at 5:18:01 PM Pierre-Yves David <
pierre-yves.david@ens-lyon.org> wrote:

> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1416973254 28800
> #      Tue Nov 25 19:40:54 2014 -0800
> # Branch stable
> # Node ID e655cc8ea56eb08a4f1af813b3b00364385b7daa
> # Parent  6c8af433ac6e7ec4870d05db82a6671620329240
> revert: look for copies information for all local modifications
>
> Renaming a file over an existing one marks the file as modified. So we
> track rename source in modified file too.
>
> diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
> --- a/mercurial/cmdutil.py
> +++ b/mercurial/cmdutil.py
> @@ -2529,16 +2529,20 @@ def revert(ui, repo, ctx, parents, *pats
>          # or just forget etc)
>          if parent == node:
>              dsmodified = modified
>              dsadded = added
>              dsremoved = removed
> +            # store all local modification, useful later for renames
> detection
> +            localchanges = dsmodified | dsadded
>              modified, added, removed = set(), set(), set()
>          else:
>              changes = repo.status(node1=parent, match=m)
>              dsmodified = set(changes[0])
>              dsadded    = set(changes[1])
>              dsremoved  = set(changes[2])
> +            # store all local modification, useful later for renames
> detection
> +            localchanges = dsmodified | dsadded
>
>              # only take into account for removes between wc and target
>              clean |= dsremoved - removed
>              dsremoved &= removed
>              # distinct between dirstate remove and other
> @@ -2568,11 +2572,11 @@ def revert(ui, repo, ctx, parents, *pats
>              dsadded |= mergeadd
>              dsmodified -= mergeadd
>
>          # if f is a rename, update `names` to also revert the source
>          cwd = repo.getcwd()
> -        for f in dsadded:
> +        for f in localchanges:
>              src = repo.dirstate.copied(f)
>              # XXX should we check for rename down to target node?
>              if src and src not in names and repo.dirstate[src] == 'r':
>                  dsremoved.add(src)
>                  names[src] = (repo.pathto(src, cwd), True)
> diff --git a/tests/test-revert.t b/tests/test-revert.t
> --- a/tests/test-revert.t
> +++ b/tests/test-revert.t
> @@ -232,10 +232,16 @@ reverting a rename target should revert
>    $ hg mv a newa
>    $ hg revert newa
>    $ hg st a newa
>    ? newa
>
> +Also true for move overwriting existing file
> +
> +  $ hg mv --force a b/b
> +  $ hg revert b/b
> +  $ hg status a b/b
> +
>    $ cd ..
>
>    $ hg init ignored
>    $ cd ignored
>    $ echo '^ignored$' > .hgignore
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
>
Matt Mackall - Nov. 27, 2014, 5:24 p.m.
On Wed, 2014-11-26 at 17:16 -0800, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1416973254 28800
> #      Tue Nov 25 19:40:54 2014 -0800
> # Branch stable
> # Node ID e655cc8ea56eb08a4f1af813b3b00364385b7daa
> # Parent  6c8af433ac6e7ec4870d05db82a6671620329240
> revert: look for copies information for all local modifications

These are queued for stable, thanks.

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2529,16 +2529,20 @@  def revert(ui, repo, ctx, parents, *pats
         # or just forget etc)
         if parent == node:
             dsmodified = modified
             dsadded = added
             dsremoved = removed
+            # store all local modification, useful later for renames detection
+            localchanges = dsmodified | dsadded
             modified, added, removed = set(), set(), set()
         else:
             changes = repo.status(node1=parent, match=m)
             dsmodified = set(changes[0])
             dsadded    = set(changes[1])
             dsremoved  = set(changes[2])
+            # store all local modification, useful later for renames detection
+            localchanges = dsmodified | dsadded
 
             # only take into account for removes between wc and target
             clean |= dsremoved - removed
             dsremoved &= removed
             # distinct between dirstate remove and other
@@ -2568,11 +2572,11 @@  def revert(ui, repo, ctx, parents, *pats
             dsadded |= mergeadd
             dsmodified -= mergeadd
 
         # if f is a rename, update `names` to also revert the source
         cwd = repo.getcwd()
-        for f in dsadded:
+        for f in localchanges:
             src = repo.dirstate.copied(f)
             # XXX should we check for rename down to target node?
             if src and src not in names and repo.dirstate[src] == 'r':
                 dsremoved.add(src)
                 names[src] = (repo.pathto(src, cwd), True)
diff --git a/tests/test-revert.t b/tests/test-revert.t
--- a/tests/test-revert.t
+++ b/tests/test-revert.t
@@ -232,10 +232,16 @@  reverting a rename target should revert 
   $ hg mv a newa
   $ hg revert newa
   $ hg st a newa
   ? newa
 
+Also true for move overwriting existing file
+
+  $ hg mv --force a b/b
+  $ hg revert b/b
+  $ hg status a b/b
+
   $ cd ..
 
   $ hg init ignored
   $ cd ignored
   $ echo '^ignored$' > .hgignore