Behavior of 'rm' and 'mv' under bazaar

Neil Martinsen-Burrell nmb at wartburg.edu
Wed Oct 13 17:31:59 BST 2010


On 2010-10-13 09:45 , Tom Browder wrote:
> On Thu, Sep 30, 2010 at 06:13, Tom Browder<tom.browder at gmail.com>  wrote:
>> On Thu, Sep 30, 2010 at 01:24, Eric Siegerman<lists08-bzr at davor.org>  wrote:
>>> On Thu, 2010-09-30 at 11:09 +1000, Ben Finney wrote:
>>>> That's right. An OS-level ‘rm’ or ‘mv’ is just another change Bazaar
>>>> will track; if you ‘bzr status’ then you'll see Bazaar notices when
>>>> files aren't there any more, and will record that fact when you
>
> I've had a little more practical bzr experience now, and the rm thing
> is still a little unsettling.  However, I think this work flow will
> work from my experiments (please confirm):
>
> I have a bzr rep:
>
> cd repo
>
> # hack on new files a, b, c
> bzr add a b c
> bzr ci -m"add new files"
>
> # hack on a and b
> bzr ci -m"mod files"
>
> # Time goes on for many revisions, file c is forgotten until
> # one day I inadvertently remove it with 'rm'.
> # I don't notice bzr's msg about c being removed on the
> # next commit.
> # Time goes on for many more revisions,
> # Sometime later I need file c and notice it's gone--panic!
> bzr log -v c
>
> I can see the revision where the file was removed, say 10.  Then I can do
>
>    bzr revert -r10 c
>
> And, voila!  There it is at its last committed state.

Here is the session I used to check this:

nmb at guttle[~/tmp]$ bzr init test
cd test
  Created a standalone tree (format: 2a)
nmb at guttle[~/tmp]$ cd test
nmb at guttle[~/tmp/test]$ touch a b c
nmb at guttle[~/tmp/test]$ bzr add
adding a
adding b
adding c
nmb at guttle[~/tmp/test]$ bzr ci -m1
Committing to: /Users/nmb/tmp/test/
added a
added b
added c
Committed revision 1.
nmb at guttle[~/tmp/test]$ bzr rm c
deleted c
nmb at guttle[~/tmp/test]$ bzr ci -m 'deleted c'
Committing to: /Users/nmb/tmp/test/
deleted c
Committed revision 2.
nmb at guttle[~/tmp/test]$ ls
a	b
nmb at guttle[~/tmp/test]$ bzr revert -r1 c
+N  c 

nmb at guttle[~/tmp/test]$ bzr st 

added:
   c

> I have lost any
> pending changes from the deletion, but the same thing happens with
> subversion.

Can you say more about what you mean by "pending changes from the 
deletion"?  If the file c is no longer present, how does it have any 
changes?

> And, importantly, no other files or directories are changed.
>
> But, and this is different from subversion, c is shown as a new file
> which MUST be committed if I want it in the current mainline.

This is true.  Relative to the previous revision, c is a new file.  The 
fact that there was a file named c in a previous revision isn't relevant 
to Bazaar.  In Bazaar, there is (currently) no way to indicate that the 
file c in this revision is the same as the file with the same name in a 
previous revision.  (Internally to Bazaar they have different file IDs.)

> (For this situation, it would be very handy to have a way to ask bzr
> for a list of removed files, perhaps an option to 'bzr log'.)

Given Bazaar's strong facilities for extensions, here is a very basic 
plugin that provides a --deleted format for log which shows only the 
deleted items.  Using my example above,

nmb at guttle[~/tmp/test]$ bzr log -v --deleted
Showing only deleted items (use with --verbose)
r2 deleted c
removed:
   c

Simply save the following as ~/.bzr/plugins/deleted_log_formatter.py and 
do ``bzr log -v --deleted``.
---
# Log formatter that only shows deleted files

"""Provide a log format that shows ONLY deleted items."""

from bzrlib.log import (LogFormatter,
                         log_formatter_registry,
                        )

class DeletedLogFormatter(LogFormatter):

     supports_diff = False
     supports_delta = True
     supports_merge_revisions = True

     def begin_log(self):
         self.to_file.write("Showing only deleted items (use with 
--verbose)\n")

     def log_revision(self, revision):
         if revision.delta is not None and len(revision.delta.removed) > 0:
             self.to_file.write('r%s %s\n' % (revision.revno,
                                              revision.rev.message))
             from bzrlib.delta import report_delta
             def filter_removed(path, id):
                 return any(path==item[0] for item in 
revision.delta.removed)
             report_delta(self.to_file, revision.delta,
                          filter=filter_removed)

log_formatter_registry.register('deleted', DeletedLogFormatter,
                                 'Show only deleted items')



More information about the bazaar mailing list