Merge lp:~jelmer/bzr-builddeb/quilt-tree-policy into lp:bzr-builddeb

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: 691
Merged at revision: 689
Proposed branch: lp:~jelmer/bzr-builddeb/quilt-tree-policy
Merge into: lp:bzr-builddeb
Diff against target: 223 lines (+144/-3)
5 files modified
__init__.py (+11/-0)
config.py (+3/-0)
merge_quilt.py (+43/-1)
quilt.py (+28/-2)
tests/test_merge_quilt.py (+59/-0)
To merge this branch: bzr merge lp:~jelmer/bzr-builddeb/quilt-tree-policy
Reviewer Review Type Date Requested Status
James Westby Approve
Review via email: mp+87751@code.launchpad.net

Description of the change

Add a hook and configuration setting that allows automatically applying patches after merges/pulls.

Together with my other changes, this makes it easy to always have patches
applied in the working tree, but unapplied in revisions (which helps with
merging).

To post a comment you must log in.
Revision history for this message
James Westby (james-w) wrote :

What state does this leave things in if the quilt patches don't apply
after the operation?

Thanks,

James

review: Approve

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-05 18:53:13 +0000
3+++ __init__.py 2012-01-06 13:45:28 +0000
4@@ -210,6 +210,9 @@
5 from bzrlib.plugins.builddeb.merge_quilt import tree_unapply_patches
6 trace.note("Unapplying quilt patches to prevent spurious conflicts")
7 merger._quilt_tempdirs = []
8+ series_file_id = merger.working_tree.path2id("debian/patches/series")
9+ if series_file_id is not None:
10+ merger._old_quilt_series = merger.working_tree.get_file_lines(series_file_id)
11 if merger.working_tree.path2id("debian/patches") is not None:
12 quilt_pop_all(working_dir=merger.working_tree.basedir)
13 try:
14@@ -245,6 +248,14 @@
15 import shutil
16 for dir in getattr(merger, "_quilt_tempdirs", []):
17 shutil.rmtree(dir)
18+ from bzrlib.plugins.builddeb.util import debuild_config
19+ config = debuild_config(merger.working_tree, merger.working_tree)
20+ policy = config.quilt_tree_policy
21+ if policy is None:
22+ return
23+ from bzrlib.plugins.builddeb.merge_quilt import post_process_quilt_patches
24+ post_process_quilt_patches(
25+ merger.working_tree, getattr(merger, "_old_quilt_series", []), policy)
26
27
28 def pre_merge_fix_ancestry(merger):
29
30=== modified file 'config.py'
31--- config.py 2011-11-22 14:05:25 +0000
32+++ config.py 2012-01-06 13:45:28 +0000
33@@ -295,6 +295,9 @@
34 commit_message_from_changelog = _bool_property('commit-message-from-changelog',
35 "Whether the commit message should come from debian/changelog", default=False)
36
37+ quilt_tree_policy = _opt_property('quilt-tree-policy',
38+ "Whether to automatically apply/unapply quilt patches after tree operations")
39+
40
41 def _test():
42 import doctest
43
44=== modified file 'merge_quilt.py'
45--- merge_quilt.py 2012-01-05 11:38:00 +0000
46+++ merge_quilt.py 2012-01-06 13:45:28 +0000
47@@ -31,7 +31,11 @@
48 trace,
49 )
50
51-from bzrlib.plugins.builddeb.quilt import quilt_pop_all
52+from bzrlib.plugins.builddeb.quilt import (
53+ quilt_pop_all,
54+ quilt_push,
55+ quilt_pop,
56+ )
57
58
59 class NoUnapplyingMerger(_mod_merge.Merge3Merger):
60@@ -86,3 +90,41 @@
61 except:
62 shutil.rmtree(target_dir)
63 raise
64+
65+
66+def post_process_quilt_patches(tree, old_patches, policy):
67+ """(Un)apply patches after a merge.
68+
69+ :param tree: Working tree to work in
70+ :param old_patches: List of patches applied before the operation (usually a merge)
71+ """
72+ new_patches = tree.get_file_lines(tree.path2id("debian/patches/series"))
73+ applied_file_id = tree.path2id(".pc/applied-patches")
74+ if applied_file_id is not None:
75+ applied_patches = tree.get_file_lines(applied_file_id, ".pc/applied-patches")
76+ else:
77+ applied_patches = []
78+ if policy == "applied":
79+ to_apply = []
80+ for p in new_patches:
81+ if p in old_patches:
82+ continue
83+ if not p in applied_patches:
84+ to_apply.append(p)
85+ if to_apply == []:
86+ return
87+ trace.note("Applying %d quilt patches.", to_apply)
88+ for p in to_apply:
89+ quilt_push(tree.basedir, p)
90+ elif policy == "unapplied":
91+ to_unapply = []
92+ for p in new_patches:
93+ if p in old_patches:
94+ continue
95+ if p in applied_patches:
96+ to_unapply.append(p)
97+ if to_unapply == []:
98+ return
99+ trace.note("Unapplying %d quilt patches", to_unapply)
100+ for p in to_unapply:
101+ quilt_pop(tree.basedir, p)
102
103=== modified file 'quilt.py'
104--- quilt.py 2012-01-04 23:28:23 +0000
105+++ quilt.py 2012-01-06 13:45:28 +0000
106@@ -101,7 +101,20 @@
107 :param patches_dir: Optional patches directory
108 :param series_file: Optional series file
109 """
110- return run_quilt(["pop", "-a"], working_dir=working_dir, patches_dir=patches_dir, series_file=series_file, quiet=quiet)
111+ return run_quilt(["pop", "-a"], working_dir=working_dir,
112+ patches_dir=patches_dir, series_file=series_file, quiet=quiet)
113+
114+
115+def quilt_pop(working_dir, patch, patches_dir=None, series_file=None, quiet=None):
116+ """Pop a patch.
117+
118+ :param working_dir: Directory to work in
119+ :param patch: Patch to apply
120+ :param patches_dir: Optional patches directory
121+ :param series_file: Optional series file
122+ """
123+ return run_quilt(["pop", patch], working_dir=working_dir,
124+ patches_dir=patches_dir, series_file=series_file, quiet=quiet)
125
126
127 def quilt_push_all(working_dir, patches_dir=None, series_file=None, quiet=None):
128@@ -111,7 +124,20 @@
129 :param patches_dir: Optional patches directory
130 :param series_file: Optional series file
131 """
132- return run_quilt(["push", "-a"], working_dir=working_dir, patches_dir=patches_dir, series_file=series_file, quiet=quiet)
133+ return run_quilt(["push", "-a"], working_dir=working_dir,
134+ patches_dir=patches_dir, series_file=series_file, quiet=quiet)
135+
136+
137+def quilt_push(working_dir, patch, patches_dir=None, series_file=None, quiet=None):
138+ """Push a patch.
139+
140+ :param working_dir: Directory to work in
141+ :param patch: Patch to push
142+ :param patches_dir: Optional patches directory
143+ :param series_file: Optional series file
144+ """
145+ return run_quilt(["push", patch], working_dir=working_dir,
146+ patches_dir=patches_dir, series_file=series_file, quiet=quiet)
147
148
149 def quilt_applied(working_dir, patches_dir=None, series_file=None):
150
151=== modified file 'tests/test_merge_quilt.py'
152--- tests/test_merge_quilt.py 2012-01-05 11:38:00 +0000
153+++ tests/test_merge_quilt.py 2012-01-06 13:45:28 +0000
154@@ -19,6 +19,7 @@
155
156 """Tests for the merge_quilt code."""
157
158+import os
159 import shutil
160
161 from bzrlib.hooks import install_lazy_named_hook
162@@ -125,3 +126,61 @@
163 # "a" should be unapplied again
164 self.assertPathDoesNotExist("a/a")
165 self.assertEquals(1, conflicts)
166+
167+ def test_auto_apply_patches_after_checkout(self):
168+ self.enable_hooks()
169+
170+ tree_a = self.make_branch_and_tree('a')
171+
172+ self.build_tree(['a/debian/', 'a/debian/patches/'])
173+ self.build_tree_contents([
174+ ('a/debian/patches/series', 'patch1\n'),
175+ ('a/debian/patches/patch1', TRIVIAL_PATCH)])
176+ tree_a.smart_add([tree_a.basedir])
177+ tree_a.commit('initial')
178+
179+ self.build_tree_contents([
180+ (os.path.join(self.test_home_dir, ".bazaar/builddeb.conf"),
181+ "[BUILDDEB]\nquilt-tree-policy = applied\n")])
182+
183+ tree_b = tree_a.branch.create_checkout("b")
184+ self.expectFailure("patches not yet applied after checkout",
185+ self.assertFileEqual, "a\n", "b/a")
186+
187+ def test_auto_apply_patches_after_update(self):
188+ self.enable_hooks()
189+
190+ tree_a = self.make_branch_and_tree('a')
191+ tree_b = tree_a.branch.create_checkout("b")
192+
193+ self.build_tree(['a/debian/', 'a/debian/patches/'])
194+ self.build_tree_contents([
195+ ('a/debian/patches/series', 'patch1\n'),
196+ ('a/debian/patches/patch1', TRIVIAL_PATCH)])
197+ tree_a.smart_add([tree_a.basedir])
198+ tree_a.commit('initial')
199+
200+ self.build_tree(["b/.bzr-builddeb/"])
201+ self.build_tree_contents([("b/.bzr-builddeb/local.conf", "[BUILDDEB]\nquilt-tree-policy = applied\n")])
202+
203+ tree_b.update()
204+ self.assertFileEqual("a\n", "b/a")
205+
206+ def test_auto_unapply_patches_after_update(self):
207+ self.enable_hooks()
208+
209+ tree_a = self.make_branch_and_tree('a')
210+ tree_b = tree_a.branch.create_checkout("b")
211+
212+ self.build_tree(['a/debian/', 'a/debian/patches/'])
213+ self.build_tree_contents([
214+ ('a/debian/patches/series', 'patch1\n'),
215+ ('a/debian/patches/patch1', TRIVIAL_PATCH)])
216+ tree_a.smart_add([tree_a.basedir])
217+ tree_a.commit('initial')
218+
219+ self.build_tree(["b/.bzr-builddeb/"])
220+ self.build_tree_contents([("b/.bzr-builddeb/local.conf", "[BUILDDEB]\nquilt-tree-policy = unapplied\n")])
221+
222+ tree_b.update()
223+ self.assertPathDoesNotExist("b/a")

Subscribers

People subscribed via source and target branches