mercurial/tagmerge.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sat, 10 Mar 2018 18:42:00 -0800
changeset 36878 ccb70a77f746
parent 36734 b77ff4fbe9ad
child 43076 2372284d9457
permissions -rw-r--r--
hgweb: refactor 304 handling code We had generic code in wsgirequest for handling HTTP 304 responses. We also had a special case for it in the catch all exception handler in the WSGI application. We only ever raise 304 in one place. So, we don't need to treat it specially in the catch all exception handler. But it is useful to validate behavior of 304 responses. We port the code that sends a 304 to use the new response API. We then move the code for screening 304 sanity into the new response API. As part of doing so, we discovered that we would send Content-Length: 0. This is not allowed. So, we fix our response code to not emit that header for empty response bodies. Differential Revision: https://phab.mercurial-scm.org/D2794
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
     1
# tagmerge.py - merge .hgtags files
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
     2
#
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
     3
# Copyright 2014 Angel Ezquerra <angel.ezquerra@gmail.com>
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
     4
#
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
     7
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
     8
# This module implements an automatic merge algorithm for mercurial's tag files
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
     9
#
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    10
# The tagmerge algorithm implemented in this module is able to resolve most
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    11
# merge conflicts that currently would trigger a .hgtags merge conflict. The
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    12
# only case that it does not (and cannot) handle is that in which two tags point
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    13
# to different revisions on each merge parent _and_ their corresponding tag
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    14
# histories have the same rank (i.e. the same length). In all other cases the
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    15
# merge algorithm will choose the revision belonging to the parent with the
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    16
# highest ranked tag history. The merged tag history is the combination of both
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    17
# tag histories (special care is taken to try to combine common tag histories
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    18
# where possible).
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    19
#
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    20
# In addition to actually merging the tags from two parents, taking into
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    21
# account the base, the algorithm also tries to minimize the difference
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    22
# between the merged tag file and the first parent's tag file (i.e. it tries to
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    23
# make the merged tag order as as similar as possible to the first parent's tag
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    24
# file order).
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    25
#
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    26
# The algorithm works as follows:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    27
# 1. read the tags from p1, p2 and the base
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    28
#     - when reading the p1 tags, also get the line numbers associated to each
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    29
#       tag node (these will be used to sort the merged tags in a way that
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    30
#       minimizes the diff to p1). Ignore the file numbers when reading p2 and
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    31
#       the base
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    32
# 2. recover the "lost tags" (i.e. those that are found in the base but not on
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    33
#    p1 or p2) and add them back to p1 and/or p2
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    34
#     - at this point the only tags that are on p1 but not on p2 are those new
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    35
#       tags that were introduced in p1. Same thing for the tags that are on p2
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    36
#       but not on p2
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    37
# 3. take all tags that are only on p1 or only on p2 (but not on the base)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    38
#     - Note that these are the tags that were introduced between base and p1
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    39
#       and between base and p2, possibly on separate clones
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    40
# 4. for each tag found both on p1 and p2 perform the following merge algorithm:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    41
#     - the tags conflict if their tag "histories" have the same "rank" (i.e.
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 22200
diff changeset
    42
#       length) AND the last (current) tag is NOT the same
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    43
#     - for non conflicting tags:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    44
#         - choose which are the high and the low ranking nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    45
#             - the high ranking list of nodes is the one that is longer.
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    46
#               In case of draw favor p1
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    47
#             - the merged node list is made of 3 parts:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    48
#                 - first the nodes that are common to the beginning of both
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    49
#                   the low and the high ranking nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    50
#                 - second the non common low ranking nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    51
#                 - finally the non common high ranking nodes (with the last
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    52
#                   one being the merged tag node)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    53
#             - note that this is equivalent to putting the whole low ranking
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    54
#               node list first, followed by the non common high ranking nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    55
#     - note that during the merge we keep the "node line numbers", which will
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    56
#       be used when writing the merged tags to the tag file
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    57
# 5. write the merged tags taking into account to their positions in the first
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    58
#    parent (i.e. try to keep the relative ordering of the nodes that come
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    59
#    from p1). This minimizes the diff between the merged and the p1 tag files
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 22200
diff changeset
    60
#    This is done by using the following algorithm
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    61
#     - group the nodes for a given tag that must be written next to each other
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    62
#         - A: nodes that come from consecutive lines on p1
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    63
#         - B: nodes that come from p2 (i.e. whose associated line number is
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    64
#              None) and are next to one of the a nodes in A
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    65
#         - each group is associated with a line number coming from p1
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    66
#     - generate a "tag block" for each of the groups
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    67
#         - a tag block is a set of consecutive "node tag" lines belonging to
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    68
#           the same tag and which will be written next to each other on the
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    69
#           merged tags file
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    70
#     - sort the "tag blocks" according to their associated number line
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    71
#         - put blocks whose nodes come all from p2 first
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    72
#     - write the tag blocks in the sorted order
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    73
25981
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    74
from __future__ import absolute_import
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    75
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    76
from .i18n import _
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    77
from .node import (
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    78
    hex,
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    79
    nullid,
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    80
)
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    81
from .import (
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    82
    tags as tagsmod,
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    83
    util,
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    84
)
fa91c49a9b9f tagmerge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23139
diff changeset
    85
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    86
hexnullid = hex(nullid)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    87
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    88
def readtagsformerge(ui, repo, lines, fn='', keeplinenums=False):
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    89
    '''read the .hgtags file into a structure that is suitable for merging
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    90
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 22200
diff changeset
    91
    Depending on the keeplinenums flag, clear the line numbers associated
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 22200
diff changeset
    92
    with each tag. This is done because only the line numbers of the first
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 22200
diff changeset
    93
    parent are useful for merging.
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    94
    '''
