##// END OF EJS Templates
log: add -L/--line-range option to follow file history by line range...
Denis Laxalde -
r34858:84c6b938 default
parent child Browse files
Show More
This diff has been collapsed as it changes many lines, (869 lines changed) Show them Hide them
@@ -0,0 +1,869 b''
1 $ cat >> $HGRCPATH << EOF
2 > [diff]
3 > git = true
4 > EOF
5
6 $ hg init
7 $ cat > foo << EOF
8 > 0
9 > 1
10 > 2
11 > 3
12 > 4
13 > EOF
14 $ hg ci -Am init
15 adding foo
16 $ cat > foo << EOF
17 > 0
18 > 0
19 > 0
20 > 0
21 > 1
22 > 2
23 > 3
24 > 4
25 > EOF
26 $ hg ci -m 'more 0'
27 $ sed 's/2/2+/' foo > foo.new
28 $ mv foo.new foo
29 $ cat > bar << EOF
30 > a
31 > b
32 > c
33 > d
34 > e
35 > EOF
36 $ hg add bar
37 $ hg ci -Am "2 -> 2+; added bar"
38 $ cat >> foo << EOF
39 > 5
40 > 6
41 > 7
42 > 8
43 > 9
44 > 10
45 > 11
46 > EOF
47 $ hg ci -m "to 11"
48
49 Add some changes with two diff hunks
50
51 $ sed 's/^1$/ 1/' foo > foo.new
52 $ mv foo.new foo
53 $ sed 's/^11$/11+/' foo > foo.new
54 $ mv foo.new foo
55 $ hg ci -m '11 -> 11+; leading space before "1"'
56 (make sure there are two hunks in "foo")
57 $ hg diff -c .
58 diff --git a/foo b/foo
59 --- a/foo
60 +++ b/foo
61 @@ -2,7 +2,7 @@
62 0
63 0
64 0
65 -1
66 + 1
67 2+
68 3
69 4
70 @@ -12,4 +12,4 @@
71 8
72 9
73 10
74 -11
75 +11+
76 $ sed 's/3/3+/' foo > foo.new
77 $ mv foo.new foo
78 $ sed 's/^11+$/11-/' foo > foo.new
79 $ mv foo.new foo
80 $ sed 's/a/a+/' bar > bar.new
81 $ mv bar.new bar
82 $ hg ci -m 'foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+'
83 (make sure there are two hunks in "foo")
84 $ hg diff -c . foo
85 diff --git a/foo b/foo
86 --- a/foo
87 +++ b/foo
88 @@ -4,7 +4,7 @@
89 0
90 1
91 2+
92 -3
93 +3+
94 4
95 5
96 6
97 @@ -12,4 +12,4 @@
98 8
99 9
100 10
101 -11+
102 +11-
103
104 $ hg log -f -L foo,5-7 -p
105 changeset: 5:cfdf972b3971
106 tag: tip
107 user: test
108 date: Thu Jan 01 00:00:00 1970 +0000
109 summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
110
111 diff --git a/foo b/foo
112 --- a/foo
113 +++ b/foo
114 @@ -4,7 +4,7 @@
115 0
116 1
117 2+
118 -3
119 +3+
120 4
121 5
122 6
123
124 changeset: 4:eaec41c1a0c9
125 user: test
126 date: Thu Jan 01 00:00:00 1970 +0000
127 summary: 11 -> 11+; leading space before "1"
128
129 diff --git a/foo b/foo
130 --- a/foo
131 +++ b/foo
132 @@ -2,7 +2,7 @@
133 0
134 0
135 0
136 -1
137 + 1
138 2+
139 3
140 4
141
142 changeset: 2:63a884426fd0
143 user: test
144 date: Thu Jan 01 00:00:00 1970 +0000
145 summary: 2 -> 2+; added bar
146
147 diff --git a/foo b/foo
148 --- a/foo
149 +++ b/foo
150 @@ -3,6 +3,6 @@
151 0
152 0
153 1
154 -2
155 +2+
156 3
157 4
158
159 changeset: 0:5ae1f82b9a00
160 user: test
161 date: Thu Jan 01 00:00:00 1970 +0000
162 summary: init
163
164 diff --git a/foo b/foo
165 new file mode 100644
166 --- /dev/null
167 +++ b/foo
168 @@ -0,0 +1,5 @@
169 +0
170 +1
171 +2
172 +3
173 +4
174
175
176 With --template.
177
178 $ hg log -f -L foo,5-7 -T '{rev}:{node|short} {desc|firstline}\n'
179 5:cfdf972b3971 foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
180 4:eaec41c1a0c9 11 -> 11+; leading space before "1"
181 2:63a884426fd0 2 -> 2+; added bar
182 0:5ae1f82b9a00 init
183 $ hg log -f -L foo,5-7 -T json
184 [
185 {
186 "rev": 5,
187 "node": "cfdf972b3971a2a59638bf9583c0debbffee5404",
188 "branch": "default",
189 "phase": "draft",
190 "user": "test",
191 "date": [0, 0],
192 "desc": "foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+",
193 "bookmarks": [],
194 "tags": ["tip"],
195 "parents": ["eaec41c1a0c9ad0a5e999611d0149d171beffb8c"]
196 },
197 {
198 "rev": 4,
199 "node": "eaec41c1a0c9ad0a5e999611d0149d171beffb8c",
200 "branch": "default",
201 "phase": "draft",
202 "user": "test",
203 "date": [0, 0],
204 "desc": "11 -> 11+; leading space before \"1\"",
205 "bookmarks": [],
206 "tags": [],
207 "parents": ["730a61fbaecf426c17c2c66bc42d195b5d5b0ba8"]
208 },
209 {
210 "rev": 2,
211 "node": "63a884426fd0b277fcd55895bbb2f230434576eb",
212 "branch": "default",
213 "phase": "draft",
214 "user": "test",
215 "date": [0, 0],
216 "desc": "2 -> 2+; added bar",
217 "bookmarks": [],
218 "tags": [],
219 "parents": ["29a1e7c6b80024f63f310a2d71de979e9d2996d7"]
220 },
221 {
222 "rev": 0,
223 "node": "5ae1f82b9a000ff1e0967d0dac1c58b9d796e1b4",
224 "branch": "default",
225 "phase": "draft",
226 "user": "test",
227 "date": [0, 0],
228 "desc": "init",
229 "bookmarks": [],
230 "tags": [],
231 "parents": ["0000000000000000000000000000000000000000"]
232 }
233 ]
234
235 With some white-space diff option, respective revisions are skipped.
236
237 $ hg log -f -L foo,5-7 -p --config diff.ignorews=true
238 changeset: 5:cfdf972b3971
239 tag: tip
240 user: test
241 date: Thu Jan 01 00:00:00 1970 +0000
242 summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
243
244 diff --git a/foo b/foo
245 --- a/foo
246 +++ b/foo
247 @@ -4,7 +4,7 @@
248 0
249 1
250 2+
251 -3
252 +3+
253 4
254 5
255 6
256
257 changeset: 2:63a884426fd0
258 user: test
259 date: Thu Jan 01 00:00:00 1970 +0000
260 summary: 2 -> 2+; added bar
261
262 diff --git a/foo b/foo
263 --- a/foo
264 +++ b/foo
265 @@ -3,6 +3,6 @@
266 0
267 0
268 1
269 -2
270 +2+
271 3
272 4
273
274 changeset: 0:5ae1f82b9a00
275 user: test
276 date: Thu Jan 01 00:00:00 1970 +0000
277 summary: init
278
279 diff --git a/foo b/foo
280 new file mode 100644
281 --- /dev/null
282 +++ b/foo
283 @@ -0,0 +1,5 @@
284 +0
285 +1
286 +2
287 +3
288 +4
289
290
291 Regular file patterns are allowed with -L and their diff shows all lines.
292
293 $ hg log -f -L foo,5-7 -p bar
294 changeset: 5:cfdf972b3971
295 tag: tip
296 user: test
297 date: Thu Jan 01 00:00:00 1970 +0000
298 summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
299
300 diff --git a/bar b/bar
301 --- a/bar
302 +++ b/bar
303 @@ -1,4 +1,4 @@
304 -a
305 +a+
306 b
307 c
308 d
309 diff --git a/foo b/foo
310 --- a/foo
311 +++ b/foo
312 @@ -4,7 +4,7 @@
313 0
314 1
315 2+
316 -3
317 +3+
318 4
319 5
320 6
321
322 changeset: 2:63a884426fd0
323 user: test
324 date: Thu Jan 01 00:00:00 1970 +0000
325 summary: 2 -> 2+; added bar
326
327 diff --git a/bar b/bar
328 new file mode 100644
329 --- /dev/null
330 +++ b/bar
331 @@ -0,0 +1,5 @@
332 +a
333 +b
334 +c
335 +d
336 +e
337 diff --git a/foo b/foo
338 --- a/foo
339 +++ b/foo
340 @@ -3,6 +3,6 @@
341 0
342 0
343 1
344 -2
345 +2+
346 3
347 4
348
349
350 Option --rev acts as a restriction.
351
352 $ hg log -f -L foo,5-7 -p -r 'desc(2)'
353 changeset: 2:63a884426fd0
354 user: test
355 date: Thu Jan 01 00:00:00 1970 +0000
356 summary: 2 -> 2+; added bar
357
358 diff --git a/foo b/foo
359 --- a/foo
360 +++ b/foo
361 @@ -3,6 +3,6 @@
362 0
363 0
364 1
365 -2
366 +2+
367 3
368 4
369
370 changeset: 0:5ae1f82b9a00
371 user: test
372 date: Thu Jan 01 00:00:00 1970 +0000
373 summary: init
374
375 diff --git a/foo b/foo
376 new file mode 100644
377 --- /dev/null
378 +++ b/foo
379 @@ -0,0 +1,5 @@
380 +0
381 +1
382 +2
383 +3
384 +4
385
386
387 With several -L patterns, changes touching any files in their respective line
388 range are show.
389
390 $ hg log -f -L foo,5-7 -L bar,1-2 -p
391 changeset: 5:cfdf972b3971
392 tag: tip
393 user: test
394 date: Thu Jan 01 00:00:00 1970 +0000
395 summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
396
397 diff --git a/bar b/bar
398 --- a/bar
399 +++ b/bar
400 @@ -1,4 +1,4 @@
401 -a
402 +a+
403 b
404 c
405 d
406 diff --git a/foo b/foo
407 --- a/foo
408 +++ b/foo
409 @@ -4,7 +4,7 @@
410 0
411 1
412 2+
413 -3
414 +3+
415 4
416 5
417 6
418
419 changeset: 4:eaec41c1a0c9
420 user: test
421 date: Thu Jan 01 00:00:00 1970 +0000
422 summary: 11 -> 11+; leading space before "1"
423
424 diff --git a/foo b/foo
425 --- a/foo
426 +++ b/foo
427 @@ -2,7 +2,7 @@
428 0
429 0
430 0
431 -1
432 + 1
433 2+
434 3
435 4
436
437 changeset: 2:63a884426fd0
438 user: test
439 date: Thu Jan 01 00:00:00 1970 +0000
440 summary: 2 -> 2+; added bar
441
442 diff --git a/bar b/bar
443 new file mode 100644
444 --- /dev/null
445 +++ b/bar
446 @@ -0,0 +1,5 @@
447 +a
448 +b
449 +c
450 +d
451 +e
452 diff --git a/foo b/foo
453 --- a/foo
454 +++ b/foo
455 @@ -3,6 +3,6 @@
456 0
457 0
458 1
459 -2
460 +2+
461 3
462 4
463
464 changeset: 0:5ae1f82b9a00
465 user: test
466 date: Thu Jan 01 00:00:00 1970 +0000
467 summary: init
468
469 diff --git a/foo b/foo
470 new file mode 100644
471 --- /dev/null
472 +++ b/foo
473 @@ -0,0 +1,5 @@
474 +0
475 +1
476 +2
477 +3
478 +4
479
480
481 Multiple -L options with the same file yields changes touching any of
482 specified line ranges.
483
484 $ hg log -f -L foo,5-7 -L foo,14-15 -p
485 changeset: 5:cfdf972b3971
486 tag: tip
487 user: test
488 date: Thu Jan 01 00:00:00 1970 +0000
489 summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
490
491 diff --git a/foo b/foo
492 --- a/foo
493 +++ b/foo
494 @@ -4,7 +4,7 @@
495 0
496 1
497 2+
498 -3
499 +3+
500 4
501 5
502 6
503 @@ -12,4 +12,4 @@
504 8
505 9
506 10
507 -11+
508 +11-
509
510 changeset: 4:eaec41c1a0c9
511 user: test
512 date: Thu Jan 01 00:00:00 1970 +0000
513 summary: 11 -> 11+; leading space before "1"
514
515 diff --git a/foo b/foo
516 --- a/foo
517 +++ b/foo
518 @@ -2,7 +2,7 @@
519 0
520 0
521 0
522 -1
523 + 1
524 2+
525 3
526 4
527 @@ -12,4 +12,4 @@
528 8
529 9
530 10
531 -11
532 +11+
533
534 changeset: 3:730a61fbaecf
535 user: test
536 date: Thu Jan 01 00:00:00 1970 +0000
537 summary: to 11
538
539 diff --git a/foo b/foo
540 --- a/foo
541 +++ b/foo
542 @@ -6,3 +6,10 @@
543 2+
544 3
545 4
546 +5
547 +6
548 +7
549 +8
550 +9
551 +10
552 +11
553
554 changeset: 2:63a884426fd0
555 user: test
556 date: Thu Jan 01 00:00:00 1970 +0000
557 summary: 2 -> 2+; added bar
558
559 diff --git a/foo b/foo
560 --- a/foo
561 +++ b/foo
562 @@ -3,6 +3,6 @@
563 0
564 0
565 1
566 -2
567 +2+
568 3
569 4
570
571 changeset: 0:5ae1f82b9a00
572 user: test
573 date: Thu Jan 01 00:00:00 1970 +0000
574 summary: init
575
576 diff --git a/foo b/foo
577 new file mode 100644
578 --- /dev/null
579 +++ b/foo
580 @@ -0,0 +1,5 @@
581 +0
582 +1
583 +2
584 +3
585 +4
586
587
588 A file with a comma in its name.
589
590 $ cat > ba,z << EOF
591 > q
592 > w
593 > e
594 > r
595 > t
596 > y
597 > EOF
598 $ hg ci -Am 'querty'
599 adding ba,z
600 $ cat >> ba,z << EOF
601 > u
602 > i
603 > o
604 > p
605 > EOF
606 $ hg ci -m 'more keys'
607 $ cat > ba,z << EOF
608 > a
609 > z
610 > e
611 > r
612 > t
613 > y
614 > u
615 > i
616 > o
617 > p
618 > EOF
619 $ hg ci -m 'azerty'
620 $ hg log -f -L ba,z,1-2 -p
621 changeset: 8:52373265138b
622 tag: tip
623 user: test
624 date: Thu Jan 01 00:00:00 1970 +0000
625 summary: azerty
626
627 diff --git a/ba,z b/ba,z
628 --- a/ba,z
629 +++ b/ba,z
630 @@ -1,5 +1,5 @@
631 -q
632 -w
633 +a
634 +z
635 e
636 r
637 t
638
639 changeset: 6:96ba8850f316
640 user: test
641 date: Thu Jan 01 00:00:00 1970 +0000
642 summary: querty
643
644 diff --git a/ba,z b/ba,z
645 new file mode 100644
646 --- /dev/null
647 +++ b/ba,z
648 @@ -0,0 +1,6 @@
649 +q
650 +w
651 +e
652 +r
653 +t
654 +y
655
656
657 Exact prefix kinds work in -L options.
658
659 $ mkdir dir
660 $ cd dir
661 $ hg log -f -L path:foo,5-7 -p
662 changeset: 5:cfdf972b3971
663 user: test
664 date: Thu Jan 01 00:00:00 1970 +0000
665 summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
666
667 diff --git a/foo b/foo
668 --- a/foo
669 +++ b/foo
670 @@ -4,7 +4,7 @@
671 0
672 1
673 2+
674 -3
675 +3+
676 4
677 5
678 6
679
680 changeset: 4:eaec41c1a0c9
681 user: test
682 date: Thu Jan 01 00:00:00 1970 +0000
683 summary: 11 -> 11+; leading space before "1"
684
685 diff --git a/foo b/foo
686 --- a/foo
687 +++ b/foo
688 @@ -2,7 +2,7 @@
689 0
690 0
691 0
692 -1
693 + 1
694 2+
695 3
696 4
697
698 changeset: 2:63a884426fd0
699 user: test
700 date: Thu Jan 01 00:00:00 1970 +0000
701 summary: 2 -> 2+; added bar
702
703 diff --git a/foo b/foo
704 --- a/foo
705 +++ b/foo
706 @@ -3,6 +3,6 @@
707 0
708 0
709 1
710 -2
711 +2+
712 3
713 4
714
715 changeset: 0:5ae1f82b9a00
716 user: test
717 date: Thu Jan 01 00:00:00 1970 +0000
718 summary: init
719
720 diff --git a/foo b/foo
721 new file mode 100644
722 --- /dev/null
723 +++ b/foo
724 @@ -0,0 +1,5 @@
725 +0
726 +1
727 +2
728 +3
729 +4
730
731
732 Renames are followed.
733
734 $ hg mv ../foo baz
735 $ sed 's/1/1+/' baz > baz.new
736 $ mv baz.new baz
737 $ hg ci -m 'foo -> dir/baz; 1-1+'
738 $ hg diff -c .
739 diff --git a/foo b/dir/baz
740 rename from foo
741 rename to dir/baz
742 --- a/foo
743 +++ b/dir/baz
744 @@ -2,7 +2,7 @@
745 0
746 0
747 0
748 - 1
749 + 1+
750 2+
751 3+
752 4
753 @@ -11,5 +11,5 @@
754 7
755 8
756 9
757 -10
758 -11-
759 +1+0
760 +1+1-
761 $ hg log -f -L relpath:baz,5-7 -p
762 changeset: 9:6af29c3a778f
763 tag: tip
764 user: test
765 date: Thu Jan 01 00:00:00 1970 +0000
766 summary: foo -> dir/baz; 1-1+
767
768 diff --git a/foo b/dir/baz
769 copy from foo
770 copy to dir/baz
771 --- a/foo
772 +++ b/dir/baz
773 @@ -2,7 +2,7 @@
774 0
775 0
776 0
777 - 1
778 + 1+
779 2+
780 3+
781 4
782
783 changeset: 5:cfdf972b3971
784 user: test
785 date: Thu Jan 01 00:00:00 1970 +0000
786 summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
787
788 diff --git a/foo b/foo
789 --- a/foo
790 +++ b/foo
791 @@ -4,7 +4,7 @@
792 0
793 1
794 2+
795 -3
796 +3+
797 4
798 5
799 6
800
801 changeset: 4:eaec41c1a0c9
802 user: test
803 date: Thu Jan 01 00:00:00 1970 +0000
804 summary: 11 -> 11+; leading space before "1"
805
806 diff --git a/foo b/foo
807 --- a/foo
808 +++ b/foo
809 @@ -2,7 +2,7 @@
810 0
811 0
812 0
813 -1
814 + 1
815 2+
816 3
817 4
818
819 changeset: 2:63a884426fd0
820 user: test
821 date: Thu Jan 01 00:00:00 1970 +0000
822 summary: 2 -> 2+; added bar
823
824 diff --git a/foo b/foo
825 --- a/foo
826 +++ b/foo
827 @@ -3,6 +3,6 @@
828 0
829 0
830 1
831 -2
832 +2+
833 3
834 4
835
836 changeset: 0:5ae1f82b9a00
837 user: test
838 date: Thu Jan 01 00:00:00 1970 +0000
839 summary: init
840
841 diff --git a/foo b/foo
842 new file mode 100644
843 --- /dev/null
844 +++ b/foo
845 @@ -0,0 +1,5 @@
846 +0
847 +1
848 +2
849 +3
850 +4
851
852 Option --follow is required.
853
854 $ hg log -L foo,5-7
855 abort: --line-range requires --follow
856 [255]
857
858 Non-exact pattern kinds are not allowed.
859
860 $ cd ..
861 $ hg log -f -L glob:*a*,1-2
862 hg: parse error: line range pattern 'glob:*a*' must match exactly one file
863 [255]
864
865 Graph log does work yet.
866
867 $ hg log -f -L dir/baz,5-7 --graph
868 abort: graph not supported with line range patterns
869 [255]
@@ -26,12 +26,14 b' from . import ('
26 changelog,
26 changelog,
27 copies,
27 copies,
28 crecord as crecordmod,
28 crecord as crecordmod,
29 dagop,
29 dirstateguard,
30 dirstateguard,
30 encoding,
31 encoding,
31 error,
32 error,
32 formatter,
33 formatter,
33 graphmod,
34 graphmod,
34 match as matchmod,
35 match as matchmod,
36 mdiff,
35 obsolete,
37 obsolete,
36 patch,
38 patch,
37 pathutil,
39 pathutil,
@@ -2585,6 +2587,87 b' def getlogrevs(repo, pats, opts):'
2585
2587
2586 return revs, expr, filematcher
2588 return revs, expr, filematcher
2587
2589
2590 def _parselinerangelogopt(repo, opts):
2591 """Parse --line-range log option and return a list of tuples (filename,
2592 (fromline, toline)).
2593 """
2594 linerangebyfname = []
2595 for pat in opts.get('line_range', []):
2596 try:
2597 pat, linerange = pat.rsplit(',', 1)
2598 except ValueError:
2599 raise error.Abort(_('malformatted line-range pattern %s') % pat)
2600 try:
2601 fromline, toline = map(int, linerange.split('-'))
2602 except ValueError:
2603 raise error.Abort(_("invalid line range for %s") % pat)
2604 msg = _("line range pattern '%s' must match exactly one file") % pat
2605 fname = scmutil.parsefollowlinespattern(repo, None, pat, msg)
2606 linerangebyfname.append(
2607 (fname, util.processlinerange(fromline, toline)))
2608 return linerangebyfname
2609
2610 def getloglinerangerevs(repo, userrevs, opts):
2611 """Return (revs, filematcher, hunksfilter).
2612
2613 "revs" are revisions obtained by processing "line-range" log options and
2614 walking block ancestors of each specified file/line-range.
2615
2616 "filematcher(rev) -> match" is a factory function returning a match object
2617 for a given revision for file patterns specified in --line-range option.
2618 If neither --stat nor --patch options are passed, "filematcher" is None.
2619
2620 "hunksfilter(rev) -> filterfn(fctx, hunks)" is a factory function
2621 returning a hunks filtering function.
2622 If neither --stat nor --patch options are passed, "filterhunks" is None.
2623 """
2624 wctx = repo[None]
2625
2626 # Two-levels map of "rev -> file ctx -> [line range]".
2627 linerangesbyrev = {}
2628 for fname, (fromline, toline) in _parselinerangelogopt(repo, opts):
2629 fctx = wctx.filectx(fname)
2630 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline):
2631 rev = fctx.introrev()
2632 if rev not in userrevs:
2633 continue
2634 linerangesbyrev.setdefault(
2635 rev, {}).setdefault(
2636 fctx.path(), []).append(linerange)
2637
2638 filematcher = None
2639 hunksfilter = None
2640 if opts.get('patch') or opts.get('stat'):
2641
2642 def nofilterhunksfn(fctx, hunks):
2643 return hunks
2644
2645 def hunksfilter(rev):
2646 fctxlineranges = linerangesbyrev.get(rev)
2647 if fctxlineranges is None:
2648 return nofilterhunksfn
2649
2650 def filterfn(fctx, hunks):
2651 lineranges = fctxlineranges.get(fctx.path())
2652 if lineranges is not None:
2653 for hr, lines in hunks:
2654 if any(mdiff.hunkinrange(hr[2:], lr)
2655 for lr in lineranges):
2656 yield hr, lines
2657 else:
2658 for hunk in hunks:
2659 yield hunk
2660
2661 return filterfn
2662
2663 def filematcher(rev):
2664 files = list(linerangesbyrev.get(rev, []))
2665 return scmutil.matchfiles(repo, files)
2666
2667 revs = sorted(linerangesbyrev, reverse=True)
2668
2669 return revs, filematcher, hunksfilter
2670
2588 def _graphnodeformatter(ui, displayer):
2671 def _graphnodeformatter(ui, displayer):
2589 spec = ui.config('ui', 'graphnodetemplate')
2672 spec = ui.config('ui', 'graphnodetemplate')
2590 if not spec:
2673 if not spec:
@@ -3234,6 +3234,9 b' def locate(ui, repo, *pats, **opts):'
3234 ('k', 'keyword', [],
3234 ('k', 'keyword', [],
3235 _('do case-insensitive search for a given text'), _('TEXT')),
3235 _('do case-insensitive search for a given text'), _('TEXT')),
3236 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3236 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3237 ('L', 'line-range', [],
3238 _('follow line range of specified file (EXPERIMENTAL)'),
3239 _('FILE,RANGE')),
3237 ('', 'removed', None, _('include revisions where files were removed')),
3240 ('', 'removed', None, _('include revisions where files were removed')),
3238 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3241 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3239 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3242 ('u', 'user', [], _('revisions committed by user'), _('USER')),
@@ -3275,6 +3278,14 b' def log(ui, repo, *pats, **opts):'
3275 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
3278 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
3276 of a '|' indicates one or more revisions in a path are omitted.
3279 of a '|' indicates one or more revisions in a path are omitted.
3277
3280
3281 .. container:: verbose
3282
3283 Use -L/--line-range FILE,M-N options to follow the history of lines
3284 from M to N in FILE. With -p/--patch only diff hunks affecting
3285 specified line range will be shown. This option requires --follow;
3286 it can be specified multiple times. Currently, this option is not
3287 compatible with --graph. This option is experimental.
3288
3278 .. note::
3289 .. note::
3279
3290
3280 :hg:`log --patch` may generate unexpected diff output for merge
3291 :hg:`log --patch` may generate unexpected diff output for merge
@@ -3290,6 +3301,14 b' def log(ui, repo, *pats, **opts):'
3290
3301
3291 .. container:: verbose
3302 .. container:: verbose
3292
3303
3304 .. note::
3305
3306 The history resulting from -L/--line-range options depends on diff
3307 options; for instance if white-spaces are ignored, respective changes
3308 with only white-spaces in specified line range will not be listed.
3309
3310 .. container:: verbose
3311
3293 Some examples:
3312 Some examples:
3294
3313
3295 - changesets with full descriptions and file lists::
3314 - changesets with full descriptions and file lists::
@@ -3336,6 +3355,15 b' def log(ui, repo, *pats, **opts):'
3336
3355
3337 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3356 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3338
3357
3358 - changesets touching lines 13 to 23 for file.c::
3359
3360 hg log -L file.c,13-23
3361
3362 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
3363 main.c with patch::
3364
3365 hg log -L file.c,13-23 -L main.c,2-6 -p
3366
3339 See :hg:`help dates` for a list of formats valid for -d/--date.
3367 See :hg:`help dates` for a list of formats valid for -d/--date.
3340
3368
3341 See :hg:`help revisions` for more about specifying and ordering
3369 See :hg:`help revisions` for more about specifying and ordering
@@ -3350,14 +3378,38 b' def log(ui, repo, *pats, **opts):'
3350
3378
3351 """
3379 """
3352 opts = pycompat.byteskwargs(opts)
3380 opts = pycompat.byteskwargs(opts)
3381 linerange = opts.get('line_range')
3382
3383 if linerange and not opts.get('follow'):
3384 raise error.Abort(_('--line-range requires --follow'))
3385
3353 if opts.get('follow') and opts.get('rev'):
3386 if opts.get('follow') and opts.get('rev'):
3354 opts['rev'] = [revsetlang.formatspec('reverse(::%lr)', opts.get('rev'))]
3387 opts['rev'] = [revsetlang.formatspec('reverse(::%lr)', opts.get('rev'))]
3355 del opts['follow']
3388 del opts['follow']
3356
3389
3357 if opts.get('graph'):
3390 if opts.get('graph'):
3391 if linerange:
3392 raise error.Abort(_('graph not supported with line range patterns'))
3358 return cmdutil.graphlog(ui, repo, pats, opts)
3393 return cmdutil.graphlog(ui, repo, pats, opts)
3359
3394
3360 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
3395 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
3396 hunksfilter = None
3397
3398 if linerange:
3399 revs, lrfilematcher, hunksfilter = cmdutil.getloglinerangerevs(
3400 repo, revs, opts)
3401
3402 if filematcher is not None and lrfilematcher is not None:
3403 basefilematcher = filematcher
3404
3405 def filematcher(rev):
3406 files = (basefilematcher(rev).files()
3407 + lrfilematcher(rev).files())
3408 return scmutil.matchfiles(repo, files)
3409
3410 elif filematcher is None:
3411 filematcher = lrfilematcher
3412
3361 limit = cmdutil.loglimit(opts)
3413 limit = cmdutil.loglimit(opts)
3362 count = 0
3414 count = 0
3363
3415
@@ -3385,7 +3437,12 b' def log(ui, repo, *pats, **opts):'
3385 revmatchfn = filematcher(ctx.rev())
3437 revmatchfn = filematcher(ctx.rev())
3386 else:
3438 else:
3387 revmatchfn = None
3439 revmatchfn = None
3388 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
3440 if hunksfilter:
3441 revhunksfilter = hunksfilter(rev)
3442 else:
3443 revhunksfilter = None
3444 displayer.show(ctx, copies=copies, matchfn=revmatchfn,
3445 hunksfilterfn=revhunksfilter)
3389 if displayer.flush(ctx):
3446 if displayer.flush(ctx):
3390 count += 1
3447 count += 1
3391
3448
@@ -225,7 +225,7 b' Show all commands + options'
225 export: output, switch-parent, rev, text, git, binary, nodates
225 export: output, switch-parent, rev, text, git, binary, nodates
226 forget: include, exclude
226 forget: include, exclude
227 init: ssh, remotecmd, insecure
227 init: ssh, remotecmd, insecure
228 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
228 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
229 merge: force, rev, preview, tool
229 merge: force, rev, preview, tool
230 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
230 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
231 push: force, rev, bookmark, branch, new-branch, pushvars, ssh, remotecmd, insecure
231 push: force, rev, bookmark, branch, new-branch, pushvars, ssh, remotecmd, insecure
General Comments 0
You need to be logged in to leave comments. Login now