Merge lp:~pauljnixon/bzr/context_in_diffs into lp:bzr

Proposed by Paul Nixon
Status: Merged
Approved by: Martin Packman
Approved revision: no longer in the source branch.
Merged at revision: 6547
Proposed branch: lp:~pauljnixon/bzr/context_in_diffs
Merge into: lp:bzr
Diff against target: 234 lines (+92/-12)
4 files modified
bzrlib/builtins.py (+7/-2)
bzrlib/diff.py (+18/-10)
bzrlib/tests/test_diff.py (+63/-0)
doc/en/release-notes/bzr-2.6.txt (+4/-0)
To merge this branch: bzr merge lp:~pauljnixon/bzr/context_in_diffs
Reviewer Review Type Date Requested Status
Martin Packman (community) Approve
Jelmer Vernooij (community) Approve
Review via email: mp+115819@code.launchpad.net

This proposal supersedes a proposal from 2012-07-06.

Commit message

Add option to specify how much context bzr should use in diffs

Description of the change

Patiencediff (used by default for "bzr diff" command) includes the ability to control how many lines of context to output for each changed section. I made this accessible as an option to bzr diff, as "--context" so an example would be "bzr diff -r-2 --context 6"

As per requests made of the previous merge proposal, I have changed the defaults to be constant, added tests, and updated the release notes.

I have also made this accessible to Loggerhead which I will propose for merging if this goes in.

This is the first time I have proposed anything for merging, if I'm doing something wrong just let me know and I'll fix it.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote : Posted in a previous version of this proposal

Hi Paul,

The changes don't look unreasonable. At a first glance, two notes: it would be nice to have a constant for the default number of context lines. Can you please add some basic tests for the new option?

Cheers,

Jelmer
--
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

Paul <email address hidden> wrote:

Paul has proposed merging lp:~pauljnixon/bzr/context_in_diffs into lp:bzr.

Requested reviews:
bzr-core (bzr-core)

For more details, see:
https://code.launchpad.net/~pauljnixon/bzr/context_in_diffs/+merge/113793

Patiencediff (used by default for "bzr diff" command) includes the ability to control how many lines of context to output for each changed section. I made this accessible as an option to bzr diff, as "--context" so an example would be "bzr diff -r-2 --context 6"

I have also made this accessible to Loggerhead which I will propose for merging if this goes in.

This is the first time I have proposed anything for merging, if I'm doing something wrong just let me know and I'll fix it.
--
https://code.launchpad.net/~pauljnixon/bzr/context_in_diffs/+merge/113793
Your team Bazaar Codereview Subscribers is subscribed to branch lp:bzr.

Revision history for this message
Paul Nixon (pauljnixon) wrote : Posted in a previous version of this proposal

Okay, I'll make those changes.

On Fri, Jul 6, 2012 at 6:28 PM, Jelmer Vernooij
<email address hidden> wrote:
> Hi Paul,
>
> The changes don't look unreasonable. At a first glance, two notes: it would be nice to have a constant for the default number of context lines. Can you please add some basic tests for the new option?
>
> Cheers,
>
> Jelmer
> --
> Sent from my Android phone with K-9 Mail. Please excuse my brevity.
>
> Paul <email address hidden> wrote:
>
> Paul has proposed merging lp:~pauljnixon/bzr/context_in_diffs into lp:bzr.
>
> Requested reviews:
> bzr-core (bzr-core)
>
> For more details, see:
> https://code.launchpad.net/~pauljnixon/bzr/context_in_diffs/+merge/113793
>
> Patiencediff (used by default for "bzr diff" command) includes the ability to control how many lines of context to output for each changed section. I made this accessible as an option to bzr diff, as "--context" so an example would be "bzr diff -r-2 --context 6"
>
> I have also made this accessible to Loggerhead which I will propose for merging if this goes in.
>
> This is the first time I have proposed anything for merging, if I'm doing something wrong just let me know and I'll fix it.
> --
> https://code.launchpad.net/~pauljnixon/bzr/context_in_diffs/+merge/113793
> Your team Bazaar Codereview Subscribers is subscribed to branch lp:bzr.
>
>
> https://code.launchpad.net/~pauljnixon/bzr/context_in_diffs/+merge/113793
> You are the owner of lp:~pauljnixon/bzr/context_in_diffs.

