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
1=== modified file '__init__.py'
2--- __init__.py 2012-01-02 18:18:55 +0000
3+++ __init__.py 2012-01-02 22:09:26 +0000
4@@ -191,6 +191,53 @@
5 return db.tag_name(changelog.version)
6
7
8+def pre_merge(merger):
9+ pre_merge_fix_ancestry(merger)
10+ if getattr(merger, "_no_quilt_unapplying", False):
11+ return
12+ pre_merge_quilt(merger)
13+
14+
15+def pre_merge_quilt(merger):
16+ if (merger.this_tree.path2id("debian/patches") is None and
17+ merger.base_tree.path2id("debian/patches") is None):
18+ return
19+ import shutil
20+ from bzrlib import trace
21+ from bzrlib.plugins.builddeb.errors import QuiltUnapplyError
22+ from bzrlib.plugins.builddeb.quilt import QuiltError
23+ from bzrlib.plugins.builddeb.merge_quilt import tree_unapply_patches
24+ trace.note("Unapplying quilt patches to prevent spurious conflicts")
25+ merger._quilt_tempdirs = []
26+ try:
27+ merger.this_tree, this_dir = tree_unapply_patches(merger.this_tree, merger.this_branch)
28+ except QuiltError, e:
29+ shutil.rmtree(this_dir)
30+ raise QuiltUnapplyError("this", e.msg)
31+ else:
32+ merger._quilt_tempdirs.append(this_dir)
33+ try:
34+ merger.base_tree, base_dir = tree_unapply_patches(merger.base_tree, merger.this_branch)
35+ except QuiltError, e:
36+ shutil.rmtree(base_dir)
37+ raise QuiltUnapplyError("base", e.msg)
38+ else:
39+ merger._quilt_tempdirs.append(base_dir)
40+ try:
41+ merger.other_tree, other_dir = tree_unapply_patches(merger.other_tree, merger.other_branch)
42+ except QuiltError, e:
43+ shutil.rmtree(other_dir)
44+ raise QuiltUnapplyError("other", e.msg)
45+ else:
46+ merger._quilt_tempdirs.append(other_dir)
47+
48+
49+def post_merge_quilt_cleanup(merger):
50+ import shutil
51+ for dir in getattr(merger, "_quilt_tempdirs", []):
52+ shutil.rmtree(dir)
53+
54+
55 def pre_merge_fix_ancestry(merger):
56 from bzrlib.plugins.builddeb.config import BUILD_TYPE_NATIVE
57 from bzrlib.plugins.builddeb.util import debuild_config
58@@ -210,6 +257,7 @@
59 fix_ancestry_as_needed(merger.this_tree, merger.other_branch,
60 source_revid=merger.other_tree.get_revision_id())
61
62+
63 try:
64 from bzrlib.hooks import install_lazy_named_hook
65 except ImportError: # Compatibility with bzr < 2.4
66@@ -258,8 +306,12 @@
67 "Automatically determine tag names from Debian version")
68 install_lazy_named_hook(
69 "bzrlib.merge", "Merger.hooks",
70- "pre_merge", pre_merge_fix_ancestry,
71- "Fix the branch ancestry prior to a merge")
72+ 'pre_merge', pre_merge,
73+ 'Debian quilt patch (un)applying and ancestry fixing')
74+ install_lazy_named_hook(
75+ "bzrlib.merge", "Merger.hooks",
76+ 'post_merge', post_merge_quilt_cleanup,
77+ 'Cleaning up quilt temporary directories')
78
79 try:
80 from bzrlib.revisionspec import revspec_registry
81
82=== modified file 'debian/changelog'
83--- debian/changelog 2012-01-02 18:01:36 +0000
84+++ debian/changelog 2012-01-02 22:09:26 +0000
85@@ -5,6 +5,8 @@
86 commands like 'bzr bash-completion'. LP: #903650
87 * Provide merge-package functionality as a hook for 'bzr merge'.
88 LP: #486075, LP: #910900
89+ * Automatically unapply patches before merge operations.
90+ LP: #815854
91
92 -- Jelmer Vernooij <jelmer@debian.org> Mon, 02 Jan 2012 17:57:33 +0100
93
94
95=== modified file 'errors.py'
96--- errors.py 2012-01-02 18:01:36 +0000
97+++ errors.py 2012-01-02 22:09:26 +0000
98@@ -235,3 +235,15 @@
99
100 _fmt = ("Importing packages using source format 3.0 multiple tarballs "
101 "is not yet supported.")
102+
103+
104+class QuiltUnapplyError(BzrError):
105+
106+ _fmt = ("Unable to unapply quilt patches for %(kind)r tree: %(msg)s")
107+
108+ def __init__(self, kind, msg):
109+ BzrError.__init__(self)
110+ self.kind = kind
111+ if msg.count("\n") == 1:
112+ msg = msg.strip()
113+ self.msg = msg
114
115=== modified file 'merge_quilt.py'
116--- merge_quilt.py 2012-01-02 22:09:26 +0000
117+++ merge_quilt.py 2012-01-02 22:09:26 +0000
118@@ -21,13 +21,24 @@
119 """Quilt patch handling."""
120
121 from __future__ import absolute_import
122+
123+import shutil
124 import tempfile
125+from bzrlib.revisiontree import RevisionTree
126+from bzrlib import (
127+ merge as _mod_merge,
128+ trace,
129+ )
130
131-from bzrlib import trace
132 from bzrlib.plugins.builddeb.quilt import quilt_pop_all
133
134
135-def tree_unapply_patches(orig_tree):
136+class NoUnapplyingMerger(_mod_merge.Merge3Merger):
137+
138+ _no_quilt_unapplying = True
139+
140+
141+def tree_unapply_patches(orig_tree, orig_branch):
142 """Return a tree with patches unapplied.
143
144 :param tree: Tree from which to unapply quilt patches
145@@ -41,7 +52,19 @@
146 return orig_tree, None
147
148 target_dir = tempfile.mkdtemp()
149- tree = orig_tree.branch.create_checkout(target_dir, lightweight=True)
150- trace.warning("Applying quilt patches for %r in %s", orig_tree, target_dir)
151- quilt_pop_all(working_dir=tree.basedir)
152- return tree, target_dir
153+ try:
154+ if isinstance(orig_tree, RevisionTree):
155+ tree = orig_branch.create_checkout(target_dir, lightweight=True,
156+ accelerator_tree=orig_tree, revision_id=orig_tree.get_revision_id())
157+ else:
158+ tree = orig_branch.create_checkout(target_dir, lightweight=True,
159+ revision_id=orig_tree.last_revision(), accelerator_tree=orig_tree)
160+ merger = _mod_merge.Merger.from_uncommitted(tree, orig_tree)
161+ merger.merge_type = NoUnapplyingMerger
162+ merger.do_merge()
163+ trace.mutter("Applying quilt patches for %r in %s", orig_tree, target_dir)
164+ quilt_pop_all(working_dir=tree.basedir)
165+ return tree, target_dir
166+ except:
167+ shutil.rmtree(target_dir)
168+ raise
169
170=== modified file 'tests/test_merge_quilt.py'
171--- tests/test_merge_quilt.py 2011-12-20 14:44:17 +0000
172+++ tests/test_merge_quilt.py 2012-01-02 22:09:26 +0000
173@@ -18,3 +18,25 @@
174 #
175
176 """Tests for the merge_quilt code."""
177+
178+from bzrlib.plugins.builddeb.tests import ExecutableFeature
179+from bzrlib.plugins.builddeb.merge_quilt import quilt_pop_all
180+
181+from bzrlib.tests import TestCaseWithTransport
182+
183+quilt_feature = ExecutableFeature('quilt')
184+
185+
186+class QuiltTests(TestCaseWithTransport):
187+
188+ _test_needs_features = [quilt_feature]
189+
190+ def test_push_all_empty(self):
191+ source = self.make_branch_and_tree('source')
192+ self.build_tree(['source/debian/', 'source/debian/patches/'])
193+ self.build_tree_contents([
194+ ("test.recipe", "# bzr-builder format 0.3 "
195+ "deb-version 1\nsource 3\n"),
196+ ("source/debian/patches/series", "\n")])
197+ source.add(["debian", "debian/patches", "debian/patches/series"])
198+ quilt_pop_all("source", quiet=True)

Subscribers

People subscribed via source and target branches