Bug 4381 - Changing the executable bit of "filename" during merge gives missing entries in "hg log filename"
Summary: Changing the executable bit of "filename" during merge gives missing entries ...
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: Mercurial (show other bugs)
Version: 2.8.2
Hardware: PC Linux
: normal bug
Assignee: Bugzilla
URL: https://bitbucket.org/ezio_melotti/hg...
Keywords: easy
Depends on:
Blocks:
 
Reported: 2014-09-21 08:01 UTC by Ezio Melotti
Modified: 2015-01-22 15:04 UTC (History)
3 users (show)

See Also:
Python Version: ---


Attachments
sh file to create the test repo (558 bytes, application/x-shellscript)
2014-09-21 08:01 UTC, Ezio Melotti
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ezio Melotti 2014-09-21 08:01 UTC
Created attachment 1792 [details]
sh file to create the test repo

I noticed that one of the files in my repo wasn't executable anymore, and did "hg log filename" to find out which changeset removed the +x bit, but the relevant changeset was missing from the output.

"hg help log" doesn't mention anything about changesets that altered the mode, but since they affect the file I would expect them to be included.

I confirmed this on 2.8.2, but it's been confirmed on #mercurial that the issue seems to affect Mercurial 3+.

I created a test repo, and the issue can be reproduced by doing:
hg clone https://bitbucket.org/ezio_melotti/hg-log-bug
hg log test.txt --template '{rev}:{node} {desc}'
I also attached a .sh file that can be used to create the repo locally (untested, I just copied the commands I used to create the test repo).

Here the output doesn't include the two changesets that altered the file mode, and I would expect them to be there:

$ hg log test.txt --template '{rev}:{node} {desc}\n'
5:816136756249f5bcca8cc8414178f9ea1f4d527c Add a third line to the test file.
3:2976a8c5bc09f9bf1a8b045e15e2e3f6b7562b48 Add another line to the test file.
1:5f34d45a82eb5621d1d3116f7b4031c828188dd0 Add a line to the test file.
0:61d7d36c80d58be7f2f24e5b8a733b944c7ee865 Add test file.


Additionally, if I try
hg log --removed test.txt --template '{rev}:{node} {desc}\n'
all the changesets are showed (including the two that changed the file mode), even though none of them removed the only file in the repo:

$ hg log --removed test.txt --template '{rev}:{node} {desc}\n'
5:816136756249f5bcca8cc8414178f9ea1f4d527c Add a third line to the test file.
4:7e5702446f0009ba96d14d103373b9ae0e8a98af Restore file mode.
3:2976a8c5bc09f9bf1a8b045e15e2e3f6b7562b48 Add another line to the test file.
2:bbe84a7cb402d3dd583579b6583a154d574e6ac5 Change file mode.
1:5f34d45a82eb5621d1d3116f7b4031c828188dd0 Add a line to the test file.
0:61d7d36c80d58be7f2f24e5b8a733b944c7ee865 Add test file.

This might be a separate bug (let me know if I need to report it separately).


In my repo I also noticed another possible issue.  The file mode got changed during a merge and restored afterwards with a regular commit.  Even if I use hg log --removed, the merge cset is not included.  I haven't tried reproducing this on a test repo.
FWIW the repo is https://bitbucket.org/italianmarssociety/v-eras-blender/ (repo size is about 150-200MB), the file is test/testtango, the changesets that changed the mode are 0ec67db (the merge) and 047589d (the regular commit).  This is the output I get:

# 0ec67db an 047589d are missing
$ hg log --git test/testtango --template '{rev}:{node} {desc}\n'
22:2a4fb8e25775b41c77b94ecf3bae24b4386f308f Add tests for unpolled attributes.
20:f818f8d5d77581c8c555467031a9f58ba2ca4633 Fix test_tango.py.
10:88ca43cea3d332510b8c9c57c7a5ae3ec8bc5cd2 Add tests for Tango and a script to patch PyTango3.

# only 047589d is included with --remove, 0ec67db is still missing
$ hg log --git --removed test/testtango --template '{rev}:{node} {desc}\n'
57:047589dc07b37edeb17c379936d233fc51b9acf3 Restore modes of testtango that got accidentally changed in 0ec67db3bcca.
22:2a4fb8e25775b41c77b94ecf3bae24b4386f308f Add tests for unpolled attributes.
20:f818f8d5d77581c8c555467031a9f58ba2ca4633 Fix test_tango.py.
10:88ca43cea3d332510b8c9c57c7a5ae3ec8bc5cd2 Add tests for Tango and a script to patch PyTango3.
Comment 1 Faheem Mitha 2014-09-21 08:32 UTC
Here is a repro recipe. I believe this captures the essential features of
the bug.

Summary: in a merge, change permissions of a file during the merge. Change it
back later. In the test script, I added the same empty file twice, backing up the second time to the null cset.

The following odd things happen. First, `hg log -vG filename` only shows one of 4 csets. Second. --removed makes 3 of the 4 csets show up. There seems no reason why --removed should make any difference.

Weird stuff. Apparently a corner case nobody has ever hit before,
or at least, never reported.

                                                          Faheem

#############################################################
Reproduction script
#############################################################
#!/bin/sh

hg init test
cd test
touch foo
stat -c "%a %n" foo
hg add foo
hg ci -m "add foo"
hg up null
touch foo
hg add foo
hg ci -m "add foo again"
hg merge -r 0
chmod ugo+x foo
# stat -c "%a %n" foo
hg ci -m "branch merge, changing permissions of foo to 755"
chmod ugo-x foo
# stat -c "%a %n" foo
hg ci -m "changing permissions of foo back to 644"

###########################################################
Running log on the resulting repository.
###########################################################