Revision history for this message
Gordon Tyler (doxxx) wrote : Posted in a previous version of this proposal

I always forget this myself: add an entry to doc/en/release-notes/bzr-2.6.txt describing your change.

Revision history for this message
Paul Nixon (pauljnixon) wrote : Posted in a previous version of this proposal

Jelmer, Gordon:

Thank you both for your advice.
I have added tests, changed the defaults to be consistent (3, the
default for patiencediff), and edited the release notes.
Is there anything else I should do?

Thank you,
---Paul

On Sun, Jul 8, 2012 at 7:04 PM, Gordon Tyler <email address hidden> wrote:
> I always forget this myself: add an entry to doc/en/release-notes/bzr-2.6.txt describing your change.
> --
> https://code.launchpad.net/~pauljnixon/bzr/context_in_diffs/+merge/113793

Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Hi Paul,

Thanks for the changes; it would still be nice to have a constant for the default number of context lines, rather than having that constant duplicated in various places in the code.

Revision history for this message
Paul Nixon (pauljnixon) wrote :

Hello Jelmer:

The first time you asked, I didn't understand what you meant, and thought you wanted it to always be 3 instead of being 3 in some places and 5 in one (something I had done for testing and forgot to take out). Now it's defined as default_context_amount at the top of bzrlib/diff.py. Is that the right place for it?

Thanks,
---Paul

> Hi Paul,
>
> Thanks for the changes; it would still be nice to have a constant for the
> default number of context lines, rather than having that constant duplicated
> in various places in the code.

Revision history for this message
Jelmer Vernooij (jelmer) wrote :

> Hello Jelmer:
>
> The first time you asked, I didn't understand what you meant, and thought you
> wanted it to always be 3 instead of being 3 in some places and 5 in one
> (something I had done for testing and forgot to take out). Now it's defined
> as default_context_amount at the top of bzrlib/diff.py. Is that the right
> place for it?
Yep, that seems reasonable. It would be nice though to have its name in all-caps, consistent with the other constant names.

Cheers,

Jelmer

Revision history for this message
Paul Nixon (pauljnixon) wrote :

Hello Jelmer:

The change you requested has been made. Should I be re-proposing for merging when I update the branch?

Thank you,
---Paul

Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Thanks! Looks good to me now.

review: Approve
Revision history for this message
Martin Packman (gz) wrote :

I'd like -C as a short option, which might be a bit confusing as this is really more like -U, but that shouldn't hold this branch up from landing.

review: Approve
Revision history for this message
Martin Packman (gz) wrote :

Can you execute the contributor agreement? It can be done online without too much fuss:

<http://www.canonical.com/contributors>

Revision history for this message
Paul Nixon (pauljnixon) wrote :

Hello Martin:

I submitted an agreement.

Thank you,
---Paul

On Sat, Jul 28, 2012 at 8:56 AM, Martin Packman
<email address hidden> wrote:
> Can you execute the contributor agreement? It can be done online without too much fuss:
>
> <http://www.canonical.com/contributors>
> --
> https://code.launchpad.net/~pauljnixon/bzr/context_in_diffs/+merge/115819
> You are the owner of lp:~pauljnixon/bzr/context_in_diffs.

Revision history for this message
Martin Packman (gz) wrote :

Thanks Paul!

