[Pkg-bazaar-commits] ./bzr/unstable r70: Prepare for smart recursive add.
mbp at sourcefrog.net
mbp at sourcefrog.net
Fri Apr 10 07:27:31 UTC 2009
------------------------------------------------------------
revno: 70
committer: mbp at sourcefrog.net
timestamp: Wed 2005-03-23 14:09:50 +1100
message:
Prepare for smart recursive add.
- New Inventory.add_path, so that callers don't need to know so much
about path lookup.
- Make gen_file_id public.
- New add module and smart_add function; does previous add operations
more cleanly but not recursive mode yet.
- New warning() function.
added:
bzrlib/add.py
modified:
bzrlib/__init__.py
bzrlib/branch.py
bzrlib/commands.py
bzrlib/inventory.py
bzrlib/trace.py
bzrlib/tree.py
-------------- next part --------------
=== modified file 'bzrlib/__init__.py'
--- a/bzrlib/__init__.py 2005-03-09 04:46:15 +0000
+++ b/bzrlib/__init__.py 2005-03-23 03:09:50 +0000
@@ -22,6 +22,8 @@
from osutils import format_date
from tree import Tree
from diff import diff_trees
+from trace import mutter, warning
+import add
BZRDIR = ".bzr"
=== added file 'bzrlib/add.py'
--- a/bzrlib/add.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/add.py 2005-03-23 03:09:50 +0000
@@ -0,0 +1,68 @@
+# Copyright (C) 2005 Canonical Ltd
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import types, os, sys, stat
+import bzrlib
+
+from osutils import quotefn
+from errors import bailout
+
+def smart_add(file_list, verbose=False, recurse=False):
+ """Add files to version, optionall recursing into directories.
+
+ This is designed more towards DWIM for humans than API simplicity.
+ For the specific behaviour see the help for cmd_add().
+ """
+ assert file_list
+ assert not isinstance(file_list, types.StringTypes)
+ b = bzrlib.branch.Branch(file_list[0], find_root=True)
+ inv = b.read_working_inventory()
+ dirty = False
+
+ for f in file_list:
+ rf = b.relpath(f)
+ af = b.abspath(rf)
+
+ bzrlib.mutter("smart add of %r" % f)
+
+ if bzrlib.branch.is_control_file(af):
+ bailout("cannot add control file %r" % af)
+
+ kind = bzrlib.osutils.file_kind(f)
+ if kind == 'file':
+ if inv.path2id(rf):
+ bzrlib.warning("%r is already versioned" % f)
+ continue
+ elif kind == 'directory':
+ if inv.path2id(rf):
+ if not recurse:
+ bzrlib.warning("%r is already versioned" % f)
+ continue
+ else:
+ # TODO: don't add, but recurse down
+ continue
+ else:
+ bailout("can't smart_add file kind %r" % kind)
+
+ file_id = bzrlib.branch.gen_file_id(rf)
+ inv.add_path(rf, kind=kind, file_id=file_id)
+ bzrlib.mutter("added %r kind %r file_id={%s}" % (rf, kind, file_id))
+ dirty = True
+ if verbose:
+ bzrlib.textui.show_status('A', kind, quotefn(f))
+
+ if dirty:
+ b._write_inventory(inv)
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py 2005-03-22 08:00:50 +0000
+++ b/bzrlib/branch.py 2005-03-23 03:09:50 +0000
@@ -1,3 +1,5 @@
+# Copyright (C) 2005 Canonical Ltd
+
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@@ -202,6 +204,7 @@
will be committed to the next revision.
"""
## TODO: factor out to atomicfile? is rename safe on windows?
+ ## TODO: Maybe some kind of clean/dirty marker on inventory?
tmpfname = self.controlfilename('inventory.tmp')
tmpf = file(tmpfname, 'w')
inv.write_xml(tmpf)
@@ -272,30 +275,23 @@
fullpath = os.path.normpath(self.abspath(f))
- if isfile(fullpath):
- kind = 'file'
- elif isdir(fullpath):
- kind = 'directory'
- else:
- bailout('cannot add: not a regular file or directory: %s' % quotefn(f))
-
- if len(fp) > 1:
- parent_name = joinpath(fp[:-1])
- mutter("lookup parent %r" % parent_name)
- parent_id = inv.path2id(parent_name)
- if parent_id == None:
- bailout("cannot add: parent %r is not versioned"
- % joinpath(fp[:-1]))
- else:
- parent_id = None
-
- file_id = _gen_file_id(fp[-1])
- inv.add(InventoryEntry(file_id, fp[-1], kind=kind, parent_id=parent_id))
+ try:
+ kind = file_kind(fullpath)
+ except OSError:
+ # maybe something better?
+ bailout('cannot add: not a regular file or directory: %s' % quotefn(f))
+
+ if kind != 'file' and kind != 'directory':
+ bailout('cannot add: not a regular file or directory: %s' % quotefn(f))
+
+ file_id = gen_file_id(f)
+ inv.add_path(f, kind=kind, file_id=file_id)
+
if verbose:
show_status('A', kind, quotefn(f))
- mutter("add file %s file_id:{%s} kind=%r parent_id={%s}"
- % (f, file_id, kind, parent_id))
+ mutter("add file %s file_id:{%s} kind=%r" % (f, file_id, kind))
+
self._write_inventory(inv)
@@ -476,7 +472,7 @@
entry.text_id)
else:
- entry.text_id = _gen_file_id(entry.name)
+ entry.text_id = gen_file_id(entry.name)
self.text_store.add(content, entry.text_id)
mutter(' stored with text_id {%s}' % entry.text_id)
if verbose:
@@ -798,6 +794,8 @@
## mutter('check %r for control file' % ((head, tail), ))
if tail == bzrlib.BZRDIR:
return True
+ if filename == head:
+ break
filename = head
return False
@@ -810,15 +808,18 @@
return s
-def _gen_file_id(name):
+def gen_file_id(name):
"""Return new file id.
This should probably generate proper UUIDs, but for the moment we
cope with just randomness because running uuidgen every time is
slow."""
- assert '/' not in name
- while name[0] == '.':
- name = name[1:]
+ idx = name.rfind('/')
+ if idx != -1:
+ name = name[idx+1 : ]
+
+ name = name.lstrip('.')
+
s = hexlify(rand_bytes(8))
return '-'.join((name, compact_date(time.time()), s))
=== modified file 'bzrlib/commands.py'
--- a/bzrlib/commands.py 2005-03-22 11:43:02 +0000
+++ b/bzrlib/commands.py 2005-03-23 03:09:50 +0000
@@ -165,15 +165,34 @@
print Branch('.').revno()
+
def cmd_add(file_list, verbose=False):
- """Add specified files.
+ """Add specified files or directories.
+
+ In non-recursive mode, all the named items are added, regardless
+ of whether they were previously ignored. A warning is given if
+ any of the named files are already versioned.
+
+ In recursive mode (the default), files are treated the same way
+ but the behaviour for directories is different. Directories that
+ are already versioned do not give a warning. All directories,
+ whether already versioned or not, are searched for files or
+ subdirectories that are neither versioned or ignored, and these
+ are added. This search proceeds recursively into versioned
+ directories.
+
+ Therefore simply saying 'bzr add .' will version all files that
+ are currently unknown.
+ """
+ if True:
+ bzrlib.add.smart_add(file_list, verbose)
+ else:
+ # old way
+ assert file_list
+ b = Branch(file_list[0], find_root=True)
+ b.add([b.relpath(f) for f in file_list], verbose=verbose)
+
- Fails if the files are already added.
- """
- assert file_list
- b = Branch(file_list[0], find_root=True)
- b.add([b.relpath(f) for f in file_list], verbose=verbose)
-
def cmd_relpath(filename):
print Branch(filename).relpath(filename)
@@ -508,7 +527,7 @@
bzrlib.trace.verbose = False
for m in bzrlib.store, bzrlib.inventory, bzrlib.branch, bzrlib.osutils, \
- bzrlib.tree, bzrlib.tests, bzrlib.commands:
+ bzrlib.tree, bzrlib.tests, bzrlib.commands, bzrlib.add:
mf, mt = doctest.testmod(m)
failures += mf
tests += mt
=== modified file 'bzrlib/inventory.py'
--- a/bzrlib/inventory.py 2005-03-12 07:38:31 +0000
+++ b/bzrlib/inventory.py 2005-03-23 03:09:50 +0000
@@ -31,8 +31,10 @@
from xml import XMLMixin
from errors import bailout
-from osutils import uuid, quotefn, splitpath, joinpath, appendpath
-from trace import mutter
+
+import bzrlib
+from bzrlib.osutils import uuid, quotefn, splitpath, joinpath, appendpath
+from bzrlib.trace import mutter
class InventoryEntry(XMLMixin):
"""Description of a versioned file.
@@ -360,6 +362,23 @@
self._tree[entry.file_id] = {}
+ def add_path(self, relpath, kind, file_id=None):
+ """Add entry from a path.
+
+ The immediate parent must already be versioned"""
+ parts = bzrlib.osutils.splitpath(relpath)
+ if len(parts) == 0:
+ bailout("cannot re-add root of inventory")
+
+ if file_id is None:
+ file_id = bzrlib.branch.gen_file_id(relpath)
+
+ parent_id = self.path2id(parts[:-1])
+ ie = InventoryEntry(file_id, parts[-1],
+ kind=kind, parent_id=parent_id)
+ return self.add(ie)
+
+
def __delitem__(self, file_id):
"""Remove entry by id.
@@ -468,10 +487,11 @@
This returns the entry of the last component in the path,
which may be either a file or a directory.
"""
- assert isinstance(name, types.StringTypes)
+ if isinstance(name, types.StringTypes):
+ name = splitpath(name)
parent_id = None
- for f in splitpath(name):
+ for f in name:
try:
cie = self._tree[parent_id][f]
assert cie.name == f
@@ -497,6 +517,8 @@
+
+
if __name__ == '__main__':
import doctest, inventory
doctest.testmod(inventory)
=== modified file 'bzrlib/trace.py'
--- a/bzrlib/trace.py 2005-03-22 01:17:00 +0000
+++ b/bzrlib/trace.py 2005-03-23 03:09:50 +0000
@@ -41,6 +41,12 @@
verbose = False
+def warning(msg):
+ b = 'bzr: warning: ' + msg + '\n'
+ sys.stderr.write(b)
+ _tracefile.write(b)
+ _tracefile.flush()
+
def mutter(msg):
_tracefile.write(msg)
_tracefile.write('\n')
=== modified file 'bzrlib/tree.py'
--- a/bzrlib/tree.py 2005-03-22 07:28:45 +0000
+++ b/bzrlib/tree.py 2005-03-23 03:09:50 +0000
@@ -1,5 +1,4 @@
-#! /usr/bin/env python
-# -*- coding: UTF-8 -*-
+# Copyright (C) 2005 Canonical Ltd
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
More information about the Pkg-bazaar-commits
mailing list