faheem@orwell:~/mode/test$ hg log -vG
@  changeset:   3:35e689070f3e
|  tag:         tip
|  user:        Faheem Mitha <faheem@faheem.info>
|  date:        Sun Sep 21 17:55:33 2014 +0530
|  files:       foo
|  description:
|  changing permissions of foo back to 644
|
|
o    changeset:   2:55e6a3637d94
|\   parent:      1:b428f2e6e2f2
| |  parent:      0:ce7896ecd896
| |  user:        Faheem Mitha <faheem@faheem.info>
| |  date:        Sun Sep 21 17:55:33 2014 +0530
| |  description:
| |  branch merge, changing permissions of foo to 755
| |
| |
| o  changeset:   1:b428f2e6e2f2
|    parent:      -1:000000000000
|    user:        Faheem Mitha <faheem@faheem.info>
|    date:        Sun Sep 21 17:55:33 2014 +0530
|    files:       foo
|    description:
|    add foo again
|
|
o  changeset:   0:ce7896ecd896
   user:        Faheem Mitha <faheem@faheem.info>
   date:        Sun Sep 21 17:55:33 2014 +0530
   files:       foo
   description:
   add foo

##########################################################

faheem@orwell:~/mode/test$ hg log -vG foo
o  changeset:   0:ce7896ecd896
   user:        Faheem Mitha <faheem@faheem.info>
   date:        Sun Sep 21 17:55:33 2014 +0530
   files:       foo
   description:
   add foo

############################################################

faheem@orwell:~/mode/test$ hg log -vG foo --removed
@    changeset:   3:35e689070f3e
|\   tag:         tip
| |  user:        Faheem Mitha <faheem@faheem.info>
| |  date:        Sun Sep 21 17:55:33 2014 +0530
| |  files:       foo
| |  description:
| |  changing permissions of foo back to 644
| |
| |
| o  changeset:   1:b428f2e6e2f2
|    parent:      -1:000000000000
|    user:        Faheem Mitha <faheem@faheem.info>
|    date:        Sun Sep 21 17:55:33 2014 +0530
|    files:       foo
|    description:
|    add foo again
|
|
o  changeset:   0:ce7896ecd896
   user:        Faheem Mitha <faheem@faheem.info>
   date:        Sun Sep 21 17:55:33 2014 +0530
   files:       foo
   description:
   add foo
Comment 2 Faheem Mitha 2014-09-21 08:49 UTC
Actually, the first part at least can be reproduced without any mode change. Maybe it's that linkrev bug again.

#######################

hg init test
cd test
touch foo
stat -c "%a %n" foo
hg add foo
hg ci -m "add foo"
hg up null
touch foo
hg add foo
hg ci -m "add foo again"
hg merge -r 0
hg ci -m "branch merge"

#######################

faheem@orwell:~/mode/test$ hg log -v
changeset:   2:cf5629ef3de1
tag:         tip
parent:      1:357cbbd5c7d0
parent:      0:28978a1fb659
user:        Faheem Mitha <faheem@faheem.info>
date:        Sun Sep 21 18:17:00 2014 +0530
description:
branch merge


changeset:   1:357cbbd5c7d0
parent:      -1:000000000000
user:        Faheem Mitha <faheem@faheem.info>
date:        Sun Sep 21 18:17:00 2014 +0530
files:       foo
description:
add foo again


changeset:   0:28978a1fb659
user:        Faheem Mitha <faheem@faheem.info>
date:        Sun Sep 21 18:17:00 2014 +0530
files:       foo
description:
add foo

################################################

faheem@orwell:~/mode/test$ hg log -vG foo
o  changeset:   0:28978a1fb659
   user:        Faheem Mitha <faheem@faheem.info>
   date:        Sun Sep 21 18:17:00 2014 +0530
   files:       foo
   description:
   add foo
Comment 3 Faheem Mitha 2014-09-21 08:50 UTC
Addendum (to the last comment):

faheem@orwell:~/mode/test$ hg log -vG foo --removed 
o  changeset:   1:357cbbd5c7d0
   parent:      -1:000000000000
   user:        Faheem Mitha <faheem@faheem.info>
   date:        Sun Sep 21 18:17:00 2014 +0530
   files:       foo
   description:
   add foo again


o  changeset:   0:28978a1fb659
   user:        Faheem Mitha <faheem@faheem.info>
   date:        Sun Sep 21 18:17:00 2014 +0530
   files:       foo
   description:
   add foo
Comment 4 Matt Mackall 2014-09-21 09:33 UTC
Works as intended.

We speed up file-level logging by only showing changes that result in a file-level delta being recorded. That means we can avoid looking at every single changelog revision, which can be 10-1000 times faster on non-trivial repos.

That performance difference is important to some people, so we won't be changing the behavior here.

This means we miss some things that don't involve new deltas:

- duplicate changes on nearby branches
- removals
- changes of exec bit

The --removed switch means "use the slow path that shows even things that don't actually result in a file delta, like removals"

This is almost completely documented in 'hg help log', except for the mention of exec bits:

    Note:
       for performance reasons, log FILE may omit duplicate changes made on
       branches and will not show deletions. To see all changes including
       duplicates and deletions, use the --removed switch.

So I'm marking this as an easy documentation bug.

(The merge piece is indeed a separate bug: you'll note that hg log -v of your merge doesn't mention your file in the files list.. which means even hg log --removed can't find it. I've created bug 4382 to track it.)
Comment 5 HG Bot 2014-09-22 17:15 UTC
Fixed by http://selenic.com/repo/hg/rev/abf4e98b8ff2
Matt Mackall <mpm@selenic.com>
help: mention mode in hg log --removed help (issue4381)

(please test the fix)
Comment 6 Matt Mackall 2015-01-22 15:04 UTC
Bulk testing -> fixed