Patchwork [3,of,3,RFC] revert: clear the flagstate entry when reverting a file

login
register
mail settings
Submitter Matt Harbison
Date July 3, 2016, 10 p.m.
Message ID <94ecafb966d765fc0575.1467583213@Envy>
Download mbox | patch
Permalink /patch/15728/
State RFC, archived
Headers show

Comments

Matt Harbison - July 3, 2016, 10 p.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1467574478 14400
#      Sun Jul 03 15:34:38 2016 -0400
# Node ID 94ecafb966d765fc05750380b706f13fadea362a
# Parent  e6da62c6d4b29f29a1cad36e72d98d9208186e51
revert: clear the flagstate entry when reverting a file

This allows the file to resume the state manufactured from the manifest on
platforms without native flags support.

The point at which the state file is being written is when an individual file
is reverted.  The tradeoff here is writing the state file N times vs. once.  But
in the case of once, it would be possible for revert to say that it reverted
some files, an error occurs causing it to bail, and then those same files have
their old state (but I suspect wouldn't on Unix in the same scenario).

I had to comment out the transaction backup because there is no transaction
occurring at this time in revert.  I'm a bit surprised that dirstate.write() is
forcing a transaction to be supplied, but then lets it supply None.  I didn't
pay a lot of attention to the dirstate transaction code when it was changed, so
I need to be clued in on how to proceed.

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -3247,9 +3247,12 @@ 
     excluded_files = []
     matcher_opts = {"exclude": excluded_files}
 
+    fs = repo[None].flagstate
     def checkout(f):
         fc = ctx[f]
         repo.wwrite(f, fc.data(), fc.flags())
+        fs[f] = fc.flags()
+        fs.write(repo.currenttransaction())  # XXX: val is None, but no warning
 
     audit_path = pathutil.pathauditor(repo.root)
     for f in actions['forget'][0]:
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -290,7 +290,7 @@ 
 
     def write(self, tr):
         if self._dirty:
-            tr.addbackup('flagstate')  # was fncache
+            #tr.addbackup('flagstate')  # was fncache
             fp = self._repo.svfs('flagstate', mode='wb', atomictemp=True)
             try:
                 for k, v in self._entries.iteritems():
diff --git a/tests/test-flags2.t b/tests/test-flags2.t
--- a/tests/test-flags2.t
+++ b/tests/test-flags2.t
@@ -56,11 +56,29 @@ 
   $ hg files -v
            7 x noexec.txt
            7   noexec2.txt
+  $ hg revert --no-backup noexec.txt
+  $ hg files -v
+           7   noexec.txt
+           7   noexec2.txt
+
+Revert to +x
+
+  $ hg flags -x noexec.txt
+  $ hg ci -m "+x"
+  $ hg flags -n noexec.txt
+  $ hg files -v
+           7   noexec.txt
+           7   noexec2.txt
+  $ hg revert --no-backup noexec.txt
+  $ hg files -v
+           7 x noexec.txt
+           7   noexec2.txt
 
 Update -C to nuke it
+  $ hg flags -n noexec.txt
   $ hg update -C
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg files -v
-           7   noexec.txt
+           7 x noexec.txt
            7   noexec2.txt