Merge lp:~lifeless/bzr/bug-515631 into lp:bzr

Proposed by Robert Collins
Status: Merged
Merged at revision: not available
Proposed branch: lp:~lifeless/bzr/bug-515631
Merge into: lp:bzr
Diff against target: 120 lines (+41/-11)
3 files modified
NEWS (+4/-0)
bzrlib/export/dir_exporter.py (+8/-9)
bzrlib/tests/test_export.py (+29/-2)
To merge this branch: bzr merge lp:~lifeless/bzr/bug-515631
Reviewer Review Type Date Requested Status
James Westby Approve
Review via email: mp+18415@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

* Set the mtime of files exported to a directory by ``bzr export`` all to
  the same value to avoid confusing ``make`` and other date-based build
  systems. (Robert Collins, #515631)

This bug affects 'bzr builddeb'

Revision history for this message
James Westby (james-w) wrote :

Looks good to me, please land.

Thanks,

James

review: Approve
Revision history for this message
Robert Collins (lifeless) wrote :

On Tue, 2010-02-02 at 00:33 +0000, James Westby wrote:
> Review: Approve
> Looks good to me, please land.

Its landed.... we may want to ship a patch in the Debian 2.1 package
with this, for packagers.

-Rob

Revision history for this message
Martin Pool (mbp) wrote :

I think this would be reasonable to land directly to 2.1.1:

* it's a bug (at least arguably)
* the change is quite small

Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Martin Pool wrote:
> I think this would be reasonable to land directly to 2.1.1:
>
> * it's a bug (at least arguably)
> * the change is quite small

Well, 2.1.0 is scheduled for Thurs, and we already have 1 or 2 bugfixes
pending in that branch....

I certainly agree that this can go into the stable 2.1 series. (Arguably
we could even get it into the 2.0 series...)

John
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAktoYKQACgkQJdeBCYSNAAMfigCfbN7pX6XxcbNYcGZxlNncA8n1
ahcAmQFajg7523LIbGs9m84yV0xZNPn8
=j5TX
-----END PGP SIGNATURE-----

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS'
2--- NEWS 2010-02-01 11:40:56 +0000
3+++ NEWS 2010-02-01 22:30:26 +0000
4@@ -25,6 +25,10 @@
5 * Fix "AttributeError in Inter1and2Helper" during fetch.
6 (Martin Pool, #513432)
7
8+* Set the mtime of files exported to a directory by ``bzr export`` all to
9+ the same value to avoid confusing ``make`` and other date-based build
10+ systems. (Robert Collins, #515631)
11+
12 Improvements
13 ************
14
15
16=== modified file 'bzrlib/export/dir_exporter.py'
17--- bzrlib/export/dir_exporter.py 2009-12-18 05:38:40 +0000
18+++ bzrlib/export/dir_exporter.py 2010-02-01 22:30:26 +0000
19@@ -1,4 +1,4 @@
20-# Copyright (C) 2005, 2009 Canonical Ltd
21+# Copyright (C) 2005, 2009-2010 Canonical Ltd
22 #
23 # This program is free software; you can redistribute it and/or modify
24 # it under the terms of the GNU General Public License as published by
25@@ -14,12 +14,12 @@
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28
29-"""Export a Tree to a non-versioned directory.
30-"""
31+"""Export a bzrlib.tree.Tree to a new or empty directory."""
32
33 import errno
34 import os
35 import StringIO
36+import time
37
38 from bzrlib import errors, osutils
39 from bzrlib.export import _export_iter_entries
40@@ -33,14 +33,11 @@
41 def dir_exporter(tree, dest, root, subdir, filtered=False):
42 """Export this tree to a new directory.
43
44- `dest` should not exist, and will be created holding the
45- contents of this tree.
46-
47- TODO: To handle subdirectories we need to create the
48- directories first.
49+ `dest` should either not exist or should be empty. If it does not exist it
50+ will be created holding the contents of this tree.
51
52 :note: If the export fails, the destination directory will be
53- left in a half-assed state.
54+ left in an incompletely exported state: export is not transactional.
55 """
56 mutter('export version %r', tree)
57 try:
58@@ -79,6 +76,7 @@
59 # The data returned here can be in any order, but we've already created all
60 # the directories
61 flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | getattr(os, 'O_BINARY', 0)
62+ now = time.time()
63 for (relpath, executable), chunks in tree.iter_files_bytes(to_fetch):
64 if filtered:
65 filters = tree._content_filter_stack(relpath)
66@@ -94,3 +92,4 @@
67 out.writelines(chunks)
68 finally:
69 out.close()
70+ os.utime(fullpath, (now, now))
71
72=== modified file 'bzrlib/tests/test_export.py'
73--- bzrlib/tests/test_export.py 2009-07-29 13:46:55 +0000
74+++ bzrlib/tests/test_export.py 2010-02-01 22:30:26 +0000
75@@ -1,4 +1,4 @@
76-# Copyright (C) 2009 Canonical Ltd
77+# Copyright (C) 2009-2010 Canonical Ltd
78 #
79 # This program is free software; you can redistribute it and/or modify
80 # it under the terms of the GNU General Public License as published by
81@@ -15,7 +15,7 @@
82 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
83
84 import os
85-
86+import time
87
88 from bzrlib import (
89 errors,
90@@ -62,3 +62,30 @@
91 wt.commit('1')
92 self.build_tree(['target/', 'target/foo'])
93 self.assertRaises(errors.BzrError, export.export, wt, 'target', format="dir")
94+
95+ def test_dir_export_files_same_timestamp(self):
96+ builder = self.make_branch_builder('source')
97+ builder.start_series()
98+ builder.build_snapshot(None, None, [
99+ ('add', ('', 'root-id', 'directory', '')),
100+ ('add', ('a', 'a-id', 'file', 'content\n'))])
101+ builder.build_snapshot(None, None, [
102+ ('add', ('b', 'b-id', 'file', 'content\n'))])
103+ builder.finish_series()
104+ b = builder.get_branch()
105+ b.lock_read()
106+ self.addCleanup(b.unlock)
107+ tree = b.basis_tree()
108+ orig_iter_files_bytes = tree.iter_files_bytes
109+ # Make iter_files_bytes slower, so we provoke mtime skew
110+ def iter_files_bytes(to_fetch):
111+ for thing in orig_iter_files_bytes(to_fetch):
112+ yield thing
113+ time.sleep(1)
114+ tree.iter_files_bytes = iter_files_bytes
115+ export.export(tree, 'target', format='dir')
116+ t = self.get_transport('target')
117+ st_a = t.stat('a')
118+ st_b = t.stat('b')
119+ # All files must be given the same mtime.
120+ self.assertEqual(st_a.st_mtime, st_b.st_mtime)