22200
b27c3beaaf30 cleanup: avoid local vars shadowing imports
Mads Kiilerich <madski@unity3d.com>
parents: 21922
diff changeset
    95
    filetags = tagsmod._readtaghist(ui, repo, lines, fn=fn, recode=None,
b27c3beaaf30 cleanup: avoid local vars shadowing imports
Mads Kiilerich <madski@unity3d.com>
parents: 21922
diff changeset
    96
                                    calcnodelines=True)[1]
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    97
    for tagname, taginfo in filetags.items():
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    98
        if not keeplinenums:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
    99
            for el in taginfo:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   100
                el[1] = None
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   101
    return filetags
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   102
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   103
def grouptagnodesbyline(tagnodes):
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   104
    '''
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   105
    Group nearby nodes (i.e. those that must be written next to each other)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   106
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   107
    The input is a list of [node, position] pairs, corresponding to a given tag
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   108
    The position is the line number where the node was found on the first parent
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   109
    .hgtags file, or None for those nodes that came from the base or the second
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   110
    parent .hgtags files.
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   111
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   112
    This function groups those [node, position] pairs, returning a list of
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   113
    groups of nodes that must be written next to each other because their
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   114
    positions are consecutive or have no position preference (because their
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   115
    position is None).
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   116
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   117
    The result is a list of [position, [consecutive node list]]
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   118
    '''
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   119
    firstlinenum = None
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   120
    for hexnode, linenum in tagnodes:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   121
        firstlinenum = linenum
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   122
        if firstlinenum is not None:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   123
            break
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   124
    if firstlinenum is None:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   125
        return [[None, [el[0] for el in tagnodes]]]
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   126
    tagnodes[0][1] = firstlinenum
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   127
    groupednodes = [[firstlinenum, []]]
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   128
    prevlinenum = firstlinenum
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   129
    for hexnode, linenum in tagnodes:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   130
        if linenum is not None and linenum - prevlinenum > 1:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   131
            groupednodes.append([linenum, []])
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   132
        groupednodes[-1][1].append(hexnode)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   133
        if linenum is not None:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   134
            prevlinenum = linenum
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   135
    return groupednodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   136
33421
d1aa3fee4ca4 tagmerge: use workingfilectx to write merged tags
Phil Cohen <phillco@fb.com>
parents: 31415
diff changeset
   137
def writemergedtags(fcd, mergedtags):
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   138
    '''
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   139
    write the merged tags while trying to minimize the diff to the first parent
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   140
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   141
    This function uses the ordering info stored on the merged tags dict to
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   142
    generate an .hgtags file which is correct (in the sense that its contents
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   143
    correspond to the result of the tag merge) while also being as close as
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   144
    possible to the first parent's .hgtags file.
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   145
    '''
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   146
    # group the node-tag pairs that must be written next to each other
36733
66250de006c6 py3: do not mutate dict while iterating in tagmerge
Yuya Nishihara <yuya@tcha.org>
parents: 33421
diff changeset
   147
    for tname, taglist in list(mergedtags.items()):
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   148
        mergedtags[tname] = grouptagnodesbyline(taglist)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   149
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   150
    # convert the grouped merged tags dict into a format that resembles the
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   151
    # final .hgtags file (i.e. a list of blocks of 'node tag' pairs)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   152
    def taglist2string(tlist, tname):
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   153
        return '\n'.join(['%s %s' % (hexnode, tname) for hexnode in tlist])
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   154
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   155
    finaltags = []
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   156
    for tname, tags in mergedtags.items():
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   157
        for block in tags:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   158
            block[1] = taglist2string(block[1], tname)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   159
        finaltags += tags
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   160
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   161
    # the tag groups are linked to a "position" that can be used to sort them
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   162
    # before writing them
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   163
    # the position is calculated to ensure that the diff of the merged .hgtags
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   164
    # file to the first parent's .hgtags file is as small as possible
36734
b77ff4fbe9ad py3: work around comparison between int and None in tagmerge
Yuya Nishihara <yuya@tcha.org>
parents: 36733
diff changeset
   165
    finaltags.sort(key=lambda x: -1 if x[0] is None else x[0])
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   166
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   167
    # finally we can join the sorted groups to get the final contents of the
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   168
    # merged .hgtags file, and then write it to disk
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   169
    mergedtagstring = '\n'.join([tags for rank, tags in finaltags if tags])
