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