[issue1473] Update fails to adjust dirstate mode info

Tom Karzes mercurial-bugs at selenic.com
Fri Jan 16 05:16:59 UTC 2009


New submission from Tom Karzes <Tom.Karzes at magnumsemi.com>:

This bug is related to the one I reported in issue 1456, but occurs
independently of it.  I've created a test case that fails in versions 1.0.1
through 1.1.2, as well as a recent hg-stable, mercurial-a679bd371091, which
contains the fix for issue 1456.

The problem is that the mode info in the dirstate file isn't always adjusted
properly after an update which changes the mode bits of the file in question. 
As a result, "hg status" sometimes reports files as being modified when in fact
they have not been (including their mode bits), and if the mode bits are in fact
changed to match the incorrect dirstate info, "hg status" sometimes fails to
report the file as changed when in fact it should.  In the former case, where
"hg status" reports false changes, an "hg commit" will create change sets that
contain no files.

The following scenario will reproduce the bug in versions 1.0.1 through
mercurial-a679bd371091 of Mercurial.  This example was run on Redhat Linux, and
my umask value was 022.

First, create a repository, and cd to it:

    % hg init testrepo
    % cd testrepo

Now create a file foo.txt, and add and commit it.  Its protection is 644:

    % echo foo > foo.txt
    % hg add foo.txt
    % hg ci -m 'Added foo.txt'

Now change the protection to 755 and commit it as a new change set:

    % chmod 755 foo.txt
    % hg ci -m 'Changed mode of foo.txt'

Now remove it, and update to rev 0:

    % rm foo.txt
    % hg update -r 0
    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
    %

Age the change, to make it trust its cached info:

    % sleep 3

At this point we're updated to rev 0, and the contents of foo.txt are modified.
 Everything is still ok:

    % ls -l foo.txt
    -rw-r--r--  1 tkarzes vpgrp 4 Jan 15 19:17 foo.txt
    % hg debugstate
    n   0         -1 unset               foo.txt
    %

Now we do an "hg status".  This correctly reports no changes, and as a side
effect it saves the mode information in dirstate:

    % hg status foo.txt
    % hg debugstate
    n 644          4 2009-01-15 19:17:03 foo.txt
    %

Now change the protection to 755.  This matches the protection in rev 1, but
it's a change from rev 0, which is our parent.  Everything is still ok, and
dirstate is unchanged:

    % chmod 755 foo.txt
    % ls -l foo.txt
    -rwxr-xr-x  1 tkarzes vpgrp 4 Jan 15 19:17 foo.txt
    % hg status foo.txt
    M foo.txt
    % hg debugstate
    n 644          4 2009-01-15 19:17:03 foo.txt
    %

Now we hit the bug by doing an "hg update".  This should update dirstate, but it
doesn't.  As a result, it thinks the file's protection has changed, but in fact
it matches the protection it has in its new parent (rev 1):

    % hg update
    0 files updated, 0 files merged, 0 files removed, 0 files unresolved
    % ls -l foo.txt
    -rwxr-xr-x  1 tkarzes vpgrp 4 Jan 15 19:17 foo.txt
    % hg debugstate
    n 644          4 2009-01-15 19:17:03 foo.txt
    % hg status
    M foo.txt
    %

(If you then proceed to change the protection to 644, so that it matches the
dirstate mode info but differs from the info in rev 0, "hg status" will fail to
report the change.)

----------
messages: 8411
nosy: tkarzes
priority: bug
status: unread
title: Update fails to adjust dirstate mode info
topic: merge, update

____________________________________________________
Mercurial issue tracker <mercurial-bugs at selenic.com>
<http://www.selenic.com/mercurial/bts/issue1473>
____________________________________________________




More information about the Mercurial-devel mailing list