##// END OF EJS Templates
merge: add pathconflict merge state...
Mark Thomas -
r34546:19131628 default
parent child Browse files
Show More
@@ -1,1775 +1,1796 b''
1 # merge.py - directory-level update/merge handling for Mercurial
1 # merge.py - directory-level update/merge handling for Mercurial
2 #
2 #
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import errno
10 import errno
11 import hashlib
11 import hashlib
12 import shutil
12 import shutil
13 import struct
13 import struct
14
14
15 from .i18n import _
15 from .i18n import _
16 from .node import (
16 from .node import (
17 addednodeid,
17 addednodeid,
18 bin,
18 bin,
19 hex,
19 hex,
20 modifiednodeid,
20 modifiednodeid,
21 nullhex,
21 nullhex,
22 nullid,
22 nullid,
23 nullrev,
23 nullrev,
24 )
24 )
25 from . import (
25 from . import (
26 copies,
26 copies,
27 error,
27 error,
28 filemerge,
28 filemerge,
29 match as matchmod,
29 match as matchmod,
30 obsutil,
30 obsutil,
31 pycompat,
31 pycompat,
32 scmutil,
32 scmutil,
33 subrepo,
33 subrepo,
34 util,
34 util,
35 worker,
35 worker,
36 )
36 )
37
37
38 _pack = struct.pack
38 _pack = struct.pack
39 _unpack = struct.unpack
39 _unpack = struct.unpack
40
40
41 def _droponode(data):
41 def _droponode(data):
42 # used for compatibility for v1
42 # used for compatibility for v1
43 bits = data.split('\0')
43 bits = data.split('\0')
44 bits = bits[:-2] + bits[-1:]
44 bits = bits[:-2] + bits[-1:]
45 return '\0'.join(bits)
45 return '\0'.join(bits)
46
46
47 class mergestate(object):
47 class mergestate(object):
48 '''track 3-way merge state of individual files
48 '''track 3-way merge state of individual files
49
49
50 The merge state is stored on disk when needed. Two files are used: one with
50 The merge state is stored on disk when needed. Two files are used: one with
51 an old format (version 1), and one with a new format (version 2). Version 2
51 an old format (version 1), and one with a new format (version 2). Version 2
52 stores a superset of the data in version 1, including new kinds of records
52 stores a superset of the data in version 1, including new kinds of records
53 in the future. For more about the new format, see the documentation for
53 in the future. For more about the new format, see the documentation for
54 `_readrecordsv2`.
54 `_readrecordsv2`.
55
55
56 Each record can contain arbitrary content, and has an associated type. This
56 Each record can contain arbitrary content, and has an associated type. This
57 `type` should be a letter. If `type` is uppercase, the record is mandatory:
57 `type` should be a letter. If `type` is uppercase, the record is mandatory:
58 versions of Mercurial that don't support it should abort. If `type` is
58 versions of Mercurial that don't support it should abort. If `type` is
59 lowercase, the record can be safely ignored.
59 lowercase, the record can be safely ignored.
60
60
61 Currently known records:
61 Currently known records:
62
62
63 L: the node of the "local" part of the merge (hexified version)
63 L: the node of the "local" part of the merge (hexified version)
64 O: the node of the "other" part of the merge (hexified version)
64 O: the node of the "other" part of the merge (hexified version)
65 F: a file to be merged entry
65 F: a file to be merged entry
66 C: a change/delete or delete/change conflict
66 C: a change/delete or delete/change conflict
67 D: a file that the external merge driver will merge internally
67 D: a file that the external merge driver will merge internally
68 (experimental)
68 (experimental)
69 P: a path conflict (file vs directory)
69 m: the external merge driver defined for this merge plus its run state
70 m: the external merge driver defined for this merge plus its run state
70 (experimental)
71 (experimental)
71 f: a (filename, dictionary) tuple of optional values for a given file
72 f: a (filename, dictionary) tuple of optional values for a given file
72 X: unsupported mandatory record type (used in tests)
73 X: unsupported mandatory record type (used in tests)
73 x: unsupported advisory record type (used in tests)
74 x: unsupported advisory record type (used in tests)
74 l: the labels for the parts of the merge.
75 l: the labels for the parts of the merge.
75
76
76 Merge driver run states (experimental):
77 Merge driver run states (experimental):
77 u: driver-resolved files unmarked -- needs to be run next time we're about
78 u: driver-resolved files unmarked -- needs to be run next time we're about
78 to resolve or commit
79 to resolve or commit
79 m: driver-resolved files marked -- only needs to be run before commit
80 m: driver-resolved files marked -- only needs to be run before commit
80 s: success/skipped -- does not need to be run any more
81 s: success/skipped -- does not need to be run any more
81
82
83 Merge record states (stored in self._state, indexed by filename):
84 u: unresolved conflict
85 r: resolved conflict
86 pu: unresolved path conflict (file conflicts with directory)
87 pr: resolved path conflict
88 d: driver-resolved conflict
89
90 The resolve command transitions between 'u' and 'r' for conflicts and
91 'pu' and 'pr' for path conflicts.
82 '''
92 '''
83 statepathv1 = 'merge/state'
93 statepathv1 = 'merge/state'
84 statepathv2 = 'merge/state2'
94 statepathv2 = 'merge/state2'
85
95
86 @staticmethod
96 @staticmethod
87 def clean(repo, node=None, other=None, labels=None):
97 def clean(repo, node=None, other=None, labels=None):
88 """Initialize a brand new merge state, removing any existing state on
98 """Initialize a brand new merge state, removing any existing state on
89 disk."""
99 disk."""
90 ms = mergestate(repo)
100 ms = mergestate(repo)
91 ms.reset(node, other, labels)
101 ms.reset(node, other, labels)
92 return ms
102 return ms
93
103
94 @staticmethod
104 @staticmethod
95 def read(repo):
105 def read(repo):
96 """Initialize the merge state, reading it from disk."""
106 """Initialize the merge state, reading it from disk."""
97 ms = mergestate(repo)
107 ms = mergestate(repo)
98 ms._read()
108 ms._read()
99 return ms
109 return ms
100
110
101 def __init__(self, repo):
111 def __init__(self, repo):
102 """Initialize the merge state.
112 """Initialize the merge state.
103
113
104 Do not use this directly! Instead call read() or clean()."""
114 Do not use this directly! Instead call read() or clean()."""
105 self._repo = repo
115 self._repo = repo
106 self._dirty = False
116 self._dirty = False
107 self._labels = None
117 self._labels = None
108
118
109 def reset(self, node=None, other=None, labels=None):
119 def reset(self, node=None, other=None, labels=None):
110 self._state = {}
120 self._state = {}
111 self._stateextras = {}
121 self._stateextras = {}
112 self._local = None
122 self._local = None
113 self._other = None
123 self._other = None
114 self._labels = labels
124 self._labels = labels
115 for var in ('localctx', 'otherctx'):
125 for var in ('localctx', 'otherctx'):
116 if var in vars(self):
126 if var in vars(self):
117 delattr(self, var)
127 delattr(self, var)
118 if node:
128 if node:
119 self._local = node
129 self._local = node
120 self._other = other
130 self._other = other
121 self._readmergedriver = None
131 self._readmergedriver = None
122 if self.mergedriver:
132 if self.mergedriver:
123 self._mdstate = 's'
133 self._mdstate = 's'
124 else:
134 else:
125 self._mdstate = 'u'
135 self._mdstate = 'u'
126 shutil.rmtree(self._repo.vfs.join('merge'), True)
136 shutil.rmtree(self._repo.vfs.join('merge'), True)
127 self._results = {}
137 self._results = {}
128 self._dirty = False
138 self._dirty = False
129
139
130 def _read(self):
140 def _read(self):
131 """Analyse each record content to restore a serialized state from disk
141 """Analyse each record content to restore a serialized state from disk
132
142
133 This function process "record" entry produced by the de-serialization
143 This function process "record" entry produced by the de-serialization
134 of on disk file.
144 of on disk file.
135 """
145 """
136 self._state = {}
146 self._state = {}
137 self._stateextras = {}
147 self._stateextras = {}
138 self._local = None
148 self._local = None
139 self._other = None
149 self._other = None
140 for var in ('localctx', 'otherctx'):
150 for var in ('localctx', 'otherctx'):
141 if var in vars(self):
151 if var in vars(self):
142 delattr(self, var)
152 delattr(self, var)
143 self._readmergedriver = None
153 self._readmergedriver = None
144 self._mdstate = 's'
154 self._mdstate = 's'
145 unsupported = set()
155 unsupported = set()
146 records = self._readrecords()
156 records = self._readrecords()
147 for rtype, record in records:
157 for rtype, record in records:
148 if rtype == 'L':
158 if rtype == 'L':
149 self._local = bin(record)
159 self._local = bin(record)
150 elif rtype == 'O':
160 elif rtype == 'O':
151 self._other = bin(record)
161 self._other = bin(record)
152 elif rtype == 'm':
162 elif rtype == 'm':
153 bits = record.split('\0', 1)
163 bits = record.split('\0', 1)
154 mdstate = bits[1]
164 mdstate = bits[1]
155 if len(mdstate) != 1 or mdstate not in 'ums':
165 if len(mdstate) != 1 or mdstate not in 'ums':
156 # the merge driver should be idempotent, so just rerun it
166 # the merge driver should be idempotent, so just rerun it
157 mdstate = 'u'
167 mdstate = 'u'
158
168
159 self._readmergedriver = bits[0]
169 self._readmergedriver = bits[0]
160 self._mdstate = mdstate
170 self._mdstate = mdstate
161 elif rtype in 'FDC':
171 elif rtype in 'FDCP':
162 bits = record.split('\0')
172 bits = record.split('\0')
163 self._state[bits[0]] = bits[1:]
173 self._state[bits[0]] = bits[1:]
164 elif rtype == 'f':
174 elif rtype == 'f':
165 filename, rawextras = record.split('\0', 1)
175 filename, rawextras = record.split('\0', 1)
166 extraparts = rawextras.split('\0')
176 extraparts = rawextras.split('\0')
167 extras = {}
177 extras = {}
168 i = 0
178 i = 0
169 while i < len(extraparts):
179 while i < len(extraparts):
170 extras[extraparts[i]] = extraparts[i + 1]
180 extras[extraparts[i]] = extraparts[i + 1]
171 i += 2
181 i += 2
172
182
173 self._stateextras[filename] = extras
183 self._stateextras[filename] = extras
174 elif rtype == 'l':
184 elif rtype == 'l':
175 labels = record.split('\0', 2)
185 labels = record.split('\0', 2)
176 self._labels = [l for l in labels if len(l) > 0]
186 self._labels = [l for l in labels if len(l) > 0]
177 elif not rtype.islower():
187 elif not rtype.islower():
178 unsupported.add(rtype)
188 unsupported.add(rtype)
179 self._results = {}
189 self._results = {}
180 self._dirty = False
190 self._dirty = False
181
191
182 if unsupported:
192 if unsupported:
183 raise error.UnsupportedMergeRecords(unsupported)
193 raise error.UnsupportedMergeRecords(unsupported)
184
194
185 def _readrecords(self):
195 def _readrecords(self):
186 """Read merge state from disk and return a list of record (TYPE, data)
196 """Read merge state from disk and return a list of record (TYPE, data)
187
197
188 We read data from both v1 and v2 files and decide which one to use.
198 We read data from both v1 and v2 files and decide which one to use.
189
199
190 V1 has been used by version prior to 2.9.1 and contains less data than
200 V1 has been used by version prior to 2.9.1 and contains less data than
191 v2. We read both versions and check if no data in v2 contradicts
201 v2. We read both versions and check if no data in v2 contradicts
192 v1. If there is not contradiction we can safely assume that both v1
202 v1. If there is not contradiction we can safely assume that both v1
193 and v2 were written at the same time and use the extract data in v2. If
203 and v2 were written at the same time and use the extract data in v2. If
194 there is contradiction we ignore v2 content as we assume an old version
204 there is contradiction we ignore v2 content as we assume an old version
195 of Mercurial has overwritten the mergestate file and left an old v2
205 of Mercurial has overwritten the mergestate file and left an old v2
196 file around.
206 file around.
197
207
198 returns list of record [(TYPE, data), ...]"""
208 returns list of record [(TYPE, data), ...]"""
199 v1records = self._readrecordsv1()
209 v1records = self._readrecordsv1()
200 v2records = self._readrecordsv2()
210 v2records = self._readrecordsv2()
201 if self._v1v2match(v1records, v2records):
211 if self._v1v2match(v1records, v2records):
202 return v2records
212 return v2records
203 else:
213 else:
204 # v1 file is newer than v2 file, use it
214 # v1 file is newer than v2 file, use it
205 # we have to infer the "other" changeset of the merge
215 # we have to infer the "other" changeset of the merge
206 # we cannot do better than that with v1 of the format
216 # we cannot do better than that with v1 of the format
207 mctx = self._repo[None].parents()[-1]
217 mctx = self._repo[None].parents()[-1]
208 v1records.append(('O', mctx.hex()))
218 v1records.append(('O', mctx.hex()))
209 # add place holder "other" file node information
219 # add place holder "other" file node information
210 # nobody is using it yet so we do no need to fetch the data
220 # nobody is using it yet so we do no need to fetch the data
211 # if mctx was wrong `mctx[bits[-2]]` may fails.
221 # if mctx was wrong `mctx[bits[-2]]` may fails.
212 for idx, r in enumerate(v1records):
222 for idx, r in enumerate(v1records):
213 if r[0] == 'F':
223 if r[0] == 'F':
214 bits = r[1].split('\0')
224 bits = r[1].split('\0')
215 bits.insert(-2, '')
225 bits.insert(-2, '')
216 v1records[idx] = (r[0], '\0'.join(bits))
226 v1records[idx] = (r[0], '\0'.join(bits))
217 return v1records
227 return v1records
218
228
219 def _v1v2match(self, v1records, v2records):
229 def _v1v2match(self, v1records, v2records):
220 oldv2 = set() # old format version of v2 record
230 oldv2 = set() # old format version of v2 record
221 for rec in v2records:
231 for rec in v2records:
222 if rec[0] == 'L':
232 if rec[0] == 'L':
223 oldv2.add(rec)
233 oldv2.add(rec)
224 elif rec[0] == 'F':
234 elif rec[0] == 'F':
225 # drop the onode data (not contained in v1)
235 # drop the onode data (not contained in v1)
226 oldv2.add(('F', _droponode(rec[1])))
236 oldv2.add(('F', _droponode(rec[1])))
227 for rec in v1records:
237 for rec in v1records:
228 if rec not in oldv2:
238 if rec not in oldv2:
229 return False
239 return False
230 else:
240 else:
231 return True
241 return True
232
242
233 def _readrecordsv1(self):
243 def _readrecordsv1(self):
234 """read on disk merge state for version 1 file
244 """read on disk merge state for version 1 file
235
245
236 returns list of record [(TYPE, data), ...]
246 returns list of record [(TYPE, data), ...]
237
247
238 Note: the "F" data from this file are one entry short
248 Note: the "F" data from this file are one entry short
239 (no "other file node" entry)
249 (no "other file node" entry)
240 """
250 """
241 records = []
251 records = []
242 try:
252 try:
243 f = self._repo.vfs(self.statepathv1)
253 f = self._repo.vfs(self.statepathv1)
244 for i, l in enumerate(f):
254 for i, l in enumerate(f):
245 if i == 0:
255 if i == 0:
246 records.append(('L', l[:-1]))
256 records.append(('L', l[:-1]))
247 else:
257 else:
248 records.append(('F', l[:-1]))
258 records.append(('F', l[:-1]))
249 f.close()
259 f.close()
250 except IOError as err:
260 except IOError as err:
251 if err.errno != errno.ENOENT:
261 if err.errno != errno.ENOENT:
252 raise
262 raise
253 return records
263 return records
254
264
255 def _readrecordsv2(self):
265 def _readrecordsv2(self):
256 """read on disk merge state for version 2 file
266 """read on disk merge state for version 2 file
257
267
258 This format is a list of arbitrary records of the form:
268 This format is a list of arbitrary records of the form:
259
269
260 [type][length][content]
270 [type][length][content]
261
271
262 `type` is a single character, `length` is a 4 byte integer, and
272 `type` is a single character, `length` is a 4 byte integer, and
263 `content` is an arbitrary byte sequence of length `length`.
273 `content` is an arbitrary byte sequence of length `length`.
264
274
265 Mercurial versions prior to 3.7 have a bug where if there are
275 Mercurial versions prior to 3.7 have a bug where if there are
266 unsupported mandatory merge records, attempting to clear out the merge
276 unsupported mandatory merge records, attempting to clear out the merge
267 state with hg update --clean or similar aborts. The 't' record type
277 state with hg update --clean or similar aborts. The 't' record type
268 works around that by writing out what those versions treat as an
278 works around that by writing out what those versions treat as an
269 advisory record, but later versions interpret as special: the first
279 advisory record, but later versions interpret as special: the first
270 character is the 'real' record type and everything onwards is the data.
280 character is the 'real' record type and everything onwards is the data.
271
281
272 Returns list of records [(TYPE, data), ...]."""
282 Returns list of records [(TYPE, data), ...]."""
273 records = []
283 records = []
274 try:
284 try:
275 f = self._repo.vfs(self.statepathv2)
285 f = self._repo.vfs(self.statepathv2)
276 data = f.read()
286 data = f.read()
277 off = 0
287 off = 0
278 end = len(data)
288 end = len(data)
279 while off < end:
289 while off < end:
280 rtype = data[off]
290 rtype = data[off]
281 off += 1
291 off += 1
282 length = _unpack('>I', data[off:(off + 4)])[0]
292 length = _unpack('>I', data[off:(off + 4)])[0]
283 off += 4
293 off += 4
284 record = data[off:(off + length)]
294 record = data[off:(off + length)]
285 off += length
295 off += length
286 if rtype == 't':
296 if rtype == 't':
287 rtype, record = record[0], record[1:]
297 rtype, record = record[0], record[1:]
288 records.append((rtype, record))
298 records.append((rtype, record))
289 f.close()
299 f.close()
290 except IOError as err:
300 except IOError as err:
291 if err.errno != errno.ENOENT:
301 if err.errno != errno.ENOENT:
292 raise
302 raise
293 return records
303 return records
294
304
295 @util.propertycache
305 @util.propertycache
296 def mergedriver(self):
306 def mergedriver(self):
297 # protect against the following:
307 # protect against the following:
298 # - A configures a malicious merge driver in their hgrc, then
308 # - A configures a malicious merge driver in their hgrc, then
299 # pauses the merge
309 # pauses the merge
300 # - A edits their hgrc to remove references to the merge driver
310 # - A edits their hgrc to remove references to the merge driver
301 # - A gives a copy of their entire repo, including .hg, to B
311 # - A gives a copy of their entire repo, including .hg, to B
302 # - B inspects .hgrc and finds it to be clean
312 # - B inspects .hgrc and finds it to be clean
303 # - B then continues the merge and the malicious merge driver
313 # - B then continues the merge and the malicious merge driver
304 # gets invoked
314 # gets invoked
305 configmergedriver = self._repo.ui.config('experimental', 'mergedriver')
315 configmergedriver = self._repo.ui.config('experimental', 'mergedriver')
306 if (self._readmergedriver is not None
316 if (self._readmergedriver is not None
307 and self._readmergedriver != configmergedriver):
317 and self._readmergedriver != configmergedriver):
308 raise error.ConfigError(
318 raise error.ConfigError(
309 _("merge driver changed since merge started"),
319 _("merge driver changed since merge started"),
310 hint=_("revert merge driver change or abort merge"))
320 hint=_("revert merge driver change or abort merge"))
311
321
312 return configmergedriver
322 return configmergedriver
313
323
314 @util.propertycache
324 @util.propertycache
315 def localctx(self):
325 def localctx(self):
316 if self._local is None:
326 if self._local is None:
317 msg = "localctx accessed but self._local isn't set"
327 msg = "localctx accessed but self._local isn't set"
318 raise error.ProgrammingError(msg)
328 raise error.ProgrammingError(msg)
319 return self._repo[self._local]
329 return self._repo[self._local]
320
330
321 @util.propertycache
331 @util.propertycache
322 def otherctx(self):
332 def otherctx(self):
323 if self._other is None:
333 if self._other is None:
324 msg = "otherctx accessed but self._other isn't set"
334 msg = "otherctx accessed but self._other isn't set"
325 raise error.ProgrammingError(msg)
335 raise error.ProgrammingError(msg)
326 return self._repo[self._other]
336 return self._repo[self._other]
327
337
328 def active(self):
338 def active(self):
329 """Whether mergestate is active.
339 """Whether mergestate is active.
330
340
331 Returns True if there appears to be mergestate. This is a rough proxy
341 Returns True if there appears to be mergestate. This is a rough proxy
332 for "is a merge in progress."
342 for "is a merge in progress."
333 """
343 """
334 # Check local variables before looking at filesystem for performance
344 # Check local variables before looking at filesystem for performance
335 # reasons.
345 # reasons.
336 return bool(self._local) or bool(self._state) or \
346 return bool(self._local) or bool(self._state) or \
337 self._repo.vfs.exists(self.statepathv1) or \
347 self._repo.vfs.exists(self.statepathv1) or \
338 self._repo.vfs.exists(self.statepathv2)
348 self._repo.vfs.exists(self.statepathv2)
339
349
340 def commit(self):
350 def commit(self):
341 """Write current state on disk (if necessary)"""
351 """Write current state on disk (if necessary)"""
342 if self._dirty:
352 if self._dirty:
343 records = self._makerecords()
353 records = self._makerecords()
344 self._writerecords(records)
354 self._writerecords(records)
345 self._dirty = False
355 self._dirty = False
346
356
347 def _makerecords(self):
357 def _makerecords(self):
348 records = []
358 records = []
349 records.append(('L', hex(self._local)))
359 records.append(('L', hex(self._local)))
350 records.append(('O', hex(self._other)))
360 records.append(('O', hex(self._other)))
351 if self.mergedriver:
361 if self.mergedriver:
352 records.append(('m', '\0'.join([
362 records.append(('m', '\0'.join([
353 self.mergedriver, self._mdstate])))
363 self.mergedriver, self._mdstate])))
354 for d, v in self._state.iteritems():
364 for d, v in self._state.iteritems():
355 if v[0] == 'd':
365 if v[0] == 'd':
356 records.append(('D', '\0'.join([d] + v)))
366 records.append(('D', '\0'.join([d] + v)))
367 elif v[0] in ('pu', 'pr'):
368 records.append(('P', '\0'.join([d] + v)))
357 # v[1] == local ('cd'), v[6] == other ('dc') -- not supported by
369 # v[1] == local ('cd'), v[6] == other ('dc') -- not supported by
358 # older versions of Mercurial
370 # older versions of Mercurial
359 elif v[1] == nullhex or v[6] == nullhex:
371 elif v[1] == nullhex or v[6] == nullhex:
360 records.append(('C', '\0'.join([d] + v)))
372 records.append(('C', '\0'.join([d] + v)))
361 else:
373 else:
362 records.append(('F', '\0'.join([d] + v)))
374 records.append(('F', '\0'.join([d] + v)))
363 for filename, extras in sorted(self._stateextras.iteritems()):
375 for filename, extras in sorted(self._stateextras.iteritems()):
364 rawextras = '\0'.join('%s\0%s' % (k, v) for k, v in
376 rawextras = '\0'.join('%s\0%s' % (k, v) for k, v in
365 extras.iteritems())
377 extras.iteritems())
366 records.append(('f', '%s\0%s' % (filename, rawextras)))
378 records.append(('f', '%s\0%s' % (filename, rawextras)))
367 if self._labels is not None:
379 if self._labels is not None:
368 labels = '\0'.join(self._labels)
380 labels = '\0'.join(self._labels)
369 records.append(('l', labels))
381 records.append(('l', labels))
370 return records
382 return records
371
383
372 def _writerecords(self, records):
384 def _writerecords(self, records):
373 """Write current state on disk (both v1 and v2)"""
385 """Write current state on disk (both v1 and v2)"""
374 self._writerecordsv1(records)
386 self._writerecordsv1(records)
375 self._writerecordsv2(records)
387 self._writerecordsv2(records)
376
388
377 def _writerecordsv1(self, records):
389 def _writerecordsv1(self, records):
378 """Write current state on disk in a version 1 file"""
390 """Write current state on disk in a version 1 file"""
379 f = self._repo.vfs(self.statepathv1, 'w')
391 f = self._repo.vfs(self.statepathv1, 'w')
380 irecords = iter(records)
392 irecords = iter(records)
381 lrecords = next(irecords)
393 lrecords = next(irecords)
382 assert lrecords[0] == 'L'
394 assert lrecords[0] == 'L'
383 f.write(hex(self._local) + '\n')
395 f.write(hex(self._local) + '\n')
384 for rtype, data in irecords:
396 for rtype, data in irecords:
385 if rtype == 'F':
397 if rtype == 'F':
386 f.write('%s\n' % _droponode(data))
398 f.write('%s\n' % _droponode(data))
387 f.close()
399 f.close()
388
400
389 def _writerecordsv2(self, records):
401 def _writerecordsv2(self, records):
390 """Write current state on disk in a version 2 file
402 """Write current state on disk in a version 2 file
391
403
392 See the docstring for _readrecordsv2 for why we use 't'."""
404 See the docstring for _readrecordsv2 for why we use 't'."""
393 # these are the records that all version 2 clients can read
405 # these are the records that all version 2 clients can read
394 whitelist = 'LOF'
406 whitelist = 'LOF'
395 f = self._repo.vfs(self.statepathv2, 'w')
407 f = self._repo.vfs(self.statepathv2, 'w')
396 for key, data in records:
408 for key, data in records:
397 assert len(key) == 1
409 assert len(key) == 1
398 if key not in whitelist:
410 if key not in whitelist:
399 key, data = 't', '%s%s' % (key, data)
411 key, data = 't', '%s%s' % (key, data)
400 format = '>sI%is' % len(data)
412 format = '>sI%is' % len(data)
401 f.write(_pack(format, key, len(data), data))
413 f.write(_pack(format, key, len(data), data))
402 f.close()
414 f.close()
403
415
404 def add(self, fcl, fco, fca, fd):
416 def add(self, fcl, fco, fca, fd):
405 """add a new (potentially?) conflicting file the merge state
417 """add a new (potentially?) conflicting file the merge state
406 fcl: file context for local,
418 fcl: file context for local,
407 fco: file context for remote,
419 fco: file context for remote,
408 fca: file context for ancestors,
420 fca: file context for ancestors,
409 fd: file path of the resulting merge.
421 fd: file path of the resulting merge.
410
422
411 note: also write the local version to the `.hg/merge` directory.
423 note: also write the local version to the `.hg/merge` directory.
412 """
424 """
413 if fcl.isabsent():
425 if fcl.isabsent():
414 hash = nullhex
426 hash = nullhex
415 else:
427 else:
416 hash = hex(hashlib.sha1(fcl.path()).digest())
428 hash = hex(hashlib.sha1(fcl.path()).digest())
417 self._repo.vfs.write('merge/' + hash, fcl.data())
429 self._repo.vfs.write('merge/' + hash, fcl.data())
418 self._state[fd] = ['u', hash, fcl.path(),
430 self._state[fd] = ['u', hash, fcl.path(),
419 fca.path(), hex(fca.filenode()),
431 fca.path(), hex(fca.filenode()),
420 fco.path(), hex(fco.filenode()),
432 fco.path(), hex(fco.filenode()),
421 fcl.flags()]
433 fcl.flags()]
422 self._stateextras[fd] = {'ancestorlinknode': hex(fca.node())}
434 self._stateextras[fd] = {'ancestorlinknode': hex(fca.node())}
423 self._dirty = True
435 self._dirty = True
424
436
437 def addpath(self, path, frename, forigin):
438 """add a new conflicting path to the merge state
439 path: the path that conflicts
440 frename: the filename the conflicting file was renamed to
441 forigin: origin of the file ('l' or 'r' for local/remote)
442 """
443 self._state[path] = ['pu', frename, forigin]
444 self._dirty = True
445
425 def __contains__(self, dfile):
446 def __contains__(self, dfile):
426 return dfile in self._state
447 return dfile in self._state
427
448
428 def __getitem__(self, dfile):
449 def __getitem__(self, dfile):
429 return self._state[dfile][0]
450 return self._state[dfile][0]
430
451
431 def __iter__(self):
452 def __iter__(self):
432 return iter(sorted(self._state))
453 return iter(sorted(self._state))
433
454
434 def files(self):
455 def files(self):
435 return self._state.keys()
456 return self._state.keys()
436
457
437 def mark(self, dfile, state):
458 def mark(self, dfile, state):
438 self._state[dfile][0] = state
459 self._state[dfile][0] = state
439 self._dirty = True
460 self._dirty = True
440
461
441 def mdstate(self):
462 def mdstate(self):
442 return self._mdstate
463 return self._mdstate
443
464
444 def unresolved(self):
465 def unresolved(self):
445 """Obtain the paths of unresolved files."""
466 """Obtain the paths of unresolved files."""
446
467
447 for f, entry in self._state.iteritems():
468 for f, entry in self._state.iteritems():
448 if entry[0] == 'u':
469 if entry[0] in ('u', 'pu'):
449 yield f
470 yield f
450
471
451 def driverresolved(self):
472 def driverresolved(self):
452 """Obtain the paths of driver-resolved files."""
473 """Obtain the paths of driver-resolved files."""
453
474
454 for f, entry in self._state.items():
475 for f, entry in self._state.items():
455 if entry[0] == 'd':
476 if entry[0] == 'd':
456 yield f
477 yield f
457
478
458 def extras(self, filename):
479 def extras(self, filename):
459 return self._stateextras.setdefault(filename, {})
480 return self._stateextras.setdefault(filename, {})
460
481
461 def _resolve(self, preresolve, dfile, wctx):
482 def _resolve(self, preresolve, dfile, wctx):
462 """rerun merge process for file path `dfile`"""
483 """rerun merge process for file path `dfile`"""
463 if self[dfile] in 'rd':
484 if self[dfile] in 'rd':
464 return True, 0
485 return True, 0
465 stateentry = self._state[dfile]
486 stateentry = self._state[dfile]
466 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
487 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
467 octx = self._repo[self._other]
488 octx = self._repo[self._other]
468 extras = self.extras(dfile)
489 extras = self.extras(dfile)
469 anccommitnode = extras.get('ancestorlinknode')
490 anccommitnode = extras.get('ancestorlinknode')
470 if anccommitnode:
491 if anccommitnode:
471 actx = self._repo[anccommitnode]
492 actx = self._repo[anccommitnode]
472 else:
493 else:
473 actx = None
494 actx = None
474 fcd = self._filectxorabsent(hash, wctx, dfile)
495 fcd = self._filectxorabsent(hash, wctx, dfile)
475 fco = self._filectxorabsent(onode, octx, ofile)
496 fco = self._filectxorabsent(onode, octx, ofile)
476 # TODO: move this to filectxorabsent
497 # TODO: move this to filectxorabsent
477 fca = self._repo.filectx(afile, fileid=anode, changeid=actx)
498 fca = self._repo.filectx(afile, fileid=anode, changeid=actx)
478 # "premerge" x flags
499 # "premerge" x flags
479 flo = fco.flags()
500 flo = fco.flags()
480 fla = fca.flags()
501 fla = fca.flags()
481 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
502 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
482 if fca.node() == nullid and flags != flo:
503 if fca.node() == nullid and flags != flo:
483 if preresolve:
504 if preresolve:
484 self._repo.ui.warn(
505 self._repo.ui.warn(
485 _('warning: cannot merge flags for %s '
506 _('warning: cannot merge flags for %s '
486 'without common ancestor - keeping local flags\n')
507 'without common ancestor - keeping local flags\n')
487 % afile)
508 % afile)
488 elif flags == fla:
509 elif flags == fla:
489 flags = flo
510 flags = flo
490 if preresolve:
511 if preresolve:
491 # restore local
512 # restore local
492 if hash != nullhex:
513 if hash != nullhex:
493 f = self._repo.vfs('merge/' + hash)
514 f = self._repo.vfs('merge/' + hash)
494 wctx[dfile].write(f.read(), flags)
515 wctx[dfile].write(f.read(), flags)
495 f.close()
516 f.close()
496 else:
517 else:
497 wctx[dfile].remove(ignoremissing=True)
518 wctx[dfile].remove(ignoremissing=True)
498 complete, r, deleted = filemerge.premerge(self._repo, wctx,
519 complete, r, deleted = filemerge.premerge(self._repo, wctx,
499 self._local, lfile, fcd,
520 self._local, lfile, fcd,
500 fco, fca,
521 fco, fca,
501 labels=self._labels)
522 labels=self._labels)
502 else:
523 else:
503 complete, r, deleted = filemerge.filemerge(self._repo, wctx,
524 complete, r, deleted = filemerge.filemerge(self._repo, wctx,
504 self._local, lfile, fcd,
525 self._local, lfile, fcd,
505 fco, fca,
526 fco, fca,
506 labels=self._labels)
527 labels=self._labels)
507 if r is None:
528 if r is None:
508 # no real conflict
529 # no real conflict
509 del self._state[dfile]
530 del self._state[dfile]
510 self._stateextras.pop(dfile, None)
531 self._stateextras.pop(dfile, None)
511 self._dirty = True
532 self._dirty = True
512 elif not r:
533 elif not r:
513 self.mark(dfile, 'r')
534 self.mark(dfile, 'r')
514
535
515 if complete:
536 if complete:
516 action = None
537 action = None
517 if deleted:
538 if deleted:
518 if fcd.isabsent():
539 if fcd.isabsent():
519 # dc: local picked. Need to drop if present, which may
540 # dc: local picked. Need to drop if present, which may
520 # happen on re-resolves.
541 # happen on re-resolves.
521 action = 'f'
542 action = 'f'
522 else:
543 else:
523 # cd: remote picked (or otherwise deleted)
544 # cd: remote picked (or otherwise deleted)
524 action = 'r'
545 action = 'r'
525 else:
546 else:
526 if fcd.isabsent(): # dc: remote picked
547 if fcd.isabsent(): # dc: remote picked
527 action = 'g'
548 action = 'g'
528 elif fco.isabsent(): # cd: local picked
549 elif fco.isabsent(): # cd: local picked
529 if dfile in self.localctx:
550 if dfile in self.localctx:
530 action = 'am'
551 action = 'am'
531 else:
552 else:
532 action = 'a'
553 action = 'a'
533 # else: regular merges (no action necessary)
554 # else: regular merges (no action necessary)
534 self._results[dfile] = r, action
555 self._results[dfile] = r, action
535
556
536 return complete, r
557 return complete, r
537
558
538 def _filectxorabsent(self, hexnode, ctx, f):
559 def _filectxorabsent(self, hexnode, ctx, f):
539 if hexnode == nullhex:
560 if hexnode == nullhex:
540 return filemerge.absentfilectx(ctx, f)
561 return filemerge.absentfilectx(ctx, f)
541 else:
562 else:
542 return ctx[f]
563 return ctx[f]
543
564
544 def preresolve(self, dfile, wctx):
565 def preresolve(self, dfile, wctx):
545 """run premerge process for dfile
566 """run premerge process for dfile
546
567
547 Returns whether the merge is complete, and the exit code."""
568 Returns whether the merge is complete, and the exit code."""
548 return self._resolve(True, dfile, wctx)
569 return self._resolve(True, dfile, wctx)
549
570
550 def resolve(self, dfile, wctx):
571 def resolve(self, dfile, wctx):
551 """run merge process (assuming premerge was run) for dfile
572 """run merge process (assuming premerge was run) for dfile
552
573
553 Returns the exit code of the merge."""
574 Returns the exit code of the merge."""
554 return self._resolve(False, dfile, wctx)[1]
575 return self._resolve(False, dfile, wctx)[1]
555
576
556 def counts(self):
577 def counts(self):
557 """return counts for updated, merged and removed files in this
578 """return counts for updated, merged and removed files in this
558 session"""
579 session"""
559 updated, merged, removed = 0, 0, 0
580 updated, merged, removed = 0, 0, 0
560 for r, action in self._results.itervalues():
581 for r, action in self._results.itervalues():
561 if r is None:
582 if r is None:
562 updated += 1
583 updated += 1
563 elif r == 0:
584 elif r == 0:
564 if action == 'r':
585 if action == 'r':
565 removed += 1
586 removed += 1
566 else:
587 else:
567 merged += 1
588 merged += 1
568 return updated, merged, removed
589 return updated, merged, removed
569
590
570 def unresolvedcount(self):
591 def unresolvedcount(self):
571 """get unresolved count for this merge (persistent)"""
592 """get unresolved count for this merge (persistent)"""
572 return len(list(self.unresolved()))
593 return len(list(self.unresolved()))
573
594
574 def actions(self):
595 def actions(self):
575 """return lists of actions to perform on the dirstate"""
596 """return lists of actions to perform on the dirstate"""
576 actions = {'r': [], 'f': [], 'a': [], 'am': [], 'g': []}
597 actions = {'r': [], 'f': [], 'a': [], 'am': [], 'g': []}
577 for f, (r, action) in self._results.iteritems():
598 for f, (r, action) in self._results.iteritems():
578 if action is not None:
599 if action is not None:
579 actions[action].append((f, None, "merge result"))
600 actions[action].append((f, None, "merge result"))
580 return actions
601 return actions
581
602
582 def recordactions(self):
603 def recordactions(self):
583 """record remove/add/get actions in the dirstate"""
604 """record remove/add/get actions in the dirstate"""
584 branchmerge = self._repo.dirstate.p2() != nullid
605 branchmerge = self._repo.dirstate.p2() != nullid
585 recordupdates(self._repo, self.actions(), branchmerge)
606 recordupdates(self._repo, self.actions(), branchmerge)
586
607
587 def queueremove(self, f):
608 def queueremove(self, f):
588 """queues a file to be removed from the dirstate
609 """queues a file to be removed from the dirstate
589
610
590 Meant for use by custom merge drivers."""
611 Meant for use by custom merge drivers."""
591 self._results[f] = 0, 'r'
612 self._results[f] = 0, 'r'
592
613
593 def queueadd(self, f):
614 def queueadd(self, f):
594 """queues a file to be added to the dirstate
615 """queues a file to be added to the dirstate
595
616
596 Meant for use by custom merge drivers."""
617 Meant for use by custom merge drivers."""
597 self._results[f] = 0, 'a'
618 self._results[f] = 0, 'a'
598
619
599 def queueget(self, f):
620 def queueget(self, f):
600 """queues a file to be marked modified in the dirstate
621 """queues a file to be marked modified in the dirstate
601
622
602 Meant for use by custom merge drivers."""
623 Meant for use by custom merge drivers."""
603 self._results[f] = 0, 'g'
624 self._results[f] = 0, 'g'
604
625
605 def _getcheckunknownconfig(repo, section, name):
626 def _getcheckunknownconfig(repo, section, name):
606 config = repo.ui.config(section, name)
627 config = repo.ui.config(section, name)
607 valid = ['abort', 'ignore', 'warn']
628 valid = ['abort', 'ignore', 'warn']
608 if config not in valid:
629 if config not in valid:
609 validstr = ', '.join(["'" + v + "'" for v in valid])
630 validstr = ', '.join(["'" + v + "'" for v in valid])
610 raise error.ConfigError(_("%s.%s not valid "
631 raise error.ConfigError(_("%s.%s not valid "
611 "('%s' is none of %s)")
632 "('%s' is none of %s)")
612 % (section, name, config, validstr))
633 % (section, name, config, validstr))
613 return config
634 return config
614
635
615 def _checkunknownfile(repo, wctx, mctx, f, f2=None):
636 def _checkunknownfile(repo, wctx, mctx, f, f2=None):
616 if f2 is None:
637 if f2 is None:
617 f2 = f
638 f2 = f
618 return (repo.wvfs.audit.check(f)
639 return (repo.wvfs.audit.check(f)
619 and repo.wvfs.isfileorlink(f)
640 and repo.wvfs.isfileorlink(f)
620 and repo.dirstate.normalize(f) not in repo.dirstate
641 and repo.dirstate.normalize(f) not in repo.dirstate
621 and mctx[f2].cmp(wctx[f]))
642 and mctx[f2].cmp(wctx[f]))
622
643
623 def _checkunknownfiles(repo, wctx, mctx, force, actions, mergeforce):
644 def _checkunknownfiles(repo, wctx, mctx, force, actions, mergeforce):
624 """
645 """
625 Considers any actions that care about the presence of conflicting unknown
646 Considers any actions that care about the presence of conflicting unknown
626 files. For some actions, the result is to abort; for others, it is to
647 files. For some actions, the result is to abort; for others, it is to
627 choose a different action.
648 choose a different action.
628 """
649 """
629 conflicts = set()
650 conflicts = set()
630 warnconflicts = set()
651 warnconflicts = set()
631 abortconflicts = set()
652 abortconflicts = set()
632 unknownconfig = _getcheckunknownconfig(repo, 'merge', 'checkunknown')
653 unknownconfig = _getcheckunknownconfig(repo, 'merge', 'checkunknown')
633 ignoredconfig = _getcheckunknownconfig(repo, 'merge', 'checkignored')
654 ignoredconfig = _getcheckunknownconfig(repo, 'merge', 'checkignored')
634 if not force:
655 if not force:
635 def collectconflicts(conflicts, config):
656 def collectconflicts(conflicts, config):
636 if config == 'abort':
657 if config == 'abort':
637 abortconflicts.update(conflicts)
658 abortconflicts.update(conflicts)
638 elif config == 'warn':
659 elif config == 'warn':
639 warnconflicts.update(conflicts)
660 warnconflicts.update(conflicts)
640
661
641 for f, (m, args, msg) in actions.iteritems():
662 for f, (m, args, msg) in actions.iteritems():
642 if m in ('c', 'dc'):
663 if m in ('c', 'dc'):
643 if _checkunknownfile(repo, wctx, mctx, f):
664 if _checkunknownfile(repo, wctx, mctx, f):
644 conflicts.add(f)
665 conflicts.add(f)
645 elif m == 'dg':
666 elif m == 'dg':
646 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
667 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
647 conflicts.add(f)
668 conflicts.add(f)
648
669
649 ignoredconflicts = set([c for c in conflicts
670 ignoredconflicts = set([c for c in conflicts
650 if repo.dirstate._ignore(c)])
671 if repo.dirstate._ignore(c)])
651 unknownconflicts = conflicts - ignoredconflicts
672 unknownconflicts = conflicts - ignoredconflicts
652 collectconflicts(ignoredconflicts, ignoredconfig)
673 collectconflicts(ignoredconflicts, ignoredconfig)
653 collectconflicts(unknownconflicts, unknownconfig)
674 collectconflicts(unknownconflicts, unknownconfig)
654 else:
675 else:
655 for f, (m, args, msg) in actions.iteritems():
676 for f, (m, args, msg) in actions.iteritems():
656 if m == 'cm':
677 if m == 'cm':
657 fl2, anc = args
678 fl2, anc = args
658 different = _checkunknownfile(repo, wctx, mctx, f)
679 different = _checkunknownfile(repo, wctx, mctx, f)
659 if repo.dirstate._ignore(f):
680 if repo.dirstate._ignore(f):
660 config = ignoredconfig
681 config = ignoredconfig
661 else:
682 else:
662 config = unknownconfig
683 config = unknownconfig
663
684
664 # The behavior when force is True is described by this table:
685 # The behavior when force is True is described by this table:
665 # config different mergeforce | action backup
686 # config different mergeforce | action backup
666 # * n * | get n
687 # * n * | get n
667 # * y y | merge -
688 # * y y | merge -
668 # abort y n | merge - (1)
689 # abort y n | merge - (1)
669 # warn y n | warn + get y
690 # warn y n | warn + get y
670 # ignore y n | get y
691 # ignore y n | get y
671 #
692 #
672 # (1) this is probably the wrong behavior here -- we should
693 # (1) this is probably the wrong behavior here -- we should
673 # probably abort, but some actions like rebases currently
694 # probably abort, but some actions like rebases currently
674 # don't like an abort happening in the middle of
695 # don't like an abort happening in the middle of
675 # merge.update.
696 # merge.update.
676 if not different:
697 if not different:
677 actions[f] = ('g', (fl2, False), "remote created")
698 actions[f] = ('g', (fl2, False), "remote created")
678 elif mergeforce or config == 'abort':
699 elif mergeforce or config == 'abort':
679 actions[f] = ('m', (f, f, None, False, anc),
700 actions[f] = ('m', (f, f, None, False, anc),
680 "remote differs from untracked local")
701 "remote differs from untracked local")
681 elif config == 'abort':
702 elif config == 'abort':
682 abortconflicts.add(f)
703 abortconflicts.add(f)
683 else:
704 else:
684 if config == 'warn':
705 if config == 'warn':
685 warnconflicts.add(f)
706 warnconflicts.add(f)
686 actions[f] = ('g', (fl2, True), "remote created")
707 actions[f] = ('g', (fl2, True), "remote created")
687
708
688 for f in sorted(abortconflicts):
709 for f in sorted(abortconflicts):
689 repo.ui.warn(_("%s: untracked file differs\n") % f)
710 repo.ui.warn(_("%s: untracked file differs\n") % f)
690 if abortconflicts:
711 if abortconflicts:
691 raise error.Abort(_("untracked files in working directory "
712 raise error.Abort(_("untracked files in working directory "
692 "differ from files in requested revision"))
713 "differ from files in requested revision"))
693
714
694 for f in sorted(warnconflicts):
715 for f in sorted(warnconflicts):
695 repo.ui.warn(_("%s: replacing untracked file\n") % f)
716 repo.ui.warn(_("%s: replacing untracked file\n") % f)
696
717
697 for f, (m, args, msg) in actions.iteritems():
718 for f, (m, args, msg) in actions.iteritems():
698 backup = f in conflicts
719 backup = f in conflicts
699 if m == 'c':
720 if m == 'c':
700 flags, = args
721 flags, = args
701 actions[f] = ('g', (flags, backup), msg)
722 actions[f] = ('g', (flags, backup), msg)
702
723
703 def _forgetremoved(wctx, mctx, branchmerge):
724 def _forgetremoved(wctx, mctx, branchmerge):
704 """
725 """
705 Forget removed files
726 Forget removed files
706
727
707 If we're jumping between revisions (as opposed to merging), and if
728 If we're jumping between revisions (as opposed to merging), and if
708 neither the working directory nor the target rev has the file,
729 neither the working directory nor the target rev has the file,
709 then we need to remove it from the dirstate, to prevent the
730 then we need to remove it from the dirstate, to prevent the
710 dirstate from listing the file when it is no longer in the
731 dirstate from listing the file when it is no longer in the
711 manifest.
732 manifest.
712
733
713 If we're merging, and the other revision has removed a file
734 If we're merging, and the other revision has removed a file
714 that is not present in the working directory, we need to mark it
735 that is not present in the working directory, we need to mark it
715 as removed.
736 as removed.
716 """
737 """
717
738
718 actions = {}
739 actions = {}
719 m = 'f'
740 m = 'f'
720 if branchmerge:
741 if branchmerge:
721 m = 'r'
742 m = 'r'
722 for f in wctx.deleted():
743 for f in wctx.deleted():
723 if f not in mctx:
744 if f not in mctx:
724 actions[f] = m, None, "forget deleted"
745 actions[f] = m, None, "forget deleted"
725
746
726 if not branchmerge:
747 if not branchmerge:
727 for f in wctx.removed():
748 for f in wctx.removed():
728 if f not in mctx:
749 if f not in mctx:
729 actions[f] = 'f', None, "forget removed"
750 actions[f] = 'f', None, "forget removed"
730
751
731 return actions
752 return actions
732
753
733 def _checkcollision(repo, wmf, actions):
754 def _checkcollision(repo, wmf, actions):
734 # build provisional merged manifest up
755 # build provisional merged manifest up
735 pmmf = set(wmf)
756 pmmf = set(wmf)
736
757
737 if actions:
758 if actions:
738 # k, dr, e and rd are no-op
759 # k, dr, e and rd are no-op
739 for m in 'a', 'am', 'f', 'g', 'cd', 'dc':
760 for m in 'a', 'am', 'f', 'g', 'cd', 'dc':
740 for f, args, msg in actions[m]:
761 for f, args, msg in actions[m]:
741 pmmf.add(f)
762 pmmf.add(f)
742 for f, args, msg in actions['r']:
763 for f, args, msg in actions['r']:
743 pmmf.discard(f)
764 pmmf.discard(f)
744 for f, args, msg in actions['dm']:
765 for f, args, msg in actions['dm']:
745 f2, flags = args
766 f2, flags = args
746 pmmf.discard(f2)
767 pmmf.discard(f2)
747 pmmf.add(f)
768 pmmf.add(f)
748 for f, args, msg in actions['dg']:
769 for f, args, msg in actions['dg']:
749 pmmf.add(f)
770 pmmf.add(f)
750 for f, args, msg in actions['m']:
771 for f, args, msg in actions['m']:
751 f1, f2, fa, move, anc = args
772 f1, f2, fa, move, anc = args
752 if move:
773 if move:
753 pmmf.discard(f1)
774 pmmf.discard(f1)
754 pmmf.add(f)
775 pmmf.add(f)
755
776
756 # check case-folding collision in provisional merged manifest
777 # check case-folding collision in provisional merged manifest
757 foldmap = {}
778 foldmap = {}
758 for f in pmmf:
779 for f in pmmf:
759 fold = util.normcase(f)
780 fold = util.normcase(f)
760 if fold in foldmap:
781 if fold in foldmap:
761 raise error.Abort(_("case-folding collision between %s and %s")
782 raise error.Abort(_("case-folding collision between %s and %s")
762 % (f, foldmap[fold]))
783 % (f, foldmap[fold]))
763 foldmap[fold] = f
784 foldmap[fold] = f
764
785
765 # check case-folding of directories
786 # check case-folding of directories
766 foldprefix = unfoldprefix = lastfull = ''
787 foldprefix = unfoldprefix = lastfull = ''
767 for fold, f in sorted(foldmap.items()):
788 for fold, f in sorted(foldmap.items()):
768 if fold.startswith(foldprefix) and not f.startswith(unfoldprefix):
789 if fold.startswith(foldprefix) and not f.startswith(unfoldprefix):
769 # the folded prefix matches but actual casing is different
790 # the folded prefix matches but actual casing is different
770 raise error.Abort(_("case-folding collision between "
791 raise error.Abort(_("case-folding collision between "
771 "%s and directory of %s") % (lastfull, f))
792 "%s and directory of %s") % (lastfull, f))
772 foldprefix = fold + '/'
793 foldprefix = fold + '/'
773 unfoldprefix = f + '/'
794 unfoldprefix = f + '/'
774 lastfull = f
795 lastfull = f
775
796
776 def driverpreprocess(repo, ms, wctx, labels=None):
797 def driverpreprocess(repo, ms, wctx, labels=None):
777 """run the preprocess step of the merge driver, if any
798 """run the preprocess step of the merge driver, if any
778
799
779 This is currently not implemented -- it's an extension point."""
800 This is currently not implemented -- it's an extension point."""
780 return True
801 return True
781
802
782 def driverconclude(repo, ms, wctx, labels=None):
803 def driverconclude(repo, ms, wctx, labels=None):
783 """run the conclude step of the merge driver, if any
804 """run the conclude step of the merge driver, if any
784
805
785 This is currently not implemented -- it's an extension point."""
806 This is currently not implemented -- it's an extension point."""
786 return True
807 return True
787
808
788 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, matcher,
809 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, matcher,
789 acceptremote, followcopies, forcefulldiff=False):
810 acceptremote, followcopies, forcefulldiff=False):
790 """
811 """
791 Merge wctx and p2 with ancestor pa and generate merge action list
812 Merge wctx and p2 with ancestor pa and generate merge action list
792
813
793 branchmerge and force are as passed in to update
814 branchmerge and force are as passed in to update
794 matcher = matcher to filter file lists
815 matcher = matcher to filter file lists
795 acceptremote = accept the incoming changes without prompting
816 acceptremote = accept the incoming changes without prompting
796 """
817 """
797 if matcher is not None and matcher.always():
818 if matcher is not None and matcher.always():
798 matcher = None
819 matcher = None
799
820
800 copy, movewithdir, diverge, renamedelete, dirmove = {}, {}, {}, {}, {}
821 copy, movewithdir, diverge, renamedelete, dirmove = {}, {}, {}, {}, {}
801
822
802 # manifests fetched in order are going to be faster, so prime the caches
823 # manifests fetched in order are going to be faster, so prime the caches
803 [x.manifest() for x in
824 [x.manifest() for x in
804 sorted(wctx.parents() + [p2, pa], key=scmutil.intrev)]
825 sorted(wctx.parents() + [p2, pa], key=scmutil.intrev)]
805
826
806 if followcopies:
827 if followcopies:
807 ret = copies.mergecopies(repo, wctx, p2, pa)
828 ret = copies.mergecopies(repo, wctx, p2, pa)
808 copy, movewithdir, diverge, renamedelete, dirmove = ret
829 copy, movewithdir, diverge, renamedelete, dirmove = ret
809
830
810 boolbm = pycompat.bytestr(bool(branchmerge))
831 boolbm = pycompat.bytestr(bool(branchmerge))
811 boolf = pycompat.bytestr(bool(force))
832 boolf = pycompat.bytestr(bool(force))
812 boolm = pycompat.bytestr(bool(matcher))
833 boolm = pycompat.bytestr(bool(matcher))
813 repo.ui.note(_("resolving manifests\n"))
834 repo.ui.note(_("resolving manifests\n"))
814 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
835 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
815 % (boolbm, boolf, boolm))
836 % (boolbm, boolf, boolm))
816 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
837 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
817
838
818 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
839 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
819 copied = set(copy.values())
840 copied = set(copy.values())
820 copied.update(movewithdir.values())
841 copied.update(movewithdir.values())
821
842
822 if '.hgsubstate' in m1:
843 if '.hgsubstate' in m1:
823 # check whether sub state is modified
844 # check whether sub state is modified
824 if any(wctx.sub(s).dirty() for s in wctx.substate):
845 if any(wctx.sub(s).dirty() for s in wctx.substate):
825 m1['.hgsubstate'] = modifiednodeid
846 m1['.hgsubstate'] = modifiednodeid
826
847
827 # Don't use m2-vs-ma optimization if:
848 # Don't use m2-vs-ma optimization if:
828 # - ma is the same as m1 or m2, which we're just going to diff again later
849 # - ma is the same as m1 or m2, which we're just going to diff again later
829 # - The caller specifically asks for a full diff, which is useful during bid
850 # - The caller specifically asks for a full diff, which is useful during bid
830 # merge.
851 # merge.
831 if (pa not in ([wctx, p2] + wctx.parents()) and not forcefulldiff):
852 if (pa not in ([wctx, p2] + wctx.parents()) and not forcefulldiff):
832 # Identify which files are relevant to the merge, so we can limit the
853 # Identify which files are relevant to the merge, so we can limit the
833 # total m1-vs-m2 diff to just those files. This has significant
854 # total m1-vs-m2 diff to just those files. This has significant
834 # performance benefits in large repositories.
855 # performance benefits in large repositories.
835 relevantfiles = set(ma.diff(m2).keys())
856 relevantfiles = set(ma.diff(m2).keys())
836
857
837 # For copied and moved files, we need to add the source file too.
858 # For copied and moved files, we need to add the source file too.
838 for copykey, copyvalue in copy.iteritems():
859 for copykey, copyvalue in copy.iteritems():
839 if copyvalue in relevantfiles:
860 if copyvalue in relevantfiles:
840 relevantfiles.add(copykey)
861 relevantfiles.add(copykey)
841 for movedirkey in movewithdir:
862 for movedirkey in movewithdir:
842 relevantfiles.add(movedirkey)
863 relevantfiles.add(movedirkey)
843 filesmatcher = scmutil.matchfiles(repo, relevantfiles)
864 filesmatcher = scmutil.matchfiles(repo, relevantfiles)
844 matcher = matchmod.intersectmatchers(matcher, filesmatcher)
865 matcher = matchmod.intersectmatchers(matcher, filesmatcher)
845
866
846 diff = m1.diff(m2, match=matcher)
867 diff = m1.diff(m2, match=matcher)
847
868
848 if matcher is None:
869 if matcher is None:
849 matcher = matchmod.always('', '')
870 matcher = matchmod.always('', '')
850
871
851 actions = {}
872 actions = {}
852 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems():
873 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems():
853 if n1 and n2: # file exists on both local and remote side
874 if n1 and n2: # file exists on both local and remote side
854 if f not in ma:
875 if f not in ma:
855 fa = copy.get(f, None)
876 fa = copy.get(f, None)
856 if fa is not None:
877 if fa is not None:
857 actions[f] = ('m', (f, f, fa, False, pa.node()),
878 actions[f] = ('m', (f, f, fa, False, pa.node()),
858 "both renamed from " + fa)
879 "both renamed from " + fa)
859 else:
880 else:
860 actions[f] = ('m', (f, f, None, False, pa.node()),
881 actions[f] = ('m', (f, f, None, False, pa.node()),
861 "both created")
882 "both created")
862 else:
883 else:
863 a = ma[f]
884 a = ma[f]
864 fla = ma.flags(f)
885 fla = ma.flags(f)
865 nol = 'l' not in fl1 + fl2 + fla
886 nol = 'l' not in fl1 + fl2 + fla
866 if n2 == a and fl2 == fla:
887 if n2 == a and fl2 == fla:
867 actions[f] = ('k', (), "remote unchanged")
888 actions[f] = ('k', (), "remote unchanged")
868 elif n1 == a and fl1 == fla: # local unchanged - use remote
889 elif n1 == a and fl1 == fla: # local unchanged - use remote
869 if n1 == n2: # optimization: keep local content
890 if n1 == n2: # optimization: keep local content
870 actions[f] = ('e', (fl2,), "update permissions")
891 actions[f] = ('e', (fl2,), "update permissions")
871 else:
892 else:
872 actions[f] = ('g', (fl2, False), "remote is newer")
893 actions[f] = ('g', (fl2, False), "remote is newer")
873 elif nol and n2 == a: # remote only changed 'x'
894 elif nol and n2 == a: # remote only changed 'x'
874 actions[f] = ('e', (fl2,), "update permissions")
895 actions[f] = ('e', (fl2,), "update permissions")
875 elif nol and n1 == a: # local only changed 'x'
896 elif nol and n1 == a: # local only changed 'x'
876 actions[f] = ('g', (fl1, False), "remote is newer")
897 actions[f] = ('g', (fl1, False), "remote is newer")
877 else: # both changed something
898 else: # both changed something
878 actions[f] = ('m', (f, f, f, False, pa.node()),
899 actions[f] = ('m', (f, f, f, False, pa.node()),
879 "versions differ")
900 "versions differ")
880 elif n1: # file exists only on local side
901 elif n1: # file exists only on local side
881 if f in copied:
902 if f in copied:
882 pass # we'll deal with it on m2 side
903 pass # we'll deal with it on m2 side
883 elif f in movewithdir: # directory rename, move local
904 elif f in movewithdir: # directory rename, move local
884 f2 = movewithdir[f]
905 f2 = movewithdir[f]
885 if f2 in m2:
906 if f2 in m2:
886 actions[f2] = ('m', (f, f2, None, True, pa.node()),
907 actions[f2] = ('m', (f, f2, None, True, pa.node()),
887 "remote directory rename, both created")
908 "remote directory rename, both created")
888 else:
909 else:
889 actions[f2] = ('dm', (f, fl1),
910 actions[f2] = ('dm', (f, fl1),
890 "remote directory rename - move from " + f)
911 "remote directory rename - move from " + f)
891 elif f in copy:
912 elif f in copy:
892 f2 = copy[f]
913 f2 = copy[f]
893 actions[f] = ('m', (f, f2, f2, False, pa.node()),
914 actions[f] = ('m', (f, f2, f2, False, pa.node()),
894 "local copied/moved from " + f2)
915 "local copied/moved from " + f2)
895 elif f in ma: # clean, a different, no remote
916 elif f in ma: # clean, a different, no remote
896 if n1 != ma[f]:
917 if n1 != ma[f]:
897 if acceptremote:
918 if acceptremote:
898 actions[f] = ('r', None, "remote delete")
919 actions[f] = ('r', None, "remote delete")
899 else:
920 else:
900 actions[f] = ('cd', (f, None, f, False, pa.node()),
921 actions[f] = ('cd', (f, None, f, False, pa.node()),
901 "prompt changed/deleted")
922 "prompt changed/deleted")
902 elif n1 == addednodeid:
923 elif n1 == addednodeid:
903 # This extra 'a' is added by working copy manifest to mark
924 # This extra 'a' is added by working copy manifest to mark
904 # the file as locally added. We should forget it instead of
925 # the file as locally added. We should forget it instead of
905 # deleting it.
926 # deleting it.
906 actions[f] = ('f', None, "remote deleted")
927 actions[f] = ('f', None, "remote deleted")
907 else:
928 else:
908 actions[f] = ('r', None, "other deleted")
929 actions[f] = ('r', None, "other deleted")
909 elif n2: # file exists only on remote side
930 elif n2: # file exists only on remote side
910 if f in copied:
931 if f in copied:
911 pass # we'll deal with it on m1 side
932 pass # we'll deal with it on m1 side
912 elif f in movewithdir:
933 elif f in movewithdir:
913 f2 = movewithdir[f]
934 f2 = movewithdir[f]
914 if f2 in m1:
935 if f2 in m1:
915 actions[f2] = ('m', (f2, f, None, False, pa.node()),
936 actions[f2] = ('m', (f2, f, None, False, pa.node()),
916 "local directory rename, both created")
937 "local directory rename, both created")
917 else:
938 else:
918 actions[f2] = ('dg', (f, fl2),
939 actions[f2] = ('dg', (f, fl2),
919 "local directory rename - get from " + f)
940 "local directory rename - get from " + f)
920 elif f in copy:
941 elif f in copy:
921 f2 = copy[f]
942 f2 = copy[f]
922 if f2 in m2:
943 if f2 in m2:
923 actions[f] = ('m', (f2, f, f2, False, pa.node()),
944 actions[f] = ('m', (f2, f, f2, False, pa.node()),
924 "remote copied from " + f2)
945 "remote copied from " + f2)
925 else:
946 else:
926 actions[f] = ('m', (f2, f, f2, True, pa.node()),
947 actions[f] = ('m', (f2, f, f2, True, pa.node()),
927 "remote moved from " + f2)
948 "remote moved from " + f2)
928 elif f not in ma:
949 elif f not in ma:
929 # local unknown, remote created: the logic is described by the
950 # local unknown, remote created: the logic is described by the
930 # following table:
951 # following table:
931 #
952 #
932 # force branchmerge different | action
953 # force branchmerge different | action
933 # n * * | create
954 # n * * | create
934 # y n * | create
955 # y n * | create
935 # y y n | create
956 # y y n | create
936 # y y y | merge
957 # y y y | merge
937 #
958 #
938 # Checking whether the files are different is expensive, so we
959 # Checking whether the files are different is expensive, so we
939 # don't do that when we can avoid it.
960 # don't do that when we can avoid it.
940 if not force:
961 if not force:
941 actions[f] = ('c', (fl2,), "remote created")
962 actions[f] = ('c', (fl2,), "remote created")
942 elif not branchmerge:
963 elif not branchmerge:
943 actions[f] = ('c', (fl2,), "remote created")
964 actions[f] = ('c', (fl2,), "remote created")
944 else:
965 else:
945 actions[f] = ('cm', (fl2, pa.node()),
966 actions[f] = ('cm', (fl2, pa.node()),
946 "remote created, get or merge")
967 "remote created, get or merge")
947 elif n2 != ma[f]:
968 elif n2 != ma[f]:
948 df = None
969 df = None
949 for d in dirmove:
970 for d in dirmove:
950 if f.startswith(d):
971 if f.startswith(d):
951 # new file added in a directory that was moved
972 # new file added in a directory that was moved
952 df = dirmove[d] + f[len(d):]
973 df = dirmove[d] + f[len(d):]
953 break
974 break
954 if df is not None and df in m1:
975 if df is not None and df in m1:
955 actions[df] = ('m', (df, f, f, False, pa.node()),
976 actions[df] = ('m', (df, f, f, False, pa.node()),
956 "local directory rename - respect move from " + f)
977 "local directory rename - respect move from " + f)
957 elif acceptremote:
978 elif acceptremote:
958 actions[f] = ('c', (fl2,), "remote recreating")
979 actions[f] = ('c', (fl2,), "remote recreating")
959 else:
980 else:
960 actions[f] = ('dc', (None, f, f, False, pa.node()),
981 actions[f] = ('dc', (None, f, f, False, pa.node()),
961 "prompt deleted/changed")
982 "prompt deleted/changed")
962
983
963 return actions, diverge, renamedelete
984 return actions, diverge, renamedelete
964
985
965 def _resolvetrivial(repo, wctx, mctx, ancestor, actions):
986 def _resolvetrivial(repo, wctx, mctx, ancestor, actions):
966 """Resolves false conflicts where the nodeid changed but the content
987 """Resolves false conflicts where the nodeid changed but the content
967 remained the same."""
988 remained the same."""
968
989
969 for f, (m, args, msg) in actions.items():
990 for f, (m, args, msg) in actions.items():
970 if m == 'cd' and f in ancestor and not wctx[f].cmp(ancestor[f]):
991 if m == 'cd' and f in ancestor and not wctx[f].cmp(ancestor[f]):
971 # local did change but ended up with same content
992 # local did change but ended up with same content
972 actions[f] = 'r', None, "prompt same"
993 actions[f] = 'r', None, "prompt same"
973 elif m == 'dc' and f in ancestor and not mctx[f].cmp(ancestor[f]):
994 elif m == 'dc' and f in ancestor and not mctx[f].cmp(ancestor[f]):
974 # remote did change but ended up with same content
995 # remote did change but ended up with same content
975 del actions[f] # don't get = keep local deleted
996 del actions[f] # don't get = keep local deleted
976
997
977 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force,
998 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force,
978 acceptremote, followcopies, matcher=None,
999 acceptremote, followcopies, matcher=None,
979 mergeforce=False):
1000 mergeforce=False):
980 """Calculate the actions needed to merge mctx into wctx using ancestors"""
1001 """Calculate the actions needed to merge mctx into wctx using ancestors"""
981 # Avoid cycle.
1002 # Avoid cycle.
982 from . import sparse
1003 from . import sparse
983
1004
984 if len(ancestors) == 1: # default
1005 if len(ancestors) == 1: # default
985 actions, diverge, renamedelete = manifestmerge(
1006 actions, diverge, renamedelete = manifestmerge(
986 repo, wctx, mctx, ancestors[0], branchmerge, force, matcher,
1007 repo, wctx, mctx, ancestors[0], branchmerge, force, matcher,
987 acceptremote, followcopies)
1008 acceptremote, followcopies)
988 _checkunknownfiles(repo, wctx, mctx, force, actions, mergeforce)
1009 _checkunknownfiles(repo, wctx, mctx, force, actions, mergeforce)
989
1010
990 else: # only when merge.preferancestor=* - the default
1011 else: # only when merge.preferancestor=* - the default
991 repo.ui.note(
1012 repo.ui.note(
992 _("note: merging %s and %s using bids from ancestors %s\n") %
1013 _("note: merging %s and %s using bids from ancestors %s\n") %
993 (wctx, mctx, _(' and ').join(pycompat.bytestr(anc)
1014 (wctx, mctx, _(' and ').join(pycompat.bytestr(anc)
994 for anc in ancestors)))
1015 for anc in ancestors)))
995
1016
996 # Call for bids
1017 # Call for bids
997 fbids = {} # mapping filename to bids (action method to list af actions)
1018 fbids = {} # mapping filename to bids (action method to list af actions)
998 diverge, renamedelete = None, None
1019 diverge, renamedelete = None, None
999 for ancestor in ancestors:
1020 for ancestor in ancestors:
1000 repo.ui.note(_('\ncalculating bids for ancestor %s\n') % ancestor)
1021 repo.ui.note(_('\ncalculating bids for ancestor %s\n') % ancestor)
1001 actions, diverge1, renamedelete1 = manifestmerge(
1022 actions, diverge1, renamedelete1 = manifestmerge(
1002 repo, wctx, mctx, ancestor, branchmerge, force, matcher,
1023 repo, wctx, mctx, ancestor, branchmerge, force, matcher,
1003 acceptremote, followcopies, forcefulldiff=True)
1024 acceptremote, followcopies, forcefulldiff=True)
1004 _checkunknownfiles(repo, wctx, mctx, force, actions, mergeforce)
1025 _checkunknownfiles(repo, wctx, mctx, force, actions, mergeforce)
1005
1026
1006 # Track the shortest set of warning on the theory that bid
1027 # Track the shortest set of warning on the theory that bid
1007 # merge will correctly incorporate more information
1028 # merge will correctly incorporate more information
1008 if diverge is None or len(diverge1) < len(diverge):
1029 if diverge is None or len(diverge1) < len(diverge):
1009 diverge = diverge1
1030 diverge = diverge1
1010 if renamedelete is None or len(renamedelete) < len(renamedelete1):
1031 if renamedelete is None or len(renamedelete) < len(renamedelete1):
1011 renamedelete = renamedelete1
1032 renamedelete = renamedelete1
1012
1033
1013 for f, a in sorted(actions.iteritems()):
1034 for f, a in sorted(actions.iteritems()):
1014 m, args, msg = a
1035 m, args, msg = a
1015 repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m))
1036 repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m))
1016 if f in fbids:
1037 if f in fbids:
1017 d = fbids[f]
1038 d = fbids[f]
1018 if m in d:
1039 if m in d:
1019 d[m].append(a)
1040 d[m].append(a)
1020 else:
1041 else:
1021 d[m] = [a]
1042 d[m] = [a]
1022 else:
1043 else:
1023 fbids[f] = {m: [a]}
1044 fbids[f] = {m: [a]}
1024
1045
1025 # Pick the best bid for each file
1046 # Pick the best bid for each file
1026 repo.ui.note(_('\nauction for merging merge bids\n'))
1047 repo.ui.note(_('\nauction for merging merge bids\n'))
1027 actions = {}
1048 actions = {}
1028 dms = [] # filenames that have dm actions
1049 dms = [] # filenames that have dm actions
1029 for f, bids in sorted(fbids.items()):
1050 for f, bids in sorted(fbids.items()):
1030 # bids is a mapping from action method to list af actions
1051 # bids is a mapping from action method to list af actions
1031 # Consensus?
1052 # Consensus?
1032 if len(bids) == 1: # all bids are the same kind of method
1053 if len(bids) == 1: # all bids are the same kind of method
1033 m, l = list(bids.items())[0]
1054 m, l = list(bids.items())[0]
1034 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
1055 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
1035 repo.ui.note(_(" %s: consensus for %s\n") % (f, m))
1056 repo.ui.note(_(" %s: consensus for %s\n") % (f, m))
1036 actions[f] = l[0]
1057 actions[f] = l[0]
1037 if m == 'dm':
1058 if m == 'dm':
1038 dms.append(f)
1059 dms.append(f)
1039 continue
1060 continue
1040 # If keep is an option, just do it.
1061 # If keep is an option, just do it.
1041 if 'k' in bids:
1062 if 'k' in bids:
1042 repo.ui.note(_(" %s: picking 'keep' action\n") % f)
1063 repo.ui.note(_(" %s: picking 'keep' action\n") % f)
1043 actions[f] = bids['k'][0]
1064 actions[f] = bids['k'][0]
1044 continue
1065 continue
1045 # If there are gets and they all agree [how could they not?], do it.
1066 # If there are gets and they all agree [how could they not?], do it.
1046 if 'g' in bids:
1067 if 'g' in bids:
1047 ga0 = bids['g'][0]
1068 ga0 = bids['g'][0]
1048 if all(a == ga0 for a in bids['g'][1:]):
1069 if all(a == ga0 for a in bids['g'][1:]):
1049 repo.ui.note(_(" %s: picking 'get' action\n") % f)
1070 repo.ui.note(_(" %s: picking 'get' action\n") % f)
1050 actions[f] = ga0
1071 actions[f] = ga0
1051 continue
1072 continue
1052 # TODO: Consider other simple actions such as mode changes
1073 # TODO: Consider other simple actions such as mode changes
1053 # Handle inefficient democrazy.
1074 # Handle inefficient democrazy.
1054 repo.ui.note(_(' %s: multiple bids for merge action:\n') % f)
1075 repo.ui.note(_(' %s: multiple bids for merge action:\n') % f)
1055 for m, l in sorted(bids.items()):
1076 for m, l in sorted(bids.items()):
1056 for _f, args, msg in l:
1077 for _f, args, msg in l:
1057 repo.ui.note(' %s -> %s\n' % (msg, m))
1078 repo.ui.note(' %s -> %s\n' % (msg, m))
1058 # Pick random action. TODO: Instead, prompt user when resolving
1079 # Pick random action. TODO: Instead, prompt user when resolving
1059 m, l = list(bids.items())[0]
1080 m, l = list(bids.items())[0]
1060 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
1081 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
1061 (f, m))
1082 (f, m))
1062 actions[f] = l[0]
1083 actions[f] = l[0]
1063 if m == 'dm':
1084 if m == 'dm':
1064 dms.append(f)
1085 dms.append(f)
1065 continue
1086 continue
1066 # Work around 'dm' that can cause multiple actions for the same file
1087 # Work around 'dm' that can cause multiple actions for the same file
1067 for f in dms:
1088 for f in dms:
1068 dm, (f0, flags), msg = actions[f]
1089 dm, (f0, flags), msg = actions[f]
1069 assert dm == 'dm', dm
1090 assert dm == 'dm', dm
1070 if f0 in actions and actions[f0][0] == 'r':
1091 if f0 in actions and actions[f0][0] == 'r':
1071 # We have one bid for removing a file and another for moving it.
1092 # We have one bid for removing a file and another for moving it.
1072 # These two could be merged as first move and then delete ...
1093 # These two could be merged as first move and then delete ...
1073 # but instead drop moving and just delete.
1094 # but instead drop moving and just delete.
1074 del actions[f]
1095 del actions[f]
1075 repo.ui.note(_('end of auction\n\n'))
1096 repo.ui.note(_('end of auction\n\n'))
1076
1097
1077 _resolvetrivial(repo, wctx, mctx, ancestors[0], actions)
1098 _resolvetrivial(repo, wctx, mctx, ancestors[0], actions)
1078
1099
1079 if wctx.rev() is None:
1100 if wctx.rev() is None:
1080 fractions = _forgetremoved(wctx, mctx, branchmerge)
1101 fractions = _forgetremoved(wctx, mctx, branchmerge)
1081 actions.update(fractions)
1102 actions.update(fractions)
1082
1103
1083 prunedactions = sparse.filterupdatesactions(repo, wctx, mctx, branchmerge,
1104 prunedactions = sparse.filterupdatesactions(repo, wctx, mctx, branchmerge,
1084 actions)
1105 actions)
1085
1106
1086 return prunedactions, diverge, renamedelete
1107 return prunedactions, diverge, renamedelete
1087
1108
1088 def _getcwd():
1109 def _getcwd():
1089 try:
1110 try:
1090 return pycompat.getcwd()
1111 return pycompat.getcwd()
1091 except OSError as err:
1112 except OSError as err:
1092 if err.errno == errno.ENOENT:
1113 if err.errno == errno.ENOENT:
1093 return None
1114 return None
1094 raise
1115 raise
1095
1116
1096 def batchremove(repo, wctx, actions):
1117 def batchremove(repo, wctx, actions):
1097 """apply removes to the working directory
1118 """apply removes to the working directory
1098
1119
1099 yields tuples for progress updates
1120 yields tuples for progress updates
1100 """
1121 """
1101 verbose = repo.ui.verbose
1122 verbose = repo.ui.verbose
1102 cwd = _getcwd()
1123 cwd = _getcwd()
1103 i = 0
1124 i = 0
1104 for f, args, msg in actions:
1125 for f, args, msg in actions:
1105 repo.ui.debug(" %s: %s -> r\n" % (f, msg))
1126 repo.ui.debug(" %s: %s -> r\n" % (f, msg))
1106 if verbose:
1127 if verbose:
1107 repo.ui.note(_("removing %s\n") % f)
1128 repo.ui.note(_("removing %s\n") % f)
1108 wctx[f].audit()
1129 wctx[f].audit()
1109 try:
1130 try:
1110 wctx[f].remove(ignoremissing=True)
1131 wctx[f].remove(ignoremissing=True)
1111 except OSError as inst:
1132 except OSError as inst:
1112 repo.ui.warn(_("update failed to remove %s: %s!\n") %
1133 repo.ui.warn(_("update failed to remove %s: %s!\n") %
1113 (f, inst.strerror))
1134 (f, inst.strerror))
1114 if i == 100:
1135 if i == 100:
1115 yield i, f
1136 yield i, f
1116 i = 0
1137 i = 0
1117 i += 1
1138 i += 1
1118 if i > 0:
1139 if i > 0:
1119 yield i, f
1140 yield i, f
1120
1141
1121 if cwd and not _getcwd():
1142 if cwd and not _getcwd():
1122 # cwd was removed in the course of removing files; print a helpful
1143 # cwd was removed in the course of removing files; print a helpful
1123 # warning.
1144 # warning.
1124 repo.ui.warn(_("current directory was removed\n"
1145 repo.ui.warn(_("current directory was removed\n"
1125 "(consider changing to repo root: %s)\n") % repo.root)
1146 "(consider changing to repo root: %s)\n") % repo.root)
1126
1147
1127 # It's necessary to flush here in case we're inside a worker fork and will
1148 # It's necessary to flush here in case we're inside a worker fork and will
1128 # quit after this function.
1149 # quit after this function.
1129 wctx.flushall()
1150 wctx.flushall()
1130
1151
1131 def batchget(repo, mctx, wctx, actions):
1152 def batchget(repo, mctx, wctx, actions):
1132 """apply gets to the working directory
1153 """apply gets to the working directory
1133
1154
1134 mctx is the context to get from
1155 mctx is the context to get from
1135
1156
1136 yields tuples for progress updates
1157 yields tuples for progress updates
1137 """
1158 """
1138 verbose = repo.ui.verbose
1159 verbose = repo.ui.verbose
1139 fctx = mctx.filectx
1160 fctx = mctx.filectx
1140 ui = repo.ui
1161 ui = repo.ui
1141 i = 0
1162 i = 0
1142 with repo.wvfs.backgroundclosing(ui, expectedcount=len(actions)):
1163 with repo.wvfs.backgroundclosing(ui, expectedcount=len(actions)):
1143 for f, (flags, backup), msg in actions:
1164 for f, (flags, backup), msg in actions:
1144 repo.ui.debug(" %s: %s -> g\n" % (f, msg))
1165 repo.ui.debug(" %s: %s -> g\n" % (f, msg))
1145 if verbose:
1166 if verbose:
1146 repo.ui.note(_("getting %s\n") % f)
1167 repo.ui.note(_("getting %s\n") % f)
1147
1168
1148 if backup:
1169 if backup:
1149 absf = repo.wjoin(f)
1170 absf = repo.wjoin(f)
1150 orig = scmutil.origpath(ui, repo, absf)
1171 orig = scmutil.origpath(ui, repo, absf)
1151 try:
1172 try:
1152 if repo.wvfs.isfileorlink(f):
1173 if repo.wvfs.isfileorlink(f):
1153 util.rename(absf, orig)
1174 util.rename(absf, orig)
1154 except OSError as e:
1175 except OSError as e:
1155 if e.errno != errno.ENOENT:
1176 if e.errno != errno.ENOENT:
1156 raise
1177 raise
1157 wctx[f].clearunknown()
1178 wctx[f].clearunknown()
1158 wctx[f].write(fctx(f).data(), flags, backgroundclose=True)
1179 wctx[f].write(fctx(f).data(), flags, backgroundclose=True)
1159 if i == 100:
1180 if i == 100:
1160 yield i, f
1181 yield i, f
1161 i = 0
1182 i = 0
1162 i += 1
1183 i += 1
1163 if i > 0:
1184 if i > 0:
1164 yield i, f
1185 yield i, f
1165
1186
1166 # It's necessary to flush here in case we're inside a worker fork and will
1187 # It's necessary to flush here in case we're inside a worker fork and will
1167 # quit after this function.
1188 # quit after this function.
1168 wctx.flushall()
1189 wctx.flushall()
1169
1190
1170 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None):
1191 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None):
1171 """apply the merge action list to the working directory
1192 """apply the merge action list to the working directory
1172
1193
1173 wctx is the working copy context
1194 wctx is the working copy context
1174 mctx is the context to be merged into the working copy
1195 mctx is the context to be merged into the working copy
1175
1196
1176 Return a tuple of counts (updated, merged, removed, unresolved) that
1197 Return a tuple of counts (updated, merged, removed, unresolved) that
1177 describes how many files were affected by the update.
1198 describes how many files were affected by the update.
1178 """
1199 """
1179
1200
1180 updated, merged, removed = 0, 0, 0
1201 updated, merged, removed = 0, 0, 0
1181 ms = mergestate.clean(repo, wctx.p1().node(), mctx.node(), labels)
1202 ms = mergestate.clean(repo, wctx.p1().node(), mctx.node(), labels)
1182 moves = []
1203 moves = []
1183 for m, l in actions.items():
1204 for m, l in actions.items():
1184 l.sort()
1205 l.sort()
1185
1206
1186 # 'cd' and 'dc' actions are treated like other merge conflicts
1207 # 'cd' and 'dc' actions are treated like other merge conflicts
1187 mergeactions = sorted(actions['cd'])
1208 mergeactions = sorted(actions['cd'])
1188 mergeactions.extend(sorted(actions['dc']))
1209 mergeactions.extend(sorted(actions['dc']))
1189 mergeactions.extend(actions['m'])
1210 mergeactions.extend(actions['m'])
1190 for f, args, msg in mergeactions:
1211 for f, args, msg in mergeactions:
1191 f1, f2, fa, move, anc = args
1212 f1, f2, fa, move, anc = args
1192 if f == '.hgsubstate': # merged internally
1213 if f == '.hgsubstate': # merged internally
1193 continue
1214 continue
1194 if f1 is None:
1215 if f1 is None:
1195 fcl = filemerge.absentfilectx(wctx, fa)
1216 fcl = filemerge.absentfilectx(wctx, fa)
1196 else:
1217 else:
1197 repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f))
1218 repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f))
1198 fcl = wctx[f1]
1219 fcl = wctx[f1]
1199 if f2 is None:
1220 if f2 is None:
1200 fco = filemerge.absentfilectx(mctx, fa)
1221 fco = filemerge.absentfilectx(mctx, fa)
1201 else:
1222 else:
1202 fco = mctx[f2]
1223 fco = mctx[f2]
1203 actx = repo[anc]
1224 actx = repo[anc]
1204 if fa in actx:
1225 if fa in actx:
1205 fca = actx[fa]
1226 fca = actx[fa]
1206 else:
1227 else:
1207 # TODO: move to absentfilectx
1228 # TODO: move to absentfilectx
1208 fca = repo.filectx(f1, fileid=nullrev)
1229 fca = repo.filectx(f1, fileid=nullrev)
1209 ms.add(fcl, fco, fca, f)
1230 ms.add(fcl, fco, fca, f)
1210 if f1 != f and move:
1231 if f1 != f and move:
1211 moves.append(f1)
1232 moves.append(f1)
1212
1233
1213 _updating = _('updating')
1234 _updating = _('updating')
1214 _files = _('files')
1235 _files = _('files')
1215 progress = repo.ui.progress
1236 progress = repo.ui.progress
1216
1237
1217 # remove renamed files after safely stored
1238 # remove renamed files after safely stored
1218 for f in moves:
1239 for f in moves:
1219 if wctx[f].lexists():
1240 if wctx[f].lexists():
1220 repo.ui.debug("removing %s\n" % f)
1241 repo.ui.debug("removing %s\n" % f)
1221 wctx[f].audit()
1242 wctx[f].audit()
1222 wctx[f].remove()
1243 wctx[f].remove()
1223
1244
1224 numupdates = sum(len(l) for m, l in actions.items() if m != 'k')
1245 numupdates = sum(len(l) for m, l in actions.items() if m != 'k')
1225
1246
1226 if [a for a in actions['r'] if a[0] == '.hgsubstate']:
1247 if [a for a in actions['r'] if a[0] == '.hgsubstate']:
1227 subrepo.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1248 subrepo.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1228
1249
1229 # remove in parallel (must come first)
1250 # remove in parallel (must come first)
1230 z = 0
1251 z = 0
1231 prog = worker.worker(repo.ui, 0.001, batchremove, (repo, wctx),
1252 prog = worker.worker(repo.ui, 0.001, batchremove, (repo, wctx),
1232 actions['r'])
1253 actions['r'])
1233 for i, item in prog:
1254 for i, item in prog:
1234 z += i
1255 z += i
1235 progress(_updating, z, item=item, total=numupdates, unit=_files)
1256 progress(_updating, z, item=item, total=numupdates, unit=_files)
1236 removed = len(actions['r'])
1257 removed = len(actions['r'])
1237
1258
1238 # We should flush before forking into worker processes, since those workers
1259 # We should flush before forking into worker processes, since those workers
1239 # flush when they complete, and we don't want to duplicate work.
1260 # flush when they complete, and we don't want to duplicate work.
1240 wctx.flushall()
1261 wctx.flushall()
1241
1262
1242 # get in parallel
1263 # get in parallel
1243 prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx, wctx),
1264 prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx, wctx),
1244 actions['g'])
1265 actions['g'])
1245 for i, item in prog:
1266 for i, item in prog:
1246 z += i
1267 z += i
1247 progress(_updating, z, item=item, total=numupdates, unit=_files)
1268 progress(_updating, z, item=item, total=numupdates, unit=_files)
1248 updated = len(actions['g'])
1269 updated = len(actions['g'])
1249
1270
1250 if [a for a in actions['g'] if a[0] == '.hgsubstate']:
1271 if [a for a in actions['g'] if a[0] == '.hgsubstate']:
1251 subrepo.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1272 subrepo.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1252
1273
1253 # forget (manifest only, just log it) (must come first)
1274 # forget (manifest only, just log it) (must come first)
1254 for f, args, msg in actions['f']:
1275 for f, args, msg in actions['f']:
1255 repo.ui.debug(" %s: %s -> f\n" % (f, msg))
1276 repo.ui.debug(" %s: %s -> f\n" % (f, msg))
1256 z += 1
1277 z += 1
1257 progress(_updating, z, item=f, total=numupdates, unit=_files)
1278 progress(_updating, z, item=f, total=numupdates, unit=_files)
1258
1279
1259 # re-add (manifest only, just log it)
1280 # re-add (manifest only, just log it)
1260 for f, args, msg in actions['a']:
1281 for f, args, msg in actions['a']:
1261 repo.ui.debug(" %s: %s -> a\n" % (f, msg))
1282 repo.ui.debug(" %s: %s -> a\n" % (f, msg))
1262 z += 1
1283 z += 1
1263 progress(_updating, z, item=f, total=numupdates, unit=_files)
1284 progress(_updating, z, item=f, total=numupdates, unit=_files)
1264
1285
1265 # re-add/mark as modified (manifest only, just log it)
1286 # re-add/mark as modified (manifest only, just log it)
1266 for f, args, msg in actions['am']:
1287 for f, args, msg in actions['am']:
1267 repo.ui.debug(" %s: %s -> am\n" % (f, msg))
1288 repo.ui.debug(" %s: %s -> am\n" % (f, msg))
1268 z += 1
1289 z += 1
1269 progress(_updating, z, item=f, total=numupdates, unit=_files)
1290 progress(_updating, z, item=f, total=numupdates, unit=_files)
1270
1291
1271 # keep (noop, just log it)
1292 # keep (noop, just log it)
1272 for f, args, msg in actions['k']:
1293 for f, args, msg in actions['k']:
1273 repo.ui.debug(" %s: %s -> k\n" % (f, msg))
1294 repo.ui.debug(" %s: %s -> k\n" % (f, msg))
1274 # no progress
1295 # no progress
1275
1296
1276 # directory rename, move local
1297 # directory rename, move local
1277 for f, args, msg in actions['dm']:
1298 for f, args, msg in actions['dm']:
1278 repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
1299 repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
1279 z += 1
1300 z += 1
1280 progress(_updating, z, item=f, total=numupdates, unit=_files)
1301 progress(_updating, z, item=f, total=numupdates, unit=_files)
1281 f0, flags = args
1302 f0, flags = args
1282 repo.ui.note(_("moving %s to %s\n") % (f0, f))
1303 repo.ui.note(_("moving %s to %s\n") % (f0, f))
1283 wctx[f].audit()
1304 wctx[f].audit()
1284 wctx[f].write(wctx.filectx(f0).data(), flags)
1305 wctx[f].write(wctx.filectx(f0).data(), flags)
1285 wctx[f0].remove()
1306 wctx[f0].remove()
1286 updated += 1
1307 updated += 1
1287
1308
1288 # local directory rename, get
1309 # local directory rename, get
1289 for f, args, msg in actions['dg']:
1310 for f, args, msg in actions['dg']:
1290 repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
1311 repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
1291 z += 1
1312 z += 1
1292 progress(_updating, z, item=f, total=numupdates, unit=_files)
1313 progress(_updating, z, item=f, total=numupdates, unit=_files)
1293 f0, flags = args
1314 f0, flags = args
1294 repo.ui.note(_("getting %s to %s\n") % (f0, f))
1315 repo.ui.note(_("getting %s to %s\n") % (f0, f))
1295 wctx[f].write(mctx.filectx(f0).data(), flags)
1316 wctx[f].write(mctx.filectx(f0).data(), flags)
1296 updated += 1
1317 updated += 1
1297
1318
1298 # exec
1319 # exec
1299 for f, args, msg in actions['e']:
1320 for f, args, msg in actions['e']:
1300 repo.ui.debug(" %s: %s -> e\n" % (f, msg))
1321 repo.ui.debug(" %s: %s -> e\n" % (f, msg))
1301 z += 1
1322 z += 1
1302 progress(_updating, z, item=f, total=numupdates, unit=_files)
1323 progress(_updating, z, item=f, total=numupdates, unit=_files)
1303 flags, = args
1324 flags, = args
1304 wctx[f].audit()
1325 wctx[f].audit()
1305 wctx[f].setflags('l' in flags, 'x' in flags)
1326 wctx[f].setflags('l' in flags, 'x' in flags)
1306 updated += 1
1327 updated += 1
1307
1328
1308 # the ordering is important here -- ms.mergedriver will raise if the merge
1329 # the ordering is important here -- ms.mergedriver will raise if the merge
1309 # driver has changed, and we want to be able to bypass it when overwrite is
1330 # driver has changed, and we want to be able to bypass it when overwrite is
1310 # True
1331 # True
1311 usemergedriver = not overwrite and mergeactions and ms.mergedriver
1332 usemergedriver = not overwrite and mergeactions and ms.mergedriver
1312
1333
1313 if usemergedriver:
1334 if usemergedriver:
1314 ms.commit()
1335 ms.commit()
1315 proceed = driverpreprocess(repo, ms, wctx, labels=labels)
1336 proceed = driverpreprocess(repo, ms, wctx, labels=labels)
1316 # the driver might leave some files unresolved
1337 # the driver might leave some files unresolved
1317 unresolvedf = set(ms.unresolved())
1338 unresolvedf = set(ms.unresolved())
1318 if not proceed:
1339 if not proceed:
1319 # XXX setting unresolved to at least 1 is a hack to make sure we
1340 # XXX setting unresolved to at least 1 is a hack to make sure we
1320 # error out
1341 # error out
1321 return updated, merged, removed, max(len(unresolvedf), 1)
1342 return updated, merged, removed, max(len(unresolvedf), 1)
1322 newactions = []
1343 newactions = []
1323 for f, args, msg in mergeactions:
1344 for f, args, msg in mergeactions:
1324 if f in unresolvedf:
1345 if f in unresolvedf:
1325 newactions.append((f, args, msg))
1346 newactions.append((f, args, msg))
1326 mergeactions = newactions
1347 mergeactions = newactions
1327
1348
1328 # premerge
1349 # premerge
1329 tocomplete = []
1350 tocomplete = []
1330 for f, args, msg in mergeactions:
1351 for f, args, msg in mergeactions:
1331 repo.ui.debug(" %s: %s -> m (premerge)\n" % (f, msg))
1352 repo.ui.debug(" %s: %s -> m (premerge)\n" % (f, msg))
1332 z += 1
1353 z += 1
1333 progress(_updating, z, item=f, total=numupdates, unit=_files)
1354 progress(_updating, z, item=f, total=numupdates, unit=_files)
1334 if f == '.hgsubstate': # subrepo states need updating
1355 if f == '.hgsubstate': # subrepo states need updating
1335 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
1356 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
1336 overwrite, labels)
1357 overwrite, labels)
1337 continue
1358 continue
1338 wctx[f].audit()
1359 wctx[f].audit()
1339 complete, r = ms.preresolve(f, wctx)
1360 complete, r = ms.preresolve(f, wctx)
1340 if not complete:
1361 if not complete:
1341 numupdates += 1
1362 numupdates += 1
1342 tocomplete.append((f, args, msg))
1363 tocomplete.append((f, args, msg))
1343
1364
1344 # merge
1365 # merge
1345 for f, args, msg in tocomplete:
1366 for f, args, msg in tocomplete:
1346 repo.ui.debug(" %s: %s -> m (merge)\n" % (f, msg))
1367 repo.ui.debug(" %s: %s -> m (merge)\n" % (f, msg))
1347 z += 1
1368 z += 1
1348 progress(_updating, z, item=f, total=numupdates, unit=_files)
1369 progress(_updating, z, item=f, total=numupdates, unit=_files)
1349 ms.resolve(f, wctx)
1370 ms.resolve(f, wctx)
1350
1371
1351 ms.commit()
1372 ms.commit()
1352
1373
1353 unresolved = ms.unresolvedcount()
1374 unresolved = ms.unresolvedcount()
1354
1375
1355 if usemergedriver and not unresolved and ms.mdstate() != 's':
1376 if usemergedriver and not unresolved and ms.mdstate() != 's':
1356 if not driverconclude(repo, ms, wctx, labels=labels):
1377 if not driverconclude(repo, ms, wctx, labels=labels):
1357 # XXX setting unresolved to at least 1 is a hack to make sure we
1378 # XXX setting unresolved to at least 1 is a hack to make sure we
1358 # error out
1379 # error out
1359 unresolved = max(unresolved, 1)
1380 unresolved = max(unresolved, 1)
1360
1381
1361 ms.commit()
1382 ms.commit()
1362
1383
1363 msupdated, msmerged, msremoved = ms.counts()
1384 msupdated, msmerged, msremoved = ms.counts()
1364 updated += msupdated
1385 updated += msupdated
1365 merged += msmerged
1386 merged += msmerged
1366 removed += msremoved
1387 removed += msremoved
1367
1388
1368 extraactions = ms.actions()
1389 extraactions = ms.actions()
1369 if extraactions:
1390 if extraactions:
1370 mfiles = set(a[0] for a in actions['m'])
1391 mfiles = set(a[0] for a in actions['m'])
1371 for k, acts in extraactions.iteritems():
1392 for k, acts in extraactions.iteritems():
1372 actions[k].extend(acts)
1393 actions[k].extend(acts)
1373 # Remove these files from actions['m'] as well. This is important
1394 # Remove these files from actions['m'] as well. This is important
1374 # because in recordupdates, files in actions['m'] are processed
1395 # because in recordupdates, files in actions['m'] are processed
1375 # after files in other actions, and the merge driver might add
1396 # after files in other actions, and the merge driver might add
1376 # files to those actions via extraactions above. This can lead to a
1397 # files to those actions via extraactions above. This can lead to a
1377 # file being recorded twice, with poor results. This is especially
1398 # file being recorded twice, with poor results. This is especially
1378 # problematic for actions['r'] (currently only possible with the
1399 # problematic for actions['r'] (currently only possible with the
1379 # merge driver in the initial merge process; interrupted merges
1400 # merge driver in the initial merge process; interrupted merges
1380 # don't go through this flow).
1401 # don't go through this flow).
1381 #
1402 #
1382 # The real fix here is to have indexes by both file and action so
1403 # The real fix here is to have indexes by both file and action so
1383 # that when the action for a file is changed it is automatically
1404 # that when the action for a file is changed it is automatically
1384 # reflected in the other action lists. But that involves a more
1405 # reflected in the other action lists. But that involves a more
1385 # complex data structure, so this will do for now.
1406 # complex data structure, so this will do for now.
1386 #
1407 #
1387 # We don't need to do the same operation for 'dc' and 'cd' because
1408 # We don't need to do the same operation for 'dc' and 'cd' because
1388 # those lists aren't consulted again.
1409 # those lists aren't consulted again.
1389 mfiles.difference_update(a[0] for a in acts)
1410 mfiles.difference_update(a[0] for a in acts)
1390
1411
1391 actions['m'] = [a for a in actions['m'] if a[0] in mfiles]
1412 actions['m'] = [a for a in actions['m'] if a[0] in mfiles]
1392
1413
1393 progress(_updating, None, total=numupdates, unit=_files)
1414 progress(_updating, None, total=numupdates, unit=_files)
1394
1415
1395 return updated, merged, removed, unresolved
1416 return updated, merged, removed, unresolved
1396
1417
1397 def recordupdates(repo, actions, branchmerge):
1418 def recordupdates(repo, actions, branchmerge):
1398 "record merge actions to the dirstate"
1419 "record merge actions to the dirstate"
1399 # remove (must come first)
1420 # remove (must come first)
1400 for f, args, msg in actions.get('r', []):
1421 for f, args, msg in actions.get('r', []):
1401 if branchmerge:
1422 if branchmerge:
1402 repo.dirstate.remove(f)
1423 repo.dirstate.remove(f)
1403 else:
1424 else:
1404 repo.dirstate.drop(f)
1425 repo.dirstate.drop(f)
1405
1426
1406 # forget (must come first)
1427 # forget (must come first)
1407 for f, args, msg in actions.get('f', []):
1428 for f, args, msg in actions.get('f', []):
1408 repo.dirstate.drop(f)
1429 repo.dirstate.drop(f)
1409
1430
1410 # re-add
1431 # re-add
1411 for f, args, msg in actions.get('a', []):
1432 for f, args, msg in actions.get('a', []):
1412 repo.dirstate.add(f)
1433 repo.dirstate.add(f)
1413
1434
1414 # re-add/mark as modified
1435 # re-add/mark as modified
1415 for f, args, msg in actions.get('am', []):
1436 for f, args, msg in actions.get('am', []):
1416 if branchmerge:
1437 if branchmerge:
1417 repo.dirstate.normallookup(f)
1438 repo.dirstate.normallookup(f)
1418 else:
1439 else:
1419 repo.dirstate.add(f)
1440 repo.dirstate.add(f)
1420
1441
1421 # exec change
1442 # exec change
1422 for f, args, msg in actions.get('e', []):
1443 for f, args, msg in actions.get('e', []):
1423 repo.dirstate.normallookup(f)
1444 repo.dirstate.normallookup(f)
1424
1445
1425 # keep
1446 # keep
1426 for f, args, msg in actions.get('k', []):
1447 for f, args, msg in actions.get('k', []):
1427 pass
1448 pass
1428
1449
1429 # get
1450 # get
1430 for f, args, msg in actions.get('g', []):
1451 for f, args, msg in actions.get('g', []):
1431 if branchmerge:
1452 if branchmerge:
1432 repo.dirstate.otherparent(f)
1453 repo.dirstate.otherparent(f)
1433 else:
1454 else:
1434 repo.dirstate.normal(f)
1455 repo.dirstate.normal(f)
1435
1456
1436 # merge
1457 # merge
1437 for f, args, msg in actions.get('m', []):
1458 for f, args, msg in actions.get('m', []):
1438 f1, f2, fa, move, anc = args
1459 f1, f2, fa, move, anc = args
1439 if branchmerge:
1460 if branchmerge:
1440 # We've done a branch merge, mark this file as merged
1461 # We've done a branch merge, mark this file as merged
1441 # so that we properly record the merger later
1462 # so that we properly record the merger later
1442 repo.dirstate.merge(f)
1463 repo.dirstate.merge(f)
1443 if f1 != f2: # copy/rename
1464 if f1 != f2: # copy/rename
1444 if move:
1465 if move:
1445 repo.dirstate.remove(f1)
1466 repo.dirstate.remove(f1)
1446 if f1 != f:
1467 if f1 != f:
1447 repo.dirstate.copy(f1, f)
1468 repo.dirstate.copy(f1, f)
1448 else:
1469 else:
1449 repo.dirstate.copy(f2, f)
1470 repo.dirstate.copy(f2, f)
1450 else:
1471 else:
1451 # We've update-merged a locally modified file, so
1472 # We've update-merged a locally modified file, so
1452 # we set the dirstate to emulate a normal checkout
1473 # we set the dirstate to emulate a normal checkout
1453 # of that file some time in the past. Thus our
1474 # of that file some time in the past. Thus our
1454 # merge will appear as a normal local file
1475 # merge will appear as a normal local file
1455 # modification.
1476 # modification.
1456 if f2 == f: # file not locally copied/moved
1477 if f2 == f: # file not locally copied/moved
1457 repo.dirstate.normallookup(f)
1478 repo.dirstate.normallookup(f)
1458 if move:
1479 if move:
1459 repo.dirstate.drop(f1)
1480 repo.dirstate.drop(f1)
1460
1481
1461 # directory rename, move local
1482 # directory rename, move local
1462 for f, args, msg in actions.get('dm', []):
1483 for f, args, msg in actions.get('dm', []):
1463 f0, flag = args
1484 f0, flag = args
1464 if branchmerge:
1485 if branchmerge:
1465 repo.dirstate.add(f)
1486 repo.dirstate.add(f)
1466 repo.dirstate.remove(f0)
1487 repo.dirstate.remove(f0)
1467 repo.dirstate.copy(f0, f)
1488 repo.dirstate.copy(f0, f)
1468 else:
1489 else:
1469 repo.dirstate.normal(f)
1490 repo.dirstate.normal(f)
1470 repo.dirstate.drop(f0)
1491 repo.dirstate.drop(f0)
1471
1492
1472 # directory rename, get
1493 # directory rename, get
1473 for f, args, msg in actions.get('dg', []):
1494 for f, args, msg in actions.get('dg', []):
1474 f0, flag = args
1495 f0, flag = args
1475 if branchmerge:
1496 if branchmerge:
1476 repo.dirstate.add(f)
1497 repo.dirstate.add(f)
1477 repo.dirstate.copy(f0, f)
1498 repo.dirstate.copy(f0, f)
1478 else:
1499 else:
1479 repo.dirstate.normal(f)
1500 repo.dirstate.normal(f)
1480
1501
1481 def update(repo, node, branchmerge, force, ancestor=None,
1502 def update(repo, node, branchmerge, force, ancestor=None,
1482 mergeancestor=False, labels=None, matcher=None, mergeforce=False,
1503 mergeancestor=False, labels=None, matcher=None, mergeforce=False,
1483 updatecheck=None, wc=None):
1504 updatecheck=None, wc=None):
1484 """
1505 """
1485 Perform a merge between the working directory and the given node
1506 Perform a merge between the working directory and the given node
1486
1507
1487 node = the node to update to
1508 node = the node to update to
1488 branchmerge = whether to merge between branches
1509 branchmerge = whether to merge between branches
1489 force = whether to force branch merging or file overwriting
1510 force = whether to force branch merging or file overwriting
1490 matcher = a matcher to filter file lists (dirstate not updated)
1511 matcher = a matcher to filter file lists (dirstate not updated)
1491 mergeancestor = whether it is merging with an ancestor. If true,
1512 mergeancestor = whether it is merging with an ancestor. If true,
1492 we should accept the incoming changes for any prompts that occur.
1513 we should accept the incoming changes for any prompts that occur.
1493 If false, merging with an ancestor (fast-forward) is only allowed
1514 If false, merging with an ancestor (fast-forward) is only allowed
1494 between different named branches. This flag is used by rebase extension
1515 between different named branches. This flag is used by rebase extension
1495 as a temporary fix and should be avoided in general.
1516 as a temporary fix and should be avoided in general.
1496 labels = labels to use for base, local and other
1517 labels = labels to use for base, local and other
1497 mergeforce = whether the merge was run with 'merge --force' (deprecated): if
1518 mergeforce = whether the merge was run with 'merge --force' (deprecated): if
1498 this is True, then 'force' should be True as well.
1519 this is True, then 'force' should be True as well.
1499
1520
1500 The table below shows all the behaviors of the update command
1521 The table below shows all the behaviors of the update command
1501 given the -c and -C or no options, whether the working directory
1522 given the -c and -C or no options, whether the working directory
1502 is dirty, whether a revision is specified, and the relationship of
1523 is dirty, whether a revision is specified, and the relationship of
1503 the parent rev to the target rev (linear or not). Match from top first. The
1524 the parent rev to the target rev (linear or not). Match from top first. The
1504 -n option doesn't exist on the command line, but represents the
1525 -n option doesn't exist on the command line, but represents the
1505 experimental.updatecheck=noconflict option.
1526 experimental.updatecheck=noconflict option.
1506
1527
1507 This logic is tested by test-update-branches.t.
1528 This logic is tested by test-update-branches.t.
1508
1529
1509 -c -C -n -m dirty rev linear | result
1530 -c -C -n -m dirty rev linear | result
1510 y y * * * * * | (1)
1531 y y * * * * * | (1)
1511 y * y * * * * | (1)
1532 y * y * * * * | (1)
1512 y * * y * * * | (1)
1533 y * * y * * * | (1)
1513 * y y * * * * | (1)
1534 * y y * * * * | (1)
1514 * y * y * * * | (1)
1535 * y * y * * * | (1)
1515 * * y y * * * | (1)
1536 * * y y * * * | (1)
1516 * * * * * n n | x
1537 * * * * * n n | x
1517 * * * * n * * | ok
1538 * * * * n * * | ok
1518 n n n n y * y | merge
1539 n n n n y * y | merge
1519 n n n n y y n | (2)
1540 n n n n y y n | (2)
1520 n n n y y * * | merge
1541 n n n y y * * | merge
1521 n n y n y * * | merge if no conflict
1542 n n y n y * * | merge if no conflict
1522 n y n n y * * | discard
1543 n y n n y * * | discard
1523 y n n n y * * | (3)
1544 y n n n y * * | (3)
1524
1545
1525 x = can't happen
1546 x = can't happen
1526 * = don't-care
1547 * = don't-care
1527 1 = incompatible options (checked in commands.py)
1548 1 = incompatible options (checked in commands.py)
1528 2 = abort: uncommitted changes (commit or update --clean to discard changes)
1549 2 = abort: uncommitted changes (commit or update --clean to discard changes)
1529 3 = abort: uncommitted changes (checked in commands.py)
1550 3 = abort: uncommitted changes (checked in commands.py)
1530
1551
1531 The merge is performed inside ``wc``, a workingctx-like objects. It defaults
1552 The merge is performed inside ``wc``, a workingctx-like objects. It defaults
1532 to repo[None] if None is passed.
1553 to repo[None] if None is passed.
1533
1554
1534 Return the same tuple as applyupdates().
1555 Return the same tuple as applyupdates().
1535 """
1556 """
1536 # Avoid cycle.
1557 # Avoid cycle.
1537 from . import sparse
1558 from . import sparse
1538
1559
1539 # This function used to find the default destination if node was None, but
1560 # This function used to find the default destination if node was None, but
1540 # that's now in destutil.py.
1561 # that's now in destutil.py.
1541 assert node is not None
1562 assert node is not None
1542 if not branchmerge and not force:
1563 if not branchmerge and not force:
1543 # TODO: remove the default once all callers that pass branchmerge=False
1564 # TODO: remove the default once all callers that pass branchmerge=False
1544 # and force=False pass a value for updatecheck. We may want to allow
1565 # and force=False pass a value for updatecheck. We may want to allow
1545 # updatecheck='abort' to better suppport some of these callers.
1566 # updatecheck='abort' to better suppport some of these callers.
1546 if updatecheck is None:
1567 if updatecheck is None:
1547 updatecheck = 'linear'
1568 updatecheck = 'linear'
1548 assert updatecheck in ('none', 'linear', 'noconflict')
1569 assert updatecheck in ('none', 'linear', 'noconflict')
1549 # If we're doing a partial update, we need to skip updating
1570 # If we're doing a partial update, we need to skip updating
1550 # the dirstate, so make a note of any partial-ness to the
1571 # the dirstate, so make a note of any partial-ness to the
1551 # update here.
1572 # update here.
1552 if matcher is None or matcher.always():
1573 if matcher is None or matcher.always():
1553 partial = False
1574 partial = False
1554 else:
1575 else:
1555 partial = True
1576 partial = True
1556 with repo.wlock():
1577 with repo.wlock():
1557 if wc is None:
1578 if wc is None:
1558 wc = repo[None]
1579 wc = repo[None]
1559 pl = wc.parents()
1580 pl = wc.parents()
1560 p1 = pl[0]
1581 p1 = pl[0]
1561 pas = [None]
1582 pas = [None]
1562 if ancestor is not None:
1583 if ancestor is not None:
1563 pas = [repo[ancestor]]
1584 pas = [repo[ancestor]]
1564
1585
1565 overwrite = force and not branchmerge
1586 overwrite = force and not branchmerge
1566
1587
1567 p2 = repo[node]
1588 p2 = repo[node]
1568 if pas[0] is None:
1589 if pas[0] is None:
1569 if repo.ui.configlist('merge', 'preferancestor') == ['*']:
1590 if repo.ui.configlist('merge', 'preferancestor') == ['*']:
1570 cahs = repo.changelog.commonancestorsheads(p1.node(), p2.node())
1591 cahs = repo.changelog.commonancestorsheads(p1.node(), p2.node())
1571 pas = [repo[anc] for anc in (sorted(cahs) or [nullid])]
1592 pas = [repo[anc] for anc in (sorted(cahs) or [nullid])]
1572 else:
1593 else:
1573 pas = [p1.ancestor(p2, warn=branchmerge)]
1594 pas = [p1.ancestor(p2, warn=branchmerge)]
1574
1595
1575 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
1596 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
1576
1597
1577 ### check phase
1598 ### check phase
1578 if not overwrite:
1599 if not overwrite:
1579 if len(pl) > 1:
1600 if len(pl) > 1:
1580 raise error.Abort(_("outstanding uncommitted merge"))
1601 raise error.Abort(_("outstanding uncommitted merge"))
1581 ms = mergestate.read(repo)
1602 ms = mergestate.read(repo)
1582 if list(ms.unresolved()):
1603 if list(ms.unresolved()):
1583 raise error.Abort(_("outstanding merge conflicts"))
1604 raise error.Abort(_("outstanding merge conflicts"))
1584 if branchmerge:
1605 if branchmerge:
1585 if pas == [p2]:
1606 if pas == [p2]:
1586 raise error.Abort(_("merging with a working directory ancestor"
1607 raise error.Abort(_("merging with a working directory ancestor"
1587 " has no effect"))
1608 " has no effect"))
1588 elif pas == [p1]:
1609 elif pas == [p1]:
1589 if not mergeancestor and wc.branch() == p2.branch():
1610 if not mergeancestor and wc.branch() == p2.branch():
1590 raise error.Abort(_("nothing to merge"),
1611 raise error.Abort(_("nothing to merge"),
1591 hint=_("use 'hg update' "
1612 hint=_("use 'hg update' "
1592 "or check 'hg heads'"))
1613 "or check 'hg heads'"))
1593 if not force and (wc.files() or wc.deleted()):
1614 if not force and (wc.files() or wc.deleted()):
1594 raise error.Abort(_("uncommitted changes"),
1615 raise error.Abort(_("uncommitted changes"),
1595 hint=_("use 'hg status' to list changes"))
1616 hint=_("use 'hg status' to list changes"))
1596 for s in sorted(wc.substate):
1617 for s in sorted(wc.substate):
1597 wc.sub(s).bailifchanged()
1618 wc.sub(s).bailifchanged()
1598
1619
1599 elif not overwrite:
1620 elif not overwrite:
1600 if p1 == p2: # no-op update
1621 if p1 == p2: # no-op update
1601 # call the hooks and exit early
1622 # call the hooks and exit early
1602 repo.hook('preupdate', throw=True, parent1=xp2, parent2='')
1623 repo.hook('preupdate', throw=True, parent1=xp2, parent2='')
1603 repo.hook('update', parent1=xp2, parent2='', error=0)
1624 repo.hook('update', parent1=xp2, parent2='', error=0)
1604 return 0, 0, 0, 0
1625 return 0, 0, 0, 0
1605
1626
1606 if (updatecheck == 'linear' and
1627 if (updatecheck == 'linear' and
1607 pas not in ([p1], [p2])): # nonlinear
1628 pas not in ([p1], [p2])): # nonlinear
1608 dirty = wc.dirty(missing=True)
1629 dirty = wc.dirty(missing=True)
1609 if dirty:
1630 if dirty:
1610 # Branching is a bit strange to ensure we do the minimal
1631 # Branching is a bit strange to ensure we do the minimal
1611 # amount of call to obsutil.foreground.
1632 # amount of call to obsutil.foreground.
1612 foreground = obsutil.foreground(repo, [p1.node()])
1633 foreground = obsutil.foreground(repo, [p1.node()])
1613 # note: the <node> variable contains a random identifier
1634 # note: the <node> variable contains a random identifier
1614 if repo[node].node() in foreground:
1635 if repo[node].node() in foreground:
1615 pass # allow updating to successors
1636 pass # allow updating to successors
1616 else:
1637 else:
1617 msg = _("uncommitted changes")
1638 msg = _("uncommitted changes")
1618 hint = _("commit or update --clean to discard changes")
1639 hint = _("commit or update --clean to discard changes")
1619 raise error.UpdateAbort(msg, hint=hint)
1640 raise error.UpdateAbort(msg, hint=hint)
1620 else:
1641 else:
1621 # Allow jumping branches if clean and specific rev given
1642 # Allow jumping branches if clean and specific rev given
1622 pass
1643 pass
1623
1644
1624 if overwrite:
1645 if overwrite:
1625 pas = [wc]
1646 pas = [wc]
1626 elif not branchmerge:
1647 elif not branchmerge:
1627 pas = [p1]
1648 pas = [p1]
1628
1649
1629 # deprecated config: merge.followcopies
1650 # deprecated config: merge.followcopies
1630 followcopies = repo.ui.configbool('merge', 'followcopies')
1651 followcopies = repo.ui.configbool('merge', 'followcopies')
1631 if overwrite:
1652 if overwrite:
1632 followcopies = False
1653 followcopies = False
1633 elif not pas[0]:
1654 elif not pas[0]:
1634 followcopies = False
1655 followcopies = False
1635 if not branchmerge and not wc.dirty(missing=True):
1656 if not branchmerge and not wc.dirty(missing=True):
1636 followcopies = False
1657 followcopies = False
1637
1658
1638 ### calculate phase
1659 ### calculate phase
1639 actionbyfile, diverge, renamedelete = calculateupdates(
1660 actionbyfile, diverge, renamedelete = calculateupdates(
1640 repo, wc, p2, pas, branchmerge, force, mergeancestor,
1661 repo, wc, p2, pas, branchmerge, force, mergeancestor,
1641 followcopies, matcher=matcher, mergeforce=mergeforce)
1662 followcopies, matcher=matcher, mergeforce=mergeforce)
1642
1663
1643 if updatecheck == 'noconflict':
1664 if updatecheck == 'noconflict':
1644 for f, (m, args, msg) in actionbyfile.iteritems():
1665 for f, (m, args, msg) in actionbyfile.iteritems():
1645 if m not in ('g', 'k', 'e', 'r'):
1666 if m not in ('g', 'k', 'e', 'r'):
1646 msg = _("conflicting changes")
1667 msg = _("conflicting changes")
1647 hint = _("commit or update --clean to discard changes")
1668 hint = _("commit or update --clean to discard changes")
1648 raise error.Abort(msg, hint=hint)
1669 raise error.Abort(msg, hint=hint)
1649
1670
1650 # Prompt and create actions. Most of this is in the resolve phase
1671 # Prompt and create actions. Most of this is in the resolve phase
1651 # already, but we can't handle .hgsubstate in filemerge or
1672 # already, but we can't handle .hgsubstate in filemerge or
1652 # subrepo.submerge yet so we have to keep prompting for it.
1673 # subrepo.submerge yet so we have to keep prompting for it.
1653 if '.hgsubstate' in actionbyfile:
1674 if '.hgsubstate' in actionbyfile:
1654 f = '.hgsubstate'
1675 f = '.hgsubstate'
1655 m, args, msg = actionbyfile[f]
1676 m, args, msg = actionbyfile[f]
1656 prompts = filemerge.partextras(labels)
1677 prompts = filemerge.partextras(labels)
1657 prompts['f'] = f
1678 prompts['f'] = f
1658 if m == 'cd':
1679 if m == 'cd':
1659 if repo.ui.promptchoice(
1680 if repo.ui.promptchoice(
1660 _("local%(l)s changed %(f)s which other%(o)s deleted\n"
1681 _("local%(l)s changed %(f)s which other%(o)s deleted\n"
1661 "use (c)hanged version or (d)elete?"
1682 "use (c)hanged version or (d)elete?"
1662 "$$ &Changed $$ &Delete") % prompts, 0):
1683 "$$ &Changed $$ &Delete") % prompts, 0):
1663 actionbyfile[f] = ('r', None, "prompt delete")
1684 actionbyfile[f] = ('r', None, "prompt delete")
1664 elif f in p1:
1685 elif f in p1:
1665 actionbyfile[f] = ('am', None, "prompt keep")
1686 actionbyfile[f] = ('am', None, "prompt keep")
1666 else:
1687 else:
1667 actionbyfile[f] = ('a', None, "prompt keep")
1688 actionbyfile[f] = ('a', None, "prompt keep")
1668 elif m == 'dc':
1689 elif m == 'dc':
1669 f1, f2, fa, move, anc = args
1690 f1, f2, fa, move, anc = args
1670 flags = p2[f2].flags()
1691 flags = p2[f2].flags()
1671 if repo.ui.promptchoice(
1692 if repo.ui.promptchoice(
1672 _("other%(o)s changed %(f)s which local%(l)s deleted\n"
1693 _("other%(o)s changed %(f)s which local%(l)s deleted\n"
1673 "use (c)hanged version or leave (d)eleted?"
1694 "use (c)hanged version or leave (d)eleted?"
1674 "$$ &Changed $$ &Deleted") % prompts, 0) == 0:
1695 "$$ &Changed $$ &Deleted") % prompts, 0) == 0:
1675 actionbyfile[f] = ('g', (flags, False), "prompt recreating")
1696 actionbyfile[f] = ('g', (flags, False), "prompt recreating")
1676 else:
1697 else:
1677 del actionbyfile[f]
1698 del actionbyfile[f]
1678
1699
1679 # Convert to dictionary-of-lists format
1700 # Convert to dictionary-of-lists format
1680 actions = dict((m, []) for m in 'a am f g cd dc r dm dg m e k'.split())
1701 actions = dict((m, []) for m in 'a am f g cd dc r dm dg m e k'.split())
1681 for f, (m, args, msg) in actionbyfile.iteritems():
1702 for f, (m, args, msg) in actionbyfile.iteritems():
1682 if m not in actions:
1703 if m not in actions:
1683 actions[m] = []
1704 actions[m] = []
1684 actions[m].append((f, args, msg))
1705 actions[m].append((f, args, msg))
1685
1706
1686 if not util.fscasesensitive(repo.path):
1707 if not util.fscasesensitive(repo.path):
1687 # check collision between files only in p2 for clean update
1708 # check collision between files only in p2 for clean update
1688 if (not branchmerge and
1709 if (not branchmerge and
1689 (force or not wc.dirty(missing=True, branch=False))):
1710 (force or not wc.dirty(missing=True, branch=False))):
1690 _checkcollision(repo, p2.manifest(), None)
1711 _checkcollision(repo, p2.manifest(), None)
1691 else:
1712 else:
1692 _checkcollision(repo, wc.manifest(), actions)
1713 _checkcollision(repo, wc.manifest(), actions)
1693
1714
1694 # divergent renames
1715 # divergent renames
1695 for f, fl in sorted(diverge.iteritems()):
1716 for f, fl in sorted(diverge.iteritems()):
1696 repo.ui.warn(_("note: possible conflict - %s was renamed "
1717 repo.ui.warn(_("note: possible conflict - %s was renamed "
1697 "multiple times to:\n") % f)
1718 "multiple times to:\n") % f)
1698 for nf in fl:
1719 for nf in fl:
1699 repo.ui.warn(" %s\n" % nf)
1720 repo.ui.warn(" %s\n" % nf)
1700
1721
1701 # rename and delete
1722 # rename and delete
1702 for f, fl in sorted(renamedelete.iteritems()):
1723 for f, fl in sorted(renamedelete.iteritems()):
1703 repo.ui.warn(_("note: possible conflict - %s was deleted "
1724 repo.ui.warn(_("note: possible conflict - %s was deleted "
1704 "and renamed to:\n") % f)
1725 "and renamed to:\n") % f)
1705 for nf in fl:
1726 for nf in fl:
1706 repo.ui.warn(" %s\n" % nf)
1727 repo.ui.warn(" %s\n" % nf)
1707
1728
1708 ### apply phase
1729 ### apply phase
1709 if not branchmerge: # just jump to the new rev
1730 if not branchmerge: # just jump to the new rev
1710 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
1731 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
1711 if not partial:
1732 if not partial:
1712 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
1733 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
1713 # note that we're in the middle of an update
1734 # note that we're in the middle of an update
1714 repo.vfs.write('updatestate', p2.hex())
1735 repo.vfs.write('updatestate', p2.hex())
1715
1736
1716 stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels)
1737 stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels)
1717 wc.flushall()
1738 wc.flushall()
1718
1739
1719 if not partial:
1740 if not partial:
1720 with repo.dirstate.parentchange():
1741 with repo.dirstate.parentchange():
1721 repo.setparents(fp1, fp2)
1742 repo.setparents(fp1, fp2)
1722 recordupdates(repo, actions, branchmerge)
1743 recordupdates(repo, actions, branchmerge)
1723 # update completed, clear state
1744 # update completed, clear state
1724 util.unlink(repo.vfs.join('updatestate'))
1745 util.unlink(repo.vfs.join('updatestate'))
1725
1746
1726 if not branchmerge:
1747 if not branchmerge:
1727 repo.dirstate.setbranch(p2.branch())
1748 repo.dirstate.setbranch(p2.branch())
1728
1749
1729 # If we're updating to a location, clean up any stale temporary includes
1750 # If we're updating to a location, clean up any stale temporary includes
1730 # (ex: this happens during hg rebase --abort).
1751 # (ex: this happens during hg rebase --abort).
1731 if not branchmerge:
1752 if not branchmerge:
1732 sparse.prunetemporaryincludes(repo)
1753 sparse.prunetemporaryincludes(repo)
1733
1754
1734 if not partial:
1755 if not partial:
1735 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
1756 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
1736 return stats
1757 return stats
1737
1758
1738 def graft(repo, ctx, pctx, labels, keepparent=False):
1759 def graft(repo, ctx, pctx, labels, keepparent=False):
1739 """Do a graft-like merge.
1760 """Do a graft-like merge.
1740
1761
1741 This is a merge where the merge ancestor is chosen such that one
1762 This is a merge where the merge ancestor is chosen such that one
1742 or more changesets are grafted onto the current changeset. In
1763 or more changesets are grafted onto the current changeset. In
1743 addition to the merge, this fixes up the dirstate to include only
1764 addition to the merge, this fixes up the dirstate to include only
1744 a single parent (if keepparent is False) and tries to duplicate any
1765 a single parent (if keepparent is False) and tries to duplicate any
1745 renames/copies appropriately.
1766 renames/copies appropriately.
1746
1767
1747 ctx - changeset to rebase
1768 ctx - changeset to rebase
1748 pctx - merge base, usually ctx.p1()
1769 pctx - merge base, usually ctx.p1()
1749 labels - merge labels eg ['local', 'graft']
1770 labels - merge labels eg ['local', 'graft']
1750 keepparent - keep second parent if any
1771 keepparent - keep second parent if any
1751
1772
1752 """
1773 """
1753 # If we're grafting a descendant onto an ancestor, be sure to pass
1774 # If we're grafting a descendant onto an ancestor, be sure to pass
1754 # mergeancestor=True to update. This does two things: 1) allows the merge if
1775 # mergeancestor=True to update. This does two things: 1) allows the merge if
1755 # the destination is the same as the parent of the ctx (so we can use graft
1776 # the destination is the same as the parent of the ctx (so we can use graft
1756 # to copy commits), and 2) informs update that the incoming changes are
1777 # to copy commits), and 2) informs update that the incoming changes are
1757 # newer than the destination so it doesn't prompt about "remote changed foo
1778 # newer than the destination so it doesn't prompt about "remote changed foo
1758 # which local deleted".
1779 # which local deleted".
1759 mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node())
1780 mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node())
1760
1781
1761 stats = update(repo, ctx.node(), True, True, pctx.node(),
1782 stats = update(repo, ctx.node(), True, True, pctx.node(),
1762 mergeancestor=mergeancestor, labels=labels)
1783 mergeancestor=mergeancestor, labels=labels)
1763
1784
1764 pother = nullid
1785 pother = nullid
1765 parents = ctx.parents()
1786 parents = ctx.parents()
1766 if keepparent and len(parents) == 2 and pctx in parents:
1787 if keepparent and len(parents) == 2 and pctx in parents:
1767 parents.remove(pctx)
1788 parents.remove(pctx)
1768 pother = parents[0].node()
1789 pother = parents[0].node()
1769
1790
1770 with repo.dirstate.parentchange():
1791 with repo.dirstate.parentchange():
1771 repo.setparents(repo['.'].node(), pother)
1792 repo.setparents(repo['.'].node(), pother)
1772 repo.dirstate.write(repo.currenttransaction())
1793 repo.dirstate.write(repo.currenttransaction())
1773 # fix up dirstate for copies and renames
1794 # fix up dirstate for copies and renames
1774 copies.duplicatecopies(repo, ctx.rev(), pctx.rev())
1795 copies.duplicatecopies(repo, ctx.rev(), pctx.rev())
1775 return stats
1796 return stats
General Comments 0
You need to be logged in to leave comments. Login now