Further improve handling of symlink targets/deps.
In commit redo-0.11-4-g34669fb, we changed os.stat into os.lstat to avoid false positives in the "manual override" detector: a .do file that generates $3 as a symlink would trigger manual override if the *target* of that symlink ever changed, which is incorrect. Unfortunately using os.lstat() leads to a different problem: if X depends on Y and Y is a symlink to Z, then X would not be rebuilt when Z changes, which is clearly wrong. The fix is twofold: 1. read_stamp() should change on changes to both the link itself, *and* the target of the link. 2. We shouldn't mark a target as overridden under so many situations. We'll use *only* the primary mtime of the os.lstat(), not all the other bits in the stamp. Step 2 fixes a few other false positives also. For example, if you 'cp -a' a whole tree to another location, the st_ino of all the targets will change, which would trigger a mass of "manual override" warnings. Although a change in inode is sufficient to count an input as having changed (just to be extra safe), it should *not* be considered a manual override. Now we can distinguish between the two. Because the stamp format has changed, update the SCHEMA_VER field. I should have done this every other time I changed the stamp format, but I forgot. Sorry. That leads to spurious "manually modified" warnings after upgrading redo.
This commit is contained in:
parent
69890d0c57
commit
672b748394
9 changed files with 129 additions and 44 deletions
|
|
@ -147,7 +147,7 @@ class BuildJob:
|
|||
newstamp = sf.read_stamp()
|
||||
if (sf.is_generated and
|
||||
newstamp != state.STAMP_MISSING and
|
||||
(sf.stamp != newstamp or sf.is_override)):
|
||||
(sf.is_override or state.detect_override(sf.stamp, newstamp))):
|
||||
state.warn_override(_nice(t))
|
||||
if not sf.is_override:
|
||||
warn('%s - old: %r\n' % (_nice(t), sf.stamp))
|
||||
|
|
@ -345,7 +345,8 @@ class BuildJob:
|
|||
sf.is_override = False
|
||||
if sf.is_checked() or sf.is_changed():
|
||||
# it got checked during the run; someone ran redo-stamp.
|
||||
# update_stamp would call set_changed(); we don't want that
|
||||
# update_stamp would call set_changed(); we don't want that,
|
||||
# so only use read_stamp.
|
||||
sf.stamp = sf.read_stamp()
|
||||
else:
|
||||
sf.csum = None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue