hg status and intermediate file changes

Jason Harris jason at jasonfharris.com
Thu Feb 24 07:53:03 CST 2011


On Feb 24, 2011, at 2:09 PM, Mads Kiilerich wrote:

> On 02/24/2011 11:18 AM, Jason Harris wrote:
>> Hi All,
>> 
>> One of my MacHg users and code contributors Eugene Golushkov posted the following issue to me:
>> 
>> https://bitbucket.org/jfh/machg/issue/200
>> 
>> Towards the end of this issue he uncovered what seems to be a problem in core Mercurial:
>> 
>> If I run:
>> 
>> hg init bob
>> cd bob
>> echo one>  theFile
>> hg commit -A -m "initial"
>> echo two>  theFile
>> hg commit -m "secondary"
>> echo one>  theFile
>> hg commit -m "change back"
>> hg status --rev 0:2
>> 
>> this yields the result
>> 
>> M theFile
>> 
>> the status command according to the documentation states:
>>  "If two revisions are given, the differences between them are shown."
>> 
>> So status is reporting 'theFile' as of version 2 is different than that as of version 0, Whereas if you actually run the diff
>> 
>> hg diff --rev 0:2
>> 
>> there are no differences whatsoever.
> 
> I think that is intentional and correct behavior.
> 
> The status command looks at the meta information, not at the file content. The file _was_ modified, and the difference between files with same content do in some cases matter.

When would this matter?

> They have different history and are thus different.

Whats the use case of when you ask for status --rev 334:350 that you actually wanted to know if there was any changes to the files in between these revisions...? The very large use case I imagine for a user requesting the status between different revisions, is they want to compare the states of the files at the start and at the end to see what was the net difference to the files. When would users ever care that they changed in between? If they want to see the actual differences then they use diff... But to see which files differ they use status.

> Status should only look at content when it is reporting relative to the working directory, in which case it has to predict what commit would do next.
> 
> Diff will however look at the content (but only where the meta information says that it is relevant).
> 
> The wording in the help could perhaps be rephrased so it doesn't give the wrong association to the diff command. Perhaps something like "the changes between them" or "the status changes between them"?

But the wording in the help makes perfect sense :)

Also right now the "changed" status is inconsistent with the "added / removed" status. For instance if I add and then remove and then re-add a file and then do the status difference from the start to the end, since the file was added and then removed will it show as added? or removed? or both? Since certainly it has been added removed and re-added in the interim...

Ie evaluate:

hg init bob
cd bob
echo one>  theFile
hg commit -A -m "initial"
echo two>  theFile
hg commit -m "secondary"
echo one>  theFile
hg commit -m "change back"
echo other>  secondFile
hg commit -A -m "adding secondFile"
rm secondFile
hg commit -A -m "removing secondFile"
echo other>  secondFile
hg commit -A -m "readding secondFile"
hg status --rev 0:2
hg status --rev 3:5

But the output of the hg status --rev 3:5 doesn't report anything about adding or removing.

Ie the output for me is:

[Bolt:~/test/bob] bob 5(5) ⌘ hg status --rev 0:2
M theFile
[Bolt:~/test/bob] bob 5(5) ⌘ hg status --rev 3:5
[Bolt:~/test/bob] bob 5(5) ⌘ hg status --rev 0:5
M theFile
A secondFile
[Bolt:~/test/bob] bob 5(5) ⌘ hg status --rev 4:5
A secondFile
[Bolt:~/test/bob] bob 5(5) ⌘ hg status --rev 3:4
R secondFile



>> Why this is bitting us is that after having eg two branches and doing appropriate transplants and merges etc, it's really nice to compare one branch relative to another and know what are the real differences. If there are lots of false positives like this where it looks like there is a difference but in fact there isn't, ... well ...  it's much harder to sift through the files.
>> 
>> In any case Eugene provided the fix. (I ran it through the test suite and everything seemed to pass although there was a lot of noise in the test suite since some tests are failing for me. Very likely it's my configuration though since eg the cvs tests have always failed for me, etc...)
>> 
>> His patch is as follows:
>> 
>> # HG changeset patch
>> # User jfh<jason at jasonfharris.com>
>> # Date 2011-02-24 11:10:08 +0100
>> # Node ID 75323eb95610231e671d1b200c32d6205594b7a7
>> # Parent  acbe171c8fbe9b789057f84fb962a9c2a966a787
>> make status --rev star:finish only report true changes and not intermediate changes
>> 
>> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
>> --- a/mercurial/localrepo.py
>> +++ b/mercurial/localrepo.py
>> @@ -1223,7 +1223,7 @@
>>                  if fn in mf1:
>>                      if (mf1.flags(fn) != mf2.flags(fn) or
>>                          (mf1[fn] != mf2[fn] and
>> -                         (mf2[fn] or ctx1[fn].cmp(ctx2[fn])))):
>> +                         ctx1[fn].cmp(ctx2[fn]))):
>>                          modified.append(fn)
>>                      elif listclean:
>>                          clean.append(fn)
>> 
>> Can someone confirm this is the right way to fix this? If so I will send the patch formally, along with a change to the test suite to catch this case.
> 
> I think this line of code is dead, and there shouldn't be a cmp here at all.
> 
> See http://www.selenic.com/pipermail/mercurial-devel/2011-February/028488.html

(I'd just like to point out for the other observers, that the link just quoted above was actually done by Mads today in response to my email. (At first I thought it was some historical precedent that had actually been previously fixed or something, and wasn't just in response to my first email...) So the topic is still in flux...)

So in conclusion, basically I can see *lots* of upside / use of status showing the differences between start and end revisions. What are the upsides / use of  status showing the intermediate changes?

If we keep it the way it is how do we actually  see "If two revisions are given, the differences between them are shown." would we have an option --true-changes or something to status? Maybe --real-changes yuck... 

Cheers,
  Jas


More information about the Mercurial-devel mailing list