Bug 884 - [inotify] Build products not ignored until .hgignore touched
Summary: [inotify] Build products not ignored until .hgignore touched
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: Mercurial (show other bugs)
Version: unspecified
Hardware: All All
: urgent bug
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-12-19 15:22 UTC by Jesse Glick
Modified: 2012-05-13 04:47 UTC (History)
7 users (show)

See Also:
Python Version: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jesse Glick 2007-12-19 15:22 UTC
Using the INotify extension (539db616abeb), there is a bit of a problem with
ignore lists. Newly created ignored files (common during a build) are listed as
unknown until you make some change to .hgignore. Test case:

$ hg init hg-inotify-test
$ cd hg-inotify-test
$ echo '^build$' > .hgignore
$ hg ci -m ignorelist -A
adding .hgignore
$ mkdir build
$ touch build/x
$ touch build/y
$ hg stat
? build/x
? build/y
$ touch .hgignore
$ hg stat
$
Comment 1 Benoit Boissinot 2008-09-06 13:31 UTC
I can't reproduce, can you add more info or test with a more recent mercurial ?
Comment 2 Jesse Glick 2008-09-09 14:37 UTC
I cannot reproduce in Hg 1.0 or 1.0.2.
Comment 3 Jesse Glick 2008-09-09 15:07 UTC
Update: it looks like I was not really testing anything, because apparently the
inotify extension no longer does anything unless you explicitly 'hg inserve'.
(It used to automatically start the daemon on demand but it seems this is no
longer true?) When I update the test case accordingly, I get the original bug,
plus an error:


#!/bin/sh
cd /tmp
killall hg
rm -rf hg-inotify-test
hg init hg-inotify-test
cd hg-inotify-test
hg inserve &
echo '^build$' > .hgignore
hg ci -m ignorelist -A
mkdir build
touch build/x
touch build/y
echo 'stat #1'
hg stat
touch .hgignore
echo 'stat #2'
hg stat


hg: no process killed
adding .hgignore
stat #1
M .hgignore
? build/x
? build/y
stat #2
** unknown exception encountered, details follow
** report bug details to http://www.selenic.com/mercurial/bts
** or mercurial@selenic.com
** Mercurial Distributed SCM (version 1.0.2)
Traceback (most recent call last):
  File "/home/jglick/bin/hg", line 20, in <module>
    mercurial.dispatch.run()
  File "/home/jglick/lib/python/mercurial/dispatch.py", line 20, in run
    sys.exit(dispatch(sys.argv[1:]))
  File "/home/jglick/lib/python/mercurial/dispatch.py", line 29, in dispatch
    return _runcatch(u, args)
  File "/home/jglick/lib/python/mercurial/dispatch.py", line 45, in _runcatch
    return _dispatch(ui, args)
  File "/home/jglick/lib/python/mercurial/dispatch.py", line 364, in _dispatch
    ret = _runcommand(ui, options, cmd, d)
  File "/home/jglick/lib/python/mercurial/dispatch.py", line 417, in _runcommand
    return checkargs()
  File "/home/jglick/lib/python/mercurial/dispatch.py", line 373, in checkargs
    return cmdfunc()
  File "/home/jglick/lib/python/mercurial/dispatch.py", line 356, in <lambda>
    d = lambda: func(ui, repo, *args, **cmdoptions)
  File "/home/jglick/lib/python/hgext/inotify/__init__.py", line 36, in serve
    cmdutil.service(opts, initfn=service.init, runfn=service.run)
  File "/home/jglick/lib/python/mercurial/cmdutil.py", line 561, in service
    return runfn()
  File "/home/jglick/lib/python/hgext/inotify/__init__.py", line 31, in run
    self.master.run()
  File "/home/jglick/lib/python/hgext/inotify/server.py", line 686, in run
    self.table[fd].handle_event(fd, event)
  File "/home/jglick/lib/python/hgext/inotify/server.py", line 595, in handle_event
    self.watcher.handle_timeout()
  File "/home/jglick/lib/python/hgext/inotify/server.py", line 541, in
handle_timeout
    self.deferred_event(wpath, evt)
  File "/home/jglick/lib/python/hgext/inotify/server.py", line 454, in
deferred_event
    self.modified(wpath)
  File "/home/jglick/lib/python/hgext/inotify/server.py", line 420, in modified
    self.update_hgignore()
  File "/home/jglick/lib/python/hgext/inotify/server.py", line 383, in
update_hgignore
    if self.repo.dirstate.ignorefunc is not None:
  File "/home/jglick/lib/python/mercurial/dirstate.py", line 70, in __getattr__
    raise AttributeError, name
AttributeError: ignorefunc
Comment 4 Benoit Boissinot 2008-09-09 15:15 UTC
Too bad there were no tests for inotify before :/ that would have avoided this
breakage. I'll look into it.
Comment 5 Benoit Boissinot 2008-09-09 16:13 UTC
diff --git a/hgext/inotify/server.py b/hgext/inotify/server.py
--- a/hgext/inotify/server.py
+++ b/hgext/inotify/server.py
@@ -265,10 +265,7 @@
         return type_
 
     def updatestatus(self, wfn, st=None, status=None, oldstatus=None):
