[Pkg-bazaar-commits] ./bzr/unstable r491: - Selective commit!

Martin Pool mbp at sourcefrog.net
Fri Apr 10 08:19:17 UTC 2009


------------------------------------------------------------
revno: 491
committer: Martin Pool <mbp at sourcefrog.net>
timestamp: Thu 2005-05-12 13:10:29 +1000
message:
  - Selective commit!
  - commit is now more verbose by default
modified:
  NEWS
  TODO
  bzrlib/commands.py
  bzrlib/commit.py
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS	2005-05-11 06:18:45 +0000
+++ b/NEWS	2005-05-12 03:10:29 +0000
@@ -53,6 +53,8 @@
 
     * New optional parameter ``bzr info [BRANCH]``.
 
+    * New form ``bzr commit SELECTED`` to commit only selected files.
+
   
   BUG FIXES:
 

=== modified file 'TODO'
--- a/TODO	2005-05-12 02:12:14 +0000
+++ b/TODO	2005-05-12 03:10:29 +0000
@@ -84,11 +84,6 @@
 
   http://www.gelato.unsw.edu.au/archives/git/0504/2194.html
   
-* testbzr should by default test the bzr binary in the same directory
-  as the testbzr script, or take a path to it as a first parameter.
-
-  Should show the version from bzr and the path name.
-
 * RemoteBranch could maintain a cache either in memory or on disk.  We
   know more than an external cache might about which files are
   immutable and which can vary.  On the other hand, it's much simpler
@@ -106,8 +101,6 @@
   option definitions are global we can define them just once and
   reference them from each command.
 
-* Selective commit of only some files.
-
 * Merge Aaron's merge code.
 
 * Merge revert patch.
@@ -130,6 +123,11 @@
 
 * More test cases.
 
+  - Selected-file commit
+
+  - Impossible selected-file commit: adding things in non-versioned
+    directories, crossing renames, etc.
+
 * Write a reproducible benchmark, perhaps importing various kernel versions.
 
 * Change test.sh from Bourne shell into something in pure Python so

=== modified file 'bzrlib/commands.py'
--- a/bzrlib/commands.py	2005-05-11 10:14:09 +0000
+++ b/bzrlib/commands.py	2005-05-12 03:10:29 +0000
@@ -774,16 +774,23 @@
 class cmd_commit(Command):
     """Commit changes into a new revision.
 
-    TODO: Commit only selected files.
+    If selected files are specified, only changes to those files are
+    committed.  If a directory is specified then its contents are also
+    committed.
+
+    A selected-file commit may fail in some cases where the committed
+    tree would be invalid, such as trying to commit a file in a
+    newly-added directory that is not itself committed.
 
     TODO: Run hooks on tree to-be-committed, and after commit.
 
     TODO: Strict commit that fails if there are unknown or deleted files.
     """
+    takes_args = ['selected*']
     takes_options = ['message', 'file', 'verbose']
     aliases = ['ci', 'checkin']
 
-    def run(self, message=None, file=None, verbose=False):
+    def run(self, message=None, file=None, verbose=False, selected_list=None):
         from bzrlib.commit import commit
 
         ## Warning: shadows builtin file()
@@ -798,7 +805,7 @@
             message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
 
         b = Branch('.')
-        commit(b, message, verbose=verbose)
+        commit(b, message, verbose=verbose, specific_files=selected_list)
 
 
 class cmd_check(Command):

=== modified file 'bzrlib/commit.py'
--- a/bzrlib/commit.py	2005-05-11 10:14:09 +0000
+++ b/bzrlib/commit.py	2005-05-12 03:10:29 +0000
@@ -18,7 +18,8 @@
 
 def commit(branch, message, timestamp=None, timezone=None,
            committer=None,
-           verbose=False):
+           verbose=True,
+           specific_files=None):
     """Commit working copy as a new revision.
 
     The basic approach is to add all the file texts into the
@@ -37,18 +38,20 @@
 
     timestamp -- if not None, seconds-since-epoch for a
          postdated/predated commit.
+
+    specific_files
+        If true, commit only those files.
     """
 
     import os, time, tempfile
 
     from inventory import Inventory
     from osutils import isdir, isfile, sha_string, quotefn, \
-         local_time_offset, username
+         local_time_offset, username, kind_marker, is_inside_any
     
     from branch import gen_file_id
     from errors import BzrError
     from revision import Revision
