Rev 4818: (vila) Merge 2.0 into 2.1 including fixes for #331095, #507557, in file:///home/pqm/archives/thelove/bzr/2.1/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Mon Mar 1 22:25:31 GMT 2010


At file:///home/pqm/archives/thelove/bzr/2.1/

------------------------------------------------------------
revno: 4818 [merge]
revision-id: pqm at pqm.ubuntu.com-20100301222528-f2izc24k55x6rnei
parent: pqm at pqm.ubuntu.com-20100219054806-ygp8odvprqxf42ai
parent: v.ladeuil+lp at free.fr-20100301215157-8tz9ooj4vr4p75tb
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: 2.1
timestamp: Mon 2010-03-01 22:25:28 +0000
message:
  (vila) Merge 2.0 into 2.1 including fixes for #331095, #507557,
  	#185103, #524184 and #369501
added:
  NEWS-template.txt              newstemplate.txt-20100219053124-f4a3zo3ujiyawh7n-1
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/_patiencediff_c.c       _patiencediff_c.c-20070721205602-q3imkipwlgagp3cy-1
  bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
  bzrlib/lockdir.py              lockdir.py-20060220222025-98258adf27fbdda3
  bzrlib/tests/test_lockdir.py   test_lockdir.py-20060220222025-33d4221569a3d600
  doc/en/user-guide/introducing_bazaar.txt introducing_bazaar.t-20071114035000-q36a9h57ps06uvnl-5
=== modified file 'NEWS'
--- a/NEWS	2010-02-19 04:54:24 +0000
+++ b/NEWS	2010-03-01 21:51:57 +0000
@@ -356,19 +356,41 @@
 ############################
 
 :Codename:
-:2.0.5:
+:2.0.5: NOT RELEASED YET
 
 Bug Fixes
 *********
 
