mercurial/merge.py
changeset 20651 c1a52dd56eb4
parent 20642 0dc7a50345c2
child 20652 2a4871c2511d
equal deleted inserted replaced
20650:e811b93f2cb1 20651:c1a52dd56eb4
    45     O: the node of the "other" part of the merge (hexified version)
    45     O: the node of the "other" part of the merge (hexified version)
    46     F: a file to be merged entry
    46     F: a file to be merged entry
    47     '''
    47     '''
    48     statepathv1 = "merge/state"
    48     statepathv1 = "merge/state"
    49     statepathv2 = "merge/state2"
    49     statepathv2 = "merge/state2"
       
    50 
    50     def __init__(self, repo):
    51     def __init__(self, repo):
    51         self._repo = repo
    52         self._repo = repo
    52         self._dirty = False
    53         self._dirty = False
    53         self._read()
    54         self._read()
       
    55 
    54     def reset(self, node=None, other=None):
    56     def reset(self, node=None, other=None):
    55         self._state = {}
    57         self._state = {}
    56         if node:
    58         if node:
    57             self._local = node
    59             self._local = node
    58             self._other = other
    60             self._other = other
    59         shutil.rmtree(self._repo.join("merge"), True)
    61         shutil.rmtree(self._repo.join("merge"), True)
    60         self._dirty = False
    62         self._dirty = False
       
    63 
    61     def _read(self):
    64     def _read(self):
    62         self._state = {}
    65         self._state = {}
    63         records = self._readrecords()
    66         records = self._readrecords()
    64         for rtype, record in records:
    67         for rtype, record in records:
    65             if rtype == 'L':
    68             if rtype == 'L':
    71                 self._state[bits[0]] = bits[1:]
    74                 self._state[bits[0]] = bits[1:]
    72             elif not rtype.islower():
    75             elif not rtype.islower():
    73                 raise util.Abort(_('unsupported merge state record:'
    76                 raise util.Abort(_('unsupported merge state record:'
    74                                    % rtype))
    77                                    % rtype))
    75         self._dirty = False
    78         self._dirty = False
       
    79 
    76     def _readrecords(self):
    80     def _readrecords(self):
    77         v1records = self._readrecordsv1()
    81         v1records = self._readrecordsv1()
    78         v2records = self._readrecordsv2()
    82         v2records = self._readrecordsv2()
    79         oldv2 = set() # old format version of v2 record
    83         oldv2 = set() # old format version of v2 record
    80         for rec in v2records:
    84         for rec in v2records:
    99                         bits.insert(-2, '')
   103                         bits.insert(-2, '')
   100                         v1records[idx] = (r[0], "\0".join(bits))
   104                         v1records[idx] = (r[0], "\0".join(bits))
   101                 return v1records
   105                 return v1records
   102         else:
   106         else:
   103             return v2records
   107             return v2records
       
   108 
   104     def _readrecordsv1(self):
   109     def _readrecordsv1(self):
   105         records = []
   110         records = []
   106         try:
   111         try:
   107             f = self._repo.opener(self.statepathv1)
   112             f = self._repo.opener(self.statepathv1)
   108             for i, l in enumerate(f):
   113             for i, l in enumerate(f):
   113             f.close()
   118             f.close()
   114         except IOError, err:
   119         except IOError, err:
   115             if err.errno != errno.ENOENT:
   120             if err.errno != errno.ENOENT:
   116                 raise
   121                 raise
   117         return records
   122         return records
       
   123 
   118     def _readrecordsv2(self):
   124     def _readrecordsv2(self):
   119         records = []
   125         records = []
   120         try:
   126         try:
   121             f = self._repo.opener(self.statepathv2)
   127             f = self._repo.opener(self.statepathv2)
   122             data = f.read()
   128             data = f.read()
   133             f.close()
   139             f.close()
   134         except IOError, err:
   140         except IOError, err:
   135             if err.errno != errno.ENOENT:
   141             if err.errno != errno.ENOENT:
   136                 raise
   142                 raise
   137         return records
   143         return records
       
   144 
   138     def commit(self):
   145     def commit(self):
   139         if self._dirty:
   146         if self._dirty:
   140             records = []
   147             records = []
   141             records.append(("L", hex(self._local)))
   148             records.append(("L", hex(self._local)))
   142             records.append(("O", hex(self._other)))
   149             records.append(("O", hex(self._other)))
   143             for d, v in self._state.iteritems():
   150             for d, v in self._state.iteritems():
   144                 records.append(("F", "\0".join([d] + v)))
   151                 records.append(("F", "\0".join([d] + v)))
   145             self._writerecords(records)
   152             self._writerecords(records)
   146             self._dirty = False
   153             self._dirty = False
       
   154 
   147     def _writerecords(self, records):
   155     def _writerecords(self, records):
   148         self._writerecordsv1(records)
   156         self._writerecordsv1(records)
   149         self._writerecordsv2(records)
   157         self._writerecordsv2(records)
       
   158 
   150     def _writerecordsv1(self, records):
   159     def _writerecordsv1(self, records):
   151         f = self._repo.opener(self.statepathv1, "w")
   160         f = self._repo.opener(self.statepathv1, "w")
   152         irecords = iter(records)
   161         irecords = iter(records)
   153         lrecords = irecords.next()
   162         lrecords = irecords.next()
   154         assert lrecords[0] == 'L'
   163         assert lrecords[0] == 'L'
   155         f.write(hex(self._local) + "\n")
   164         f.write(hex(self._local) + "\n")
   156         for rtype, data in irecords:
   165         for rtype, data in irecords:
   157             if rtype == "F":
   166             if rtype == "F":
   158                 f.write("%s\n" % _droponode(data))
   167                 f.write("%s\n" % _droponode(data))
   159         f.close()
   168         f.close()
       
   169 
   160     def _writerecordsv2(self, records):
   170     def _writerecordsv2(self, records):
   161         f = self._repo.opener(self.statepathv2, "w")
   171         f = self._repo.opener(self.statepathv2, "w")
   162         for key, data in records:
   172         for key, data in records:
   163             assert len(key) == 1
   173             assert len(key) == 1
   164             format = ">sI%is" % len(data)
   174             format = ">sI%is" % len(data)
   165             f.write(_pack(format, key, len(data), data))
   175             f.write(_pack(format, key, len(data), data))
   166         f.close()
   176         f.close()
       
   177 
   167     def add(self, fcl, fco, fca, fd):
   178     def add(self, fcl, fco, fca, fd):
   168         hash = util.sha1(fcl.path()).hexdigest()
   179         hash = util.sha1(fcl.path()).hexdigest()
   169         self._repo.opener.write("merge/" + hash, fcl.data())
   180         self._repo.opener.write("merge/" + hash, fcl.data())
   170         self._state[fd] = ['u', hash, fcl.path(),
   181         self._state[fd] = ['u', hash, fcl.path(),
   171                            fca.path(), hex(fca.filenode()),
   182                            fca.path(), hex(fca.filenode()),
   172                            fco.path(), hex(fco.filenode()),
   183                            fco.path(), hex(fco.filenode()),
   173                            fcl.flags()]
   184                            fcl.flags()]
   174         self._dirty = True
   185         self._dirty = True
       
   186 
   175     def __contains__(self, dfile):
   187     def __contains__(self, dfile):
   176         return dfile in self._state
   188         return dfile in self._state
       
   189 
   177     def __getitem__(self, dfile):
   190     def __getitem__(self, dfile):
   178         return self._state[dfile][0]
   191         return self._state[dfile][0]
       
   192 
   179     def __iter__(self):
   193     def __iter__(self):
   180         l = self._state.keys()
   194         l = self._state.keys()
   181         l.sort()
   195         l.sort()
   182         for f in l:
   196         for f in l:
   183             yield f
   197             yield f
       
   198 
   184     def files(self):
   199     def files(self):
   185         return self._state.keys()
   200         return self._state.keys()
       
   201 
   186     def mark(self, dfile, state):
   202     def mark(self, dfile, state):
   187         self._state[dfile][0] = state
   203         self._state[dfile][0] = state
   188         self._dirty = True
   204         self._dirty = True
       
   205 
   189     def resolve(self, dfile, wctx):
   206     def resolve(self, dfile, wctx):
   190         if self[dfile] == 'r':
   207         if self[dfile] == 'r':
   191             return 0
   208             return 0
   192         stateentry = self._state[dfile]
   209         stateentry = self._state[dfile]
   193         state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
   210         state, hash, lfile, afile, anode, ofile, onode, flags = stateentry