-    from textui import show_status
     from trace import mutter, note
 
     branch._need_writelock()
@@ -65,11 +68,14 @@
     # detect missing/deleted files, and remove them from the
     # working inventory.
 
-    work_inv = branch.read_working_inventory()
+    work_tree = branch.working_tree()
+    work_inv = work_tree.inventory
     inv = Inventory()
     basis = branch.basis_tree()
     basis_inv = basis.inventory
     missing_ids = []
+
+    print 'looking for changes...'
     for path, entry in work_inv.iter_entries():
         ## TODO: Cope with files that have gone missing.
 
@@ -82,18 +88,21 @@
         file_id = entry.file_id
         mutter('commit prep file %s, id %r ' % (p, file_id))
 
-        if not os.path.exists(p):
+        if specific_files and not is_inside_any(specific_files, path):
+            if basis_inv.has_id(file_id):
+                # carry over with previous state
+                inv.add(basis_inv[file_id].copy())
+            else:
+                # omit this from committed inventory
+                pass
+            continue
+
+        if not work_tree.has_id(file_id):
+            note('deleted %s%s' % (path, kind_marker(entry.kind)))
             mutter("    file is missing, removing from inventory")
-            if verbose:
-                show_status('D', entry.kind, quotefn(path))
             missing_ids.append(file_id)
             continue
 
-        # TODO: Handle files that have been deleted
-
-        # TODO: Maybe a special case for empty files?  Seems a
-        # waste to store them many times.
-
         inv.add(entry)
 
         if basis_inv.has_id(file_id):
@@ -104,41 +113,47 @@
 
         if entry.kind == 'directory':
             if not isdir(p):
-                raise BzrError("%s is entered as directory but not a directory" % quotefn(p))
+                raise BzrError("%s is entered as directory but not a directory"
+                               % quotefn(p))
         elif entry.kind == 'file':
             if not isfile(p):
                 raise BzrError("%s is entered as file but is not a file" % quotefn(p))
 
-            content = file(p, 'rb').read()
-
-            entry.text_sha1 = sha_string(content)
-            entry.text_size = len(content)
+            new_sha1 = work_tree.get_file_sha1(file_id)
 
             old_ie = basis_inv.has_id(file_id) and basis_inv[file_id]
             if (old_ie
-                and (old_ie.text_size == entry.text_size)
-                and (old_ie.text_sha1 == entry.text_sha1)):
+                and old_ie.text_sha1 == new_sha1):
                 ## assert content == basis.get_file(file_id).read()
-                entry.text_id = basis_inv[file_id].text_id
+                entry.text_id = old_ie.text_id
+                entry.text_sha1 = new_sha1
+                entry.text_size = old_ie.text_size
                 mutter('    unchanged from previous text_id {%s}' %
                        entry.text_id)
-
             else:
+                content = file(p, 'rb').read()
+
+                entry.text_sha1 = sha_string(content)
+                entry.text_size = len(content)
+
                 entry.text_id = gen_file_id(entry.name)
                 branch.text_store.add(content, entry.text_id)
                 mutter('    stored with text_id {%s}' % entry.text_id)
-                if verbose:
-                    if not old_ie:
-                        state = 'A'
-                    elif (old_ie.name == entry.name
-                          and old_ie.parent_id == entry.parent_id):
-                        state = 'M'
-                    else:
-                        state = 'R'
+                if not old_ie:
+                    note('added %s' % path)
+                elif (old_ie.name == entry.name
+                      and old_ie.parent_id == entry.parent_id):
+                    note('modified %s' % path)
+                else:
+                    note('renamed %s' % path)
 
-                    show_status(state, entry.kind, quotefn(path))
 
     for file_id in missing_ids:
+        # Any files that have been deleted are now removed from the
+        # working inventory.  Files that were not selected for commit
+        # are left as they were in the working inventory and ommitted
+        # from the revision inventory.
+        
         # have to do this later so we don't mess up the iterator.
         # since parents may be removed before their children we
         # have to test.
@@ -196,8 +211,7 @@
 
     branch.append_revision(rev_id)
 
-    if verbose:
-        note("commited r%d" % branch.revno())
+    note("commited r%d" % branch.revno())
 
 
 



More information about the Pkg-bazaar-commits mailing list