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': |
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 |