Merge lp:~jelmer/bzr/diff-format into lp:bzr

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Ian Clatworthy
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~jelmer/bzr/diff-format
Merge into: lp:bzr
Diff against target: 193 lines (+65/-24)
4 files modified
NEWS (+3/-0)
bzrlib/builtins.py (+13/-3)
bzrlib/diff.py (+25/-21)
bzrlib/tests/blackbox/test_diff.py (+24/-0)
To merge this branch: bzr merge lp:~jelmer/bzr/diff-format
Reviewer Review Type Date Requested Status
Ian Clatworthy Approve
Review via email: mp+22837@code.launchpad.net

Description of the change

This adds support for a --format option to 'bzr diff', defaulting to the current DiffTree implementation in Bazaar.

bzr-git and bzr-svn already ship with custom DiffTree implementations to output diffs in the formats supported by Subversion and Git.

To post a comment you must log in.
Revision history for this message
Ian Clatworthy (ian-clatworthy) wrote :

I'd prefer to see the default diff format looked up using the registry API for getting the default. Otherwise, this looks fine by me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS'
2--- NEWS 2010-04-02 15:10:54 +0000
3+++ NEWS 2010-04-05 22:03:20 +0000
4@@ -16,6 +16,9 @@
5 New Features
6 ************
7
8+* ``bzr diff`` now supports a --format option, which can be used to
9+ select alternative diff formats. (Jelmer Vernooij, #555994)
10+
11 Bug Fixes
12 *********
13
14
15=== modified file 'bzrlib/builtins.py'
16--- bzrlib/builtins.py 2010-04-01 04:38:26 +0000
17+++ bzrlib/builtins.py 2010-04-05 22:03:20 +0000
18@@ -1954,14 +1954,19 @@
19 help='Use this command to compare files.',
20 type=unicode,
21 ),
22+ RegistryOption('format',
23+ help='Diff format to use.',
24+ lazy_registry=('bzrlib.diff', 'format_registry'),
25+ value_switches=False, title='Diff format'),
26 ]
27 aliases = ['di', 'dif']
28 encoding_type = 'exact'
29
30 @display_command
31 def run(self, revision=None, file_list=None, diff_options=None,
32- prefix=None, old=None, new=None, using=None):
33- from bzrlib.diff import get_trees_and_branches_to_diff, show_diff_trees
34+ prefix=None, old=None, new=None, using=None, format=None):
35+ from bzrlib.diff import (get_trees_and_branches_to_diff,
36+ show_diff_trees)
37
38 if (prefix is None) or (prefix == '0'):
39 # diff -p0 format
40@@ -1981,6 +1986,10 @@
41 raise errors.BzrCommandError('bzr diff --revision takes exactly'
42 ' one or two revision specifiers')
43
44+ if using is not None and format is not None:
45+ raise errors.BzrCommandError('--using and --format are mutually '
46+ 'exclusive.')
47+
48 (old_tree, new_tree,
49 old_branch, new_branch,
50 specific_files, extra_trees) = get_trees_and_branches_to_diff(
51@@ -1989,7 +1998,8 @@
52 specific_files=specific_files,
53 external_diff_options=diff_options,
54 old_label=old_label, new_label=new_label,
55- extra_trees=extra_trees, using=using)
56+ extra_trees=extra_trees, using=using,
57+ format_cls=format)
58
59
60 class cmd_deleted(Command):
61
62=== modified file 'bzrlib/diff.py'
63--- bzrlib/diff.py 2010-02-23 07:43:11 +0000
64+++ bzrlib/diff.py 2010-04-05 22:03:20 +0000
65@@ -43,6 +43,9 @@
66 from bzrlib.workingtree import WorkingTree
67 """)
68
69+from bzrlib.registry import (
70+ Registry,
71+ )
72 from bzrlib.symbol_versioning import (
73 deprecated_function,
74 )
75@@ -411,25 +414,22 @@
76 old_label='a/', new_label='b/',
77 extra_trees=None,
78 path_encoding='utf8',
79- using=None):
80+ using=None,
81+ format_cls=None):
82 """Show in text form the changes from one tree to another.
83
84- to_file
85- The output stream.
86-
87- specific_files
88- Include only changes to these files - None for all changes.
89-
90- external_diff_options
91- If set, use an external GNU diff and pass these options.
92-
93- extra_trees
94- If set, more Trees to use for looking up file ids
95-
96- path_encoding
97- If set, the path will be encoded as specified, otherwise is supposed
98- to be utf8
99+ :param to_file: The output stream.
100+ :param specific_files:Include only changes to these files - None for all
101+ changes.
102+ :param external_diff_options: If set, use an external GNU diff and pass
103+ these options.
104+ :param extra_trees: If set, more Trees to use for looking up file ids
105+ :param path_encoding: If set, the path will be encoded as specified,
106+ otherwise is supposed to be utf8
107+ :param format_cls: Formatter class (DiffTree subclass)
108 """
109+ if format_cls is None:
110+ format_cls = DiffTree
111 old_tree.lock_read()
112 try:
113 if extra_trees is not None:
114@@ -437,10 +437,10 @@
115 tree.lock_read()
116 new_tree.lock_read()
117 try:
118- differ = DiffTree.from_trees_options(old_tree, new_tree, to_file,
119- path_encoding,
120- external_diff_options,
121- old_label, new_label, using)
122+ differ = format_cls.from_trees_options(old_tree, new_tree, to_file,
123+ path_encoding,
124+ external_diff_options,
125+ old_label, new_label, using)
126 return differ.show_diff(specific_files, extra_trees)
127 finally:
128 new_tree.unlock()
129@@ -882,7 +882,7 @@
130 def show_diff(self, specific_files, extra_trees=None):
131 """Write tree diff to self.to_file
132
133- :param sepecific_files: the specific files to compare (recursive)
134+ :param specific_files: the specific files to compare (recursive)
135 :param extra_trees: extra trees to use for mapping paths to file_ids
136 """
137 try:
138@@ -978,3 +978,7 @@
139 if error_path is None:
140 error_path = old_path
141 raise errors.NoDiffFound(error_path)
142+
143+
144+format_registry = Registry()
145+format_registry.register('default', DiffTree)
146
147=== modified file 'bzrlib/tests/blackbox/test_diff.py'
148--- bzrlib/tests/blackbox/test_diff.py 2010-03-24 14:15:01 +0000
149+++ bzrlib/tests/blackbox/test_diff.py 2010-04-05 22:03:20 +0000
150@@ -25,6 +25,10 @@
151 tests,
152 workingtree,
153 )
154+from bzrlib.diff import (
155+ DiffTree,
156+ format_registry as diff_format_registry,
157+ )
158
159
160 def subst_dates(string):
161@@ -132,6 +136,10 @@
162 out, err = self.run_bzr('diff -r 1..23..123', retcode=3,
163 error_regexes=('one or two revision specifiers',))
164
165+ def test_diff_using_and_format(self):
166+ out, err = self.run_bzr('diff --format=default --using=mydi', retcode=3,
167+ error_regexes=('are mutually exclusive',))
168+
169 def test_diff_nonexistent_revision(self):
170 out, err = self.run_bzr('diff -r 123', retcode=3,
171 error_regexes=("Requested revision: '123' does not "
172@@ -297,6 +305,22 @@
173 output = self.run_bzr('diff -r 1.. branch1', retcode=1)
174 self.assertContainsRe(output[0], '\n\\-original line\n\\+repo line\n')
175
176+ def test_custom_format(self):
177+ class BooDiffTree(DiffTree):
178+
179+ def show_diff(self, specific_files, extra_trees=None):
180+ self.to_file.write("BOO!\n")
181+ return super(BooDiffTree, self).show_diff(specific_files,
182+ extra_trees)
183+
184+ diff_format_registry.register("boo", BooDiffTree,
185+ "Scary diff format")
186+ self.addCleanup(diff_format_registry.remove, "boo")
187+ self.make_example_branch()
188+ self.build_tree_contents([('hello', 'hello world!\n')])
189+ output = self.run_bzr('diff --format=boo', retcode=1)
190+ self.assertTrue("BOO!" in output[0])
191+
192
193 class TestCheckoutDiff(TestDiff):
194