Can't add file in subdir if changing subdir from file to dir (traceback if entry.name in parent.children)

Bug #205636 reported by Vincent Ladeuil
2
Affects Status Importance Assigned to Milestone
Bazaar
Fix Released
High
Martin Pool
bzr Upload plugin
Won't Fix
High
Unassigned

Bug Description

This may or not be related to #192859 or #173944.

Doing (simplified to exhibit the bug):

rm -fr bug
mkdir bug
cd bug
bzr init .
echo foo > mutable
bzr add mutable
bzr commit -m 'add mutable as a file'
rm mutable
mkdir mutable

# The point is to change a file into a dir
echo bar > mutable/file
# The following fails with a traceback
bzr add mutable/file

# But ! Doing the following works
bzr st
bzr add mutable/file
bzr commit -m 'add file under mutable'

Shell script attached.

Revision history for this message
Vincent Ladeuil (vila) wrote :
Vincent Ladeuil (vila)
Changed in bzr:
importance: Undecided → High
Revision history for this message
Vincent Ladeuil (vila) wrote :

I should have mentioned that I encounter the problem when using bzrlib, not bzr from the command line.

I.e. there is an ugly time dependency hidden somewhere.

Changed in bzr-upload:
importance: Undecided → High
status: New → Confirmed
Changed in bzr:
status: New → Confirmed
Revision history for this message
Vincent Ladeuil (vila) wrote :

Still occuring with bzr 1.5dev

<cough> Can someone have at least a look ? I don't know enough of dirstate internals to do it myself but I've the feeling that it is strongly related to dirstate.

Revision history for this message
John A Meinel (jameinel) wrote :

I don't believe it is Dirstate, I believe it is actually our Inventory logic.

Well, depends on how you want to argue it. Specifically

'bzr status' uses 'iter_changes()' which is written to detect changes on disk, like someone changing a file into a directory, etc. As such, doing "bzr status" rewrites portions to note that it is actually a directory now.

'bzr add' doesn't use iter_changes(), and wasn't written with the ability autodetect other pieces changing kind.

This is a bit of fallout from way back when we decided to let objects change kind without explicit notification. (You used to have to 'rm+add' if you had an object change kind.)

How critical is this bug for you? I realize it is present, I'm not 100% sure what it would take to fix.

IMO, there is a simple workaround "bzr status" or a rm+add pair. (It is very arguable that a file becoming a directory should not preserve the same file id. Because it is no longer the same "object". For example, a patch to that file will certainly not apply to the directory, etc. I believe we allow it for simplicity, to not force people to rm+add, but in the internal model, it is pretty ugly.)

Revision history for this message
Vincent Ladeuil (vila) wrote :

I first encounter this bug in the bzr-upload plugin test suite (see test_change_file_into_dir) where after doing self.tree.commit() I ended up with a tree still having uncommited changes.

Since the point of the test is to commit without using 'bzr st' nor a 'rm+add' pair, your proposed work-around does not suit me :-(

From your explanation, I'm under the impression that there are in fact several bugs here...

Revision history for this message
Matthew Fuller (fullermd) wrote : Re: [Bug 205636] Re: Can't add file in subdir if changing subdir from file to dir (traceback if entry.name in parent.children)

On Mon, May 05, 2008 at 01:35:36PM -0000 I heard the voice of
John A Meinel, and lo! it spake thus:
>
> (It is very arguable that a file becoming a directory should not
> preserve the same file id. Because it is no longer the same
> "object". For example, a patch to that file will certainly not apply
> to the directory, etc.

OTOH, a symlink turning into a file/directory (or vice versa) could
well be considered the same "object" afterward. So you could end up
having to special case which type changes are changes, and which are
rm/add's...

--
Matthew Fuller
<email address hidden>

Revision history for this message
John A Meinel (jameinel) wrote :

I disagree. If you have a patch to a file, and that file becomes a symlink, what do you do with the patch? Apply it to the target of the symlink? (And if that symlink points outside of the working tree?)

Similarly, if you have a directory, which becomes a symlink. And then a file is added into that directory. Where does the file show up in the new tree? Inside the target of the symlink?

I believe in both cases the concept of tracking the object by identity, the identity has actually changed.

Vincent, as such, I'm sure a lot of our logic doesn't handle objects changing kinds very well. It is honestly arguable whether we should even handle it in the first place. And most of it was written when we didn't even allow it. I believe the motivation for allowing it was for converting from Arch, where Arch could allow it.

Revision history for this message
Vincent Ladeuil (vila) wrote :

Sorry for not replying sooner John.

As far as bzr-upload is concerned, the bug is not relevant anymore so I close it there.

Changed in bzr-upload:
status: Confirmed → Won't Fix
Revision history for this message
Parth Malwankar (parthm) wrote :

Looks like this bug is fixed. I will go ahead and mark it as such.

[tmp]% mkdir dirbug
[tmp]% cd dirbug
[dirbug]% ls
[dirbug]% bzr init
Created a standalone tree (format: 2a)
[dirbug]% echo foo > mutable
[dirbug]% bzr add
adding mutable
[dirbug]% bzr ci -m "mutable file"
Committing to: /home/parthm/tmp/dirbug/
added mutable
Committed revision 1.
[dirbug]% rm mutable
[dirbug]% bzr st
removed:
  mutable
[dirbug]% mkdir mutable
[dirbug]% echo bar > mutable/file
[dirbug]% bzr add mutable/file
adding mutable/file
[dirbug]% bzr st
added:
  mutable/file
kind changed:
  mutable (file => directory)
[dirbug]% bzr ci -m "added file"
Committing to: /home/parthm/tmp/dirbug/
modified mutable
added mutable/file
Committed revision 2.
[dirbug]% cd ..

[tmp]%
[tmp]% sh -e bug3.sh
+ rm -fr bug
+ mkdir bug
+ cd bug
+ bzr init .
Created a standalone tree (format: 2a)
+ echo foo
+ bzr add mutable
adding mutable
+ bzr commit -m add mutable as a file
Committing to: /home/parthm/tmp/bug/
added mutable
Committed revision 1.
+ rm mutable
+ mkdir mutable
+ echo bar
+ bzr add mutable/file
adding mutable/file
+ bzr st
added:
  mutable/file
kind changed:
  mutable (file => directory)
+ bzr add mutable/file
+ bzr commit -m add file under mutable
Committing to: /home/parthm/tmp/bug/
modified mutable
added mutable/file
Committed revision 2.
[tmp]%

Changed in bzr:
status: Confirmed → Fix Released
Revision history for this message
Martin Packman (gz) wrote :

Fixed by changes for bug 192859 so in all current bzr releases. We want some specific tests for this bug though I think.

Revision history for this message
Vincent Ladeuil (vila) wrote :

Digging the bzr-upload history around the time I filed this bug should give some possible tests (if not directly re-usable, I distinctly remember one that was reproducing the issue).

Revision history for this message
Martin Pool (mbp) wrote :

According to the discussion in bug 662254 this is still present in 2.1.2.

Changed in bzr:
status: Fix Released → Confirmed
Revision history for this message
Martin Packman (gz) wrote :

Sorry about that, there's actually a variation of this bug that is indeed not fixed in 2.1.2 which bug 251864 covers. I've updated the duplicates to point to the right thing - really this time!

Changed in bzr:
assignee: nobody → Martin Pool (mbp)
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.