[issue3081] New files lose 'added' state when updating across a directory rename

Greg Ward bugs at mercurial.selenic.com
Tue Nov 1 17:03:46 CDT 2011


New submission from Greg Ward <greg-hg at gerg.ca>:

We have a directory that was renamed in two directions: some of the files
moved into a "library" dir and some moved into a "webapp" dir. If I add a
new file on an old branch (before the split), and then update to a new
branch (post split), the new file remains in my working dir and gets moved
... but it loses its "added" status. It becomes "normal", so it's not seen
by "hg status" or "hg commit".

The effect of this is that I can still build on my machine, but I commit a
bad changeset that does not build.

I'm unable to come up with a small reproduction for this, so here are
real-life examples from our production source tree. Apologies for the long
filenames.

First, some context.

The old branch contains these files:

 PACS/SeriesMover/servlet/SeriesMover/Constants.java
 PACS/SeriesMover/servlet/SeriesMover/DicomExternQueryServiceFactory.java
 [...]
 PACS/SeriesMover/servlet/SeriesMover/SeriesMoverServlet.java
 PACS/SeriesMover/servlet/SeriesMover/SeriesMoverTester.java
 PACS/SeriesMover/servlet/SeriesMover/TestAll.java
 PACS/SeriesMover/servlet/SeriesMover/TestSeriesMover.java
 PACS/SeriesMover/servlet/SeriesMover/UserData.java

Some of these are library classes used by other apps, and some of them are a
standalone web service. Hence the refactoring.

Newer branches, post-split, look like this:

 PACS/SeriesMoverLibrary/source/com/intelerad/lib/seriesmover/Constants.java
 PACS/SeriesMoverLibrary/source/com/intelerad/lib/seriesmover/DicomExternQueryServiceFactory.java
 [...]
 PACS/SeriesMoverLibrary/source/com/intelerad/lib/seriesmover/TestAll.java
 PACS/SeriesMoverLibrary/source/com/intelerad/lib/seriesmover/TestSeriesMover.java
 PACS/SeriesMoverLibrary/source/com/intelerad/lib/seriesmover/UserData.java
 [...]
 Web/SeriesMover/source/com/intelerad/seriesmover/SeriesMoverContextListener.java
 Web/SeriesMover/source/com/intelerad/seriesmover/SeriesMoverServlet.java

So if I add a new file on the old branch, it's not clear to me where it's
going to wind up after a merge. I imagine Mercurial takes an educated guess
and follows the herd in such cases, which argues for moving the new file to
PACS/SeriesMoverLibrary/source/com/intelerad/lib/seriesmover. OK, let's see
what happens.

Add a new file *on the old branch*:

  $ hg update -C PACS-4-3-1
  4721 files updated, 0 files merged, 1777 files removed, 0 files unresolved
       
  $ echo newstuff > PACS/SeriesMover/servlet/SeriesMover/NewFile.java
  $ hg add
  adding PACS/SeriesMover/servlet/SeriesMover/NewFile.java
  $ hg status
  A PACS/SeriesMover/servlet/SeriesMover/NewFile.java
  $ hg debugstate | grep NewFile
  a   0         -1 unset              
PACS/SeriesMover/servlet/SeriesMover/NewFile.java

No surprises there.

Now update to the new branch. Here's what I expect to happen:

  * NewFile.java gets moved <somewhere> -- I would expect Mercurial to give
this 
    its best try, but no worries if it gets it wrong. It's ambiguous!
  * NewFile.java remains in state "A" *wherever it winds up*
  * the content of NewFile.java is unaffected by the update

Here's what actually happens:

  $ hg update default
  5964 files updated, 0 files merged, 535 files removed, 0 files unresolved
                                                                 
  $ hg status 
  $ hg debugstate | grep NewFile
  n 660          9 2011-11-01 17:57:14
PACS/SeriesMoverLibrary/SeriesMover/NewFile.java
  $ cat PACS/SeriesMoverLibrary/SeriesMover/NewFile.java
  newstuff

So Mercurial guessed wrong about the new directory name. That's too bad, but
no big deal. It's NOT the bug I'm reporting here.

The real bug is the state change: the file *was* in state 'added', but now
it is 'normal'. So neither status nor commit see it.

  $ hg commit -m"add NewFile.java"
  nothing changed

In reality, this new file was combined with modifications, so the build
broke even though it worked fine in the original developer's working dir. Yuck.

I have reproduced this in our production source tree with Mercurial 1.5.4,
1.8.4, 1.9.3, and 
2.0-rc+105-87248de09135. It's not a recent regression.

No luck shrinking it down to a bite-sized test case. ;-(

----------
messages: 17917
nosy: gward
priority: bug
status: unread
title: New files lose 'added' state when updating across a directory rename

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


More information about the Mercurial-devel mailing list