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