Revision history for this message
Martin Packman (gz) wrote :

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/builtins.py'
2--- bzrlib/builtins.py 2012-07-23 17:56:45 +0000
3+++ bzrlib/builtins.py 2012-07-24 17:00:28 +0000
4@@ -2335,13 +2335,18 @@
5 help='Diff format to use.',
6 lazy_registry=('bzrlib.diff', 'format_registry'),
7 title='Diff format'),
8+ Option('context',
9+ help='How many lines of context to show.',
10+ type=int,
11+ ),
12 ]
13 aliases = ['di', 'dif']
14 encoding_type = 'exact'
15
16 @display_command
17 def run(self, revision=None, file_list=None, diff_options=None,
18- prefix=None, old=None, new=None, using=None, format=None):
19+ prefix=None, old=None, new=None, using=None, format=None,
20+ context=None):
21 from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
22 show_diff_trees)
23
24@@ -2380,7 +2385,7 @@
25 old_label=old_label, new_label=new_label,
26 extra_trees=extra_trees,
27 path_encoding=path_encoding,
28- using=using,
29+ using=using, context=context,
30 format_cls=format)
31
32
33
34=== modified file 'bzrlib/diff.py'
35--- bzrlib/diff.py 2011-12-18 12:46:49 +0000
36+++ bzrlib/diff.py 2012-07-24 17:00:28 +0000
37@@ -49,6 +49,7 @@
38 )
39 from bzrlib.trace import mutter, note, warning
40
41+DEFAULT_CONTEXT_AMOUNT = 3
42
43 class AtTemplate(string.Template):
44 """Templating class that uses @ instead of $."""
45@@ -72,7 +73,7 @@
46
47 def internal_diff(old_filename, oldlines, new_filename, newlines, to_file,
48 allow_binary=False, sequence_matcher=None,
49- path_encoding='utf8'):
50+ path_encoding='utf8', context_lines=DEFAULT_CONTEXT_AMOUNT):
51 # FIXME: difflib is wrong if there is no trailing newline.
52 # The syntax used by patch seems to be "\ No newline at
53 # end of file" following the last diff line from that
54@@ -98,7 +99,7 @@
55 ud = patiencediff.unified_diff(oldlines, newlines,
56 fromfile=old_filename.encode(path_encoding, 'replace'),
57 tofile=new_filename.encode(path_encoding, 'replace'),
58- sequencematcher=sequence_matcher)
59+ n=context_lines, sequencematcher=sequence_matcher)
60
61 ud = list(ud)
62 if len(ud) == 0: # Identical contents, nothing to do
63@@ -426,7 +427,8 @@
64 extra_trees=None,
65 path_encoding='utf8',
66 using=None,
67- format_cls=None):
68+ format_cls=None,
69+ context=DEFAULT_CONTEXT_AMOUNT):
70 """Show in text form the changes from one tree to another.
71
72 :param to_file: The output stream.
73@@ -439,6 +441,8 @@
74 otherwise is supposed to be utf8
75 :param format_cls: Formatter class (DiffTree subclass)
76 """
77+ if context is None:
78+ context = DEFAULT_CONTEXT_AMOUNT
79 if format_cls is None:
80 format_cls = DiffTree
81 old_tree.lock_read()
82@@ -451,7 +455,8 @@
83 differ = format_cls.from_trees_options(old_tree, new_tree, to_file,
84 path_encoding,
85 external_diff_options,
86- old_label, new_label, using)
87+ old_label, new_label, using,
88+ context_lines=context)
89 return differ.show_diff(specific_files, extra_trees)
90 finally:
91 new_tree.unlock()
92@@ -615,13 +620,15 @@
93 # or removed in a diff.
94 EPOCH_DATE = '1970-01-01 00:00:00 +0000'
95
96- def __init__(self, old_tree, new_tree, to_file, path_encoding='utf-8',
97- old_label='', new_label='', text_differ=internal_diff):
98+ def __init__(self, old_tree, new_tree, to_file, path_encoding='utf-8',
99+ old_label='', new_label='', text_differ=internal_diff,
100+ context_lines=DEFAULT_CONTEXT_AMOUNT):
101 DiffPath.__init__(self, old_tree, new_tree, to_file, path_encoding)
102 self.text_differ = text_differ
103 self.old_label = old_label
104 self.new_label = new_label
105 self.path_encoding = path_encoding
106+ self.context_lines = context_lines
107
108 def diff(self, file_id, old_path, new_path, old_kind, new_kind):
109 """Compare two files in unified diff format
110@@ -675,7 +682,8 @@
111 from_text = _get_text(self.old_tree, from_file_id, from_path)
112 to_text = _get_text(self.new_tree, to_file_id, to_path)
113 self.text_differ(from_label, from_text, to_label, to_text,
114- self.to_file, path_encoding=self.path_encoding)
115+ self.to_file, path_encoding=self.path_encoding,
116+ context_lines=self.context_lines)
117 except errors.BinaryFile:
118 self.to_file.write(
119 ("Binary files %s and %s differ\n" %
120@@ -905,7 +913,7 @@
121 @classmethod
122 def from_trees_options(klass, old_tree, new_tree, to_file,
123 path_encoding, external_diff_options, old_label,
124- new_label, using):
125+ new_label, using, context_lines):
126 """Factory for producing a DiffTree.
127
128 Designed to accept options used by show_diff_trees.
129@@ -926,7 +934,7 @@
130 extra_factories = []
131 if external_diff_options:
132 opts = external_diff_options.split()
133- def diff_file(olab, olines, nlab, nlines, to_file, path_encoding=None):
134+ def diff_file(olab, olines, nlab, nlines, to_file, path_encoding=None, context_lines=None):
135 """:param path_encoding: not used but required
136 to match the signature of internal_diff.
137 """
138@@ -934,7 +942,7 @@
139 else:
140 diff_file = internal_diff
141 diff_text = DiffText(old_tree, new_tree, to_file, path_encoding,
142- old_label, new_label, diff_file)
143+ old_label, new_label, diff_file, context_lines=context_lines)
144 return klass(old_tree, new_tree, to_file, path_encoding, diff_text,
145 extra_factories)
146
147
148=== modified file 'bzrlib/tests/test_diff.py'
149--- bzrlib/tests/test_diff.py 2012-01-25 21:13:15 +0000
150+++ bzrlib/tests/test_diff.py 2012-07-24 17:00:28 +0000
151@@ -211,6 +211,69 @@
152 self.assertIsInstance(output.getvalue(), str,
153 'internal_diff should return bytestrings')
154
155+ def test_internal_diff_default_context(self):
156+ output = StringIO()
157+ diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
158+ 'same_text\n','same_text\n','old_text\n'],
159+ 'new', ['same_text\n','same_text\n','same_text\n',
160+ 'same_text\n','same_text\n','new_text\n'], output)
161+ lines = output.getvalue().splitlines(True)
162+ self.check_patch(lines)
163+ self.assertEquals(['--- old\n',
164+ '+++ new\n',
165+ '@@ -3,4 +3,4 @@\n',
166+ ' same_text\n',
167+ ' same_text\n',
168+ ' same_text\n',
169+ '-old_text\n',
170+ '+new_text\n',
171+ '\n',
172+ ]
173+ , lines)
174+
175+ def test_internal_diff_no_context(self):
176+ output = StringIO()
177+ diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
178+ 'same_text\n','same_text\n','old_text\n'],
179+ 'new', ['same_text\n','same_text\n','same_text\n',
180+ 'same_text\n','same_text\n','new_text\n'], output,
181+ context_lines=0)
182+ lines = output.getvalue().splitlines(True)
183+ self.check_patch(lines)
184+ self.assertEquals(['--- old\n',
185+ '+++ new\n',
186+ '@@ -6,1 +6,1 @@\n',
187+ '-old_text\n',
188+ '+new_text\n',
189+ '\n',
190+ ]
191+ , lines)
192+
193+ def test_internal_diff_more_context(self):
194+ output = StringIO()
195+ diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
196+ 'same_text\n','same_text\n','old_text\n'],
197+ 'new', ['same_text\n','same_text\n','same_text\n',
198+ 'same_text\n','same_text\n','new_text\n'], output,
199+ context_lines=4)
200+ lines = output.getvalue().splitlines(True)
201+ self.check_patch(lines)
202+ self.assertEquals(['--- old\n',
203+ '+++ new\n',
204+ '@@ -2,5 +2,5 @@\n',
205+ ' same_text\n',
206+ ' same_text\n',
207+ ' same_text\n',
208+ ' same_text\n',
209+ '-old_text\n',
210+ '+new_text\n',
211+ '\n',
212+ ]
213+ , lines)
214+
215+
216+
217+
218
219 class TestDiffFiles(tests.TestCaseInTempDir):
220
221
222=== modified file 'doc/en/release-notes/bzr-2.6.txt'
223--- doc/en/release-notes/bzr-2.6.txt 2012-07-24 12:53:36 +0000
224+++ doc/en/release-notes/bzr-2.6.txt 2012-07-24 17:00:28 +0000
225@@ -21,6 +21,10 @@
226 * ``bzr switch --store`` now stores uncommitted changes in the branch, and
227 restores them when switching back to the branch. (Aaron Bentley)
228
229+* New option '--context' for 'bzr diff' command, to configure the amount of
230+ context (i.e. showing lines that have not changed). Also available as the
231+ named parameter 'context_lines' to bzrlib.diff.internal_diff(). (Paul Nixon)
232+
233 Improvements
234 ************
235