+* Avoid ``malloc(0)`` in ``patiencediff``, which is non-portable.
+  (Martin Pool, #331095)
+
+* Concurrent autopacking is more resilient to already-renamed pack files.
+  If we find that a file we are about to obsolete is already obsoleted, we
+  do not try to rename it, and we leave the file in ``obsolete_packs``.
+  The code is also fault tolerant if a file goes missing, assuming that
+  another process already removed the file.
+  (John Arbash Meinel, Gareth White, #507557)
+
+* Cope with the lockdir ``held/info`` file being empty, which seems to
+  happen fairly often if the process is suddenly interrupted while taking
+  a lock.
+  (Martin Pool, #185103)
+
 * Handle renames correctly when there are files or directories that 
   differ only in case.  (Chris Jones, Martin Pool, #368931)
 
+* Fixed CHM generation by moving the NEWS section template into
+  a separate file. (Ian Clatworthy, #524184)
+
 * If ``bzr push --create-prefix`` triggers an unexpected ``NoSuchFile``
   error, report that error rather than failing with an unhelpful
   ``UnboundLocalError``.
   (Andrew Bennetts, #423563)
 
+* Running ``bzr`` command without any arguments now shows bzr
+  version number along with rest of the help text.
+  (Parth Malwankar, #369501)
+
 Documentation
 *************
 
@@ -11853,37 +11875,5 @@
   diff, status, etc.
 
 
-bzr ?.?.? (not released yet)
-############################
-
-:Codename: template
-:2.0.2: ???
-
-Compatibility Breaks
-********************
-
-New Features
-************
-
-Bug Fixes
-*********
-
-Improvements
-************
-
-Documentation
-*************
-
-API Changes
-***********
-
-Internals
-*********
-
-Testing
-*******
-
-
-
 ..
    vim: tw=74 ft=rst ff=unix

=== added file 'NEWS-template.txt'
--- a/NEWS-template.txt	1970-01-01 00:00:00 +0000
+++ b/NEWS-template.txt	2010-02-19 07:13:45 +0000
@@ -0,0 +1,31 @@
+bzr ?.?.?
+#########
+
+:Codename: Nirvana
+:2.x.y: NOT RELEASED YET
+
+Compatibility Breaks
+********************
+
+New Features
+************
+
+Bug Fixes
+*********
+
+Improvements
+************
+
+Documentation
+*************
+
+API Changes
+***********
+
+Internals
+*********
+
+Testing
+*******
+
+

=== modified file 'bzrlib/_patiencediff_c.c'
--- a/bzrlib/_patiencediff_c.c	2009-10-29 06:11:23 +0000
+++ b/bzrlib/_patiencediff_c.c	2010-03-01 21:51:57 +0000
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2007 Canonical Ltd
+ Copyright (C) 2007, 2010 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
@@ -46,6 +46,12 @@
 #define SENTINEL -1
 
 
+/* malloc returns NULL on some platforms if you try to allocate nothing,
+ * causing <https://bugs.edge.launchpad.net/bzr/+bug/511267> and
+ * <https://bugs.edge.launchpad.net/bzr/+bug/331095>.  On glibc it passes, but
+ * let's make it fail to aid testing. */
+#define guarded_malloc(x) ( (x) ? malloc(x) : NULL )
+
 enum {
     OP_EQUAL = 0,
     OP_INSERT,
@@ -183,7 +189,8 @@
     while (hsize < bsize + 1)
         hsize *= 2;
 
-    hashtable = (struct bucket *)malloc(sizeof(struct bucket) * hsize);
+    /* can't be 0 */
+    hashtable = (struct bucket *) guarded_malloc(sizeof(struct bucket) * hsize);
     if (hashtable == NULL) {
         PyErr_NoMemory();
         return 0;
@@ -460,7 +467,7 @@
     last_a_pos = alo - 1;
     last_b_pos = blo - 1;
 
-    lcs = (struct matching_line *)malloc(sizeof(struct matching_line) * (bhi - blo));
+    lcs = (struct matching_line *)guarded_malloc(sizeof(struct matching_line) * (bhi - blo));
     if (lcs == NULL)
         return 0;
 
@@ -620,13 +627,15 @@
     if (!equate_lines(&hashtable, a, b, asize, bsize))
         goto error;
 
-    matches = (struct matching_line *)malloc(sizeof(struct matching_line) * bsize);
-    if (matches == NULL)
-        goto error;
+    if (bsize > 0) {
+        matches = (struct matching_line *)guarded_malloc(sizeof(struct matching_line) * bsize);
+        if (matches == NULL)
+            goto error;
 
-    backpointers = (Py_ssize_t *)malloc(sizeof(Py_ssize_t) * bsize * 4);
-    if (backpointers == NULL)
-        goto error;
+        backpointers = (Py_ssize_t *)guarded_malloc(sizeof(Py_ssize_t) * bsize * 4);
+        if (backpointers == NULL)
+            goto error;
+    }
 
     nmatches = unique_lcs(matches, &hashtable, backpointers, a, b, 0, 0, asize, bsize);
 
@@ -692,13 +701,19 @@
         goto error;
 
     matches.count = 0;
-    matches.matches = (struct matching_block *)malloc(sizeof(struct matching_block) * bsize);
-    if (matches.matches == NULL)
-        goto error;
-
-    backpointers = (Py_ssize_t *)malloc(sizeof(Py_ssize_t) * bsize * 4);
-    if (backpointers == NULL)
-        goto error;
+
+    if (bsize > 0) {
+        matches.matches = (struct matching_block *)guarded_malloc(sizeof(struct matching_block) * bsize);
+        if (matches.matches == NULL)
+            goto error;
+
+        backpointers = (Py_ssize_t *)guarded_malloc(sizeof(Py_ssize_t) * bsize * 4);
+        if (backpointers == NULL)
+            goto error;
+    } else {
+        matches.matches = NULL;
+        backpointers = NULL;
+    }
 
     res = recurse_matches(&matches, &hashtable, backpointers,
                           a, b, alo, blo, ahi, bhi, maxrecursion);
@@ -765,11 +780,15 @@
             return NULL;
         }
 
-        self->backpointers = (Py_ssize_t *)malloc(sizeof(Py_ssize_t) * self->bsize * 4);
-        if (self->backpointers == NULL) {
-            Py_DECREF(self);
-            PyErr_NoMemory();
-            return NULL;
+        if (self->bsize > 0) {
+            self->backpointers = (Py_ssize_t *)guarded_malloc(sizeof(Py_ssize_t) * self->bsize * 4);
+            if (self->backpointers == NULL) {
+                Py_DECREF(self);
+                PyErr_NoMemory();
+                return NULL;
+            }
+        } else {
+            self->backpointers = NULL;
         }
 
     }
@@ -812,9 +831,13 @@
     struct matching_blocks matches;
 
     matches.count = 0;
-    matches.matches = (struct matching_block *)malloc(sizeof(struct matching_block) * self->bsize);
-    if (matches.matches == NULL)
-        return PyErr_NoMemory();
+    if (self->bsize > 0) {
+        matches.matches = (struct matching_block *)
+            guarded_malloc(sizeof(struct matching_block) * self->bsize);
+        if (matches.matches == NULL)
+            return PyErr_NoMemory();
+    } else
+        matches.matches = NULL;
 
     res = recurse_matches(&matches, &self->hashtable, self->backpointers,
                           self->a, self->b, 0, 0,
@@ -900,7 +923,7 @@
     struct matching_blocks matches;
 
     matches.count = 0;
-    matches.matches = (struct matching_block *)malloc(sizeof(struct matching_block) * (self->bsize + 1));
+    matches.matches = (struct matching_block *)guarded_malloc(sizeof(struct matching_block) * (self->bsize + 1));
     if (matches.matches == NULL)
         return PyErr_NoMemory();
 
@@ -1013,7 +1036,7 @@
         return NULL;
 
     matches.count = 0;
-    matches.matches = (struct matching_block *)malloc(sizeof(struct matching_block) * (self->bsize + 1));
+    matches.matches = (struct matching_block *)guarded_malloc(sizeof(struct matching_block) * (self->bsize + 1));
     if (matches.matches == NULL)
         return PyErr_NoMemory();
 
@@ -1031,7 +1054,7 @@
     matches.count++;
 
     ncodes = 0;
-    codes = (struct opcode *)malloc(sizeof(struct opcode) * matches.count * 2);
+    codes = (struct opcode *)guarded_malloc(sizeof(struct opcode) * matches.count * 2);
     if (codes == NULL) {
         free(matches.matches);
         return PyErr_NoMemory();
@@ -1252,3 +1275,7 @@
     PyModule_AddObject(m, "PatienceSequenceMatcher_c",
                        (PyObject *)&PatienceSequenceMatcherType);
 }
+
+
+/* vim: sw=4 et 
+ */

=== modified file 'bzrlib/help_topics/__init__.py'
--- a/bzrlib/help_topics/__init__.py	2010-02-16 16:08:40 +0000
+++ b/bzrlib/help_topics/__init__.py	2010-03-01 21:51:57 +0000
@@ -278,7 +278,7 @@
 
 
 _basic_help = \
-"""Bazaar -- a free distributed version-control tool
+"""Bazaar %s -- a free distributed version-control tool
 http://bazaar-vcs.org/
 
 Basic commands:
@@ -302,7 +302,7 @@
   bzr help init      more help on e.g. init command
   bzr help commands  list all commands
   bzr help topics    list all help topics
-"""
+""" % bzrlib.__version__
 
 
 _global_options = \

=== modified file 'bzrlib/lockdir.py'
--- a/bzrlib/lockdir.py	2010-02-17 17:11:16 +0000
+++ b/bzrlib/lockdir.py	2010-03-01 21:51:57 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006-2010 Canonical Ltd
+# Copyright (C) 2006, 2007, 2008, 2010 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
@@ -252,7 +252,7 @@
         if info is None:
             raise LockFailed(self, "lock was renamed into place, but "
                 "now is missing!")
-        if info['nonce'] != self.nonce:
+        if info.get('nonce') != self.nonce:
             self._trace("rename succeeded, "
                 "but lock is still held by someone else")
             raise LockContention(self)
@@ -430,7 +430,7 @@
     def peek(self):
         """Check if the lock is held by anyone.
 
-        If it is held, this returns the lock info structure as a rio Stanza,
+        If it is held, this returns the lock info structure as a dict
         which contains some information about the current lock holder.
         Otherwise returns None.
         """
@@ -459,8 +459,14 @@
         return s.to_string()
 
     def _parse_info(self, info_bytes):
-        # TODO: Handle if info_bytes is empty
-        return rio.read_stanza(osutils.split_lines(info_bytes)).as_dict()
+        stanza = rio.read_stanza(osutils.split_lines(info_bytes))
+        if stanza is None:
+            # see bug 185013; we fairly often end up with the info file being
+            # empty after an interruption; we could log a message here but
+            # there may not be much we can say
+            return {}
+        else:
+            return stanza.as_dict()
 
     def attempt_lock(self):
         """Take the lock; fail if it's already held.
@@ -611,11 +617,16 @@
     def _format_lock_info(self, info):
         """Turn the contents of peek() into something for the user"""
         lock_url = self.transport.abspath(self.path)
-        delta = time.time() - int(info['start_time'])
+        start_time = info.get('start_time')
+        if start_time is None:
+            time_ago = '(unknown)'
+        else:
+            time_ago = format_delta(time.time() - int(info['start_time']))
         return [
             'lock %s' % (lock_url,),
-            'held by %(user)s on host %(hostname)s [process #%(pid)s]' % info,
-            'locked %s' % (format_delta(delta),),
+            'held by %s on host %s [process #%s]' %
+                tuple([info.get(x, '<unknown>') for x in ['user', 'hostname', 'pid']]),
+            'locked %s' % (time_ago,),
             ]
 
     def validate_token(self, token):

=== modified file 'bzrlib/tests/test_lockdir.py'
--- a/bzrlib/tests/test_lockdir.py	2010-02-17 17:11:16 +0000
+++ b/bzrlib/tests/test_lockdir.py	2010-03-01 21:51:57 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006-2010 Canonical Ltd
+# Copyright (C) 2006, 2007, 2008, 2010 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
@@ -666,6 +666,25 @@
         # no kibble
         check_dir(['held'])
 
+    def test_no_lockdir_info(self):
+        """We can cope with empty info files."""
+        # This seems like a fairly common failure case - see
+        # <https://bugs.edge.launchpad.net/bzr/+bug/185103> and all its dupes.
+        # Processes are often interrupted after opening the file
+        # before the actual contents are committed.
+        t = self.get_transport()
+        t.mkdir('test_lock')
+        t.mkdir('test_lock/held')
+        t.put_bytes('test_lock/held/info', '')
+        lf = LockDir(t, 'test_lock')
+        info = lf.peek()
+        formatted_info = lf._format_lock_info(info)
+        self.assertEquals(
+            ['lock %s' % t.abspath('test_lock'),
+             'held by <unknown> on host <unknown> [process #<unknown>]',
+             'locked (unknown)'],
+            formatted_info)
+
 
 class TestLockDirHooks(TestCaseWithTransport):
 

=== modified file 'doc/en/user-guide/introducing_bazaar.txt'
--- a/doc/en/user-guide/introducing_bazaar.txt	2010-01-04 02:25:11 +0000
+++ b/doc/en/user-guide/introducing_bazaar.txt	2010-03-01 21:51:57 +0000
@@ -134,7 +134,7 @@
 details on the commands and options available.
 
 .. _Bazaar in five minutes: ../mini-tutorial/index.html
-.. _Bazaar Quick Start Card: ../quick-reference/quick-start-summary.svg
+.. _Bazaar Quick Start Card: ../quick-reference/index.html
 .. _Bazaar User Reference: ../user-reference/index.html
 
 We hope you find this manual useful. If you have suggestions on how it




More information about the bazaar-commits mailing list