mercurial/pure/diffhelpers.py
author the31k <the31k@thethirty.one>
Thu, 31 Aug 2017 18:24:08 +0300
changeset 34091 abf91c4f9608
parent 27336 80214358ac88
child 37566 f53b55b162f4
permissions -rw-r--r--
branches: correctly show inactive multiheaded branches Issue being fixed here: `hg branches` incorrectly renders inactive multiheaded branches as active if they have closed heads. Example: ``` $ hg log --template '{rev}:{node|short} "{desc}" ({branch}) [parents: {parents}]\n' 4:2e2fa7af8357 "merge" (default) [parents: 0:c94e548c8c7d 3:7be622ae5832 ] 3:7be622ae5832 "2" (somebranch) [parents: 1:81c1d9458987 ] 2:be82cf30409c "close" (somebranch) [parents: ] 1:81c1d9458987 "1" (somebranch) [parents: ] 0:c94e548c8c7d "initial" (default) [parents: ] $ hg branches default 4:2e2fa7af8357 somebranch 3:7be622ae5832 ``` Branch `somebranch` have two heads, the 1st one being closed (rev 2) and the other one being merged into default (rev 3). This branch should be shown as inactive one. This happens because we intersect branch heads with repo heads to check branch activity. In this case intersection in a set with one node (rev 2). This head is closed but the branch is marked as active nevertheless. Fix is to check branch activity by intersecting only open heads set. Fixed output: ``` $ hg branches default 4:2e2fa7af8357 somebranch 3:7be622ae5832 (inactive) ``` Relevant tests for multihead branches added to test-branches suite. Implentation note about adding `iteropen` method: At first I have tried to modify `iterbranches` is such a way that it would filter out closed heads itself. For example it could have `closed=False` parameter. But in this case we would have to filter closed tips as well. Reasoning in terms of `hg branches` we actually are not allowed to do this. Also, we need to do heads filtering only if tip is not closed itself. But if it is - we are ok to skip filtering, because branch is already known to be inactive. So we can't implement heads filtering in `iterbranches` in elegant way, because we will end up with something like `closed_heads=False` or even `closed_heads_is_tip_is_open`. Finally I decided to move this logic to the `branches` function, adding `iteropen` helper method. Differential Revision: https://phab.mercurial-scm.org/D583
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
     1
# diffhelpers.py - pure Python implementation of diffhelpers.c
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
     2
#
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
     3
# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7702
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 8225
diff changeset
     6
# GNU General Public License version 2 or any later version.
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
     7
27336
80214358ac88 diffhelpers: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 12387
diff changeset
     8
from __future__ import absolute_import
80214358ac88 diffhelpers: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 12387
diff changeset
     9
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    10
def addlines(fp, hunk, lena, lenb, a, b):
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    11
    while True:
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    12
        todoa = lena - len(a)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    13
        todob = lenb - len(b)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    14
        num = max(todoa, todob)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    15
        if num == 0:
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    16
            break
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    17
        for i in xrange(num):
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    18
            s = fp.readline()
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    19
            c = s[0]
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    20
            if s == "\\ No newline at end of file\n":
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    21
                fix_newline(hunk, a, b)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    22
                continue
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    23
            if c == "\n":
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    24
                # Some patches may be missing the control char
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    25
                # on empty lines. Supply a leading space.
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    26
                s = " \n"
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    27
            hunk.append(s)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    28
            if c == "+":
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    29
                b.append(s[1:])
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    30
            elif c == "-":
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    31
                a.append(s)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    32
            else:
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    33
                b.append(s[1:])
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    34
                a.append(s)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    35
    return 0
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    36
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    37
def fix_newline(hunk, a, b):
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    38
    l = hunk[-1]
10551
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
    39
    # tolerate CRLF in last line
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
    40
    if l.endswith('\r\n'):
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
    41
        hline = l[:-2]
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
    42
    else:
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
    43
        hline = l[:-1]
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
    44
    c = hline[0]
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    45
12387
4f8067c94729 cleanup: use x in (a, b) instead of x == a or x == b
Brodie Rao <brodie@bitheap.org>
parents: 10551
diff changeset
    46
    if c in " +":
10551
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
    47
        b[-1] = hline[1:]
12387
4f8067c94729 cleanup: use x in (a, b) instead of x == a or x == b
Brodie Rao <brodie@bitheap.org>
parents: 10551
diff changeset
    48
    if c in " -":
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    49
        a[-1] = hline
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    50
    hunk[-1] = hline
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    51
    return 0
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    52
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    53
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    54
def testhunk(a, b, bstart):
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    55
    alen = len(a)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    56
    blen = len(b)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    57
    if alen > blen - bstart:
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    58
        return -1
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    59
    for i in xrange(alen):
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    60
        if a[i][1:] != b[i + bstart]:
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    61
            return -1
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    62
    return 0