Replacing a directory with a symlink fails after status

Bug #174027 reported by Matthew Z Haralovich
2
Affects Status Importance Assigned to Milestone
Bazaar
Fix Released
Medium
Robert Collins

Bug Description

The following script breaks with 1.0~rc1-3bazaar1. Somehow the problem only occurs when status is called before the second commit.

#!/bin/bash

bzr init
mkdir red
mkdir red/green
touch red/green/blue
touch red/green/yellow
bzr add
bzr commit -m "first\!"
rm red/ -rf
ln -s /tmp red
bzr status
bzr commit -m "Changed red to a link."

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

Just to follow up, this gives me:
Committing to: /Users/jameinel/dev/,tmp/foobar/
modified red
deleted red/green
deleted red/green/blue
deleted red/green/yellow
bzr: ERROR: dirstate: inconsistent delta, with tree 0. 'red/green/yellow' 'yellow-20071204222254-c1dyqoauqny7znz5-4'

If I look closely at the dirstate file just before the commit, (after status) it has noticed that 'red' is a symlink, and updated its node to mark it as such.

But then it thinks that red/green is still an existing directory (because you didn't do 'bzr rm red' to indicate otherwise).

At that point the dirstate claims that:

red => symlink
red/greed => directory
red/green/blue => file
red/green/yellow => file

So we need to think a little about how to fix this. Possible problems are:

bzr init
mkdir -p red red/green
touch red/green/blue red/green/yellow
bzr add
bzr commit -m "init"

At this point if you did:
mv red other
ln -s other red

At that point, you really want to run "bzr mv --after red other"
to let us know that red was actually renamed, and not just transformed into a symlink.

If you ran 'bzr status' and we noticed it turn into a symlink, and then auto-removed the children, the mv would not see that the child files were renamed as well, because they would have already been marked as deleted.

Or put another way, doing:

mv red other
ln -s other red
bzr status
#oops
rm red
mv other red
bzr status

Should end up as a no-op (no changes).

But that does mean in the short term the dirstate would consider itself "invalid" because it has files that are children of a node which is not a directory. (note the same thing happens if you mv red other; touch red).

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

I think this dirstate bug has now been fixed; could someone please retest this with 1.3 or 1.4dev?

Changed in bzr:
importance: Undecided → Medium
status: New → Incomplete
Revision history for this message
John A Meinel (jameinel) wrote :

The original bug listed here has been fix, but now it is triggering:
bzr: ERROR: An inconsistent delta was supplied involving 'red/green/yellow', 'yellow-20080424202523-kuhw22sdsabg3g9i-4'
reason: This was marked as a real delete, but the WT state claims that it still exists and is versioned.

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

I should mention that it does report the files as deleted first:
% bzr commit -m "Changed red to a link"
Committing to: /home/jameinel/dev/,tmp/174027/
modified red
deleted red/green
deleted red/green/blue
deleted red/green/yellow
bzr: ERROR: An inconsistent delta was supplied involving 'red/green/yellow', 'yellow-20080424202523-kuhw22sdsabg3g9i-4'
reason: This was marked as a real delete, but the WT state claims that it still exists and is versioned.

Changed in bzr:
status: Incomplete → Fix Released
assignee: nobody → Robert Collins (lifeless)
milestone: none → 1.18rc1
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

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