Merge lp:~jelmer/bzr-builddeb/quilt-hooks into lp:bzr-builddeb

Proposed by Jelmer Vernooij
Status: Merged
Merged at revision: 685
Proposed branch: lp:~jelmer/bzr-builddeb/quilt-hooks
Merge into: lp:bzr-builddeb
Prerequisite: lp:~jelmer/bzr-builddeb/quilt
Diff against target: 198 lines (+119/-8)
5 files modified
__init__.py (+54/-2)
debian/changelog (+2/-0)
errors.py (+12/-0)
merge_quilt.py (+29/-6)
tests/test_merge_quilt.py (+22/-0)
To merge this branch: bzr merge lp:~jelmer/bzr-builddeb/quilt-hooks
Reviewer Review Type Date Requested Status
James Westby Approve
Review via email: mp+87290@code.launchpad.net

Description of the change

Add hooks for merge to unapply patches before merging.

This means that if there are conflicting patches that are being merged, only the patch files will end up with conflicts - the working tree is kept clean.

To post a comment you must log in.
lp:~jelmer/bzr-builddeb/quilt-hooks updated
680. By Jelmer Vernooij

Automatically unapply patches before merge operations.
LP: #815854

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

Woop, thanks a lot for this one!

10 + if getattr(merger, "_no_quilt_unapplying", False):

Is that to avoid recursion?

This looks good. I'm interested to know how well it works :-)

Thanks,

James

Revision history for this message
James Westby (james-w) :
review: Approve
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

> Woop, thanks a lot for this one!
>
> 10 + if getattr(merger, "_no_quilt_unapplying", False):
>
> Is that to avoid recursion?
Yep. I found out the hard way :)

