mercurial/metadata.py
changeset 45516 1f50bcc96595
parent 45346 c6eea5804551
child 45517 df87821081ee
equal deleted inserted replaced
45515:e3df1f560d9a 45516:1f50bcc96595
    21     sidedata as sidedatamod,
    21     sidedata as sidedatamod,
    22 )
    22 )
    23 
    23 
    24 
    24 
    25 class ChangingFiles(object):
    25 class ChangingFiles(object):
    26     """A class recording the changes made to a file by a revision
    26     """A class recording the changes made to a file by a changeset
       
    27 
       
    28     Actions performed on files are gathered into 3 sets:
       
    29 
       
    30     - added:   files actively added in the changeset.
       
    31     - removed: files removed in the revision
       
    32     - touched: files affected by the merge
       
    33 
       
    34     and copies information is held by 2 mappings
       
    35 
       
    36     - copied_from_p1: {"<new-name>": "<source-name-in-p1>"} mapping for copies
       
    37     - copied_from_p2: {"<new-name>": "<source-name-in-p2>"} mapping for copies
       
    38 
       
    39     See their inline help for details.
    27     """
    40     """
    28 
    41 
    29     def __init__(
    42     def __init__(
    30         self, touched=(), added=(), removed=(), p1_copies=(), p2_copies=(),
    43         self, touched=(), added=(), removed=(), p1_copies=(), p2_copies=(),
    31     ):
    44     ):
    37         self._p1_copies = dict(p1_copies)
    50         self._p1_copies = dict(p1_copies)
    38         self._p2_copies = dict(p2_copies)
    51         self._p2_copies = dict(p2_copies)
    39 
    52 
    40     @property
    53     @property
    41     def added(self):
    54     def added(self):
       
    55         """files actively added in the changeset
       
    56 
       
    57         Any file present in that revision that was absent in all the changeset's
       
    58         parents.
       
    59 
       
    60         In case of merge, this means a file absent in one of the parents but
       
    61         existing in the other will *not* be contained in this set. (They were
       
    62         added by an ancestor)
       
    63         """
    42         return frozenset(self._added)
    64         return frozenset(self._added)
    43 
    65 
    44     def mark_added(self, filename):
    66     def mark_added(self, filename):
    45         self._added.add(filename)
    67         self._added.add(filename)
    46         self._touched.add(filename)
    68         self._touched.add(filename)
    49         for f in filenames:
    71         for f in filenames:
    50             self.mark_added(f)
    72             self.mark_added(f)
    51 
    73 
    52     @property
    74     @property
    53     def removed(self):
    75     def removed(self):
       
    76         """files actively removed by the changeset
       
    77 
       
    78         In case of merge this will only contain the set of files removing "new"
       
    79         content. For any file absent in the current changeset:
       
    80 
       
    81         a) If the file exists in both parents, it is clearly "actively" removed
       
    82         by this changeset.
       
    83 
       
    84         b) If a file exists in only one parent and in none of the common
       
    85         ancestors, then the file was newly added in one of the merged branches
       
    86         and then got "actively" removed.
       
    87 
       
    88         c) If a file exists in only one parent and at least one of the common
       
    89         ancestors using the same filenode, then the file was unchanged on one
       
    90         side and deleted on the other side. The merge "passively" propagated
       
    91         that deletion, but didn't "actively" remove the file. In this case the
       
    92         file is *not* included in the `removed` set.
       
    93 
       
    94         d) If a file exists in only one parent and at least one of the common
       
    95         ancestors using a different filenode, then the file was changed on one
       
    96         side and removed on the other side. The merge process "actively"
       
    97         decided to drop the new change and delete the file. Unlike in the
       
    98         previous case, (c), the file included in the `removed` set.
       
    99 
       
   100         Summary table for merge:
       
   101 
       
   102         case | exists in parents | exists in gca || removed
       
   103          (a) |       both        |     *         ||   yes
       
   104          (b) |       one         |     none      ||   yes
       
   105          (c) |       one         | same filenode ||   no
       
   106          (d) |       one         |  new filenode ||   yes
       
   107         """
    54         return frozenset(self._removed)
   108         return frozenset(self._removed)
    55 
   109 
    56     def mark_removed(self, filename):
   110     def mark_removed(self, filename):
    57         self._removed.add(filename)
   111         self._removed.add(filename)
    58         self._touched.add(filename)
   112         self._touched.add(filename)
    61         for f in filenames:
   115         for f in filenames:
    62             self.mark_removed(f)
   116             self.mark_removed(f)
    63 
   117 
    64     @property
   118     @property
    65     def touched(self):
   119     def touched(self):
       
   120         """files either actively modified, added or removed"""
    66         return frozenset(self._touched)
   121         return frozenset(self._touched)
    67 
   122 
    68     def mark_touched(self, filename):
   123     def mark_touched(self, filename):
    69         self._touched.add(filename)
   124         self._touched.add(filename)
    70 
   125