33421
d1aa3fee4ca4 tagmerge: use workingfilectx to write merged tags
Phil Cohen <phillco@fb.com>
parents: 31415
diff changeset
   170
    fcd.write(mergedtagstring + '\n', fcd.flags())
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   171
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   172
def singletagmerge(p1nodes, p2nodes):
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   173
    '''
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   174
    merge the nodes corresponding to a single tag
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   175
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   176
    Note that the inputs are lists of node-linenum pairs (i.e. not just lists
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   177
    of nodes)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   178
    '''
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   179
    if not p2nodes:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   180
        return p1nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   181
    if not p1nodes:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   182
        return p2nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   183
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   184
    # there is no conflict unless both tags point to different revisions
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   185
    # and have a non identical tag history
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   186
    p1currentnode = p1nodes[-1][0]
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   187
    p2currentnode = p2nodes[-1][0]
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   188
    if p1currentnode != p2currentnode and len(p1nodes) == len(p2nodes):
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   189
        # cannot merge two tags with same rank pointing to different nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   190
        return None
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   191
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   192
    # which are the highest ranking (hr) / lowest ranking (lr) nodes?
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   193
    if len(p1nodes) >= len(p2nodes):
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   194
        hrnodes, lrnodes = p1nodes, p2nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   195
    else:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   196
        hrnodes, lrnodes = p2nodes, p1nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   197
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   198
    # the lowest ranking nodes will be written first, followed by the highest
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   199
    # ranking nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   200
    # to avoid unwanted tag rank explosion we try to see if there are some
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   201
    # common nodes that can be written only once
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   202
    commonidx = len(lrnodes)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   203
    for n in range(len(lrnodes)):
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   204
        if hrnodes[n][0] != lrnodes[n][0]:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   205
            commonidx = n
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   206
            break
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   207
        lrnodes[n][1] = p1nodes[n][1]
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   208
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   209
    # the merged node list has 3 parts:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   210
    # - common nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   211
    # - non common lowest ranking nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   212
    # - non common highest ranking nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   213
    # note that the common nodes plus the non common lowest ranking nodes is the
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   214
    # whole list of lr nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   215
    return lrnodes + hrnodes[commonidx:]
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   216
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   217
def merge(repo, fcd, fco, fca):
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   218
    '''
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   219
    Merge the tags of two revisions, taking into account the base tags
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   220
    Try to minimize the diff between the merged tags and the first parent tags
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   221
    '''
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   222
    ui = repo.ui
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   223
    # read the p1, p2 and base tags
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   224
    # only keep the line numbers for the p1 tags
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   225
    p1tags = readtagsformerge(
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   226
        ui, repo, fcd.data().splitlines(), fn="p1 tags",
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   227
        keeplinenums=True)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   228
    p2tags = readtagsformerge(
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   229
        ui, repo, fco.data().splitlines(), fn="p2 tags",
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   230
        keeplinenums=False)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   231
    basetags = readtagsformerge(
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   232
        ui, repo, fca.data().splitlines(), fn="base tags",
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   233
        keeplinenums=False)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   234
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   235
    # recover the list of "lost tags" (i.e. those that were found on the base
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   236
    # revision but not on one of the revisions being merged)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   237
    basetagset = set(basetags)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   238
    for n, pntags in enumerate((p1tags, p2tags)):
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   239
        pntagset = set(pntags)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   240
        pnlosttagset = basetagset - pntagset
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   241
        for t in pnlosttagset:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   242
            pntags[t] = basetags[t]
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   243
            if pntags[t][-1][0] != hexnullid:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   244
                pntags[t].append([hexnullid, None])
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   245
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   246
    conflictedtags = []  # for reporting purposes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   247
    mergedtags = util.sortdict(p1tags)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   248
    # sortdict does not implement iteritems()
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   249
    for tname, p2nodes in p2tags.items():
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   250
        if tname not in mergedtags:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   251
            mergedtags[tname] = p2nodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   252
            continue
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   253
        p1nodes = mergedtags[tname]
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   254
        mergednodes = singletagmerge(p1nodes, p2nodes)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   255
        if mergednodes is None:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   256
            conflictedtags.append(tname)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   257
            continue
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   258
        mergedtags[tname] = mergednodes
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   259
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   260
    if conflictedtags:
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   261
        numconflicts = len(conflictedtags)
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   262
        ui.warn(_('automatic .hgtags merge failed\n'
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   263
            'the following %d tags are in conflict: %s\n')
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   264
            % (numconflicts, ', '.join(sorted(conflictedtags))))
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   265
        return True, 1
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   266
33421
d1aa3fee4ca4 tagmerge: use workingfilectx to write merged tags
Phil Cohen <phillco@fb.com>
parents: 31415
diff changeset
   267
    writemergedtags(fcd, mergedtags)
21922
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   268
    ui.note(_('.hgtags merged successfully\n'))
50e20154cb68 filemerge: add internal:tagmerge merge tool
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
diff changeset
   269
    return False, 0