> This looks good. I'm interested to know how well it works :-)
Thanks, me too.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '__init__.py'
--- __init__.py 2012-01-02 18:18:55 +0000
+++ __init__.py 2012-01-02 22:09:26 +0000
@@ -191,6 +191,53 @@
191 return db.tag_name(changelog.version)191 return db.tag_name(changelog.version)
192192
193193
194def pre_merge(merger):
195 pre_merge_fix_ancestry(merger)
196 if getattr(merger, "_no_quilt_unapplying", False):
197 return
198 pre_merge_quilt(merger)
199
200
201def pre_merge_quilt(merger):
202 if (merger.this_tree.path2id("debian/patches") is None and
203 merger.base_tree.path2id("debian/patches") is None):
204 return
205 import shutil
206 from bzrlib import trace
207 from bzrlib.plugins.builddeb.errors import QuiltUnapplyError
208 from bzrlib.plugins.builddeb.quilt import QuiltError
209 from bzrlib.plugins.builddeb.merge_quilt import tree_unapply_patches
210 trace.note("Unapplying quilt patches to prevent spurious conflicts")
211 merger._quilt_tempdirs = []
212 try:
213 merger.this_tree, this_dir = tree_unapply_patches(merger.this_tree, merger.this_branch)
214 except QuiltError, e:
215 shutil.rmtree(this_dir)
216 raise QuiltUnapplyError("this", e.msg)
217 else:
218 merger._quilt_tempdirs.append(this_dir)
219 try:
220 merger.base_tree, base_dir = tree_unapply_patches(merger.base_tree, merger.this_branch)
221 except QuiltError, e:
222 shutil.rmtree(base_dir)
223 raise QuiltUnapplyError("base", e.msg)
224 else:
225 merger._quilt_tempdirs.append(base_dir)
226 try:
227 merger.other_tree, other_dir = tree_unapply_patches(merger.other_tree, merger.other_branch)
228 except QuiltError, e:
229 shutil.rmtree(other_dir)
230 raise QuiltUnapplyError("other", e.msg)
231 else:
232 merger._quilt_tempdirs.append(other_dir)
233
234
235def post_merge_quilt_cleanup(merger):
236 import shutil
237 for dir in getattr(merger, "_quilt_tempdirs", []):
238 shutil.rmtree(dir)
239
240
194def pre_merge_fix_ancestry(merger):241def pre_merge_fix_ancestry(merger):
195 from bzrlib.plugins.builddeb.config import BUILD_TYPE_NATIVE242 from bzrlib.plugins.builddeb.config import BUILD_TYPE_NATIVE
196 from bzrlib.plugins.builddeb.util import debuild_config243 from bzrlib.plugins.builddeb.util import debuild_config
@@ -210,6 +257,7 @@
210 fix_ancestry_as_needed(merger.this_tree, merger.other_branch,257 fix_ancestry_as_needed(merger.this_tree, merger.other_branch,
211 source_revid=merger.other_tree.get_revision_id())258 source_revid=merger.other_tree.get_revision_id())
212259
260
213try:261try:
214 from bzrlib.hooks import install_lazy_named_hook262 from bzrlib.hooks import install_lazy_named_hook
215except ImportError: # Compatibility with bzr < 2.4263except ImportError: # Compatibility with bzr < 2.4
@@ -258,8 +306,12 @@
258 "Automatically determine tag names from Debian version")306 "Automatically determine tag names from Debian version")
259 install_lazy_named_hook(307 install_lazy_named_hook(
260 "bzrlib.merge", "Merger.hooks",308 "bzrlib.merge", "Merger.hooks",
261 "pre_merge", pre_merge_fix_ancestry,309 'pre_merge', pre_merge,
262 "Fix the branch ancestry prior to a merge")310 'Debian quilt patch (un)applying and ancestry fixing')
311 install_lazy_named_hook(
312 "bzrlib.merge", "Merger.hooks",
313 'post_merge', post_merge_quilt_cleanup,
314 'Cleaning up quilt temporary directories')
263315
264try:316try:
265 from bzrlib.revisionspec import revspec_registry317 from bzrlib.revisionspec import revspec_registry
266318
=== modified file 'debian/changelog'
--- debian/changelog 2012-01-02 18:01:36 +0000
+++ debian/changelog 2012-01-02 22:09:26 +0000
@@ -5,6 +5,8 @@
5 commands like 'bzr bash-completion'. LP: #9036505 commands like 'bzr bash-completion'. LP: #903650
6 * Provide merge-package functionality as a hook for 'bzr merge'.6 * Provide merge-package functionality as a hook for 'bzr merge'.
7 LP: #486075, LP: #9109007 LP: #486075, LP: #910900
8 * Automatically unapply patches before merge operations.
9 LP: #815854
810
9 -- Jelmer Vernooij <jelmer@debian.org> Mon, 02 Jan 2012 17:57:33 +010011 -- Jelmer Vernooij <jelmer@debian.org> Mon, 02 Jan 2012 17:57:33 +0100
1012
1113
=== modified file 'errors.py'
--- errors.py 2012-01-02 18:01:36 +0000
+++ errors.py 2012-01-02 22:09:26 +0000
@@ -235,3 +235,15 @@
235235
236 _fmt = ("Importing packages using source format 3.0 multiple tarballs "236 _fmt = ("Importing packages using source format 3.0 multiple tarballs "
237 "is not yet supported.")237 "is not yet supported.")
238
239
240class QuiltUnapplyError(BzrError):
241
242 _fmt = ("Unable to unapply quilt patches for %(kind)r tree: %(msg)s")
243
244 def __init__(self, kind, msg):
245 BzrError.__init__(self)
246 self.kind = kind
247 if msg.count("\n") == 1:
248 msg = msg.strip()
249 self.msg = msg
238250
=== modified file 'merge_quilt.py'
--- merge_quilt.py 2012-01-02 22:09:26 +0000
+++ merge_quilt.py 2012-01-02 22:09:26 +0000
@@ -21,13 +21,24 @@
21"""Quilt patch handling."""21"""Quilt patch handling."""
2222
23from __future__ import absolute_import23from __future__ import absolute_import
24
25import shutil
24import tempfile26import tempfile
27from bzrlib.revisiontree import RevisionTree
28from bzrlib import (
29 merge as _mod_merge,
30 trace,
31 )
2532
26from bzrlib import trace
27from bzrlib.plugins.builddeb.quilt import quilt_pop_all33from bzrlib.plugins.builddeb.quilt import quilt_pop_all
2834
2935
30def tree_unapply_patches(orig_tree):36class NoUnapplyingMerger(_mod_merge.Merge3Merger):
37
38 _no_quilt_unapplying = True
39
40
41def tree_unapply_patches(orig_tree, orig_branch):
31 """Return a tree with patches unapplied.42 """Return a tree with patches unapplied.
3243
33 :param tree: Tree from which to unapply quilt patches44 :param tree: Tree from which to unapply quilt patches
@@ -41,7 +52,19 @@
41 return orig_tree, None52 return orig_tree, None
4253
43 target_dir = tempfile.mkdtemp()54 target_dir = tempfile.mkdtemp()
44 tree = orig_tree.branch.create_checkout(target_dir, lightweight=True)55 try:
45 trace.warning("Applying quilt patches for %r in %s", orig_tree, target_dir)56 if isinstance(orig_tree, RevisionTree):
46 quilt_pop_all(working_dir=tree.basedir)57 tree = orig_branch.create_checkout(target_dir, lightweight=True,
47 return tree, target_dir58 accelerator_tree=orig_tree, revision_id=orig_tree.get_revision_id())
59 else:
60 tree = orig_branch.create_checkout(target_dir, lightweight=True,
61 revision_id=orig_tree.last_revision(), accelerator_tree=orig_tree)
62 merger = _mod_merge.Merger.from_uncommitted(tree, orig_tree)
63 merger.merge_type = NoUnapplyingMerger
64 merger.do_merge()
65 trace.mutter("Applying quilt patches for %r in %s", orig_tree, target_dir)
66 quilt_pop_all(working_dir=tree.basedir)
67 return tree, target_dir
68 except:
69 shutil.rmtree(target_dir)
70 raise
4871
=== modified file 'tests/test_merge_quilt.py'
--- tests/test_merge_quilt.py 2011-12-20 14:44:17 +0000
+++ tests/test_merge_quilt.py 2012-01-02 22:09:26 +0000
@@ -18,3 +18,25 @@
18#18#
1919
20"""Tests for the merge_quilt code."""20"""Tests for the merge_quilt code."""
21
22from bzrlib.plugins.builddeb.tests import ExecutableFeature
23from bzrlib.plugins.builddeb.merge_quilt import quilt_pop_all
24
25from bzrlib.tests import TestCaseWithTransport
26
27quilt_feature = ExecutableFeature('quilt')
28
29
30class QuiltTests(TestCaseWithTransport):
31
32 _test_needs_features = [quilt_feature]
33
34 def test_push_all_empty(self):
35 source = self.make_branch_and_tree('source')
36 self.build_tree(['source/debian/', 'source/debian/patches/'])
37 self.build_tree_contents([
38 ("test.recipe", "# bzr-builder format 0.3 "
39 "deb-version 1\nsource 3\n"),
40 ("source/debian/patches/series", "\n")])
41 source.add(["debian", "debian/patches", "debian/patches/series"])
42 quilt_pop_all("source", quiet=True)

Subscribers

People subscribed via source and target branches