-        if st:
-            status = self.filestatus(wfn, st)
-        else:
-            self.statcache.pop(wfn, None)
+        status = self.filestatus(wfn, st)
         root, fn = self.split(wfn)
         d = self.dir(self.tree, root)
         if oldstatus is None:
@@ -380,9 +377,13 @@
         # But it's easier to do nothing than to open that can of
         # worms.
 
-        if self.repo.dirstate.ignorefunc is not None:
-            self.repo.dirstate.ignorefunc = None
+        try:
+            del self.repo.dirstate._ignore
+        except AttributeError:
+            pass
+        else:
             self.ui.note(_('rescanning due to .hgignore change\n'))
+            self.statustrees['?'].clear()
             self.scan()
 
     def getstat(self, wpath):
Comment 6 Benoit Boissinot 2008-09-09 16:46 UTC
It breaks some other stuff, sorry.
Comment 7 Benoit Boissinot 2008-09-09 23:21 UTC
On Tue, Sep 09, 2008 at 09:07:08PM -0000, Jesse Glick wrote:
>
> Jesse Glick <jesse.glick@sun.com> added the comment:
>
> Update: it looks like I was not really testing anything, because apparently the
> inotify extension no longer does anything unless you explicitly 'hg inserve'.
> (It used to automatically start the daemon on demand but it seems this is no
> longer true?)

It probably means I changed (corrected?) the behaviour, it now depends
on ui.configbool('inotify', 'autostart').
Comment 8 Jesse Glick 2008-10-14 19:46 UTC
Behavior now seems even worse than before; now the build products are not
ignored even if you do touch .hgignore:


hg: no process killed
Mercurial Distributed SCM (version 6dab29f6df37)

Copyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
adding .hgignore
stat #1
? build/x
? build/y
stat #2
? build/x
? build/y


Same if you make an actual modification to .hgignore and even commit that
modification; the ignore list never seems to be refreshed:


#!/bin/sh
cd /tmp
killall hg
rm -rf hg-inotify-test
testhg version
testhg init hg-inotify-test
cd hg-inotify-test
testhg inserve &
echo '^build$' > .hgignore
hg add .hgignore
mkdir build
touch build/x
testhg ci -m ignorelist
touch build/y
echo 'stat #1'
testhg stat
touch .hgignore
echo 'stat #2'
testhg stat
echo >> .hgignore
echo 'stat #3'
testhg stat
hg ci -m . .hgignore
echo 'stat #4'
testhg stat
touch build/x
echo 'stat #5'
testhg stat
touch build/z
echo 'stat #6'
testhg stat
testhg loc -r tip


produces for me


killed!
Mercurial Distributed SCM (version 6dab29f6df37)

Copyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
stat #1
? build/y
stat #2
? build/y
stat #3
M .hgignore
? build/y
stat #4
? build/y
stat #5
? build/y
stat #6
? build/y
? build/z
.hgignore
Comment 9 Matt Mackall 2009-06-20 10:29 UTC
Merged with issue1703
Comment 10 Nicolas Dumazet 2009-11-13 00:08 UTC
re-opening, for easier tracking.
Comment 11 Jesse Glick 2009-11-16 16:22 UTC
Still broken in Hg 1.4. I think this should be mentioned in
http://mercurial.selenic.com/wiki/WhatsNew#extensions where it says "should
now be quite stable", as I think this is a serious issue that renders the
INotify extension useless.

Note: if you replace '^build$' by '^build' then the ignore list works. But
this is in contrast to Hg's normal behavior, which treats ignorance of a
directory as implying ignorance of its contents. Demonstration:

---%<--- test
#!/bin/sh
cd /tmp
killall hg
sleep 1
rm -rf hg-inotify-test
hg init hg-inotify-test
cd hg-inotify-test
echo '^build$' > .hgignore
hg ci -m ignorelist -A
hg log
mkdir build
touch build/x
touch build/y
echo 'stat #1'
hg stat
touch .hgignore
echo 'stat #2'
hg stat
killall hg
sleep 1
echo 'stat #3'
hg stat
---%<--- actual output (inotify enabled, Hg 1.4, Ubuntu)
adding .hgignore
stat #1
A .hgignore
? build/x
? build/y
stat #2
A .hgignore
? build/x
? build/y
stat #3
---%<--- expected output (as with inotify disabled)
adding .hgignore
changeset:   0:...
tag:         tip
user:        ...
date:        ...
summary:     ignorelist

stat #1
stat #2
stat #3
---%<---

Note that even worse than the previously reported bug, 'hg commit' is
silently doing nothing!
Comment 12 Nicolas Dumazet 2009-11-17 02:03 UTC
I don't know who flagged inotify as quite stable. That might be a bit
premature. I'd love to pass the standard inotify tests with inotify
activated before spreading around the word that it's stable.

I edited the release note.
Comment 13 Renato Cunha 2010-07-20 12:00 UTC
Changeset db9d16233787 <http://selenic.com/repo/hg/rev/db9d16233787>
hopefully implements a fix for this bug. Marking as 'testing'.
Comment 14 Jesse Glick 2010-08-13 08:10 UTC
Seems fixed in 1.6.2, at least in a simple test.
Comment 15 Bugzilla 2012-05-12 08:46 UTC

--- Bug imported by bugzilla@serpentine.com 2012-05-12 08:46 EDT  ---

This bug was previously known as _bug_ 884 at http://mercurial.selenic.com/bts/issue884