##// END OF EJS Templates
merge: add file ancestor linknode to mergestate...
Durham Goode -
r28011:8abd9f78 default
parent child Browse files
Show More
@@ -1,1608 +1,1615 b''
1 # merge.py - directory-level update/merge handling for Mercurial
1 # merge.py - directory-level update/merge handling for Mercurial
2 #
2 #
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import errno
10 import errno
11 import 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 f: a (filename, dictonary) tuple of optional values for a given file
69 X: unsupported mandatory record type (used in tests)
69 X: unsupported mandatory record type (used in tests)
70 x: unsupported advisory record type (used in tests)
70 x: unsupported advisory record type (used in tests)
71
71
72 Merge driver run states (experimental):
72 Merge driver run states (experimental):
73 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
74 to resolve or commit
74 to resolve or commit
75 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
76 s: success/skipped -- does not need to be run any more
76 s: success/skipped -- does not need to be run any more
77
77
78 '''
78 '''
79 statepathv1 = 'merge/state'
79 statepathv1 = 'merge/state'
80 statepathv2 = 'merge/state2'
80 statepathv2 = 'merge/state2'
81
81
82 @staticmethod
82 @staticmethod
83 def clean(repo, node=None, other=None):
83 def clean(repo, node=None, other=None):
84 """Initialize a brand new merge state, removing any existing state on
84 """Initialize a brand new merge state, removing any existing state on
85 disk."""
85 disk."""
86 ms = mergestate(repo)
86 ms = mergestate(repo)
87 ms.reset(node, other)
87 ms.reset(node, other)
88 return ms
88 return ms
89
89
90 @staticmethod
90 @staticmethod
91 def read(repo):
91 def read(repo):
92 """Initialize the merge state, reading it from disk."""
92 """Initialize the merge state, reading it from disk."""
93 ms = mergestate(repo)
93 ms = mergestate(repo)
94 ms._read()
94 ms._read()
95 return ms
95 return ms
96
96
97 def __init__(self, repo):
97 def __init__(self, repo):
98 """Initialize the merge state.
98 """Initialize the merge state.
99
99
100 Do not use this directly! Instead call read() or clean()."""
100 Do not use this directly! Instead call read() or clean()."""
101 self._repo = repo
101 self._repo = repo
102 self._dirty = False
102 self._dirty = False
103
103
104 def reset(self, node=None, other=None):
104 def reset(self, node=None, other=None):
105 self._state = {}
105 self._state = {}
106 self._stateextras = {}
106 self._stateextras = {}
107 self._local = None
107 self._local = None
108 self._other = None
108 self._other = None
109 for var in ('localctx', 'otherctx'):
109 for var in ('localctx', 'otherctx'):
110 if var in vars(self):
110 if var in vars(self):
111 delattr(self, var)
111 delattr(self, var)
112 if node:
112 if node:
113 self._local = node
113 self._local = node
114 self._other = other
114 self._other = other
115 self._readmergedriver = None
115 self._readmergedriver = None
116 if self.mergedriver:
116 if self.mergedriver:
117 self._mdstate = 's'
117 self._mdstate = 's'
118 else:
118 else:
119 self._mdstate = 'u'
119 self._mdstate = 'u'
120 shutil.rmtree(self._repo.join('merge'), True)
120 shutil.rmtree(self._repo.join('merge'), True)
121 self._results = {}
121 self._results = {}
122 self._dirty = False
122 self._dirty = False
123
123
124 def _read(self):
124 def _read(self):
125 """Analyse each record content to restore a serialized state from disk
125 """Analyse each record content to restore a serialized state from disk
126
126
127 This function process "record" entry produced by the de-serialization
127 This function process "record" entry produced by the de-serialization
128 of on disk file.
128 of on disk file.
129 """
129 """
130 self._state = {}
130 self._state = {}
131 self._stateextras = {}
131 self._stateextras = {}
132 self._local = None
132 self._local = None
133 self._other = None
133 self._other = None
134 for var in ('localctx', 'otherctx'):
134 for var in ('localctx', 'otherctx'):
135 if var in vars(self):
135 if var in vars(self):
136 delattr(self, var)
136 delattr(self, var)
137 self._readmergedriver = None
137 self._readmergedriver = None
138 self._mdstate = 's'
138 self._mdstate = 's'
139 unsupported = set()
139 unsupported = set()
140 records = self._readrecords()
140 records = self._readrecords()
141 for rtype, record in records:
141 for rtype, record in records:
142 if rtype == 'L':
142 if rtype == 'L':
143 self._local = bin(record)
143 self._local = bin(record)
144 elif rtype == 'O':
144 elif rtype == 'O':
145 self._other = bin(record)
145 self._other = bin(record)
146 elif rtype == 'm':
146 elif rtype == 'm':
147 bits = record.split('\0', 1)
147 bits = record.split('\0', 1)
148 mdstate = bits[1]
148 mdstate = bits[1]
149 if len(mdstate) != 1 or mdstate not in 'ums':
149 if len(mdstate) != 1 or mdstate not in 'ums':
150 # the merge driver should be idempotent, so just rerun it
150 # the merge driver should be idempotent, so just rerun it
151 mdstate = 'u'
151 mdstate = 'u'
152
152
153 self._readmergedriver = bits[0]
153 self._readmergedriver = bits[0]
154 self._mdstate = mdstate
154 self._mdstate = mdstate
155 elif rtype in 'FDC':
155 elif rtype in 'FDC':
156 bits = record.split('\0')
156 bits = record.split('\0')
157 self._state[bits[0]] = bits[1:]
157 self._state[bits[0]] = bits[1:]
158 elif rtype == 'f':
158 elif rtype == 'f':
159 filename, rawextras = record.split('\0', 1)
159 filename, rawextras = record.split('\0', 1)
160 extraparts = rawextras.split('\0')
160 extraparts = rawextras.split('\0')
161 extras = {}
161 extras = {}
162 i = 0
162 i = 0
163 while i < len(extraparts):
163 while i < len(extraparts):
164 extras[extraparts[i]] = extraparts[i + 1]
164 extras[extraparts[i]] = extraparts[i + 1]
165 i += 2
165 i += 2
166
166
167 self._stateextras[filename] = extras
167 self._stateextras[filename] = extras
168 elif not rtype.islower():
168 elif not rtype.islower():
169 unsupported.add(rtype)
169 unsupported.add(rtype)
170 self._results = {}
170 self._results = {}
171 self._dirty = False
171 self._dirty = False
172
172
173 if unsupported:
173 if unsupported:
174 raise error.UnsupportedMergeRecords(unsupported)
174 raise error.UnsupportedMergeRecords(unsupported)
175
175
176 def _readrecords(self):
176 def _readrecords(self):
177 """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)
178
178
179 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.
180
180
181 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
182 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
183 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
184 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
185 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
186 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
187 file around.
187 file around.
188
188
189 returns list of record [(TYPE, data), ...]"""
189 returns list of record [(TYPE, data), ...]"""
190 v1records = self._readrecordsv1()
190 v1records = self._readrecordsv1()
191 v2records = self._readrecordsv2()
191 v2records = self._readrecordsv2()
192 if self._v1v2match(v1records, v2records):
192 if self._v1v2match(v1records, v2records):
193 return v2records
193 return v2records
194 else:
194 else:
195 # v1 file is newer than v2 file, use it
195 # v1 file is newer than v2 file, use it
196 # we have to infer the "other" changeset of the merge
196 # we have to infer the "other" changeset of the merge
197 # we cannot do better than that with v1 of the format
197 # we cannot do better than that with v1 of the format
198 mctx = self._repo[None].parents()[-1]
198 mctx = self._repo[None].parents()[-1]
199 v1records.append(('O', mctx.hex()))
199 v1records.append(('O', mctx.hex()))
200 # add place holder "other" file node information
200 # add place holder "other" file node information
201 # 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
202 # if mctx was wrong `mctx[bits[-2]]` may fails.
202 # if mctx was wrong `mctx[bits[-2]]` may fails.
203 for idx, r in enumerate(v1records):
203 for idx, r in enumerate(v1records):
204 if r[0] == 'F':
204 if r[0] == 'F':
205 bits = r[1].split('\0')
205 bits = r[1].split('\0')
206 bits.insert(-2, '')
206 bits.insert(-2, '')
207 v1records[idx] = (r[0], '\0'.join(bits))
207 v1records[idx] = (r[0], '\0'.join(bits))
208 return v1records
208 return v1records
209
209
210 def _v1v2match(self, v1records, v2records):
210 def _v1v2match(self, v1records, v2records):
211 oldv2 = set() # old format version of v2 record
211 oldv2 = set() # old format version of v2 record
212 for rec in v2records:
212 for rec in v2records:
213 if rec[0] == 'L':
213 if rec[0] == 'L':
214 oldv2.add(rec)
214 oldv2.add(rec)
215 elif rec[0] == 'F':
215 elif rec[0] == 'F':
216 # drop the onode data (not contained in v1)
216 # drop the onode data (not contained in v1)
217 oldv2.add(('F', _droponode(rec[1])))
217 oldv2.add(('F', _droponode(rec[1])))
218 for rec in v1records:
218 for rec in v1records:
219 if rec not in oldv2:
219 if rec not in oldv2:
220 return False
220 return False
221 else:
221 else:
222 return True
222 return True
223
223
224 def _readrecordsv1(self):
224 def _readrecordsv1(self):
225 """read on disk merge state for version 1 file
225 """read on disk merge state for version 1 file
226
226
227 returns list of record [(TYPE, data), ...]
227 returns list of record [(TYPE, data), ...]
228
228
229 Note: the "F" data from this file are one entry short
229 Note: the "F" data from this file are one entry short
230 (no "other file node" entry)
230 (no "other file node" entry)
231 """
231 """
232 records = []
232 records = []
233 try:
233 try:
234 f = self._repo.vfs(self.statepathv1)
234 f = self._repo.vfs(self.statepathv1)
235 for i, l in enumerate(f):
235 for i, l in enumerate(f):
236 if i == 0:
236 if i == 0:
237 records.append(('L', l[:-1]))
237 records.append(('L', l[:-1]))
238 else:
238 else:
239 records.append(('F', l[:-1]))
239 records.append(('F', l[:-1]))
240 f.close()
240 f.close()
241 except IOError as err:
241 except IOError as err:
242 if err.errno != errno.ENOENT:
242 if err.errno != errno.ENOENT:
243 raise
243 raise
244 return records
244 return records
245
245
246 def _readrecordsv2(self):
246 def _readrecordsv2(self):
247 """read on disk merge state for version 2 file
247 """read on disk merge state for version 2 file
248
248
249 This format is a list of arbitrary records of the form:
249 This format is a list of arbitrary records of the form:
250
250
251 [type][length][content]
251 [type][length][content]
252
252
253 `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
254 `content` is an arbitrary byte sequence of length `length`.
254 `content` is an arbitrary byte sequence of length `length`.
255
255
256 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
257 unsupported mandatory merge records, attempting to clear out the merge
257 unsupported mandatory merge records, attempting to clear out the merge
258 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
259 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
260 advisory record, but later versions interpret as special: the first
260 advisory record, but later versions interpret as special: the first
261 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.
262
262
263 Returns list of records [(TYPE, data), ...]."""
263 Returns list of records [(TYPE, data), ...]."""
264 records = []
264 records = []
265 try:
265 try:
266 f = self._repo.vfs(self.statepathv2)
266 f = self._repo.vfs(self.statepathv2)
267 data = f.read()
267 data = f.read()
268 off = 0
268 off = 0
269 end = len(data)
269 end = len(data)
270 while off < end:
270 while off < end:
271 rtype = data[off]
271 rtype = data[off]
272 off += 1
272 off += 1
273 length = _unpack('>I', data[off:(off + 4)])[0]
273 length = _unpack('>I', data[off:(off + 4)])[0]
274 off += 4
274 off += 4
275 record = data[off:(off + length)]
275 record = data[off:(off + length)]
276 off += length
276 off += length
277 if rtype == 't':
277 if rtype == 't':
278 rtype, record = record[0], record[1:]
278 rtype, record = record[0], record[1:]
279 records.append((rtype, record))
279 records.append((rtype, record))
280 f.close()
280 f.close()
281 except IOError as err:
281 except IOError as err:
282 if err.errno != errno.ENOENT:
282 if err.errno != errno.ENOENT:
283 raise
283 raise
284 return records
284 return records
285
285
286 @util.propertycache
286 @util.propertycache
287 def mergedriver(self):
287 def mergedriver(self):
288 # protect against the following:
288 # protect against the following:
289 # - A configures a malicious merge driver in their hgrc, then
289 # - A configures a malicious merge driver in their hgrc, then
290 # pauses the merge
290 # pauses the merge
291 # - A edits their hgrc to remove references to the merge driver
291 # - A edits their hgrc to remove references to the merge driver
292 # - 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
293 # - B inspects .hgrc and finds it to be clean
293 # - B inspects .hgrc and finds it to be clean
294 # - B then continues the merge and the malicious merge driver
294 # - B then continues the merge and the malicious merge driver
295 # gets invoked
295 # gets invoked
296 configmergedriver = self._repo.ui.config('experimental', 'mergedriver')
296 configmergedriver = self._repo.ui.config('experimental', 'mergedriver')
297 if (self._readmergedriver is not None
297 if (self._readmergedriver is not None
298 and self._readmergedriver != configmergedriver):
298 and self._readmergedriver != configmergedriver):
299 raise error.ConfigError(
299 raise error.ConfigError(
300 _("merge driver changed since merge started"),
300 _("merge driver changed since merge started"),
301 hint=_("revert merge driver change or abort merge"))
301 hint=_("revert merge driver change or abort merge"))
302
302
303 return configmergedriver
303 return configmergedriver
304
304
305 @util.propertycache
305 @util.propertycache
306 def localctx(self):
306 def localctx(self):
307 if self._local is None:
307 if self._local is None:
308 raise RuntimeError("localctx accessed but self._local isn't set")
308 raise RuntimeError("localctx accessed but self._local isn't set")
309 return self._repo[self._local]
309 return self._repo[self._local]
310
310
311 @util.propertycache
311 @util.propertycache
312 def otherctx(self):
312 def otherctx(self):
313 if self._other is None:
313 if self._other is None:
314 raise RuntimeError("localctx accessed but self._local isn't set")
314 raise RuntimeError("localctx accessed but self._local isn't set")
315 return self._repo[self._other]
315 return self._repo[self._other]
316
316
317 def active(self):
317 def active(self):
318 """Whether mergestate is active.
318 """Whether mergestate is active.
319
319
320 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
321 for "is a merge in progress."
321 for "is a merge in progress."
322 """
322 """
323 # Check local variables before looking at filesystem for performance
323 # Check local variables before looking at filesystem for performance
324 # reasons.
324 # reasons.
325 return bool(self._local) or bool(self._state) or \
325 return bool(self._local) or bool(self._state) or \
326 self._repo.vfs.exists(self.statepathv1) or \
326 self._repo.vfs.exists(self.statepathv1) or \
327 self._repo.vfs.exists(self.statepathv2)
327 self._repo.vfs.exists(self.statepathv2)
328
328
329 def commit(self):
329 def commit(self):
330 """Write current state on disk (if necessary)"""
330 """Write current state on disk (if necessary)"""
331 if self._dirty:
331 if self._dirty:
332 records = self._makerecords()
332 records = self._makerecords()
333 self._writerecords(records)
333 self._writerecords(records)
334 self._dirty = False
334 self._dirty = False
335
335
336 def _makerecords(self):
336 def _makerecords(self):
337 records = []
337 records = []
338 records.append(('L', hex(self._local)))
338 records.append(('L', hex(self._local)))
339 records.append(('O', hex(self._other)))
339 records.append(('O', hex(self._other)))
340 if self.mergedriver:
340 if self.mergedriver:
341 records.append(('m', '\0'.join([
341 records.append(('m', '\0'.join([
342 self.mergedriver, self._mdstate])))
342 self.mergedriver, self._mdstate])))
343 for d, v in self._state.iteritems():
343 for d, v in self._state.iteritems():
344 if v[0] == 'd':
344 if v[0] == 'd':
345 records.append(('D', '\0'.join([d] + v)))
345 records.append(('D', '\0'.join([d] + v)))
346 # v[1] == local ('cd'), v[6] == other ('dc') -- not supported by
346 # v[1] == local ('cd'), v[6] == other ('dc') -- not supported by
347 # older versions of Mercurial
347 # older versions of Mercurial
348 elif v[1] == nullhex or v[6] == nullhex:
348 elif v[1] == nullhex or v[6] == nullhex:
349 records.append(('C', '\0'.join([d] + v)))
349 records.append(('C', '\0'.join([d] + v)))
350 else:
350 else:
351 records.append(('F', '\0'.join([d] + v)))
351 records.append(('F', '\0'.join([d] + v)))
352 for filename, extras in sorted(self._stateextras.iteritems()):
352 for filename, extras in sorted(self._stateextras.iteritems()):
353 rawextras = '\0'.join('%s\0%s' % (k, v) for k, v in
353 rawextras = '\0'.join('%s\0%s' % (k, v) for k, v in
354 extras.iteritems())
354 extras.iteritems())
355 records.append(('f', '%s\0%s' % (filename, rawextras)))
355 records.append(('f', '%s\0%s' % (filename, rawextras)))
356 return records
356 return records
357
357
358 def _writerecords(self, records):
358 def _writerecords(self, records):
359 """Write current state on disk (both v1 and v2)"""
359 """Write current state on disk (both v1 and v2)"""
360 self._writerecordsv1(records)
360 self._writerecordsv1(records)
361 self._writerecordsv2(records)
361 self._writerecordsv2(records)
362
362
363 def _writerecordsv1(self, records):
363 def _writerecordsv1(self, records):
364 """Write current state on disk in a version 1 file"""
364 """Write current state on disk in a version 1 file"""
365 f = self._repo.vfs(self.statepathv1, 'w')
365 f = self._repo.vfs(self.statepathv1, 'w')
366 irecords = iter(records)
366 irecords = iter(records)
367 lrecords = irecords.next()
367 lrecords = irecords.next()
368 assert lrecords[0] == 'L'
368 assert lrecords[0] == 'L'
369 f.write(hex(self._local) + '\n')
369 f.write(hex(self._local) + '\n')
370 for rtype, data in irecords:
370 for rtype, data in irecords:
371 if rtype == 'F':
371 if rtype == 'F':
372 f.write('%s\n' % _droponode(data))
372 f.write('%s\n' % _droponode(data))
373 f.close()
373 f.close()
374
374
375 def _writerecordsv2(self, records):
375 def _writerecordsv2(self, records):
376 """Write current state on disk in a version 2 file
376 """Write current state on disk in a version 2 file
377
377
378 See the docstring for _readrecordsv2 for why we use 't'."""
378 See the docstring for _readrecordsv2 for why we use 't'."""
379 # these are the records that all version 2 clients can read
379 # these are the records that all version 2 clients can read
380 whitelist = 'LOF'
380 whitelist = 'LOF'
381 f = self._repo.vfs(self.statepathv2, 'w')
381 f = self._repo.vfs(self.statepathv2, 'w')
382 for key, data in records:
382 for key, data in records:
383 assert len(key) == 1
383 assert len(key) == 1
384 if key not in whitelist:
384 if key not in whitelist:
385 key, data = 't', '%s%s' % (key, data)
385 key, data = 't', '%s%s' % (key, data)
386 format = '>sI%is' % len(data)
386 format = '>sI%is' % len(data)
387 f.write(_pack(format, key, len(data), data))
387 f.write(_pack(format, key, len(data), data))
388 f.close()
388 f.close()
389
389
390 def add(self, fcl, fco, fca, fd):
390 def add(self, fcl, fco, fca, fd):
391 """add a new (potentially?) conflicting file the merge state
391 """add a new (potentially?) conflicting file the merge state
392 fcl: file context for local,
392 fcl: file context for local,
393 fco: file context for remote,
393 fco: file context for remote,
394 fca: file context for ancestors,
394 fca: file context for ancestors,
395 fd: file path of the resulting merge.
395 fd: file path of the resulting merge.
396
396
397 note: also write the local version to the `.hg/merge` directory.
397 note: also write the local version to the `.hg/merge` directory.
398 """
398 """
399 if fcl.isabsent():
399 if fcl.isabsent():
400 hash = nullhex
400 hash = nullhex
401 else:
401 else:
402 hash = util.sha1(fcl.path()).hexdigest()
402 hash = util.sha1(fcl.path()).hexdigest()
403 self._repo.vfs.write('merge/' + hash, fcl.data())
403 self._repo.vfs.write('merge/' + hash, fcl.data())
404 self._state[fd] = ['u', hash, fcl.path(),
404 self._state[fd] = ['u', hash, fcl.path(),
405 fca.path(), hex(fca.filenode()),
405 fca.path(), hex(fca.filenode()),
406 fco.path(), hex(fco.filenode()),
406 fco.path(), hex(fco.filenode()),
407 fcl.flags()]
407 fcl.flags()]
408 self._stateextras[fd] = { 'ancestorlinknode' : hex(fca.node()) }
408 self._dirty = True
409 self._dirty = True
409
410
410 def __contains__(self, dfile):
411 def __contains__(self, dfile):
411 return dfile in self._state
412 return dfile in self._state
412
413
413 def __getitem__(self, dfile):
414 def __getitem__(self, dfile):
414 return self._state[dfile][0]
415 return self._state[dfile][0]
415
416
416 def __iter__(self):
417 def __iter__(self):
417 return iter(sorted(self._state))
418 return iter(sorted(self._state))
418
419
419 def files(self):
420 def files(self):
420 return self._state.keys()
421 return self._state.keys()
421
422
422 def mark(self, dfile, state):
423 def mark(self, dfile, state):
423 self._state[dfile][0] = state
424 self._state[dfile][0] = state
424 self._dirty = True
425 self._dirty = True
425
426
426 def mdstate(self):
427 def mdstate(self):
427 return self._mdstate
428 return self._mdstate
428
429
429 def unresolved(self):
430 def unresolved(self):
430 """Obtain the paths of unresolved files."""
431 """Obtain the paths of unresolved files."""
431
432
432 for f, entry in self._state.items():
433 for f, entry in self._state.items():
433 if entry[0] == 'u':
434 if entry[0] == 'u':
434 yield f
435 yield f
435
436
436 def driverresolved(self):
437 def driverresolved(self):
437 """Obtain the paths of driver-resolved files."""
438 """Obtain the paths of driver-resolved files."""
438
439
439 for f, entry in self._state.items():
440 for f, entry in self._state.items():
440 if entry[0] == 'd':
441 if entry[0] == 'd':
441 yield f
442 yield f
442
443
443 def extras(self, filename):
444 def extras(self, filename):
444 return self._stateextras.setdefault(filename, {})
445 return self._stateextras.setdefault(filename, {})
445
446
446 def _resolve(self, preresolve, dfile, wctx, labels=None):
447 def _resolve(self, preresolve, dfile, wctx, labels=None):
447 """rerun merge process for file path `dfile`"""
448 """rerun merge process for file path `dfile`"""
448 if self[dfile] in 'rd':
449 if self[dfile] in 'rd':
449 return True, 0
450 return True, 0
450 stateentry = self._state[dfile]
451 stateentry = self._state[dfile]
451 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
452 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
452 octx = self._repo[self._other]
453 octx = self._repo[self._other]
454 extras = self.extras(dfile)
455 anccommitnode = extras.get('ancestorlinknode')
456 if anccommitnode:
457 actx = self._repo[anccommitnode]
458 else:
459 actx = None
453 fcd = self._filectxorabsent(hash, wctx, dfile)
460 fcd = self._filectxorabsent(hash, wctx, dfile)
454 fco = self._filectxorabsent(onode, octx, ofile)
461 fco = self._filectxorabsent(onode, octx, ofile)
455 # TODO: move this to filectxorabsent
462 # TODO: move this to filectxorabsent
456 fca = self._repo.filectx(afile, fileid=anode)
463 fca = self._repo.filectx(afile, fileid=anode, changeid=actx)
457 # "premerge" x flags
464 # "premerge" x flags
458 flo = fco.flags()
465 flo = fco.flags()
459 fla = fca.flags()
466 fla = fca.flags()
460 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
467 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
461 if fca.node() == nullid:
468 if fca.node() == nullid:
462 if preresolve:
469 if preresolve:
463 self._repo.ui.warn(
470 self._repo.ui.warn(
464 _('warning: cannot merge flags for %s\n') % afile)
471 _('warning: cannot merge flags for %s\n') % afile)
465 elif flags == fla:
472 elif flags == fla:
466 flags = flo
473 flags = flo
467 if preresolve:
474 if preresolve:
468 # restore local
475 # restore local
469 if hash != nullhex:
476 if hash != nullhex:
470 f = self._repo.vfs('merge/' + hash)
477 f = self._repo.vfs('merge/' + hash)
471 self._repo.wwrite(dfile, f.read(), flags)
478 self._repo.wwrite(dfile, f.read(), flags)
472 f.close()
479 f.close()
473 else:
480 else:
474 self._repo.wvfs.unlinkpath(dfile, ignoremissing=True)
481 self._repo.wvfs.unlinkpath(dfile, ignoremissing=True)
475 complete, r, deleted = filemerge.premerge(self._repo, self._local,
482 complete, r, deleted = filemerge.premerge(self._repo, self._local,
476 lfile, fcd, fco, fca,
483 lfile, fcd, fco, fca,
477 labels=labels)
484 labels=labels)
478 else:
485 else:
479 complete, r, deleted = filemerge.filemerge(self._repo, self._local,
486 complete, r, deleted = filemerge.filemerge(self._repo, self._local,
480 lfile, fcd, fco, fca,
487 lfile, fcd, fco, fca,
481 labels=labels)
488 labels=labels)
482 if r is None:
489 if r is None:
483 # no real conflict
490 # no real conflict
484 del self._state[dfile]
491 del self._state[dfile]
485 self._stateextras.pop(dfile, None)
492 self._stateextras.pop(dfile, None)
486 self._dirty = True
493 self._dirty = True
487 elif not r:
494 elif not r:
488 self.mark(dfile, 'r')
495 self.mark(dfile, 'r')
489
496
490 if complete:
497 if complete:
491 action = None
498 action = None
492 if deleted:
499 if deleted:
493 if fcd.isabsent():
500 if fcd.isabsent():
494 # dc: local picked. Need to drop if present, which may
501 # dc: local picked. Need to drop if present, which may
495 # happen on re-resolves.
502 # happen on re-resolves.
496 action = 'f'
503 action = 'f'
497 else:
504 else:
498 # cd: remote picked (or otherwise deleted)
505 # cd: remote picked (or otherwise deleted)
499 action = 'r'
506 action = 'r'
500 else:
507 else:
501 if fcd.isabsent(): # dc: remote picked
508 if fcd.isabsent(): # dc: remote picked
502 action = 'g'
509 action = 'g'
503 elif fco.isabsent(): # cd: local picked
510 elif fco.isabsent(): # cd: local picked
504 if dfile in self.localctx:
511 if dfile in self.localctx:
505 action = 'am'
512 action = 'am'
506 else:
513 else:
507 action = 'a'
514 action = 'a'
508 # else: regular merges (no action necessary)
515 # else: regular merges (no action necessary)
509 self._results[dfile] = r, action
516 self._results[dfile] = r, action
510
517
511 return complete, r
518 return complete, r
512
519
513 def _filectxorabsent(self, hexnode, ctx, f):
520 def _filectxorabsent(self, hexnode, ctx, f):
514 if hexnode == nullhex:
521 if hexnode == nullhex:
515 return filemerge.absentfilectx(ctx, f)
522 return filemerge.absentfilectx(ctx, f)
516 else:
523 else:
517 return ctx[f]
524 return ctx[f]
518
525
519 def preresolve(self, dfile, wctx, labels=None):
526 def preresolve(self, dfile, wctx, labels=None):
520 """run premerge process for dfile
527 """run premerge process for dfile
521
528
522 Returns whether the merge is complete, and the exit code."""
529 Returns whether the merge is complete, and the exit code."""
523 return self._resolve(True, dfile, wctx, labels=labels)
530 return self._resolve(True, dfile, wctx, labels=labels)
524
531
525 def resolve(self, dfile, wctx, labels=None):
532 def resolve(self, dfile, wctx, labels=None):
526 """run merge process (assuming premerge was run) for dfile
533 """run merge process (assuming premerge was run) for dfile
527
534
528 Returns the exit code of the merge."""
535 Returns the exit code of the merge."""
529 return self._resolve(False, dfile, wctx, labels=labels)[1]
536 return self._resolve(False, dfile, wctx, labels=labels)[1]
530
537
531 def counts(self):
538 def counts(self):
532 """return counts for updated, merged and removed files in this
539 """return counts for updated, merged and removed files in this
533 session"""
540 session"""
534 updated, merged, removed = 0, 0, 0
541 updated, merged, removed = 0, 0, 0
535 for r, action in self._results.itervalues():
542 for r, action in self._results.itervalues():
536 if r is None:
543 if r is None:
537 updated += 1
544 updated += 1
538 elif r == 0:
545 elif r == 0:
539 if action == 'r':
546 if action == 'r':
540 removed += 1
547 removed += 1
541 else:
548 else:
542 merged += 1
549 merged += 1
543 return updated, merged, removed
550 return updated, merged, removed
544
551
545 def unresolvedcount(self):
552 def unresolvedcount(self):
546 """get unresolved count for this merge (persistent)"""
553 """get unresolved count for this merge (persistent)"""
547 return len([True for f, entry in self._state.iteritems()
554 return len([True for f, entry in self._state.iteritems()
548 if entry[0] == 'u'])
555 if entry[0] == 'u'])
549
556
550 def actions(self):
557 def actions(self):
551 """return lists of actions to perform on the dirstate"""
558 """return lists of actions to perform on the dirstate"""
552 actions = {'r': [], 'f': [], 'a': [], 'am': [], 'g': []}
559 actions = {'r': [], 'f': [], 'a': [], 'am': [], 'g': []}
553 for f, (r, action) in self._results.iteritems():
560 for f, (r, action) in self._results.iteritems():
554 if action is not None:
561 if action is not None:
555 actions[action].append((f, None, "merge result"))
562 actions[action].append((f, None, "merge result"))
556 return actions
563 return actions
557
564
558 def recordactions(self):
565 def recordactions(self):
559 """record remove/add/get actions in the dirstate"""
566 """record remove/add/get actions in the dirstate"""
560 branchmerge = self._repo.dirstate.p2() != nullid
567 branchmerge = self._repo.dirstate.p2() != nullid
561 recordupdates(self._repo, self.actions(), branchmerge)
568 recordupdates(self._repo, self.actions(), branchmerge)
562
569
563 def queueremove(self, f):
570 def queueremove(self, f):
564 """queues a file to be removed from the dirstate
571 """queues a file to be removed from the dirstate
565
572
566 Meant for use by custom merge drivers."""
573 Meant for use by custom merge drivers."""
567 self._results[f] = 0, 'r'
574 self._results[f] = 0, 'r'
568
575
569 def queueadd(self, f):
576 def queueadd(self, f):
570 """queues a file to be added to the dirstate
577 """queues a file to be added to the dirstate
571
578
572 Meant for use by custom merge drivers."""
579 Meant for use by custom merge drivers."""
573 self._results[f] = 0, 'a'
580 self._results[f] = 0, 'a'
574
581
575 def queueget(self, f):
582 def queueget(self, f):
576 """queues a file to be marked modified in the dirstate
583 """queues a file to be marked modified in the dirstate
577
584
578 Meant for use by custom merge drivers."""
585 Meant for use by custom merge drivers."""
579 self._results[f] = 0, 'g'
586 self._results[f] = 0, 'g'
580
587
581 def _getcheckunknownconfig(repo, section, name):
588 def _getcheckunknownconfig(repo, section, name):
582 config = repo.ui.config(section, name, default='abort')
589 config = repo.ui.config(section, name, default='abort')
583 valid = ['abort', 'ignore', 'warn']
590 valid = ['abort', 'ignore', 'warn']
584 if config not in valid:
591 if config not in valid:
585 validstr = ', '.join(["'" + v + "'" for v in valid])
592 validstr = ', '.join(["'" + v + "'" for v in valid])
586 raise error.ConfigError(_("%s.%s not valid "
593 raise error.ConfigError(_("%s.%s not valid "
587 "('%s' is none of %s)")
594 "('%s' is none of %s)")
588 % (section, name, config, validstr))
595 % (section, name, config, validstr))
589 return config
596 return config
590
597
591 def _checkunknownfile(repo, wctx, mctx, f, f2=None):
598 def _checkunknownfile(repo, wctx, mctx, f, f2=None):
592 if f2 is None:
599 if f2 is None:
593 f2 = f
600 f2 = f
594 return (repo.wvfs.isfileorlink(f)
601 return (repo.wvfs.isfileorlink(f)
595 and repo.wvfs.audit.check(f)
602 and repo.wvfs.audit.check(f)
596 and repo.dirstate.normalize(f) not in repo.dirstate
603 and repo.dirstate.normalize(f) not in repo.dirstate
597 and mctx[f2].cmp(wctx[f]))
604 and mctx[f2].cmp(wctx[f]))
598
605
599 def _checkunknownfiles(repo, wctx, mctx, force, actions):
606 def _checkunknownfiles(repo, wctx, mctx, force, actions):
600 """
607 """
601 Considers any actions that care about the presence of conflicting unknown
608 Considers any actions that care about the presence of conflicting unknown
602 files. For some actions, the result is to abort; for others, it is to
609 files. For some actions, the result is to abort; for others, it is to
603 choose a different action.
610 choose a different action.
604 """
611 """
605 conflicts = set()
612 conflicts = set()
606 if not force:
613 if not force:
607 abortconflicts = set()
614 abortconflicts = set()
608 warnconflicts = set()
615 warnconflicts = set()
609 def collectconflicts(conflicts, config):
616 def collectconflicts(conflicts, config):
610 if config == 'abort':
617 if config == 'abort':
611 abortconflicts.update(conflicts)
618 abortconflicts.update(conflicts)
612 elif config == 'warn':
619 elif config == 'warn':
613 warnconflicts.update(conflicts)
620 warnconflicts.update(conflicts)
614
621
615 unknownconfig = _getcheckunknownconfig(repo, 'merge', 'checkunknown')
622 unknownconfig = _getcheckunknownconfig(repo, 'merge', 'checkunknown')
616 ignoredconfig = _getcheckunknownconfig(repo, 'merge', 'checkignored')
623 ignoredconfig = _getcheckunknownconfig(repo, 'merge', 'checkignored')
617 for f, (m, args, msg) in actions.iteritems():
624 for f, (m, args, msg) in actions.iteritems():
618 if m in ('c', 'dc'):
625 if m in ('c', 'dc'):
619 if _checkunknownfile(repo, wctx, mctx, f):
626 if _checkunknownfile(repo, wctx, mctx, f):
620 conflicts.add(f)
627 conflicts.add(f)
621 elif m == 'dg':
628 elif m == 'dg':
622 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
629 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
623 conflicts.add(f)
630 conflicts.add(f)
624
631
625 ignoredconflicts = set([c for c in conflicts
632 ignoredconflicts = set([c for c in conflicts
626 if repo.dirstate._ignore(c)])
633 if repo.dirstate._ignore(c)])
627 unknownconflicts = conflicts - ignoredconflicts
634 unknownconflicts = conflicts - ignoredconflicts
628 collectconflicts(ignoredconflicts, ignoredconfig)
635 collectconflicts(ignoredconflicts, ignoredconfig)
629 collectconflicts(unknownconflicts, unknownconfig)
636 collectconflicts(unknownconflicts, unknownconfig)
630 for f in sorted(abortconflicts):
637 for f in sorted(abortconflicts):
631 repo.ui.warn(_("%s: untracked file differs\n") % f)
638 repo.ui.warn(_("%s: untracked file differs\n") % f)
632 if abortconflicts:
639 if abortconflicts:
633 raise error.Abort(_("untracked files in working directory "
640 raise error.Abort(_("untracked files in working directory "
634 "differ from files in requested revision"))
641 "differ from files in requested revision"))
635
642
636 for f in sorted(warnconflicts):
643 for f in sorted(warnconflicts):
637 repo.ui.warn(_("%s: replacing untracked file\n") % f)
644 repo.ui.warn(_("%s: replacing untracked file\n") % f)
638
645
639 for f, (m, args, msg) in actions.iteritems():
646 for f, (m, args, msg) in actions.iteritems():
640 backup = f in conflicts
647 backup = f in conflicts
641 if m == 'c':
648 if m == 'c':
642 flags, = args
649 flags, = args
643 actions[f] = ('g', (flags, backup), msg)
650 actions[f] = ('g', (flags, backup), msg)
644 elif m == 'cm':
651 elif m == 'cm':
645 fl2, anc = args
652 fl2, anc = args
646 different = _checkunknownfile(repo, wctx, mctx, f)
653 different = _checkunknownfile(repo, wctx, mctx, f)
647 if different:
654 if different:
648 actions[f] = ('m', (f, f, None, False, anc),
655 actions[f] = ('m', (f, f, None, False, anc),
649 "remote differs from untracked local")
656 "remote differs from untracked local")
650 else:
657 else:
651 actions[f] = ('g', (fl2, backup), "remote created")
658 actions[f] = ('g', (fl2, backup), "remote created")
652
659
653 def _forgetremoved(wctx, mctx, branchmerge):
660 def _forgetremoved(wctx, mctx, branchmerge):
654 """
661 """
655 Forget removed files
662 Forget removed files
656
663
657 If we're jumping between revisions (as opposed to merging), and if
664 If we're jumping between revisions (as opposed to merging), and if
658 neither the working directory nor the target rev has the file,
665 neither the working directory nor the target rev has the file,
659 then we need to remove it from the dirstate, to prevent the
666 then we need to remove it from the dirstate, to prevent the
660 dirstate from listing the file when it is no longer in the
667 dirstate from listing the file when it is no longer in the
661 manifest.
668 manifest.
662
669
663 If we're merging, and the other revision has removed a file
670 If we're merging, and the other revision has removed a file
664 that is not present in the working directory, we need to mark it
671 that is not present in the working directory, we need to mark it
665 as removed.
672 as removed.
666 """
673 """
667
674
668 actions = {}
675 actions = {}
669 m = 'f'
676 m = 'f'
670 if branchmerge:
677 if branchmerge:
671 m = 'r'
678 m = 'r'
672 for f in wctx.deleted():
679 for f in wctx.deleted():
673 if f not in mctx:
680 if f not in mctx:
674 actions[f] = m, None, "forget deleted"
681 actions[f] = m, None, "forget deleted"
675
682
676 if not branchmerge:
683 if not branchmerge:
677 for f in wctx.removed():
684 for f in wctx.removed():
678 if f not in mctx:
685 if f not in mctx:
679 actions[f] = 'f', None, "forget removed"
686 actions[f] = 'f', None, "forget removed"
680
687
681 return actions
688 return actions
682
689
683 def _checkcollision(repo, wmf, actions):
690 def _checkcollision(repo, wmf, actions):
684 # build provisional merged manifest up
691 # build provisional merged manifest up
685 pmmf = set(wmf)
692 pmmf = set(wmf)
686
693
687 if actions:
694 if actions:
688 # k, dr, e and rd are no-op
695 # k, dr, e and rd are no-op
689 for m in 'a', 'am', 'f', 'g', 'cd', 'dc':
696 for m in 'a', 'am', 'f', 'g', 'cd', 'dc':
690 for f, args, msg in actions[m]:
697 for f, args, msg in actions[m]:
691 pmmf.add(f)
698 pmmf.add(f)
692 for f, args, msg in actions['r']:
699 for f, args, msg in actions['r']:
693 pmmf.discard(f)
700 pmmf.discard(f)
694 for f, args, msg in actions['dm']:
701 for f, args, msg in actions['dm']:
695 f2, flags = args
702 f2, flags = args
696 pmmf.discard(f2)
703 pmmf.discard(f2)
697 pmmf.add(f)
704 pmmf.add(f)
698 for f, args, msg in actions['dg']:
705 for f, args, msg in actions['dg']:
699 pmmf.add(f)
706 pmmf.add(f)
700 for f, args, msg in actions['m']:
707 for f, args, msg in actions['m']:
701 f1, f2, fa, move, anc = args
708 f1, f2, fa, move, anc = args
702 if move:
709 if move:
703 pmmf.discard(f1)
710 pmmf.discard(f1)
704 pmmf.add(f)
711 pmmf.add(f)
705
712
706 # check case-folding collision in provisional merged manifest
713 # check case-folding collision in provisional merged manifest
707 foldmap = {}
714 foldmap = {}
708 for f in sorted(pmmf):
715 for f in sorted(pmmf):
709 fold = util.normcase(f)
716 fold = util.normcase(f)
710 if fold in foldmap:
717 if fold in foldmap:
711 raise error.Abort(_("case-folding collision between %s and %s")
718 raise error.Abort(_("case-folding collision between %s and %s")
712 % (f, foldmap[fold]))
719 % (f, foldmap[fold]))
713 foldmap[fold] = f
720 foldmap[fold] = f
714
721
715 # check case-folding of directories
722 # check case-folding of directories
716 foldprefix = unfoldprefix = lastfull = ''
723 foldprefix = unfoldprefix = lastfull = ''
717 for fold, f in sorted(foldmap.items()):
724 for fold, f in sorted(foldmap.items()):
718 if fold.startswith(foldprefix) and not f.startswith(unfoldprefix):
725 if fold.startswith(foldprefix) and not f.startswith(unfoldprefix):
719 # the folded prefix matches but actual casing is different
726 # the folded prefix matches but actual casing is different
720 raise error.Abort(_("case-folding collision between "
727 raise error.Abort(_("case-folding collision between "
721 "%s and directory of %s") % (lastfull, f))
728 "%s and directory of %s") % (lastfull, f))
722 foldprefix = fold + '/'
729 foldprefix = fold + '/'
723 unfoldprefix = f + '/'
730 unfoldprefix = f + '/'
724 lastfull = f
731 lastfull = f
725
732
726 def driverpreprocess(repo, ms, wctx, labels=None):
733 def driverpreprocess(repo, ms, wctx, labels=None):
727 """run the preprocess step of the merge driver, if any
734 """run the preprocess step of the merge driver, if any
728
735
729 This is currently not implemented -- it's an extension point."""
736 This is currently not implemented -- it's an extension point."""
730 return True
737 return True
731
738
732 def driverconclude(repo, ms, wctx, labels=None):
739 def driverconclude(repo, ms, wctx, labels=None):
733 """run the conclude step of the merge driver, if any
740 """run the conclude step of the merge driver, if any
734
741
735 This is currently not implemented -- it's an extension point."""
742 This is currently not implemented -- it's an extension point."""
736 return True
743 return True
737
744
738 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, matcher,
745 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, matcher,
739 acceptremote, followcopies):
746 acceptremote, followcopies):
740 """
747 """
741 Merge p1 and p2 with ancestor pa and generate merge action list
748 Merge p1 and p2 with ancestor pa and generate merge action list
742
749
743 branchmerge and force are as passed in to update
750 branchmerge and force are as passed in to update
744 matcher = matcher to filter file lists
751 matcher = matcher to filter file lists
745 acceptremote = accept the incoming changes without prompting
752 acceptremote = accept the incoming changes without prompting
746 """
753 """
747 if matcher is not None and matcher.always():
754 if matcher is not None and matcher.always():
748 matcher = None
755 matcher = None
749
756
750 copy, movewithdir, diverge, renamedelete = {}, {}, {}, {}
757 copy, movewithdir, diverge, renamedelete = {}, {}, {}, {}
751
758
752 # manifests fetched in order are going to be faster, so prime the caches
759 # manifests fetched in order are going to be faster, so prime the caches
753 [x.manifest() for x in
760 [x.manifest() for x in
754 sorted(wctx.parents() + [p2, pa], key=lambda x: x.rev())]
761 sorted(wctx.parents() + [p2, pa], key=lambda x: x.rev())]
755
762
756 if followcopies:
763 if followcopies:
757 ret = copies.mergecopies(repo, wctx, p2, pa)
764 ret = copies.mergecopies(repo, wctx, p2, pa)
758 copy, movewithdir, diverge, renamedelete = ret
765 copy, movewithdir, diverge, renamedelete = ret
759
766
760 repo.ui.note(_("resolving manifests\n"))
767 repo.ui.note(_("resolving manifests\n"))
761 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
768 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
762 % (bool(branchmerge), bool(force), bool(matcher)))
769 % (bool(branchmerge), bool(force), bool(matcher)))
763 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
770 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
764
771
765 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
772 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
766 copied = set(copy.values())
773 copied = set(copy.values())
767 copied.update(movewithdir.values())
774 copied.update(movewithdir.values())
768
775
769 if '.hgsubstate' in m1:
776 if '.hgsubstate' in m1:
770 # check whether sub state is modified
777 # check whether sub state is modified
771 for s in sorted(wctx.substate):
778 for s in sorted(wctx.substate):
772 if wctx.sub(s).dirty():
779 if wctx.sub(s).dirty():
773 m1['.hgsubstate'] += '+'
780 m1['.hgsubstate'] += '+'
774 break
781 break
775
782
776 # Compare manifests
783 # Compare manifests
777 if matcher is not None:
784 if matcher is not None:
778 m1 = m1.matches(matcher)
785 m1 = m1.matches(matcher)
779 m2 = m2.matches(matcher)
786 m2 = m2.matches(matcher)
780 diff = m1.diff(m2)
787 diff = m1.diff(m2)
781
788
782 actions = {}
789 actions = {}
783 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems():
790 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems():
784 if n1 and n2: # file exists on both local and remote side
791 if n1 and n2: # file exists on both local and remote side
785 if f not in ma:
792 if f not in ma:
786 fa = copy.get(f, None)
793 fa = copy.get(f, None)
787 if fa is not None:
794 if fa is not None:
788 actions[f] = ('m', (f, f, fa, False, pa.node()),
795 actions[f] = ('m', (f, f, fa, False, pa.node()),
789 "both renamed from " + fa)
796 "both renamed from " + fa)
790 else:
797 else:
791 actions[f] = ('m', (f, f, None, False, pa.node()),
798 actions[f] = ('m', (f, f, None, False, pa.node()),
792 "both created")
799 "both created")
793 else:
800 else:
794 a = ma[f]
801 a = ma[f]
795 fla = ma.flags(f)
802 fla = ma.flags(f)
796 nol = 'l' not in fl1 + fl2 + fla
803 nol = 'l' not in fl1 + fl2 + fla
797 if n2 == a and fl2 == fla:
804 if n2 == a and fl2 == fla:
798 actions[f] = ('k' , (), "remote unchanged")
805 actions[f] = ('k' , (), "remote unchanged")
799 elif n1 == a and fl1 == fla: # local unchanged - use remote
806 elif n1 == a and fl1 == fla: # local unchanged - use remote
800 if n1 == n2: # optimization: keep local content
807 if n1 == n2: # optimization: keep local content
801 actions[f] = ('e', (fl2,), "update permissions")
808 actions[f] = ('e', (fl2,), "update permissions")
802 else:
809 else:
803 actions[f] = ('g', (fl2, False), "remote is newer")
810 actions[f] = ('g', (fl2, False), "remote is newer")
804 elif nol and n2 == a: # remote only changed 'x'
811 elif nol and n2 == a: # remote only changed 'x'
805 actions[f] = ('e', (fl2,), "update permissions")
812 actions[f] = ('e', (fl2,), "update permissions")
806 elif nol and n1 == a: # local only changed 'x'
813 elif nol and n1 == a: # local only changed 'x'
807 actions[f] = ('g', (fl1, False), "remote is newer")
814 actions[f] = ('g', (fl1, False), "remote is newer")
808 else: # both changed something
815 else: # both changed something
809 actions[f] = ('m', (f, f, f, False, pa.node()),
816 actions[f] = ('m', (f, f, f, False, pa.node()),
810 "versions differ")
817 "versions differ")
811 elif n1: # file exists only on local side
818 elif n1: # file exists only on local side
812 if f in copied:
819 if f in copied:
813 pass # we'll deal with it on m2 side
820 pass # we'll deal with it on m2 side
814 elif f in movewithdir: # directory rename, move local
821 elif f in movewithdir: # directory rename, move local
815 f2 = movewithdir[f]
822 f2 = movewithdir[f]
816 if f2 in m2:
823 if f2 in m2:
817 actions[f2] = ('m', (f, f2, None, True, pa.node()),
824 actions[f2] = ('m', (f, f2, None, True, pa.node()),
818 "remote directory rename, both created")
825 "remote directory rename, both created")
819 else:
826 else:
820 actions[f2] = ('dm', (f, fl1),
827 actions[f2] = ('dm', (f, fl1),
821 "remote directory rename - move from " + f)
828 "remote directory rename - move from " + f)
822 elif f in copy:
829 elif f in copy:
823 f2 = copy[f]
830 f2 = copy[f]
824 actions[f] = ('m', (f, f2, f2, False, pa.node()),
831 actions[f] = ('m', (f, f2, f2, False, pa.node()),
825 "local copied/moved from " + f2)
832 "local copied/moved from " + f2)
826 elif f in ma: # clean, a different, no remote
833 elif f in ma: # clean, a different, no remote
827 if n1 != ma[f]:
834 if n1 != ma[f]:
828 if acceptremote:
835 if acceptremote:
829 actions[f] = ('r', None, "remote delete")
836 actions[f] = ('r', None, "remote delete")
830 else:
837 else:
831 actions[f] = ('cd', (f, None, f, False, pa.node()),
838 actions[f] = ('cd', (f, None, f, False, pa.node()),
832 "prompt changed/deleted")
839 "prompt changed/deleted")
833 elif n1[20:] == 'a':
840 elif n1[20:] == 'a':
834 # This extra 'a' is added by working copy manifest to mark
841 # This extra 'a' is added by working copy manifest to mark
835 # the file as locally added. We should forget it instead of
842 # the file as locally added. We should forget it instead of
836 # deleting it.
843 # deleting it.
837 actions[f] = ('f', None, "remote deleted")
844 actions[f] = ('f', None, "remote deleted")
838 else:
845 else:
839 actions[f] = ('r', None, "other deleted")
846 actions[f] = ('r', None, "other deleted")
840 elif n2: # file exists only on remote side
847 elif n2: # file exists only on remote side
841 if f in copied:
848 if f in copied:
842 pass # we'll deal with it on m1 side
849 pass # we'll deal with it on m1 side
843 elif f in movewithdir:
850 elif f in movewithdir:
844 f2 = movewithdir[f]
851 f2 = movewithdir[f]
845 if f2 in m1:
852 if f2 in m1:
846 actions[f2] = ('m', (f2, f, None, False, pa.node()),
853 actions[f2] = ('m', (f2, f, None, False, pa.node()),
847 "local directory rename, both created")
854 "local directory rename, both created")
848 else:
855 else:
849 actions[f2] = ('dg', (f, fl2),
856 actions[f2] = ('dg', (f, fl2),
850 "local directory rename - get from " + f)
857 "local directory rename - get from " + f)
851 elif f in copy:
858 elif f in copy:
852 f2 = copy[f]
859 f2 = copy[f]
853 if f2 in m2:
860 if f2 in m2:
854 actions[f] = ('m', (f2, f, f2, False, pa.node()),
861 actions[f] = ('m', (f2, f, f2, False, pa.node()),
855 "remote copied from " + f2)
862 "remote copied from " + f2)
856 else:
863 else:
857 actions[f] = ('m', (f2, f, f2, True, pa.node()),
864 actions[f] = ('m', (f2, f, f2, True, pa.node()),
858 "remote moved from " + f2)
865 "remote moved from " + f2)
859 elif f not in ma:
866 elif f not in ma:
860 # local unknown, remote created: the logic is described by the
867 # local unknown, remote created: the logic is described by the
861 # following table:
868 # following table:
862 #
869 #
863 # force branchmerge different | action
870 # force branchmerge different | action
864 # n * * | create
871 # n * * | create
865 # y n * | create
872 # y n * | create
866 # y y n | create
873 # y y n | create
867 # y y y | merge
874 # y y y | merge
868 #
875 #
869 # Checking whether the files are different is expensive, so we
876 # Checking whether the files are different is expensive, so we
870 # don't do that when we can avoid it.
877 # don't do that when we can avoid it.
871 if not force:
878 if not force:
872 actions[f] = ('c', (fl2,), "remote created")
879 actions[f] = ('c', (fl2,), "remote created")
873 elif not branchmerge:
880 elif not branchmerge:
874 actions[f] = ('c', (fl2,), "remote created")
881 actions[f] = ('c', (fl2,), "remote created")
875 else:
882 else:
876 actions[f] = ('cm', (fl2, pa.node()),
883 actions[f] = ('cm', (fl2, pa.node()),
877 "remote created, get or merge")
884 "remote created, get or merge")
878 elif n2 != ma[f]:
885 elif n2 != ma[f]:
879 if acceptremote:
886 if acceptremote:
880 actions[f] = ('c', (fl2,), "remote recreating")
887 actions[f] = ('c', (fl2,), "remote recreating")
881 else:
888 else:
882 actions[f] = ('dc', (None, f, f, False, pa.node()),
889 actions[f] = ('dc', (None, f, f, False, pa.node()),
883 "prompt deleted/changed")
890 "prompt deleted/changed")
884
891
885 return actions, diverge, renamedelete
892 return actions, diverge, renamedelete
886
893
887 def _resolvetrivial(repo, wctx, mctx, ancestor, actions):
894 def _resolvetrivial(repo, wctx, mctx, ancestor, actions):
888 """Resolves false conflicts where the nodeid changed but the content
895 """Resolves false conflicts where the nodeid changed but the content
889 remained the same."""
896 remained the same."""
890
897
891 for f, (m, args, msg) in actions.items():
898 for f, (m, args, msg) in actions.items():
892 if m == 'cd' and f in ancestor and not wctx[f].cmp(ancestor[f]):
899 if m == 'cd' and f in ancestor and not wctx[f].cmp(ancestor[f]):
893 # local did change but ended up with same content
900 # local did change but ended up with same content
894 actions[f] = 'r', None, "prompt same"
901 actions[f] = 'r', None, "prompt same"
895 elif m == 'dc' and f in ancestor and not mctx[f].cmp(ancestor[f]):
902 elif m == 'dc' and f in ancestor and not mctx[f].cmp(ancestor[f]):
896 # remote did change but ended up with same content
903 # remote did change but ended up with same content
897 del actions[f] # don't get = keep local deleted
904 del actions[f] # don't get = keep local deleted
898
905
899 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force,
906 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force,
900 acceptremote, followcopies, matcher=None):
907 acceptremote, followcopies, matcher=None):
901 "Calculate the actions needed to merge mctx into wctx using ancestors"
908 "Calculate the actions needed to merge mctx into wctx using ancestors"
902 if len(ancestors) == 1: # default
909 if len(ancestors) == 1: # default
903 actions, diverge, renamedelete = manifestmerge(
910 actions, diverge, renamedelete = manifestmerge(
904 repo, wctx, mctx, ancestors[0], branchmerge, force, matcher,
911 repo, wctx, mctx, ancestors[0], branchmerge, force, matcher,
905 acceptremote, followcopies)
912 acceptremote, followcopies)
906 _checkunknownfiles(repo, wctx, mctx, force, actions)
913 _checkunknownfiles(repo, wctx, mctx, force, actions)
907
914
908 else: # only when merge.preferancestor=* - the default
915 else: # only when merge.preferancestor=* - the default
909 repo.ui.note(
916 repo.ui.note(
910 _("note: merging %s and %s using bids from ancestors %s\n") %
917 _("note: merging %s and %s using bids from ancestors %s\n") %
911 (wctx, mctx, _(' and ').join(str(anc) for anc in ancestors)))
918 (wctx, mctx, _(' and ').join(str(anc) for anc in ancestors)))
912
919
913 # Call for bids
920 # Call for bids
914 fbids = {} # mapping filename to bids (action method to list af actions)
921 fbids = {} # mapping filename to bids (action method to list af actions)
915 diverge, renamedelete = None, None
922 diverge, renamedelete = None, None
916 for ancestor in ancestors:
923 for ancestor in ancestors:
917 repo.ui.note(_('\ncalculating bids for ancestor %s\n') % ancestor)
924 repo.ui.note(_('\ncalculating bids for ancestor %s\n') % ancestor)
918 actions, diverge1, renamedelete1 = manifestmerge(
925 actions, diverge1, renamedelete1 = manifestmerge(
919 repo, wctx, mctx, ancestor, branchmerge, force, matcher,
926 repo, wctx, mctx, ancestor, branchmerge, force, matcher,
920 acceptremote, followcopies)
927 acceptremote, followcopies)
921 _checkunknownfiles(repo, wctx, mctx, force, actions)
928 _checkunknownfiles(repo, wctx, mctx, force, actions)
922
929
923 # Track the shortest set of warning on the theory that bid
930 # Track the shortest set of warning on the theory that bid
924 # merge will correctly incorporate more information
931 # merge will correctly incorporate more information
925 if diverge is None or len(diverge1) < len(diverge):
932 if diverge is None or len(diverge1) < len(diverge):
926 diverge = diverge1
933 diverge = diverge1
927 if renamedelete is None or len(renamedelete) < len(renamedelete1):
934 if renamedelete is None or len(renamedelete) < len(renamedelete1):
928 renamedelete = renamedelete1
935 renamedelete = renamedelete1
929
936
930 for f, a in sorted(actions.iteritems()):
937 for f, a in sorted(actions.iteritems()):
931 m, args, msg = a
938 m, args, msg = a
932 repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m))
939 repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m))
933 if f in fbids:
940 if f in fbids:
934 d = fbids[f]
941 d = fbids[f]
935 if m in d:
942 if m in d:
936 d[m].append(a)
943 d[m].append(a)
937 else:
944 else:
938 d[m] = [a]
945 d[m] = [a]
939 else:
946 else:
940 fbids[f] = {m: [a]}
947 fbids[f] = {m: [a]}
941
948
942 # Pick the best bid for each file
949 # Pick the best bid for each file
943 repo.ui.note(_('\nauction for merging merge bids\n'))
950 repo.ui.note(_('\nauction for merging merge bids\n'))
944 actions = {}
951 actions = {}
945 for f, bids in sorted(fbids.items()):
952 for f, bids in sorted(fbids.items()):
946 # bids is a mapping from action method to list af actions
953 # bids is a mapping from action method to list af actions
947 # Consensus?
954 # Consensus?
948 if len(bids) == 1: # all bids are the same kind of method
955 if len(bids) == 1: # all bids are the same kind of method
949 m, l = bids.items()[0]
956 m, l = bids.items()[0]
950 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
957 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
951 repo.ui.note(" %s: consensus for %s\n" % (f, m))
958 repo.ui.note(" %s: consensus for %s\n" % (f, m))
952 actions[f] = l[0]
959 actions[f] = l[0]
953 continue
960 continue
954 # If keep is an option, just do it.
961 # If keep is an option, just do it.
955 if 'k' in bids:
962 if 'k' in bids:
956 repo.ui.note(" %s: picking 'keep' action\n" % f)
963 repo.ui.note(" %s: picking 'keep' action\n" % f)
957 actions[f] = bids['k'][0]
964 actions[f] = bids['k'][0]
958 continue
965 continue
959 # If there are gets and they all agree [how could they not?], do it.
966 # If there are gets and they all agree [how could they not?], do it.
960 if 'g' in bids:
967 if 'g' in bids:
961 ga0 = bids['g'][0]
968 ga0 = bids['g'][0]
962 if all(a == ga0 for a in bids['g'][1:]):
969 if all(a == ga0 for a in bids['g'][1:]):
963 repo.ui.note(" %s: picking 'get' action\n" % f)
970 repo.ui.note(" %s: picking 'get' action\n" % f)
964 actions[f] = ga0
971 actions[f] = ga0
965 continue
972 continue
966 # TODO: Consider other simple actions such as mode changes
973 # TODO: Consider other simple actions such as mode changes
967 # Handle inefficient democrazy.
974 # Handle inefficient democrazy.
968 repo.ui.note(_(' %s: multiple bids for merge action:\n') % f)
975 repo.ui.note(_(' %s: multiple bids for merge action:\n') % f)
969 for m, l in sorted(bids.items()):
976 for m, l in sorted(bids.items()):
970 for _f, args, msg in l:
977 for _f, args, msg in l:
971 repo.ui.note(' %s -> %s\n' % (msg, m))
978 repo.ui.note(' %s -> %s\n' % (msg, m))
972 # Pick random action. TODO: Instead, prompt user when resolving
979 # Pick random action. TODO: Instead, prompt user when resolving
973 m, l = bids.items()[0]
980 m, l = bids.items()[0]
974 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
981 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
975 (f, m))
982 (f, m))
976 actions[f] = l[0]
983 actions[f] = l[0]
977 continue
984 continue
978 repo.ui.note(_('end of auction\n\n'))
985 repo.ui.note(_('end of auction\n\n'))
979
986
980 _resolvetrivial(repo, wctx, mctx, ancestors[0], actions)
987 _resolvetrivial(repo, wctx, mctx, ancestors[0], actions)
981
988
982 if wctx.rev() is None:
989 if wctx.rev() is None:
983 fractions = _forgetremoved(wctx, mctx, branchmerge)
990 fractions = _forgetremoved(wctx, mctx, branchmerge)
984 actions.update(fractions)
991 actions.update(fractions)
985
992
986 return actions, diverge, renamedelete
993 return actions, diverge, renamedelete
987
994
988 def batchremove(repo, actions):
995 def batchremove(repo, actions):
989 """apply removes to the working directory
996 """apply removes to the working directory
990
997
991 yields tuples for progress updates
998 yields tuples for progress updates
992 """
999 """
993 verbose = repo.ui.verbose
1000 verbose = repo.ui.verbose
994 unlink = util.unlinkpath
1001 unlink = util.unlinkpath
995 wjoin = repo.wjoin
1002 wjoin = repo.wjoin
996 audit = repo.wvfs.audit
1003 audit = repo.wvfs.audit
997 i = 0
1004 i = 0
998 for f, args, msg in actions:
1005 for f, args, msg in actions:
999 repo.ui.debug(" %s: %s -> r\n" % (f, msg))
1006 repo.ui.debug(" %s: %s -> r\n" % (f, msg))
1000 if verbose:
1007 if verbose:
1001 repo.ui.note(_("removing %s\n") % f)
1008 repo.ui.note(_("removing %s\n") % f)
1002 audit(f)
1009 audit(f)
1003 try:
1010 try:
1004 unlink(wjoin(f), ignoremissing=True)
1011 unlink(wjoin(f), ignoremissing=True)
1005 except OSError as inst:
1012 except OSError as inst:
1006 repo.ui.warn(_("update failed to remove %s: %s!\n") %
1013 repo.ui.warn(_("update failed to remove %s: %s!\n") %
1007 (f, inst.strerror))
1014 (f, inst.strerror))
1008 if i == 100:
1015 if i == 100:
1009 yield i, f
1016 yield i, f
1010 i = 0
1017 i = 0
1011 i += 1
1018 i += 1
1012 if i > 0:
1019 if i > 0:
1013 yield i, f
1020 yield i, f
1014
1021
1015 def batchget(repo, mctx, actions):
1022 def batchget(repo, mctx, actions):
1016 """apply gets to the working directory
1023 """apply gets to the working directory
1017
1024
1018 mctx is the context to get from
1025 mctx is the context to get from
1019
1026
1020 yields tuples for progress updates
1027 yields tuples for progress updates
1021 """
1028 """
1022 verbose = repo.ui.verbose
1029 verbose = repo.ui.verbose
1023 fctx = mctx.filectx
1030 fctx = mctx.filectx
1024 wwrite = repo.wwrite
1031 wwrite = repo.wwrite
1025 ui = repo.ui
1032 ui = repo.ui
1026 i = 0
1033 i = 0
1027 for f, (flags, backup), msg in actions:
1034 for f, (flags, backup), msg in actions:
1028 repo.ui.debug(" %s: %s -> g\n" % (f, msg))
1035 repo.ui.debug(" %s: %s -> g\n" % (f, msg))
1029 if verbose:
1036 if verbose:
1030 repo.ui.note(_("getting %s\n") % f)
1037 repo.ui.note(_("getting %s\n") % f)
1031
1038
1032 if backup:
1039 if backup:
1033 absf = repo.wjoin(f)
1040 absf = repo.wjoin(f)
1034 orig = scmutil.origpath(ui, repo, absf)
1041 orig = scmutil.origpath(ui, repo, absf)
1035 try:
1042 try:
1036 # TODO Mercurial has always aborted if an untracked directory
1043 # TODO Mercurial has always aborted if an untracked directory
1037 # is replaced by a tracked file, or generally with
1044 # is replaced by a tracked file, or generally with
1038 # file/directory merges. This needs to be sorted out.
1045 # file/directory merges. This needs to be sorted out.
1039 if repo.wvfs.isfileorlink(f):
1046 if repo.wvfs.isfileorlink(f):
1040 util.rename(absf, orig)
1047 util.rename(absf, orig)
1041 except OSError as e:
1048 except OSError as e:
1042 if e.errno != errno.ENOENT:
1049 if e.errno != errno.ENOENT:
1043 raise
1050 raise
1044
1051
1045 wwrite(f, fctx(f).data(), flags)
1052 wwrite(f, fctx(f).data(), flags)
1046 if i == 100:
1053 if i == 100:
1047 yield i, f
1054 yield i, f
1048 i = 0
1055 i = 0
1049 i += 1
1056 i += 1
1050 if i > 0:
1057 if i > 0:
1051 yield i, f
1058 yield i, f
1052
1059
1053 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None):
1060 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None):
1054 """apply the merge action list to the working directory
1061 """apply the merge action list to the working directory
1055
1062
1056 wctx is the working copy context
1063 wctx is the working copy context
1057 mctx is the context to be merged into the working copy
1064 mctx is the context to be merged into the working copy
1058
1065
1059 Return a tuple of counts (updated, merged, removed, unresolved) that
1066 Return a tuple of counts (updated, merged, removed, unresolved) that
1060 describes how many files were affected by the update.
1067 describes how many files were affected by the update.
1061 """
1068 """
1062
1069
1063 updated, merged, removed = 0, 0, 0
1070 updated, merged, removed = 0, 0, 0
1064 ms = mergestate.clean(repo, wctx.p1().node(), mctx.node())
1071 ms = mergestate.clean(repo, wctx.p1().node(), mctx.node())
1065 moves = []
1072 moves = []
1066 for m, l in actions.items():
1073 for m, l in actions.items():
1067 l.sort()
1074 l.sort()
1068
1075
1069 # 'cd' and 'dc' actions are treated like other merge conflicts
1076 # 'cd' and 'dc' actions are treated like other merge conflicts
1070 mergeactions = sorted(actions['cd'])
1077 mergeactions = sorted(actions['cd'])
1071 mergeactions.extend(sorted(actions['dc']))
1078 mergeactions.extend(sorted(actions['dc']))
1072 mergeactions.extend(actions['m'])
1079 mergeactions.extend(actions['m'])
1073 for f, args, msg in mergeactions:
1080 for f, args, msg in mergeactions:
1074 f1, f2, fa, move, anc = args
1081 f1, f2, fa, move, anc = args
1075 if f == '.hgsubstate': # merged internally
1082 if f == '.hgsubstate': # merged internally
1076 continue
1083 continue
1077 if f1 is None:
1084 if f1 is None:
1078 fcl = filemerge.absentfilectx(wctx, fa)
1085 fcl = filemerge.absentfilectx(wctx, fa)
1079 else:
1086 else:
1080 repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f))
1087 repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f))
1081 fcl = wctx[f1]
1088 fcl = wctx[f1]
1082 if f2 is None:
1089 if f2 is None:
1083 fco = filemerge.absentfilectx(mctx, fa)
1090 fco = filemerge.absentfilectx(mctx, fa)
1084 else:
1091 else:
1085 fco = mctx[f2]
1092 fco = mctx[f2]
1086 actx = repo[anc]
1093 actx = repo[anc]
1087 if fa in actx:
1094 if fa in actx:
1088 fca = actx[fa]
1095 fca = actx[fa]
1089 else:
1096 else:
1090 # TODO: move to absentfilectx
1097 # TODO: move to absentfilectx
1091 fca = repo.filectx(f1, fileid=nullrev)
1098 fca = repo.filectx(f1, fileid=nullrev)
1092 ms.add(fcl, fco, fca, f)
1099 ms.add(fcl, fco, fca, f)
1093 if f1 != f and move:
1100 if f1 != f and move:
1094 moves.append(f1)
1101 moves.append(f1)
1095
1102
1096 audit = repo.wvfs.audit
1103 audit = repo.wvfs.audit
1097 _updating = _('updating')
1104 _updating = _('updating')
1098 _files = _('files')
1105 _files = _('files')
1099 progress = repo.ui.progress
1106 progress = repo.ui.progress
1100
1107
1101 # remove renamed files after safely stored
1108 # remove renamed files after safely stored
1102 for f in moves:
1109 for f in moves:
1103 if os.path.lexists(repo.wjoin(f)):
1110 if os.path.lexists(repo.wjoin(f)):
1104 repo.ui.debug("removing %s\n" % f)
1111 repo.ui.debug("removing %s\n" % f)
1105 audit(f)
1112 audit(f)
1106 util.unlinkpath(repo.wjoin(f))
1113 util.unlinkpath(repo.wjoin(f))
1107
1114
1108 numupdates = sum(len(l) for m, l in actions.items() if m != 'k')
1115 numupdates = sum(len(l) for m, l in actions.items() if m != 'k')
1109
1116
1110 if [a for a in actions['r'] if a[0] == '.hgsubstate']:
1117 if [a for a in actions['r'] if a[0] == '.hgsubstate']:
1111 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
1118 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
1112
1119
1113 # remove in parallel (must come first)
1120 # remove in parallel (must come first)
1114 z = 0
1121 z = 0
1115 prog = worker.worker(repo.ui, 0.001, batchremove, (repo,), actions['r'])
1122 prog = worker.worker(repo.ui, 0.001, batchremove, (repo,), actions['r'])
1116 for i, item in prog:
1123 for i, item in prog:
1117 z += i
1124 z += i
1118 progress(_updating, z, item=item, total=numupdates, unit=_files)
1125 progress(_updating, z, item=item, total=numupdates, unit=_files)
1119 removed = len(actions['r'])
1126 removed = len(actions['r'])
1120
1127
1121 # get in parallel
1128 # get in parallel
1122 prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx), actions['g'])
1129 prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx), actions['g'])
1123 for i, item in prog:
1130 for i, item in prog:
1124 z += i
1131 z += i
1125 progress(_updating, z, item=item, total=numupdates, unit=_files)
1132 progress(_updating, z, item=item, total=numupdates, unit=_files)
1126 updated = len(actions['g'])
1133 updated = len(actions['g'])
1127
1134
1128 if [a for a in actions['g'] if a[0] == '.hgsubstate']:
1135 if [a for a in actions['g'] if a[0] == '.hgsubstate']:
1129 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
1136 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
1130
1137
1131 # forget (manifest only, just log it) (must come first)
1138 # forget (manifest only, just log it) (must come first)
1132 for f, args, msg in actions['f']:
1139 for f, args, msg in actions['f']:
1133 repo.ui.debug(" %s: %s -> f\n" % (f, msg))
1140 repo.ui.debug(" %s: %s -> f\n" % (f, msg))
1134 z += 1
1141 z += 1
1135 progress(_updating, z, item=f, total=numupdates, unit=_files)
1142 progress(_updating, z, item=f, total=numupdates, unit=_files)
1136
1143
1137 # re-add (manifest only, just log it)
1144 # re-add (manifest only, just log it)
1138 for f, args, msg in actions['a']:
1145 for f, args, msg in actions['a']:
1139 repo.ui.debug(" %s: %s -> a\n" % (f, msg))
1146 repo.ui.debug(" %s: %s -> a\n" % (f, msg))
1140 z += 1
1147 z += 1
1141 progress(_updating, z, item=f, total=numupdates, unit=_files)
1148 progress(_updating, z, item=f, total=numupdates, unit=_files)
1142
1149
1143 # re-add/mark as modified (manifest only, just log it)
1150 # re-add/mark as modified (manifest only, just log it)
1144 for f, args, msg in actions['am']:
1151 for f, args, msg in actions['am']:
1145 repo.ui.debug(" %s: %s -> am\n" % (f, msg))
1152 repo.ui.debug(" %s: %s -> am\n" % (f, msg))
1146 z += 1
1153 z += 1
1147 progress(_updating, z, item=f, total=numupdates, unit=_files)
1154 progress(_updating, z, item=f, total=numupdates, unit=_files)
1148
1155
1149 # keep (noop, just log it)
1156 # keep (noop, just log it)
1150 for f, args, msg in actions['k']:
1157 for f, args, msg in actions['k']:
1151 repo.ui.debug(" %s: %s -> k\n" % (f, msg))
1158 repo.ui.debug(" %s: %s -> k\n" % (f, msg))
1152 # no progress
1159 # no progress
1153
1160
1154 # directory rename, move local
1161 # directory rename, move local
1155 for f, args, msg in actions['dm']:
1162 for f, args, msg in actions['dm']:
1156 repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
1163 repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
1157 z += 1
1164 z += 1
1158 progress(_updating, z, item=f, total=numupdates, unit=_files)
1165 progress(_updating, z, item=f, total=numupdates, unit=_files)
1159 f0, flags = args
1166 f0, flags = args
1160 repo.ui.note(_("moving %s to %s\n") % (f0, f))
1167 repo.ui.note(_("moving %s to %s\n") % (f0, f))
1161 audit(f)
1168 audit(f)
1162 repo.wwrite(f, wctx.filectx(f0).data(), flags)
1169 repo.wwrite(f, wctx.filectx(f0).data(), flags)
1163 util.unlinkpath(repo.wjoin(f0))
1170 util.unlinkpath(repo.wjoin(f0))
1164 updated += 1
1171 updated += 1
1165
1172
1166 # local directory rename, get
1173 # local directory rename, get
1167 for f, args, msg in actions['dg']:
1174 for f, args, msg in actions['dg']:
1168 repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
1175 repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
1169 z += 1
1176 z += 1
1170 progress(_updating, z, item=f, total=numupdates, unit=_files)
1177 progress(_updating, z, item=f, total=numupdates, unit=_files)
1171 f0, flags = args
1178 f0, flags = args
1172 repo.ui.note(_("getting %s to %s\n") % (f0, f))
1179 repo.ui.note(_("getting %s to %s\n") % (f0, f))
1173 repo.wwrite(f, mctx.filectx(f0).data(), flags)
1180 repo.wwrite(f, mctx.filectx(f0).data(), flags)
1174 updated += 1
1181 updated += 1
1175
1182
1176 # exec
1183 # exec
1177 for f, args, msg in actions['e']:
1184 for f, args, msg in actions['e']:
1178 repo.ui.debug(" %s: %s -> e\n" % (f, msg))
1185 repo.ui.debug(" %s: %s -> e\n" % (f, msg))
1179 z += 1
1186 z += 1
1180 progress(_updating, z, item=f, total=numupdates, unit=_files)
1187 progress(_updating, z, item=f, total=numupdates, unit=_files)
1181 flags, = args
1188 flags, = args
1182 audit(f)
1189 audit(f)
1183 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
1190 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
1184 updated += 1
1191 updated += 1
1185
1192
1186 # the ordering is important here -- ms.mergedriver will raise if the merge
1193 # the ordering is important here -- ms.mergedriver will raise if the merge
1187 # driver has changed, and we want to be able to bypass it when overwrite is
1194 # driver has changed, and we want to be able to bypass it when overwrite is
1188 # True
1195 # True
1189 usemergedriver = not overwrite and mergeactions and ms.mergedriver
1196 usemergedriver = not overwrite and mergeactions and ms.mergedriver
1190
1197
1191 if usemergedriver:
1198 if usemergedriver:
1192 ms.commit()
1199 ms.commit()
1193 proceed = driverpreprocess(repo, ms, wctx, labels=labels)
1200 proceed = driverpreprocess(repo, ms, wctx, labels=labels)
1194 # the driver might leave some files unresolved
1201 # the driver might leave some files unresolved
1195 unresolvedf = set(ms.unresolved())
1202 unresolvedf = set(ms.unresolved())
1196 if not proceed:
1203 if not proceed:
1197 # XXX setting unresolved to at least 1 is a hack to make sure we
1204 # XXX setting unresolved to at least 1 is a hack to make sure we
1198 # error out
1205 # error out
1199 return updated, merged, removed, max(len(unresolvedf), 1)
1206 return updated, merged, removed, max(len(unresolvedf), 1)
1200 newactions = []
1207 newactions = []
1201 for f, args, msg in mergeactions:
1208 for f, args, msg in mergeactions:
1202 if f in unresolvedf:
1209 if f in unresolvedf:
1203 newactions.append((f, args, msg))
1210 newactions.append((f, args, msg))
1204 mergeactions = newactions
1211 mergeactions = newactions
1205
1212
1206 # premerge
1213 # premerge
1207 tocomplete = []
1214 tocomplete = []
1208 for f, args, msg in mergeactions:
1215 for f, args, msg in mergeactions:
1209 repo.ui.debug(" %s: %s -> m (premerge)\n" % (f, msg))
1216 repo.ui.debug(" %s: %s -> m (premerge)\n" % (f, msg))
1210 z += 1
1217 z += 1
1211 progress(_updating, z, item=f, total=numupdates, unit=_files)
1218 progress(_updating, z, item=f, total=numupdates, unit=_files)
1212 if f == '.hgsubstate': # subrepo states need updating
1219 if f == '.hgsubstate': # subrepo states need updating
1213 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
1220 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
1214 overwrite)
1221 overwrite)
1215 continue
1222 continue
1216 audit(f)
1223 audit(f)
1217 complete, r = ms.preresolve(f, wctx, labels=labels)
1224 complete, r = ms.preresolve(f, wctx, labels=labels)
1218 if not complete:
1225 if not complete:
1219 numupdates += 1
1226 numupdates += 1
1220 tocomplete.append((f, args, msg))
1227 tocomplete.append((f, args, msg))
1221
1228
1222 # merge
1229 # merge
1223 for f, args, msg in tocomplete:
1230 for f, args, msg in tocomplete:
1224 repo.ui.debug(" %s: %s -> m (merge)\n" % (f, msg))
1231 repo.ui.debug(" %s: %s -> m (merge)\n" % (f, msg))
1225 z += 1
1232 z += 1
1226 progress(_updating, z, item=f, total=numupdates, unit=_files)
1233 progress(_updating, z, item=f, total=numupdates, unit=_files)
1227 ms.resolve(f, wctx, labels=labels)
1234 ms.resolve(f, wctx, labels=labels)
1228
1235
1229 ms.commit()
1236 ms.commit()
1230
1237
1231 unresolved = ms.unresolvedcount()
1238 unresolved = ms.unresolvedcount()
1232
1239
1233 if usemergedriver and not unresolved and ms.mdstate() != 's':
1240 if usemergedriver and not unresolved and ms.mdstate() != 's':
1234 if not driverconclude(repo, ms, wctx, labels=labels):
1241 if not driverconclude(repo, ms, wctx, labels=labels):
1235 # XXX setting unresolved to at least 1 is a hack to make sure we
1242 # XXX setting unresolved to at least 1 is a hack to make sure we
1236 # error out
1243 # error out
1237 unresolved = max(unresolved, 1)
1244 unresolved = max(unresolved, 1)
1238
1245
1239 ms.commit()
1246 ms.commit()
1240
1247
1241 msupdated, msmerged, msremoved = ms.counts()
1248 msupdated, msmerged, msremoved = ms.counts()
1242 updated += msupdated
1249 updated += msupdated
1243 merged += msmerged
1250 merged += msmerged
1244 removed += msremoved
1251 removed += msremoved
1245
1252
1246 extraactions = ms.actions()
1253 extraactions = ms.actions()
1247 for k, acts in extraactions.iteritems():
1254 for k, acts in extraactions.iteritems():
1248 actions[k].extend(acts)
1255 actions[k].extend(acts)
1249
1256
1250 progress(_updating, None, total=numupdates, unit=_files)
1257 progress(_updating, None, total=numupdates, unit=_files)
1251
1258
1252 return updated, merged, removed, unresolved
1259 return updated, merged, removed, unresolved
1253
1260
1254 def recordupdates(repo, actions, branchmerge):
1261 def recordupdates(repo, actions, branchmerge):
1255 "record merge actions to the dirstate"
1262 "record merge actions to the dirstate"
1256 # remove (must come first)
1263 # remove (must come first)
1257 for f, args, msg in actions.get('r', []):
1264 for f, args, msg in actions.get('r', []):
1258 if branchmerge:
1265 if branchmerge:
1259 repo.dirstate.remove(f)
1266 repo.dirstate.remove(f)
1260 else:
1267 else:
1261 repo.dirstate.drop(f)
1268 repo.dirstate.drop(f)
1262
1269
1263 # forget (must come first)
1270 # forget (must come first)
1264 for f, args, msg in actions.get('f', []):
1271 for f, args, msg in actions.get('f', []):
1265 repo.dirstate.drop(f)
1272 repo.dirstate.drop(f)
1266
1273
1267 # re-add
1274 # re-add
1268 for f, args, msg in actions.get('a', []):
1275 for f, args, msg in actions.get('a', []):
1269 repo.dirstate.add(f)
1276 repo.dirstate.add(f)
1270
1277
1271 # re-add/mark as modified
1278 # re-add/mark as modified
1272 for f, args, msg in actions.get('am', []):
1279 for f, args, msg in actions.get('am', []):
1273 if branchmerge:
1280 if branchmerge:
1274 repo.dirstate.normallookup(f)
1281 repo.dirstate.normallookup(f)
1275 else:
1282 else:
1276 repo.dirstate.add(f)
1283 repo.dirstate.add(f)
1277
1284
1278 # exec change
1285 # exec change
1279 for f, args, msg in actions.get('e', []):
1286 for f, args, msg in actions.get('e', []):
1280 repo.dirstate.normallookup(f)
1287 repo.dirstate.normallookup(f)
1281
1288
1282 # keep
1289 # keep
1283 for f, args, msg in actions.get('k', []):
1290 for f, args, msg in actions.get('k', []):
1284 pass
1291 pass
1285
1292
1286 # get
1293 # get
1287 for f, args, msg in actions.get('g', []):
1294 for f, args, msg in actions.get('g', []):
1288 if branchmerge:
1295 if branchmerge:
1289 repo.dirstate.otherparent(f)
1296 repo.dirstate.otherparent(f)
1290 else:
1297 else:
1291 repo.dirstate.normal(f)
1298 repo.dirstate.normal(f)
1292
1299
1293 # merge
1300 # merge
1294 for f, args, msg in actions.get('m', []):
1301 for f, args, msg in actions.get('m', []):
1295 f1, f2, fa, move, anc = args
1302 f1, f2, fa, move, anc = args
1296 if branchmerge:
1303 if branchmerge:
1297 # We've done a branch merge, mark this file as merged
1304 # We've done a branch merge, mark this file as merged
1298 # so that we properly record the merger later
1305 # so that we properly record the merger later
1299 repo.dirstate.merge(f)
1306 repo.dirstate.merge(f)
1300 if f1 != f2: # copy/rename
1307 if f1 != f2: # copy/rename
1301 if move:
1308 if move:
1302 repo.dirstate.remove(f1)
1309 repo.dirstate.remove(f1)
1303 if f1 != f:
1310 if f1 != f:
1304 repo.dirstate.copy(f1, f)
1311 repo.dirstate.copy(f1, f)
1305 else:
1312 else:
1306 repo.dirstate.copy(f2, f)
1313 repo.dirstate.copy(f2, f)
1307 else:
1314 else:
1308 # We've update-merged a locally modified file, so
1315 # We've update-merged a locally modified file, so
1309 # we set the dirstate to emulate a normal checkout
1316 # we set the dirstate to emulate a normal checkout
1310 # of that file some time in the past. Thus our
1317 # of that file some time in the past. Thus our
1311 # merge will appear as a normal local file
1318 # merge will appear as a normal local file
1312 # modification.
1319 # modification.
1313 if f2 == f: # file not locally copied/moved
1320 if f2 == f: # file not locally copied/moved
1314 repo.dirstate.normallookup(f)
1321 repo.dirstate.normallookup(f)
1315 if move:
1322 if move:
1316 repo.dirstate.drop(f1)
1323 repo.dirstate.drop(f1)
1317
1324
1318 # directory rename, move local
1325 # directory rename, move local
1319 for f, args, msg in actions.get('dm', []):
1326 for f, args, msg in actions.get('dm', []):
1320 f0, flag = args
1327 f0, flag = args
1321 if branchmerge:
1328 if branchmerge:
1322 repo.dirstate.add(f)
1329 repo.dirstate.add(f)
1323 repo.dirstate.remove(f0)
1330 repo.dirstate.remove(f0)
1324 repo.dirstate.copy(f0, f)
1331 repo.dirstate.copy(f0, f)
1325 else:
1332 else:
1326 repo.dirstate.normal(f)
1333 repo.dirstate.normal(f)
1327 repo.dirstate.drop(f0)
1334 repo.dirstate.drop(f0)
1328
1335
1329 # directory rename, get
1336 # directory rename, get
1330 for f, args, msg in actions.get('dg', []):
1337 for f, args, msg in actions.get('dg', []):
1331 f0, flag = args
1338 f0, flag = args
1332 if branchmerge:
1339 if branchmerge:
1333 repo.dirstate.add(f)
1340 repo.dirstate.add(f)
1334 repo.dirstate.copy(f0, f)
1341 repo.dirstate.copy(f0, f)
1335 else:
1342 else:
1336 repo.dirstate.normal(f)
1343 repo.dirstate.normal(f)
1337
1344
1338 def update(repo, node, branchmerge, force, ancestor=None,
1345 def update(repo, node, branchmerge, force, ancestor=None,
1339 mergeancestor=False, labels=None, matcher=None):
1346 mergeancestor=False, labels=None, matcher=None):
1340 """
1347 """
1341 Perform a merge between the working directory and the given node
1348 Perform a merge between the working directory and the given node
1342
1349
1343 node = the node to update to, or None if unspecified
1350 node = the node to update to, or None if unspecified
1344 branchmerge = whether to merge between branches
1351 branchmerge = whether to merge between branches
1345 force = whether to force branch merging or file overwriting
1352 force = whether to force branch merging or file overwriting
1346 matcher = a matcher to filter file lists (dirstate not updated)
1353 matcher = a matcher to filter file lists (dirstate not updated)
1347 mergeancestor = whether it is merging with an ancestor. If true,
1354 mergeancestor = whether it is merging with an ancestor. If true,
1348 we should accept the incoming changes for any prompts that occur.
1355 we should accept the incoming changes for any prompts that occur.
1349 If false, merging with an ancestor (fast-forward) is only allowed
1356 If false, merging with an ancestor (fast-forward) is only allowed
1350 between different named branches. This flag is used by rebase extension
1357 between different named branches. This flag is used by rebase extension
1351 as a temporary fix and should be avoided in general.
1358 as a temporary fix and should be avoided in general.
1352
1359
1353 The table below shows all the behaviors of the update command
1360 The table below shows all the behaviors of the update command
1354 given the -c and -C or no options, whether the working directory
1361 given the -c and -C or no options, whether the working directory
1355 is dirty, whether a revision is specified, and the relationship of
1362 is dirty, whether a revision is specified, and the relationship of
1356 the parent rev to the target rev (linear, on the same named
1363 the parent rev to the target rev (linear, on the same named
1357 branch, or on another named branch).
1364 branch, or on another named branch).
1358
1365
1359 This logic is tested by test-update-branches.t.
1366 This logic is tested by test-update-branches.t.
1360
1367
1361 -c -C dirty rev | linear same cross
1368 -c -C dirty rev | linear same cross
1362 n n n n | ok (1) x
1369 n n n n | ok (1) x
1363 n n n y | ok ok ok
1370 n n n y | ok ok ok
1364 n n y n | merge (2) (2)
1371 n n y n | merge (2) (2)
1365 n n y y | merge (3) (3)
1372 n n y y | merge (3) (3)
1366 n y * * | discard discard discard
1373 n y * * | discard discard discard
1367 y n y * | (4) (4) (4)
1374 y n y * | (4) (4) (4)
1368 y n n * | ok ok ok
1375 y n n * | ok ok ok
1369 y y * * | (5) (5) (5)
1376 y y * * | (5) (5) (5)
1370
1377
1371 x = can't happen
1378 x = can't happen
1372 * = don't-care
1379 * = don't-care
1373 1 = abort: not a linear update (merge or update --check to force update)
1380 1 = abort: not a linear update (merge or update --check to force update)
1374 2 = abort: uncommitted changes (commit and merge, or update --clean to
1381 2 = abort: uncommitted changes (commit and merge, or update --clean to
1375 discard changes)
1382 discard changes)
1376 3 = abort: uncommitted changes (commit or update --clean to discard changes)
1383 3 = abort: uncommitted changes (commit or update --clean to discard changes)
1377 4 = abort: uncommitted changes (checked in commands.py)
1384 4 = abort: uncommitted changes (checked in commands.py)
1378 5 = incompatible options (checked in commands.py)
1385 5 = incompatible options (checked in commands.py)
1379
1386
1380 Return the same tuple as applyupdates().
1387 Return the same tuple as applyupdates().
1381 """
1388 """
1382
1389
1383 onode = node
1390 onode = node
1384 # If we're doing a partial update, we need to skip updating
1391 # If we're doing a partial update, we need to skip updating
1385 # the dirstate, so make a note of any partial-ness to the
1392 # the dirstate, so make a note of any partial-ness to the
1386 # update here.
1393 # update here.
1387 if matcher is None or matcher.always():
1394 if matcher is None or matcher.always():
1388 partial = False
1395 partial = False
1389 else:
1396 else:
1390 partial = True
1397 partial = True
1391 with repo.wlock():
1398 with repo.wlock():
1392 wc = repo[None]
1399 wc = repo[None]
1393 pl = wc.parents()
1400 pl = wc.parents()
1394 p1 = pl[0]
1401 p1 = pl[0]
1395 pas = [None]
1402 pas = [None]
1396 if ancestor is not None:
1403 if ancestor is not None:
1397 pas = [repo[ancestor]]
1404 pas = [repo[ancestor]]
1398
1405
1399 if node is None:
1406 if node is None:
1400 if (repo.ui.configbool('devel', 'all-warnings')
1407 if (repo.ui.configbool('devel', 'all-warnings')
1401 or repo.ui.configbool('devel', 'oldapi')):
1408 or repo.ui.configbool('devel', 'oldapi')):
1402 repo.ui.develwarn('update with no target')
1409 repo.ui.develwarn('update with no target')
1403 rev, _mark, _act = destutil.destupdate(repo)
1410 rev, _mark, _act = destutil.destupdate(repo)
1404 node = repo[rev].node()
1411 node = repo[rev].node()
1405
1412
1406 overwrite = force and not branchmerge
1413 overwrite = force and not branchmerge
1407
1414
1408 p2 = repo[node]
1415 p2 = repo[node]
1409 if pas[0] is None:
1416 if pas[0] is None:
1410 if repo.ui.configlist('merge', 'preferancestor', ['*']) == ['*']:
1417 if repo.ui.configlist('merge', 'preferancestor', ['*']) == ['*']:
1411 cahs = repo.changelog.commonancestorsheads(p1.node(), p2.node())
1418 cahs = repo.changelog.commonancestorsheads(p1.node(), p2.node())
1412 pas = [repo[anc] for anc in (sorted(cahs) or [nullid])]
1419 pas = [repo[anc] for anc in (sorted(cahs) or [nullid])]
1413 else:
1420 else:
1414 pas = [p1.ancestor(p2, warn=branchmerge)]
1421 pas = [p1.ancestor(p2, warn=branchmerge)]
1415
1422
1416 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
1423 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
1417
1424
1418 ### check phase
1425 ### check phase
1419 if not overwrite:
1426 if not overwrite:
1420 if len(pl) > 1:
1427 if len(pl) > 1:
1421 raise error.Abort(_("outstanding uncommitted merge"))
1428 raise error.Abort(_("outstanding uncommitted merge"))
1422 ms = mergestate.read(repo)
1429 ms = mergestate.read(repo)
1423 if list(ms.unresolved()):
1430 if list(ms.unresolved()):
1424 raise error.Abort(_("outstanding merge conflicts"))
1431 raise error.Abort(_("outstanding merge conflicts"))
1425 if branchmerge:
1432 if branchmerge:
1426 if pas == [p2]:
1433 if pas == [p2]:
1427 raise error.Abort(_("merging with a working directory ancestor"
1434 raise error.Abort(_("merging with a working directory ancestor"
1428 " has no effect"))
1435 " has no effect"))
1429 elif pas == [p1]:
1436 elif pas == [p1]:
1430 if not mergeancestor and p1.branch() == p2.branch():
1437 if not mergeancestor and p1.branch() == p2.branch():
1431 raise error.Abort(_("nothing to merge"),
1438 raise error.Abort(_("nothing to merge"),
1432 hint=_("use 'hg update' "
1439 hint=_("use 'hg update' "
1433 "or check 'hg heads'"))
1440 "or check 'hg heads'"))
1434 if not force and (wc.files() or wc.deleted()):
1441 if not force and (wc.files() or wc.deleted()):
1435 raise error.Abort(_("uncommitted changes"),
1442 raise error.Abort(_("uncommitted changes"),
1436 hint=_("use 'hg status' to list changes"))
1443 hint=_("use 'hg status' to list changes"))
1437 for s in sorted(wc.substate):
1444 for s in sorted(wc.substate):
1438 wc.sub(s).bailifchanged()
1445 wc.sub(s).bailifchanged()
1439
1446
1440 elif not overwrite:
1447 elif not overwrite:
1441 if p1 == p2: # no-op update
1448 if p1 == p2: # no-op update
1442 # call the hooks and exit early
1449 # call the hooks and exit early
1443 repo.hook('preupdate', throw=True, parent1=xp2, parent2='')
1450 repo.hook('preupdate', throw=True, parent1=xp2, parent2='')
1444 repo.hook('update', parent1=xp2, parent2='', error=0)
1451 repo.hook('update', parent1=xp2, parent2='', error=0)
1445 return 0, 0, 0, 0
1452 return 0, 0, 0, 0
1446
1453
1447 if pas not in ([p1], [p2]): # nonlinear
1454 if pas not in ([p1], [p2]): # nonlinear
1448 dirty = wc.dirty(missing=True)
1455 dirty = wc.dirty(missing=True)
1449 if dirty or onode is None:
1456 if dirty or onode is None:
1450 # Branching is a bit strange to ensure we do the minimal
1457 # Branching is a bit strange to ensure we do the minimal
1451 # amount of call to obsolete.background.
1458 # amount of call to obsolete.background.
1452 foreground = obsolete.foreground(repo, [p1.node()])
1459 foreground = obsolete.foreground(repo, [p1.node()])
1453 # note: the <node> variable contains a random identifier
1460 # note: the <node> variable contains a random identifier
1454 if repo[node].node() in foreground:
1461 if repo[node].node() in foreground:
1455 pas = [p1] # allow updating to successors
1462 pas = [p1] # allow updating to successors
1456 elif dirty:
1463 elif dirty:
1457 msg = _("uncommitted changes")
1464 msg = _("uncommitted changes")
1458 if onode is None:
1465 if onode is None:
1459 hint = _("commit and merge, or update --clean to"
1466 hint = _("commit and merge, or update --clean to"
1460 " discard changes")
1467 " discard changes")
1461 else:
1468 else:
1462 hint = _("commit or update --clean to discard"
1469 hint = _("commit or update --clean to discard"
1463 " changes")
1470 " changes")
1464 raise error.Abort(msg, hint=hint)
1471 raise error.Abort(msg, hint=hint)
1465 else: # node is none
1472 else: # node is none
1466 msg = _("not a linear update")
1473 msg = _("not a linear update")
1467 hint = _("merge or update --check to force update")
1474 hint = _("merge or update --check to force update")
1468 raise error.Abort(msg, hint=hint)
1475 raise error.Abort(msg, hint=hint)
1469 else:
1476 else:
1470 # Allow jumping branches if clean and specific rev given
1477 # Allow jumping branches if clean and specific rev given
1471 pas = [p1]
1478 pas = [p1]
1472
1479
1473 # deprecated config: merge.followcopies
1480 # deprecated config: merge.followcopies
1474 followcopies = False
1481 followcopies = False
1475 if overwrite:
1482 if overwrite:
1476 pas = [wc]
1483 pas = [wc]
1477 elif pas == [p2]: # backwards
1484 elif pas == [p2]: # backwards
1478 pas = [wc.p1()]
1485 pas = [wc.p1()]
1479 elif not branchmerge and not wc.dirty(missing=True):
1486 elif not branchmerge and not wc.dirty(missing=True):
1480 pass
1487 pass
1481 elif pas[0] and repo.ui.configbool('merge', 'followcopies', True):
1488 elif pas[0] and repo.ui.configbool('merge', 'followcopies', True):
1482 followcopies = True
1489 followcopies = True
1483
1490
1484 ### calculate phase
1491 ### calculate phase
1485 actionbyfile, diverge, renamedelete = calculateupdates(
1492 actionbyfile, diverge, renamedelete = calculateupdates(
1486 repo, wc, p2, pas, branchmerge, force, mergeancestor,
1493 repo, wc, p2, pas, branchmerge, force, mergeancestor,
1487 followcopies, matcher=matcher)
1494 followcopies, matcher=matcher)
1488
1495
1489 # Prompt and create actions. Most of this is in the resolve phase
1496 # Prompt and create actions. Most of this is in the resolve phase
1490 # already, but we can't handle .hgsubstate in filemerge or
1497 # already, but we can't handle .hgsubstate in filemerge or
1491 # subrepo.submerge yet so we have to keep prompting for it.
1498 # subrepo.submerge yet so we have to keep prompting for it.
1492 if '.hgsubstate' in actionbyfile:
1499 if '.hgsubstate' in actionbyfile:
1493 f = '.hgsubstate'
1500 f = '.hgsubstate'
1494 m, args, msg = actionbyfile[f]
1501 m, args, msg = actionbyfile[f]
1495 if m == 'cd':
1502 if m == 'cd':
1496 if repo.ui.promptchoice(
1503 if repo.ui.promptchoice(
1497 _("local changed %s which remote deleted\n"
1504 _("local changed %s which remote deleted\n"
1498 "use (c)hanged version or (d)elete?"
1505 "use (c)hanged version or (d)elete?"
1499 "$$ &Changed $$ &Delete") % f, 0):
1506 "$$ &Changed $$ &Delete") % f, 0):
1500 actionbyfile[f] = ('r', None, "prompt delete")
1507 actionbyfile[f] = ('r', None, "prompt delete")
1501 elif f in p1:
1508 elif f in p1:
1502 actionbyfile[f] = ('am', None, "prompt keep")
1509 actionbyfile[f] = ('am', None, "prompt keep")
1503 else:
1510 else:
1504 actionbyfile[f] = ('a', None, "prompt keep")
1511 actionbyfile[f] = ('a', None, "prompt keep")
1505 elif m == 'dc':
1512 elif m == 'dc':
1506 f1, f2, fa, move, anc = args
1513 f1, f2, fa, move, anc = args
1507 flags = p2[f2].flags()
1514 flags = p2[f2].flags()
1508 if repo.ui.promptchoice(
1515 if repo.ui.promptchoice(
1509 _("remote changed %s which local deleted\n"
1516 _("remote changed %s which local deleted\n"
1510 "use (c)hanged version or leave (d)eleted?"
1517 "use (c)hanged version or leave (d)eleted?"
1511 "$$ &Changed $$ &Deleted") % f, 0) == 0:
1518 "$$ &Changed $$ &Deleted") % f, 0) == 0:
1512 actionbyfile[f] = ('g', (flags, False), "prompt recreating")
1519 actionbyfile[f] = ('g', (flags, False), "prompt recreating")
1513 else:
1520 else:
1514 del actionbyfile[f]
1521 del actionbyfile[f]
1515
1522
1516 # Convert to dictionary-of-lists format
1523 # Convert to dictionary-of-lists format
1517 actions = dict((m, []) for m in 'a am f g cd dc r dm dg m e k'.split())
1524 actions = dict((m, []) for m in 'a am f g cd dc r dm dg m e k'.split())
1518 for f, (m, args, msg) in actionbyfile.iteritems():
1525 for f, (m, args, msg) in actionbyfile.iteritems():
1519 if m not in actions:
1526 if m not in actions:
1520 actions[m] = []
1527 actions[m] = []
1521 actions[m].append((f, args, msg))
1528 actions[m].append((f, args, msg))
1522
1529
1523 if not util.checkcase(repo.path):
1530 if not util.checkcase(repo.path):
1524 # check collision between files only in p2 for clean update
1531 # check collision between files only in p2 for clean update
1525 if (not branchmerge and
1532 if (not branchmerge and
1526 (force or not wc.dirty(missing=True, branch=False))):
1533 (force or not wc.dirty(missing=True, branch=False))):
1527 _checkcollision(repo, p2.manifest(), None)
1534 _checkcollision(repo, p2.manifest(), None)
1528 else:
1535 else:
1529 _checkcollision(repo, wc.manifest(), actions)
1536 _checkcollision(repo, wc.manifest(), actions)
1530
1537
1531 # divergent renames
1538 # divergent renames
1532 for f, fl in sorted(diverge.iteritems()):
1539 for f, fl in sorted(diverge.iteritems()):
1533 repo.ui.warn(_("note: possible conflict - %s was renamed "
1540 repo.ui.warn(_("note: possible conflict - %s was renamed "
1534 "multiple times to:\n") % f)
1541 "multiple times to:\n") % f)
1535 for nf in fl:
1542 for nf in fl:
1536 repo.ui.warn(" %s\n" % nf)
1543 repo.ui.warn(" %s\n" % nf)
1537
1544
1538 # rename and delete
1545 # rename and delete
1539 for f, fl in sorted(renamedelete.iteritems()):
1546 for f, fl in sorted(renamedelete.iteritems()):
1540 repo.ui.warn(_("note: possible conflict - %s was deleted "
1547 repo.ui.warn(_("note: possible conflict - %s was deleted "
1541 "and renamed to:\n") % f)
1548 "and renamed to:\n") % f)
1542 for nf in fl:
1549 for nf in fl:
1543 repo.ui.warn(" %s\n" % nf)
1550 repo.ui.warn(" %s\n" % nf)
1544
1551
1545 ### apply phase
1552 ### apply phase
1546 if not branchmerge: # just jump to the new rev
1553 if not branchmerge: # just jump to the new rev
1547 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
1554 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
1548 if not partial:
1555 if not partial:
1549 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
1556 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
1550 # note that we're in the middle of an update
1557 # note that we're in the middle of an update
1551 repo.vfs.write('updatestate', p2.hex())
1558 repo.vfs.write('updatestate', p2.hex())
1552
1559
1553 stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels)
1560 stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels)
1554
1561
1555 if not partial:
1562 if not partial:
1556 repo.dirstate.beginparentchange()
1563 repo.dirstate.beginparentchange()
1557 repo.setparents(fp1, fp2)
1564 repo.setparents(fp1, fp2)
1558 recordupdates(repo, actions, branchmerge)
1565 recordupdates(repo, actions, branchmerge)
1559 # update completed, clear state
1566 # update completed, clear state
1560 util.unlink(repo.join('updatestate'))
1567 util.unlink(repo.join('updatestate'))
1561
1568
1562 if not branchmerge:
1569 if not branchmerge:
1563 repo.dirstate.setbranch(p2.branch())
1570 repo.dirstate.setbranch(p2.branch())
1564 repo.dirstate.endparentchange()
1571 repo.dirstate.endparentchange()
1565
1572
1566 if not partial:
1573 if not partial:
1567 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
1574 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
1568 return stats
1575 return stats
1569
1576
1570 def graft(repo, ctx, pctx, labels, keepparent=False):
1577 def graft(repo, ctx, pctx, labels, keepparent=False):
1571 """Do a graft-like merge.
1578 """Do a graft-like merge.
1572
1579
1573 This is a merge where the merge ancestor is chosen such that one
1580 This is a merge where the merge ancestor is chosen such that one
1574 or more changesets are grafted onto the current changeset. In
1581 or more changesets are grafted onto the current changeset. In
1575 addition to the merge, this fixes up the dirstate to include only
1582 addition to the merge, this fixes up the dirstate to include only
1576 a single parent (if keepparent is False) and tries to duplicate any
1583 a single parent (if keepparent is False) and tries to duplicate any
1577 renames/copies appropriately.
1584 renames/copies appropriately.
1578
1585
1579 ctx - changeset to rebase
1586 ctx - changeset to rebase
1580 pctx - merge base, usually ctx.p1()
1587 pctx - merge base, usually ctx.p1()
1581 labels - merge labels eg ['local', 'graft']
1588 labels - merge labels eg ['local', 'graft']
1582 keepparent - keep second parent if any
1589 keepparent - keep second parent if any
1583
1590
1584 """
1591 """
1585 # If we're grafting a descendant onto an ancestor, be sure to pass
1592 # If we're grafting a descendant onto an ancestor, be sure to pass
1586 # mergeancestor=True to update. This does two things: 1) allows the merge if
1593 # mergeancestor=True to update. This does two things: 1) allows the merge if
1587 # the destination is the same as the parent of the ctx (so we can use graft
1594 # the destination is the same as the parent of the ctx (so we can use graft
1588 # to copy commits), and 2) informs update that the incoming changes are
1595 # to copy commits), and 2) informs update that the incoming changes are
1589 # newer than the destination so it doesn't prompt about "remote changed foo
1596 # newer than the destination so it doesn't prompt about "remote changed foo
1590 # which local deleted".
1597 # which local deleted".
1591 mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node())
1598 mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node())
1592
1599
1593 stats = update(repo, ctx.node(), True, True, pctx.node(),
1600 stats = update(repo, ctx.node(), True, True, pctx.node(),
1594 mergeancestor=mergeancestor, labels=labels)
1601 mergeancestor=mergeancestor, labels=labels)
1595
1602
1596 pother = nullid
1603 pother = nullid
1597 parents = ctx.parents()
1604 parents = ctx.parents()
1598 if keepparent and len(parents) == 2 and pctx in parents:
1605 if keepparent and len(parents) == 2 and pctx in parents:
1599 parents.remove(pctx)
1606 parents.remove(pctx)
1600 pother = parents[0].node()
1607 pother = parents[0].node()
1601
1608
1602 repo.dirstate.beginparentchange()
1609 repo.dirstate.beginparentchange()
1603 repo.setparents(repo['.'].node(), pother)
1610 repo.setparents(repo['.'].node(), pother)
1604 repo.dirstate.write(repo.currenttransaction())
1611 repo.dirstate.write(repo.currenttransaction())
1605 # fix up dirstate for copies and renames
1612 # fix up dirstate for copies and renames
1606 copies.duplicatecopies(repo, ctx.rev(), pctx.rev())
1613 copies.duplicatecopies(repo, ctx.rev(), pctx.rev())
1607 repo.dirstate.endparentchange()
1614 repo.dirstate.endparentchange()
1608 return stats
1615 return stats
@@ -1,762 +1,763 b''
1 $ hg init basic
1 $ hg init basic
2 $ cd basic
2 $ cd basic
3
3
4 should complain
4 should complain
5
5
6 $ hg backout
6 $ hg backout
7 abort: please specify a revision to backout
7 abort: please specify a revision to backout
8 [255]
8 [255]
9 $ hg backout -r 0 0
9 $ hg backout -r 0 0
10 abort: please specify just one revision
10 abort: please specify just one revision
11 [255]
11 [255]
12
12
13 basic operation
13 basic operation
14 (this also tests that editor is invoked if the commit message is not
14 (this also tests that editor is invoked if the commit message is not
15 specified explicitly)
15 specified explicitly)
16
16
17 $ echo a > a
17 $ echo a > a
18 $ hg commit -d '0 0' -A -m a
18 $ hg commit -d '0 0' -A -m a
19 adding a
19 adding a
20 $ echo b >> a
20 $ echo b >> a
21 $ hg commit -d '1 0' -m b
21 $ hg commit -d '1 0' -m b
22
22
23 $ hg status --rev tip --rev "tip^1"
23 $ hg status --rev tip --rev "tip^1"
24 M a
24 M a
25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
26 reverting a
26 reverting a
27 Backed out changeset a820f4f40a57
27 Backed out changeset a820f4f40a57
28
28
29
29
30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
31 HG: Leave message empty to abort commit.
31 HG: Leave message empty to abort commit.
32 HG: --
32 HG: --
33 HG: user: test
33 HG: user: test
34 HG: branch 'default'
34 HG: branch 'default'
35 HG: changed a
35 HG: changed a
36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
37 $ cat a
37 $ cat a
38 a
38 a
39 $ hg summary
39 $ hg summary
40 parent: 2:2929462c3dff tip
40 parent: 2:2929462c3dff tip
41 Backed out changeset a820f4f40a57
41 Backed out changeset a820f4f40a57
42 branch: default
42 branch: default
43 commit: (clean)
43 commit: (clean)
44 update: (current)
44 update: (current)
45 phases: 3 draft
45 phases: 3 draft
46
46
47 commit option
47 commit option
48
48
49 $ cd ..
49 $ cd ..
50 $ hg init commit
50 $ hg init commit
51 $ cd commit
51 $ cd commit
52
52
53 $ echo tomatoes > a
53 $ echo tomatoes > a
54 $ hg add a
54 $ hg add a
55 $ hg commit -d '0 0' -m tomatoes
55 $ hg commit -d '0 0' -m tomatoes
56
56
57 $ echo chair > b
57 $ echo chair > b
58 $ hg add b
58 $ hg add b
59 $ hg commit -d '1 0' -m chair
59 $ hg commit -d '1 0' -m chair
60
60
61 $ echo grapes >> a
61 $ echo grapes >> a
62 $ hg commit -d '2 0' -m grapes
62 $ hg commit -d '2 0' -m grapes
63
63
64 $ hg backout -d '4 0' 1 --tool=:fail
64 $ hg backout -d '4 0' 1 --tool=:fail
65 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
65 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 changeset 3:1c2161e97c0a backs out changeset 1:22cb4f70d813
66 changeset 3:1c2161e97c0a backs out changeset 1:22cb4f70d813
67 $ hg summary
67 $ hg summary
68 parent: 3:1c2161e97c0a tip
68 parent: 3:1c2161e97c0a tip
69 Backed out changeset 22cb4f70d813
69 Backed out changeset 22cb4f70d813
70 branch: default
70 branch: default
71 commit: (clean)
71 commit: (clean)
72 update: (current)
72 update: (current)
73 phases: 4 draft
73 phases: 4 draft
74
74
75 $ echo ypples > a
75 $ echo ypples > a
76 $ hg commit -d '5 0' -m ypples
76 $ hg commit -d '5 0' -m ypples
77
77
78 $ hg backout -d '6 0' 2 --tool=:fail
78 $ hg backout -d '6 0' 2 --tool=:fail
79 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
79 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
80 use 'hg resolve' to retry unresolved file merges
80 use 'hg resolve' to retry unresolved file merges
81 [1]
81 [1]
82 $ hg summary
82 $ hg summary
83 parent: 4:ed99997b793d tip
83 parent: 4:ed99997b793d tip
84 ypples
84 ypples
85 branch: default
85 branch: default
86 commit: 1 unresolved (clean)
86 commit: 1 unresolved (clean)
87 update: (current)
87 update: (current)
88 phases: 5 draft
88 phases: 5 draft
89
89
90 file that was removed is recreated
90 file that was removed is recreated
91 (this also tests that editor is not invoked if the commit message is
91 (this also tests that editor is not invoked if the commit message is
92 specified explicitly)
92 specified explicitly)
93
93
94 $ cd ..
94 $ cd ..
95 $ hg init remove
95 $ hg init remove
96 $ cd remove
96 $ cd remove
97
97
98 $ echo content > a
98 $ echo content > a
99 $ hg commit -d '0 0' -A -m a
99 $ hg commit -d '0 0' -A -m a
100 adding a
100 adding a
101
101
102 $ hg rm a
102 $ hg rm a
103 $ hg commit -d '1 0' -m b
103 $ hg commit -d '1 0' -m b
104
104
105 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
105 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
106 adding a
106 adding a
107 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
107 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
108 $ cat a
108 $ cat a
109 content
109 content
110 $ hg summary
110 $ hg summary
111 parent: 2:de31bdc76c0d tip
111 parent: 2:de31bdc76c0d tip
112 Backed out changeset 76862dcce372
112 Backed out changeset 76862dcce372
113 branch: default
113 branch: default
114 commit: (clean)
114 commit: (clean)
115 update: (current)
115 update: (current)
116 phases: 3 draft
116 phases: 3 draft
117
117
118 backout of backout is as if nothing happened
118 backout of backout is as if nothing happened
119
119
120 $ hg backout -d '3 0' --merge tip --tool=true
120 $ hg backout -d '3 0' --merge tip --tool=true
121 removing a
121 removing a
122 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
122 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
123 $ test -f a
123 $ test -f a
124 [1]
124 [1]
125 $ hg summary
125 $ hg summary
126 parent: 3:7f6d0f120113 tip
126 parent: 3:7f6d0f120113 tip
127 Backed out changeset de31bdc76c0d
127 Backed out changeset de31bdc76c0d
128 branch: default
128 branch: default
129 commit: (clean)
129 commit: (clean)
130 update: (current)
130 update: (current)
131 phases: 4 draft
131 phases: 4 draft
132
132
133 Test that 'hg rollback' restores dirstate just before opening
133 Test that 'hg rollback' restores dirstate just before opening
134 transaction: in-memory dirstate changes should be written into
134 transaction: in-memory dirstate changes should be written into
135 '.hg/journal.dirstate' as expected.
135 '.hg/journal.dirstate' as expected.
136
136
137 $ echo 'removed soon' > b
137 $ echo 'removed soon' > b
138 $ hg commit -A -d '4 0' -m 'prepare for subsequent removing'
138 $ hg commit -A -d '4 0' -m 'prepare for subsequent removing'
139 adding b
139 adding b
140 $ echo 'newly added' > c
140 $ echo 'newly added' > c
141 $ hg add c
141 $ hg add c
142 $ hg remove b
142 $ hg remove b
143 $ hg commit -d '5 0' -m 'prepare for subsequent backout'
143 $ hg commit -d '5 0' -m 'prepare for subsequent backout'
144 $ touch -t 200001010000 c
144 $ touch -t 200001010000 c
145 $ hg status -A
145 $ hg status -A
146 C c
146 C c
147 $ hg debugstate --nodates
147 $ hg debugstate --nodates
148 n 644 12 set c
148 n 644 12 set c
149 $ hg backout -d '6 0' -m 'to be rollback-ed soon' -r .
149 $ hg backout -d '6 0' -m 'to be rollback-ed soon' -r .
150 adding b
150 adding b
151 removing c
151 removing c
152 changeset 6:4bfec048029d backs out changeset 5:fac0b729a654
152 changeset 6:4bfec048029d backs out changeset 5:fac0b729a654
153 $ hg rollback -q
153 $ hg rollback -q
154 $ hg status -A
154 $ hg status -A
155 A b
155 A b
156 R c
156 R c
157 $ hg debugstate --nodates
157 $ hg debugstate --nodates
158 a 0 -1 unset b
158 a 0 -1 unset b
159 r 0 0 set c
159 r 0 0 set c
160
160
161 across branch
161 across branch
162
162
163 $ cd ..
163 $ cd ..
164 $ hg init branch
164 $ hg init branch
165 $ cd branch
165 $ cd branch
166 $ echo a > a
166 $ echo a > a
167 $ hg ci -Am0
167 $ hg ci -Am0
168 adding a
168 adding a
169 $ echo b > b
169 $ echo b > b
170 $ hg ci -Am1
170 $ hg ci -Am1
171 adding b
171 adding b
172 $ hg co -C 0
172 $ hg co -C 0
173 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
173 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
174 $ hg summary
174 $ hg summary
175 parent: 0:f7b1eb17ad24
175 parent: 0:f7b1eb17ad24
176 0
176 0
177 branch: default
177 branch: default
178 commit: (clean)
178 commit: (clean)
179 update: 1 new changesets (update)
179 update: 1 new changesets (update)
180 phases: 2 draft
180 phases: 2 draft
181
181
182 should fail
182 should fail
183
183
184 $ hg backout 1
184 $ hg backout 1
185 abort: cannot backout change that is not an ancestor
185 abort: cannot backout change that is not an ancestor
186 [255]
186 [255]
187 $ echo c > c
187 $ echo c > c
188 $ hg ci -Am2
188 $ hg ci -Am2
189 adding c
189 adding c
190 created new head
190 created new head
191 $ hg summary
191 $ hg summary
192 parent: 2:db815d6d32e6 tip
192 parent: 2:db815d6d32e6 tip
193 2
193 2
194 branch: default
194 branch: default
195 commit: (clean)
195 commit: (clean)
196 update: 1 new changesets, 2 branch heads (merge)
196 update: 1 new changesets, 2 branch heads (merge)
197 phases: 3 draft
197 phases: 3 draft
198
198
199 should fail
199 should fail
200
200
201 $ hg backout 1
201 $ hg backout 1
202 abort: cannot backout change that is not an ancestor
202 abort: cannot backout change that is not an ancestor
203 [255]
203 [255]
204 $ hg summary
204 $ hg summary
205 parent: 2:db815d6d32e6 tip
205 parent: 2:db815d6d32e6 tip
206 2
206 2
207 branch: default
207 branch: default
208 commit: (clean)
208 commit: (clean)
209 update: 1 new changesets, 2 branch heads (merge)
209 update: 1 new changesets, 2 branch heads (merge)
210 phases: 3 draft
210 phases: 3 draft
211
211
212 backout with merge
212 backout with merge
213
213
214 $ cd ..
214 $ cd ..
215 $ hg init merge
215 $ hg init merge
216 $ cd merge
216 $ cd merge
217
217
218 $ echo line 1 > a
218 $ echo line 1 > a
219 $ echo line 2 >> a
219 $ echo line 2 >> a
220 $ hg commit -d '0 0' -A -m a
220 $ hg commit -d '0 0' -A -m a
221 adding a
221 adding a
222 $ hg summary
222 $ hg summary
223 parent: 0:59395513a13a tip
223 parent: 0:59395513a13a tip
224 a
224 a
225 branch: default
225 branch: default
226 commit: (clean)
226 commit: (clean)
227 update: (current)
227 update: (current)
228 phases: 1 draft
228 phases: 1 draft
229
229
230 remove line 1
230 remove line 1
231
231
232 $ echo line 2 > a
232 $ echo line 2 > a
233 $ hg commit -d '1 0' -m b
233 $ hg commit -d '1 0' -m b
234
234
235 $ echo line 3 >> a
235 $ echo line 3 >> a
236 $ hg commit -d '2 0' -m c
236 $ hg commit -d '2 0' -m c
237
237
238 $ hg backout --merge -d '3 0' 1 --tool=true
238 $ hg backout --merge -d '3 0' 1 --tool=true
239 reverting a
239 reverting a
240 created new head
240 created new head
241 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
241 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
242 merging with changeset 3:26b8ccb9ad91
242 merging with changeset 3:26b8ccb9ad91
243 merging a
243 merging a
244 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
244 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
245 (branch merge, don't forget to commit)
245 (branch merge, don't forget to commit)
246 $ hg commit -d '4 0' -m d
246 $ hg commit -d '4 0' -m d
247 $ hg summary
247 $ hg summary
248 parent: 4:c7df5e0b9c09 tip
248 parent: 4:c7df5e0b9c09 tip
249 d
249 d
250 branch: default
250 branch: default
251 commit: (clean)
251 commit: (clean)
252 update: (current)
252 update: (current)
253 phases: 5 draft
253 phases: 5 draft
254
254
255 check line 1 is back
255 check line 1 is back
256
256
257 $ cat a
257 $ cat a
258 line 1
258 line 1
259 line 2
259 line 2
260 line 3
260 line 3
261
261
262 Test visibility of in-memory dirstate changes outside transaction to
262 Test visibility of in-memory dirstate changes outside transaction to
263 external hook process
263 external hook process
264
264
265 $ cat > $TESTTMP/checkvisibility.sh <<EOF
265 $ cat > $TESTTMP/checkvisibility.sh <<EOF
266 > echo "==== \$1:"
266 > echo "==== \$1:"
267 > hg parents --template "{rev}:{node|short}\n"
267 > hg parents --template "{rev}:{node|short}\n"
268 > echo "===="
268 > echo "===="
269 > EOF
269 > EOF
270
270
271 "hg backout --merge REV1" at REV2 below implies steps below:
271 "hg backout --merge REV1" at REV2 below implies steps below:
272
272
273 (1) update to REV1 (REV2 => REV1)
273 (1) update to REV1 (REV2 => REV1)
274 (2) revert by REV1^1
274 (2) revert by REV1^1
275 (3) commit backnig out revision (REV3)
275 (3) commit backnig out revision (REV3)
276 (4) update to REV2 (REV3 => REV2)
276 (4) update to REV2 (REV3 => REV2)
277 (5) merge with REV3 (REV2 => REV2, REV3)
277 (5) merge with REV3 (REV2 => REV2, REV3)
278
278
279 == test visibility to external preupdate hook
279 == test visibility to external preupdate hook
280
280
281 $ hg update -q -C 2
281 $ hg update -q -C 2
282 $ hg --config extensions.strip= strip 3
282 $ hg --config extensions.strip= strip 3
283 saved backup bundle to * (glob)
283 saved backup bundle to * (glob)
284
284
285 $ cat >> .hg/hgrc <<EOF
285 $ cat >> .hg/hgrc <<EOF
286 > [hooks]
286 > [hooks]
287 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
287 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
288 > EOF
288 > EOF
289
289
290 ("-m" is needed to avoid writing dirstte changes out at other than
290 ("-m" is needed to avoid writing dirstte changes out at other than
291 invocation of the hook to be examined)
291 invocation of the hook to be examined)
292
292
293 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
293 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
294 ==== preupdate:
294 ==== preupdate:
295 2:6ea3f2a197a2
295 2:6ea3f2a197a2
296 ====
296 ====
297 reverting a
297 reverting a
298 created new head
298 created new head
299 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
299 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
300 ==== preupdate:
300 ==== preupdate:
301 3:d92a3f57f067
301 3:d92a3f57f067
302 ====
302 ====
303 merging with changeset 3:d92a3f57f067
303 merging with changeset 3:d92a3f57f067
304 ==== preupdate:
304 ==== preupdate:
305 2:6ea3f2a197a2
305 2:6ea3f2a197a2
306 ====
306 ====
307 merging a
307 merging a
308 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
308 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
309 (branch merge, don't forget to commit)
309 (branch merge, don't forget to commit)
310
310
311 $ cat >> .hg/hgrc <<EOF
311 $ cat >> .hg/hgrc <<EOF
312 > [hooks]
312 > [hooks]
313 > preupdate.visibility =
313 > preupdate.visibility =
314 > EOF
314 > EOF
315
315
316 == test visibility to external update hook
316 == test visibility to external update hook
317
317
318 $ hg update -q -C 2
318 $ hg update -q -C 2
319 $ hg --config extensions.strip= strip 3
319 $ hg --config extensions.strip= strip 3
320 saved backup bundle to * (glob)
320 saved backup bundle to * (glob)
321
321
322 $ cat >> .hg/hgrc <<EOF
322 $ cat >> .hg/hgrc <<EOF
323 > [hooks]
323 > [hooks]
324 > update.visibility = sh $TESTTMP/checkvisibility.sh update
324 > update.visibility = sh $TESTTMP/checkvisibility.sh update
325 > EOF
325 > EOF
326
326
327 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
327 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
328 ==== update:
328 ==== update:
329 1:5a50a024c182
329 1:5a50a024c182
330 ====
330 ====
331 reverting a
331 reverting a
332 created new head
332 created new head
333 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
333 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
334 ==== update:
334 ==== update:
335 2:6ea3f2a197a2
335 2:6ea3f2a197a2
336 ====
336 ====
337 merging with changeset 3:d92a3f57f067
337 merging with changeset 3:d92a3f57f067
338 merging a
338 merging a
339 ==== update:
339 ==== update:
340 2:6ea3f2a197a2
340 2:6ea3f2a197a2
341 3:d92a3f57f067
341 3:d92a3f57f067
342 ====
342 ====
343 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
343 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
344 (branch merge, don't forget to commit)
344 (branch merge, don't forget to commit)
345
345
346 $ cat >> .hg/hgrc <<EOF
346 $ cat >> .hg/hgrc <<EOF
347 > [hooks]
347 > [hooks]
348 > update.visibility =
348 > update.visibility =
349 > EOF
349 > EOF
350
350
351 $ cd ..
351 $ cd ..
352
352
353 backout should not back out subsequent changesets
353 backout should not back out subsequent changesets
354
354
355 $ hg init onecs
355 $ hg init onecs
356 $ cd onecs
356 $ cd onecs
357 $ echo 1 > a
357 $ echo 1 > a
358 $ hg commit -d '0 0' -A -m a
358 $ hg commit -d '0 0' -A -m a
359 adding a
359 adding a
360 $ echo 2 >> a
360 $ echo 2 >> a
361 $ hg commit -d '1 0' -m b
361 $ hg commit -d '1 0' -m b
362 $ echo 1 > b
362 $ echo 1 > b
363 $ hg commit -d '2 0' -A -m c
363 $ hg commit -d '2 0' -A -m c
364 adding b
364 adding b
365 $ hg summary
365 $ hg summary
366 parent: 2:882396649954 tip
366 parent: 2:882396649954 tip
367 c
367 c
368 branch: default
368 branch: default
369 commit: (clean)
369 commit: (clean)
370 update: (current)
370 update: (current)
371 phases: 3 draft
371 phases: 3 draft
372
372
373 without --merge
373 without --merge
374 $ hg backout --no-commit -d '3 0' 1 --tool=true
374 $ hg backout --no-commit -d '3 0' 1 --tool=true
375 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
375 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 changeset 22bca4c721e5 backed out, don't forget to commit.
376 changeset 22bca4c721e5 backed out, don't forget to commit.
377 $ hg locate b
377 $ hg locate b
378 b
378 b
379 $ hg update -C tip
379 $ hg update -C tip
380 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
380 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
381 $ hg locate b
381 $ hg locate b
382 b
382 b
383 $ hg summary
383 $ hg summary
384 parent: 2:882396649954 tip
384 parent: 2:882396649954 tip
385 c
385 c
386 branch: default
386 branch: default
387 commit: (clean)
387 commit: (clean)
388 update: (current)
388 update: (current)
389 phases: 3 draft
389 phases: 3 draft
390
390
391 with --merge
391 with --merge
392 $ hg backout --merge -d '3 0' 1 --tool=true
392 $ hg backout --merge -d '3 0' 1 --tool=true
393 reverting a
393 reverting a
394 created new head
394 created new head
395 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
395 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
396 merging with changeset 3:3202beb76721
396 merging with changeset 3:3202beb76721
397 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
397 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
398 (branch merge, don't forget to commit)
398 (branch merge, don't forget to commit)
399 $ hg locate b
399 $ hg locate b
400 b
400 b
401 $ hg update -C tip
401 $ hg update -C tip
402 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
402 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
403 $ hg locate b
403 $ hg locate b
404 [1]
404 [1]
405
405
406 $ cd ..
406 $ cd ..
407 $ hg init m
407 $ hg init m
408 $ cd m
408 $ cd m
409 $ echo a > a
409 $ echo a > a
410 $ hg commit -d '0 0' -A -m a
410 $ hg commit -d '0 0' -A -m a
411 adding a
411 adding a
412 $ echo b > b
412 $ echo b > b
413 $ hg commit -d '1 0' -A -m b
413 $ hg commit -d '1 0' -A -m b
414 adding b
414 adding b
415 $ echo c > c
415 $ echo c > c
416 $ hg commit -d '2 0' -A -m b
416 $ hg commit -d '2 0' -A -m b
417 adding c
417 adding c
418 $ hg update 1
418 $ hg update 1
419 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
419 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
420 $ echo d > d
420 $ echo d > d
421 $ hg commit -d '3 0' -A -m c
421 $ hg commit -d '3 0' -A -m c
422 adding d
422 adding d
423 created new head
423 created new head
424 $ hg merge 2
424 $ hg merge 2
425 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
425 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
426 (branch merge, don't forget to commit)
426 (branch merge, don't forget to commit)
427 $ hg commit -d '4 0' -A -m d
427 $ hg commit -d '4 0' -A -m d
428 $ hg summary
428 $ hg summary
429 parent: 4:b2f3bb92043e tip
429 parent: 4:b2f3bb92043e tip
430 d
430 d
431 branch: default
431 branch: default
432 commit: (clean)
432 commit: (clean)
433 update: (current)
433 update: (current)
434 phases: 5 draft
434 phases: 5 draft
435
435
436 backout of merge should fail
436 backout of merge should fail
437
437
438 $ hg backout 4
438 $ hg backout 4
439 abort: cannot backout a merge changeset
439 abort: cannot backout a merge changeset
440 [255]
440 [255]
441
441
442 backout of merge with bad parent should fail
442 backout of merge with bad parent should fail
443
443
444 $ hg backout --parent 0 4
444 $ hg backout --parent 0 4
445 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
445 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
446 [255]
446 [255]
447
447
448 backout of non-merge with parent should fail
448 backout of non-merge with parent should fail
449
449
450 $ hg backout --parent 0 3
450 $ hg backout --parent 0 3
451 abort: cannot use --parent on non-merge changeset
451 abort: cannot use --parent on non-merge changeset
452 [255]
452 [255]
453
453
454 backout with valid parent should be ok
454 backout with valid parent should be ok
455
455
456 $ hg backout -d '5 0' --parent 2 4 --tool=true
456 $ hg backout -d '5 0' --parent 2 4 --tool=true
457 removing d
457 removing d
458 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
458 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
459 $ hg summary
459 $ hg summary
460 parent: 5:10e5328c8435 tip
460 parent: 5:10e5328c8435 tip
461 Backed out changeset b2f3bb92043e
461 Backed out changeset b2f3bb92043e
462 branch: default
462 branch: default
463 commit: (clean)
463 commit: (clean)
464 update: (current)
464 update: (current)
465 phases: 6 draft
465 phases: 6 draft
466
466
467 $ hg rollback
467 $ hg rollback
468 repository tip rolled back to revision 4 (undo commit)
468 repository tip rolled back to revision 4 (undo commit)
469 working directory now based on revision 4
469 working directory now based on revision 4
470 $ hg update -C
470 $ hg update -C
471 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
471 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
472 $ hg summary
472 $ hg summary
473 parent: 4:b2f3bb92043e tip
473 parent: 4:b2f3bb92043e tip
474 d
474 d
475 branch: default
475 branch: default
476 commit: (clean)
476 commit: (clean)
477 update: (current)
477 update: (current)
478 phases: 5 draft
478 phases: 5 draft
479
479
480 $ hg backout -d '6 0' --parent 3 4 --tool=true
480 $ hg backout -d '6 0' --parent 3 4 --tool=true
481 removing c
481 removing c
482 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
482 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
483 $ hg summary
483 $ hg summary
484 parent: 5:033590168430 tip
484 parent: 5:033590168430 tip
485 Backed out changeset b2f3bb92043e
485 Backed out changeset b2f3bb92043e
486 branch: default
486 branch: default
487 commit: (clean)
487 commit: (clean)
488 update: (current)
488 update: (current)
489 phases: 6 draft
489 phases: 6 draft
490
490
491 $ cd ..
491 $ cd ..
492
492
493 named branches
493 named branches
494
494
495 $ hg init named_branches
495 $ hg init named_branches
496 $ cd named_branches
496 $ cd named_branches
497
497
498 $ echo default > default
498 $ echo default > default
499 $ hg ci -d '0 0' -Am default
499 $ hg ci -d '0 0' -Am default
500 adding default
500 adding default
501 $ hg branch branch1
501 $ hg branch branch1
502 marked working directory as branch branch1
502 marked working directory as branch branch1
503 (branches are permanent and global, did you want a bookmark?)
503 (branches are permanent and global, did you want a bookmark?)
504 $ echo branch1 > file1
504 $ echo branch1 > file1
505 $ hg ci -d '1 0' -Am file1
505 $ hg ci -d '1 0' -Am file1
506 adding file1
506 adding file1
507 $ hg branch branch2
507 $ hg branch branch2
508 marked working directory as branch branch2
508 marked working directory as branch branch2
509 $ echo branch2 > file2
509 $ echo branch2 > file2
510 $ hg ci -d '2 0' -Am file2
510 $ hg ci -d '2 0' -Am file2
511 adding file2
511 adding file2
512
512
513 without --merge
513 without --merge
514 $ hg backout --no-commit -r 1 --tool=true
514 $ hg backout --no-commit -r 1 --tool=true
515 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
515 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
516 changeset bf1602f437f3 backed out, don't forget to commit.
516 changeset bf1602f437f3 backed out, don't forget to commit.
517 $ hg branch
517 $ hg branch
518 branch2
518 branch2
519 $ hg status -A
519 $ hg status -A
520 R file1
520 R file1
521 C default
521 C default
522 C file2
522 C file2
523 $ hg summary
523 $ hg summary
524 parent: 2:45bbcd363bf0 tip
524 parent: 2:45bbcd363bf0 tip
525 file2
525 file2
526 branch: branch2
526 branch: branch2
527 commit: 1 removed
527 commit: 1 removed
528 update: (current)
528 update: (current)
529 phases: 3 draft
529 phases: 3 draft
530
530
531 with --merge
531 with --merge
532 (this also tests that editor is invoked if '--edit' is specified
532 (this also tests that editor is invoked if '--edit' is specified
533 explicitly regardless of '--message')
533 explicitly regardless of '--message')
534
534
535 $ hg update -qC
535 $ hg update -qC
536 $ HGEDITOR=cat hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true --edit
536 $ HGEDITOR=cat hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true --edit
537 removing file1
537 removing file1
538 backout on branch1
538 backout on branch1
539
539
540
540
541 HG: Enter commit message. Lines beginning with 'HG:' are removed.
541 HG: Enter commit message. Lines beginning with 'HG:' are removed.
542 HG: Leave message empty to abort commit.
542 HG: Leave message empty to abort commit.
543 HG: --
543 HG: --
544 HG: user: test
544 HG: user: test
545 HG: branch 'branch2'
545 HG: branch 'branch2'
546 HG: removed file1
546 HG: removed file1
547 created new head
547 created new head
548 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
548 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
549 merging with changeset 3:d4e8f6db59fb
549 merging with changeset 3:d4e8f6db59fb
550 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
550 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
551 (branch merge, don't forget to commit)
551 (branch merge, don't forget to commit)
552 $ hg summary
552 $ hg summary
553 parent: 2:45bbcd363bf0
553 parent: 2:45bbcd363bf0
554 file2
554 file2
555 parent: 3:d4e8f6db59fb tip
555 parent: 3:d4e8f6db59fb tip
556 backout on branch1
556 backout on branch1
557 branch: branch2
557 branch: branch2
558 commit: 1 removed (merge)
558 commit: 1 removed (merge)
559 update: (current)
559 update: (current)
560 phases: 4 draft
560 phases: 4 draft
561 $ hg update -q -C 2
561 $ hg update -q -C 2
562
562
563 on branch2 with branch1 not merged, so file1 should still exist:
563 on branch2 with branch1 not merged, so file1 should still exist:
564
564
565 $ hg id
565 $ hg id
566 45bbcd363bf0 (branch2)
566 45bbcd363bf0 (branch2)
567 $ hg st -A
567 $ hg st -A
568 C default
568 C default
569 C file1
569 C file1
570 C file2
570 C file2
571 $ hg summary
571 $ hg summary
572 parent: 2:45bbcd363bf0
572 parent: 2:45bbcd363bf0
573 file2
573 file2
574 branch: branch2
574 branch: branch2
575 commit: (clean)
575 commit: (clean)
576 update: 1 new changesets, 2 branch heads (merge)
576 update: 1 new changesets, 2 branch heads (merge)
577 phases: 4 draft
577 phases: 4 draft
578
578
579 on branch2 with branch1 merged, so file1 should be gone:
579 on branch2 with branch1 merged, so file1 should be gone:
580
580
581 $ hg merge
581 $ hg merge
582 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
582 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
583 (branch merge, don't forget to commit)
583 (branch merge, don't forget to commit)
584 $ hg ci -d '4 0' -m 'merge backout of branch1'
584 $ hg ci -d '4 0' -m 'merge backout of branch1'
585 $ hg id
585 $ hg id
586 22149cdde76d (branch2) tip
586 22149cdde76d (branch2) tip
587 $ hg st -A
587 $ hg st -A
588 C default
588 C default
589 C file2
589 C file2
590 $ hg summary
590 $ hg summary
591 parent: 4:22149cdde76d tip
591 parent: 4:22149cdde76d tip
592 merge backout of branch1
592 merge backout of branch1
593 branch: branch2
593 branch: branch2
594 commit: (clean)
594 commit: (clean)
595 update: (current)
595 update: (current)
596 phases: 5 draft
596 phases: 5 draft
597
597
598 on branch1, so no file1 and file2:
598 on branch1, so no file1 and file2:
599
599
600 $ hg co -C branch1
600 $ hg co -C branch1
601 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
601 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
602 $ hg id
602 $ hg id
603 bf1602f437f3 (branch1)
603 bf1602f437f3 (branch1)
604 $ hg st -A
604 $ hg st -A
605 C default
605 C default
606 C file1
606 C file1
607 $ hg summary
607 $ hg summary
608 parent: 1:bf1602f437f3
608 parent: 1:bf1602f437f3
609 file1
609 file1
610 branch: branch1
610 branch: branch1
611 commit: (clean)
611 commit: (clean)
612 update: (current)
612 update: (current)
613 phases: 5 draft
613 phases: 5 draft
614
614
615 $ cd ..
615 $ cd ..
616
616
617 backout of empty changeset (issue4190)
617 backout of empty changeset (issue4190)
618
618
619 $ hg init emptycommit
619 $ hg init emptycommit
620 $ cd emptycommit
620 $ cd emptycommit
621
621
622 $ touch file1
622 $ touch file1
623 $ hg ci -Aqm file1
623 $ hg ci -Aqm file1
624 $ hg branch -q branch1
624 $ hg branch -q branch1
625 $ hg ci -qm branch1
625 $ hg ci -qm branch1
626 $ hg backout -v 1
626 $ hg backout -v 1
627 resolving manifests
627 resolving manifests
628 nothing changed
628 nothing changed
629 [1]
629 [1]
630
630
631 $ cd ..
631 $ cd ..
632
632
633
633
634 Test usage of `hg resolve` in case of conflict
634 Test usage of `hg resolve` in case of conflict
635 (issue4163)
635 (issue4163)
636
636
637 $ hg init issue4163
637 $ hg init issue4163
638 $ cd issue4163
638 $ cd issue4163
639 $ touch foo
639 $ touch foo
640 $ hg add foo
640 $ hg add foo
641 $ cat > foo << EOF
641 $ cat > foo << EOF
642 > one
642 > one
643 > two
643 > two
644 > three
644 > three
645 > four
645 > four
646 > five
646 > five
647 > six
647 > six
648 > seven
648 > seven
649 > height
649 > height
650 > nine
650 > nine
651 > ten
651 > ten
652 > EOF
652 > EOF
653 $ hg ci -m 'initial'
653 $ hg ci -m 'initial'
654 $ cat > foo << EOF
654 $ cat > foo << EOF
655 > one
655 > one
656 > two
656 > two
657 > THREE
657 > THREE
658 > four
658 > four
659 > five
659 > five
660 > six
660 > six
661 > seven
661 > seven
662 > height
662 > height
663 > nine
663 > nine
664 > ten
664 > ten
665 > EOF
665 > EOF
666 $ hg ci -m 'capital three'
666 $ hg ci -m 'capital three'
667 $ cat > foo << EOF
667 $ cat > foo << EOF
668 > one
668 > one
669 > two
669 > two
670 > THREE
670 > THREE
671 > four
671 > four
672 > five
672 > five
673 > six
673 > six
674 > seven
674 > seven
675 > height
675 > height
676 > nine
676 > nine
677 > TEN
677 > TEN
678 > EOF
678 > EOF
679 $ hg ci -m 'capital ten'
679 $ hg ci -m 'capital ten'
680 $ hg backout -r 'desc("capital three")' --tool internal:fail
680 $ hg backout -r 'desc("capital three")' --tool internal:fail
681 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
681 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
682 use 'hg resolve' to retry unresolved file merges
682 use 'hg resolve' to retry unresolved file merges
683 [1]
683 [1]
684 $ hg status
684 $ hg status
685 $ hg debugmergestate
685 $ hg debugmergestate
686 * version 2 records
686 * version 2 records
687 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
687 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
688 other: a30dd8addae3ce71b8667868478542bc417439e6
688 other: a30dd8addae3ce71b8667868478542bc417439e6
689 file extras: foo (ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553)
689 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
690 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
690 local path: foo (flags "")
691 local path: foo (flags "")
691 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
692 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
692 other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
693 other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
693 $ mv .hg/merge/state2 .hg/merge/state2-moved
694 $ mv .hg/merge/state2 .hg/merge/state2-moved
694 $ hg debugmergestate
695 $ hg debugmergestate
695 * version 1 records
696 * version 1 records
696 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
697 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
697 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
698 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
698 local path: foo (flags "")
699 local path: foo (flags "")
699 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
700 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
700 other path: foo (node not stored in v1 format)
701 other path: foo (node not stored in v1 format)
701 $ mv .hg/merge/state2-moved .hg/merge/state2
702 $ mv .hg/merge/state2-moved .hg/merge/state2
702 $ hg resolve -l # still unresolved
703 $ hg resolve -l # still unresolved
703 U foo
704 U foo
704 $ hg summary
705 $ hg summary
705 parent: 2:b71750c4b0fd tip
706 parent: 2:b71750c4b0fd tip
706 capital ten
707 capital ten
707 branch: default
708 branch: default
708 commit: 1 unresolved (clean)
709 commit: 1 unresolved (clean)
709 update: (current)
710 update: (current)
710 phases: 3 draft
711 phases: 3 draft
711 $ hg resolve --all --debug
712 $ hg resolve --all --debug
712 picked tool ':merge' for foo (binary False symlink False changedelete False)
713 picked tool ':merge' for foo (binary False symlink False changedelete False)
713 merging foo
714 merging foo
714 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
715 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
715 premerge successful
716 premerge successful
716 (no more unresolved files)
717 (no more unresolved files)
717 continue: hg commit
718 continue: hg commit
718 $ hg status
719 $ hg status
719 M foo
720 M foo
720 ? foo.orig
721 ? foo.orig
721 $ hg resolve -l
722 $ hg resolve -l
722 R foo
723 R foo
723 $ hg summary
724 $ hg summary
724 parent: 2:b71750c4b0fd tip
725 parent: 2:b71750c4b0fd tip
725 capital ten
726 capital ten
726 branch: default
727 branch: default
727 commit: 1 modified, 1 unknown
728 commit: 1 modified, 1 unknown
728 update: (current)
729 update: (current)
729 phases: 3 draft
730 phases: 3 draft
730 $ cat foo
731 $ cat foo
731 one
732 one
732 two
733 two
733 three
734 three
734 four
735 four
735 five
736 five
736 six
737 six
737 seven
738 seven
738 height
739 height
739 nine
740 nine
740 TEN
741 TEN
741
742
742 --no-commit shouldn't commit
743 --no-commit shouldn't commit
743
744
744 $ hg init a
745 $ hg init a
745 $ cd a
746 $ cd a
746 $ for i in 1 2 3; do
747 $ for i in 1 2 3; do
747 > touch $i
748 > touch $i
748 > hg ci -Am $i
749 > hg ci -Am $i
749 > done
750 > done
750 adding 1
751 adding 1
751 adding 2
752 adding 2
752 adding 3
753 adding 3
753 $ hg backout --no-commit .
754 $ hg backout --no-commit .
754 removing 3
755 removing 3
755 changeset cccc23d9d68f backed out, don't forget to commit.
756 changeset cccc23d9d68f backed out, don't forget to commit.
756 $ hg revert -aq
757 $ hg revert -aq
757
758
758 --no-commit can't be used with --merge
759 --no-commit can't be used with --merge
759
760
760 $ hg backout --merge --no-commit 2
761 $ hg backout --merge --no-commit 2
761 abort: cannot use --merge with --no-commit
762 abort: cannot use --merge with --no-commit
762 [255]
763 [255]
@@ -1,830 +1,830 b''
1 Create a repo with some stuff in it:
1 Create a repo with some stuff in it:
2
2
3 $ hg init a
3 $ hg init a
4 $ cd a
4 $ cd a
5 $ echo a > a
5 $ echo a > a
6 $ echo a > d
6 $ echo a > d
7 $ echo a > e
7 $ echo a > e
8 $ hg ci -qAm0
8 $ hg ci -qAm0
9 $ echo b > a
9 $ echo b > a
10 $ hg ci -m1 -u bar
10 $ hg ci -m1 -u bar
11 $ hg mv a b
11 $ hg mv a b
12 $ hg ci -m2
12 $ hg ci -m2
13 $ hg cp b c
13 $ hg cp b c
14 $ hg ci -m3 -u baz
14 $ hg ci -m3 -u baz
15 $ echo b > d
15 $ echo b > d
16 $ echo f > e
16 $ echo f > e
17 $ hg ci -m4
17 $ hg ci -m4
18 $ hg up -q 3
18 $ hg up -q 3
19 $ echo b > e
19 $ echo b > e
20 $ hg branch -q stable
20 $ hg branch -q stable
21 $ hg ci -m5
21 $ hg ci -m5
22 $ hg merge -q default --tool internal:local
22 $ hg merge -q default --tool internal:local
23 $ hg branch -q default
23 $ hg branch -q default
24 $ hg ci -m6
24 $ hg ci -m6
25 $ hg phase --public 3
25 $ hg phase --public 3
26 $ hg phase --force --secret 6
26 $ hg phase --force --secret 6
27
27
28 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
28 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
29 @ test@6.secret: 6
29 @ test@6.secret: 6
30 |\
30 |\
31 | o test@5.draft: 5
31 | o test@5.draft: 5
32 | |
32 | |
33 o | test@4.draft: 4
33 o | test@4.draft: 4
34 |/
34 |/
35 o baz@3.public: 3
35 o baz@3.public: 3
36 |
36 |
37 o test@2.public: 2
37 o test@2.public: 2
38 |
38 |
39 o bar@1.public: 1
39 o bar@1.public: 1
40 |
40 |
41 o test@0.public: 0
41 o test@0.public: 0
42
42
43
43
44 Need to specify a rev:
44 Need to specify a rev:
45
45
46 $ hg graft
46 $ hg graft
47 abort: no revisions specified
47 abort: no revisions specified
48 [255]
48 [255]
49
49
50 Can't graft ancestor:
50 Can't graft ancestor:
51
51
52 $ hg graft 1 2
52 $ hg graft 1 2
53 skipping ancestor revision 1:5d205f8b35b6
53 skipping ancestor revision 1:5d205f8b35b6
54 skipping ancestor revision 2:5c095ad7e90f
54 skipping ancestor revision 2:5c095ad7e90f
55 [255]
55 [255]
56
56
57 Specify revisions with -r:
57 Specify revisions with -r:
58
58
59 $ hg graft -r 1 -r 2
59 $ hg graft -r 1 -r 2
60 skipping ancestor revision 1:5d205f8b35b6
60 skipping ancestor revision 1:5d205f8b35b6
61 skipping ancestor revision 2:5c095ad7e90f
61 skipping ancestor revision 2:5c095ad7e90f
62 [255]
62 [255]
63
63
64 $ hg graft -r 1 2
64 $ hg graft -r 1 2
65 warning: inconsistent use of --rev might give unexpected revision ordering!
65 warning: inconsistent use of --rev might give unexpected revision ordering!
66 skipping ancestor revision 2:5c095ad7e90f
66 skipping ancestor revision 2:5c095ad7e90f
67 skipping ancestor revision 1:5d205f8b35b6
67 skipping ancestor revision 1:5d205f8b35b6
68 [255]
68 [255]
69
69
70 Can't graft with dirty wd:
70 Can't graft with dirty wd:
71
71
72 $ hg up -q 0
72 $ hg up -q 0
73 $ echo foo > a
73 $ echo foo > a
74 $ hg graft 1
74 $ hg graft 1
75 abort: uncommitted changes
75 abort: uncommitted changes
76 [255]
76 [255]
77 $ hg revert a
77 $ hg revert a
78
78
79 Graft a rename:
79 Graft a rename:
80 (this also tests that editor is invoked if '--edit' is specified)
80 (this also tests that editor is invoked if '--edit' is specified)
81
81
82 $ hg status --rev "2^1" --rev 2
82 $ hg status --rev "2^1" --rev 2
83 A b
83 A b
84 R a
84 R a
85 $ HGEDITOR=cat hg graft 2 -u foo --edit
85 $ HGEDITOR=cat hg graft 2 -u foo --edit
86 grafting 2:5c095ad7e90f "2"
86 grafting 2:5c095ad7e90f "2"
87 merging a and b to b
87 merging a and b to b
88 2
88 2
89
89
90
90
91 HG: Enter commit message. Lines beginning with 'HG:' are removed.
91 HG: Enter commit message. Lines beginning with 'HG:' are removed.
92 HG: Leave message empty to abort commit.
92 HG: Leave message empty to abort commit.
93 HG: --
93 HG: --
94 HG: user: foo
94 HG: user: foo
95 HG: branch 'default'
95 HG: branch 'default'
96 HG: added b
96 HG: added b
97 HG: removed a
97 HG: removed a
98 $ hg export tip --git
98 $ hg export tip --git
99 # HG changeset patch
99 # HG changeset patch
100 # User foo
100 # User foo
101 # Date 0 0
101 # Date 0 0
102 # Thu Jan 01 00:00:00 1970 +0000
102 # Thu Jan 01 00:00:00 1970 +0000
103 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
103 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
104 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
104 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
105 2
105 2
106
106
107 diff --git a/a b/b
107 diff --git a/a b/b
108 rename from a
108 rename from a
109 rename to b
109 rename to b
110
110
111 Look for extra:source
111 Look for extra:source
112
112
113 $ hg log --debug -r tip
113 $ hg log --debug -r tip
114 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
114 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
115 tag: tip
115 tag: tip
116 phase: draft
116 phase: draft
117 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
117 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
118 parent: -1:0000000000000000000000000000000000000000
118 parent: -1:0000000000000000000000000000000000000000
119 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
119 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
120 user: foo
120 user: foo
121 date: Thu Jan 01 00:00:00 1970 +0000
121 date: Thu Jan 01 00:00:00 1970 +0000
122 files+: b
122 files+: b
123 files-: a
123 files-: a
124 extra: branch=default
124 extra: branch=default
125 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
125 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
126 description:
126 description:
127 2
127 2
128
128
129
129
130
130
131 Graft out of order, skipping a merge and a duplicate
131 Graft out of order, skipping a merge and a duplicate
132 (this also tests that editor is not invoked if '--edit' is not specified)
132 (this also tests that editor is not invoked if '--edit' is not specified)
133
133
134 $ hg graft 1 5 4 3 'merge()' 2 -n
134 $ hg graft 1 5 4 3 'merge()' 2 -n
135 skipping ungraftable merge revision 6
135 skipping ungraftable merge revision 6
136 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
136 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
137 grafting 1:5d205f8b35b6 "1"
137 grafting 1:5d205f8b35b6 "1"
138 grafting 5:97f8bfe72746 "5"
138 grafting 5:97f8bfe72746 "5"
139 grafting 4:9c233e8e184d "4"
139 grafting 4:9c233e8e184d "4"
140 grafting 3:4c60f11aa304 "3"
140 grafting 3:4c60f11aa304 "3"
141
141
142 $ HGEDITOR=cat hg graft 1 5 'merge()' 2 --debug
142 $ HGEDITOR=cat hg graft 1 5 'merge()' 2 --debug
143 skipping ungraftable merge revision 6
143 skipping ungraftable merge revision 6
144 scanning for duplicate grafts
144 scanning for duplicate grafts
145 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
145 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
146 grafting 1:5d205f8b35b6 "1"
146 grafting 1:5d205f8b35b6 "1"
147 searching for copies back to rev 1
147 searching for copies back to rev 1
148 unmatched files in local:
148 unmatched files in local:
149 b
149 b
150 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
150 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
151 src: 'a' -> dst: 'b' *
151 src: 'a' -> dst: 'b' *
152 checking for directory renames
152 checking for directory renames
153 resolving manifests
153 resolving manifests
154 branchmerge: True, force: True, partial: False
154 branchmerge: True, force: True, partial: False
155 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
155 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
156 preserving b for resolve of b
156 preserving b for resolve of b
157 b: local copied/moved from a -> m (premerge)
157 b: local copied/moved from a -> m (premerge)
158 picked tool ':merge' for b (binary False symlink False changedelete False)
158 picked tool ':merge' for b (binary False symlink False changedelete False)
159 merging b and a to b
159 merging b and a to b
160 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
160 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
161 premerge successful
161 premerge successful
162 committing files:
162 committing files:
163 b
163 b
164 committing manifest
164 committing manifest
165 committing changelog
165 committing changelog
166 grafting 5:97f8bfe72746 "5"
166 grafting 5:97f8bfe72746 "5"
167 searching for copies back to rev 1
167 searching for copies back to rev 1
168 resolving manifests
168 resolving manifests
169 branchmerge: True, force: True, partial: False
169 branchmerge: True, force: True, partial: False
170 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
170 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
171 e: remote is newer -> g
171 e: remote is newer -> g
172 getting e
172 getting e
173 b: remote unchanged -> k
173 b: remote unchanged -> k
174 committing files:
174 committing files:
175 e
175 e
176 committing manifest
176 committing manifest
177 committing changelog
177 committing changelog
178 $ HGEDITOR=cat hg graft 4 3 --log --debug
178 $ HGEDITOR=cat hg graft 4 3 --log --debug
179 scanning for duplicate grafts
179 scanning for duplicate grafts
180 grafting 4:9c233e8e184d "4"
180 grafting 4:9c233e8e184d "4"
181 searching for copies back to rev 1
181 searching for copies back to rev 1
182 resolving manifests
182 resolving manifests
183 branchmerge: True, force: True, partial: False
183 branchmerge: True, force: True, partial: False
184 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
184 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
185 preserving e for resolve of e
185 preserving e for resolve of e
186 d: remote is newer -> g
186 d: remote is newer -> g
187 getting d
187 getting d
188 b: remote unchanged -> k
188 b: remote unchanged -> k
189 e: versions differ -> m (premerge)
189 e: versions differ -> m (premerge)
190 picked tool ':merge' for e (binary False symlink False changedelete False)
190 picked tool ':merge' for e (binary False symlink False changedelete False)
191 merging e
191 merging e
192 my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
192 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
193 e: versions differ -> m (merge)
193 e: versions differ -> m (merge)
194 picked tool ':merge' for e (binary False symlink False changedelete False)
194 picked tool ':merge' for e (binary False symlink False changedelete False)
195 my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
195 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
196 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
196 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
197 abort: unresolved conflicts, can't continue
197 abort: unresolved conflicts, can't continue
198 (use hg resolve and hg graft --continue --log)
198 (use hg resolve and hg graft --continue --log)
199 [255]
199 [255]
200
200
201 Summary should mention graft:
201 Summary should mention graft:
202
202
203 $ hg summary |grep graft
203 $ hg summary |grep graft
204 commit: 2 modified, 2 unknown, 1 unresolved (graft in progress)
204 commit: 2 modified, 2 unknown, 1 unresolved (graft in progress)
205
205
206 Commit while interrupted should fail:
206 Commit while interrupted should fail:
207
207
208 $ hg ci -m 'commit interrupted graft'
208 $ hg ci -m 'commit interrupted graft'
209 abort: graft in progress
209 abort: graft in progress
210 (use 'hg graft --continue' or 'hg update' to abort)
210 (use 'hg graft --continue' or 'hg update' to abort)
211 [255]
211 [255]
212
212
213 Abort the graft and try committing:
213 Abort the graft and try committing:
214
214
215 $ hg up -C .
215 $ hg up -C .
216 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
216 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
217 $ echo c >> e
217 $ echo c >> e
218 $ hg ci -mtest
218 $ hg ci -mtest
219
219
220 $ hg strip . --config extensions.strip=
220 $ hg strip . --config extensions.strip=
221 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
222 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
223
223
224 Graft again:
224 Graft again:
225
225
226 $ hg graft 1 5 4 3 'merge()' 2
226 $ hg graft 1 5 4 3 'merge()' 2
227 skipping ungraftable merge revision 6
227 skipping ungraftable merge revision 6
228 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
228 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
229 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
229 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
230 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
230 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
231 grafting 4:9c233e8e184d "4"
231 grafting 4:9c233e8e184d "4"
232 merging e
232 merging e
233 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
233 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
234 abort: unresolved conflicts, can't continue
234 abort: unresolved conflicts, can't continue
235 (use hg resolve and hg graft --continue)
235 (use hg resolve and hg graft --continue)
236 [255]
236 [255]
237
237
238 Continue without resolve should fail:
238 Continue without resolve should fail:
239
239
240 $ hg graft -c
240 $ hg graft -c
241 grafting 4:9c233e8e184d "4"
241 grafting 4:9c233e8e184d "4"
242 abort: unresolved merge conflicts (see "hg help resolve")
242 abort: unresolved merge conflicts (see "hg help resolve")
243 [255]
243 [255]
244
244
245 Fix up:
245 Fix up:
246
246
247 $ echo b > e
247 $ echo b > e
248 $ hg resolve -m e
248 $ hg resolve -m e
249 (no more unresolved files)
249 (no more unresolved files)
250 continue: hg graft --continue
250 continue: hg graft --continue
251
251
252 Continue with a revision should fail:
252 Continue with a revision should fail:
253
253
254 $ hg graft -c 6
254 $ hg graft -c 6
255 abort: can't specify --continue and revisions
255 abort: can't specify --continue and revisions
256 [255]
256 [255]
257
257
258 $ hg graft -c -r 6
258 $ hg graft -c -r 6
259 abort: can't specify --continue and revisions
259 abort: can't specify --continue and revisions
260 [255]
260 [255]
261
261
262 Continue for real, clobber usernames
262 Continue for real, clobber usernames
263
263
264 $ hg graft -c -U
264 $ hg graft -c -U
265 grafting 4:9c233e8e184d "4"
265 grafting 4:9c233e8e184d "4"
266 grafting 3:4c60f11aa304 "3"
266 grafting 3:4c60f11aa304 "3"
267
267
268 Compare with original:
268 Compare with original:
269
269
270 $ hg diff -r 6
270 $ hg diff -r 6
271 $ hg status --rev 0:. -C
271 $ hg status --rev 0:. -C
272 M d
272 M d
273 M e
273 M e
274 A b
274 A b
275 a
275 a
276 A c
276 A c
277 a
277 a
278 R a
278 R a
279
279
280 View graph:
280 View graph:
281
281
282 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
282 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
283 @ test@11.draft: 3
283 @ test@11.draft: 3
284 |
284 |
285 o test@10.draft: 4
285 o test@10.draft: 4
286 |
286 |
287 o test@9.draft: 5
287 o test@9.draft: 5
288 |
288 |
289 o bar@8.draft: 1
289 o bar@8.draft: 1
290 |
290 |
291 o foo@7.draft: 2
291 o foo@7.draft: 2
292 |
292 |
293 | o test@6.secret: 6
293 | o test@6.secret: 6
294 | |\
294 | |\
295 | | o test@5.draft: 5
295 | | o test@5.draft: 5
296 | | |
296 | | |
297 | o | test@4.draft: 4
297 | o | test@4.draft: 4
298 | |/
298 | |/
299 | o baz@3.public: 3
299 | o baz@3.public: 3
300 | |
300 | |
301 | o test@2.public: 2
301 | o test@2.public: 2
302 | |
302 | |
303 | o bar@1.public: 1
303 | o bar@1.public: 1
304 |/
304 |/
305 o test@0.public: 0
305 o test@0.public: 0
306
306
307 Graft again onto another branch should preserve the original source
307 Graft again onto another branch should preserve the original source
308 $ hg up -q 0
308 $ hg up -q 0
309 $ echo 'g'>g
309 $ echo 'g'>g
310 $ hg add g
310 $ hg add g
311 $ hg ci -m 7
311 $ hg ci -m 7
312 created new head
312 created new head
313 $ hg graft 7
313 $ hg graft 7
314 grafting 7:ef0ef43d49e7 "2"
314 grafting 7:ef0ef43d49e7 "2"
315
315
316 $ hg log -r 7 --template '{rev}:{node}\n'
316 $ hg log -r 7 --template '{rev}:{node}\n'
317 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
317 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
318 $ hg log -r 2 --template '{rev}:{node}\n'
318 $ hg log -r 2 --template '{rev}:{node}\n'
319 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
319 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
320
320
321 $ hg log --debug -r tip
321 $ hg log --debug -r tip
322 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
322 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
323 tag: tip
323 tag: tip
324 phase: draft
324 phase: draft
325 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
325 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
326 parent: -1:0000000000000000000000000000000000000000
326 parent: -1:0000000000000000000000000000000000000000
327 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
327 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
328 user: foo
328 user: foo
329 date: Thu Jan 01 00:00:00 1970 +0000
329 date: Thu Jan 01 00:00:00 1970 +0000
330 files+: b
330 files+: b
331 files-: a
331 files-: a
332 extra: branch=default
332 extra: branch=default
333 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
333 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
334 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
334 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
335 description:
335 description:
336 2
336 2
337
337
338
338
339 Disallow grafting an already grafted cset onto its original branch
339 Disallow grafting an already grafted cset onto its original branch
340 $ hg up -q 6
340 $ hg up -q 6
341 $ hg graft 7
341 $ hg graft 7
342 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
342 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
343 [255]
343 [255]
344
344
345 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13
345 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13
346 --- */hg-5c095ad7e90f.patch * +0000 (glob)
346 --- */hg-5c095ad7e90f.patch * +0000 (glob)
347 +++ */hg-7a4785234d87.patch * +0000 (glob)
347 +++ */hg-7a4785234d87.patch * +0000 (glob)
348 @@ -1,18 +1,18 @@
348 @@ -1,18 +1,18 @@
349 # HG changeset patch
349 # HG changeset patch
350 -# User test
350 -# User test
351 +# User foo
351 +# User foo
352 # Date 0 0
352 # Date 0 0
353 # Thu Jan 01 00:00:00 1970 +0000
353 # Thu Jan 01 00:00:00 1970 +0000
354 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
354 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
355 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
355 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
356 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
356 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
357 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
357 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
358 2
358 2
359
359
360 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
360 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
361 +diff -r b592ea63bb0c -r 7a4785234d87 a
361 +diff -r b592ea63bb0c -r 7a4785234d87 a
362 --- a/a Thu Jan 01 00:00:00 1970 +0000
362 --- a/a Thu Jan 01 00:00:00 1970 +0000
363 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
363 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
364 @@ -1,1 +0,0 @@
364 @@ -1,1 +0,0 @@
365 --b
365 --b
366 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
366 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
367 +-a
367 +-a
368 +diff -r b592ea63bb0c -r 7a4785234d87 b
368 +diff -r b592ea63bb0c -r 7a4785234d87 b
369 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
369 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
370 +++ b/b Thu Jan 01 00:00:00 1970 +0000
370 +++ b/b Thu Jan 01 00:00:00 1970 +0000
371 @@ -0,0 +1,1 @@
371 @@ -0,0 +1,1 @@
372 -+b
372 -+b
373 ++a
373 ++a
374 [1]
374 [1]
375
375
376 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
376 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
377 --- */hg-5c095ad7e90f.patch * +0000 (glob)
377 --- */hg-5c095ad7e90f.patch * +0000 (glob)
378 +++ */hg-7a4785234d87.patch * +0000 (glob)
378 +++ */hg-7a4785234d87.patch * +0000 (glob)
379 @@ -1,8 +1,8 @@
379 @@ -1,8 +1,8 @@
380 # HG changeset patch
380 # HG changeset patch
381 -# User test
381 -# User test
382 +# User foo
382 +# User foo
383 # Date 0 0
383 # Date 0 0
384 # Thu Jan 01 00:00:00 1970 +0000
384 # Thu Jan 01 00:00:00 1970 +0000
385 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
385 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
386 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
386 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
387 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
387 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
388 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
388 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
389 2
389 2
390
390
391 [1]
391 [1]
392
392
393 Disallow grafting already grafted csets with the same origin onto each other
393 Disallow grafting already grafted csets with the same origin onto each other
394 $ hg up -q 13
394 $ hg up -q 13
395 $ hg graft 2
395 $ hg graft 2
396 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
396 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
397 [255]
397 [255]
398 $ hg graft 7
398 $ hg graft 7
399 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
399 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
400 [255]
400 [255]
401
401
402 $ hg up -q 7
402 $ hg up -q 7
403 $ hg graft 2
403 $ hg graft 2
404 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
404 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
405 [255]
405 [255]
406 $ hg graft tip
406 $ hg graft tip
407 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
407 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
408 [255]
408 [255]
409
409
410 Graft with --log
410 Graft with --log
411
411
412 $ hg up -Cq 1
412 $ hg up -Cq 1
413 $ hg graft 3 --log -u foo
413 $ hg graft 3 --log -u foo
414 grafting 3:4c60f11aa304 "3"
414 grafting 3:4c60f11aa304 "3"
415 warning: can't find ancestor for 'c' copied from 'b'!
415 warning: can't find ancestor for 'c' copied from 'b'!
416 $ hg log --template '{rev} {parents} {desc}\n' -r tip
416 $ hg log --template '{rev} {parents} {desc}\n' -r tip
417 14 1:5d205f8b35b6 3
417 14 1:5d205f8b35b6 3
418 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
418 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
419
419
420 Resolve conflicted graft
420 Resolve conflicted graft
421 $ hg up -q 0
421 $ hg up -q 0
422 $ echo b > a
422 $ echo b > a
423 $ hg ci -m 8
423 $ hg ci -m 8
424 created new head
424 created new head
425 $ echo c > a
425 $ echo c > a
426 $ hg ci -m 9
426 $ hg ci -m 9
427 $ hg graft 1 --tool internal:fail
427 $ hg graft 1 --tool internal:fail
428 grafting 1:5d205f8b35b6 "1"
428 grafting 1:5d205f8b35b6 "1"
429 abort: unresolved conflicts, can't continue
429 abort: unresolved conflicts, can't continue
430 (use hg resolve and hg graft --continue)
430 (use hg resolve and hg graft --continue)
431 [255]
431 [255]
432 $ hg resolve --all
432 $ hg resolve --all
433 merging a
433 merging a
434 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
434 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
435 [1]
435 [1]
436 $ cat a
436 $ cat a
437 <<<<<<< local: aaa4406d4f0a - test: 9
437 <<<<<<< local: aaa4406d4f0a - test: 9
438 c
438 c
439 =======
439 =======
440 b
440 b
441 >>>>>>> other: 5d205f8b35b6 - bar: 1
441 >>>>>>> other: 5d205f8b35b6 - bar: 1
442 $ echo b > a
442 $ echo b > a
443 $ hg resolve -m a
443 $ hg resolve -m a
444 (no more unresolved files)
444 (no more unresolved files)
445 continue: hg graft --continue
445 continue: hg graft --continue
446 $ hg graft -c
446 $ hg graft -c
447 grafting 1:5d205f8b35b6 "1"
447 grafting 1:5d205f8b35b6 "1"
448 $ hg export tip --git
448 $ hg export tip --git
449 # HG changeset patch
449 # HG changeset patch
450 # User bar
450 # User bar
451 # Date 0 0
451 # Date 0 0
452 # Thu Jan 01 00:00:00 1970 +0000
452 # Thu Jan 01 00:00:00 1970 +0000
453 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
453 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
454 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
454 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
455 1
455 1
456
456
457 diff --git a/a b/a
457 diff --git a/a b/a
458 --- a/a
458 --- a/a
459 +++ b/a
459 +++ b/a
460 @@ -1,1 +1,1 @@
460 @@ -1,1 +1,1 @@
461 -c
461 -c
462 +b
462 +b
463
463
464 Resolve conflicted graft with rename
464 Resolve conflicted graft with rename
465 $ echo c > a
465 $ echo c > a
466 $ hg ci -m 10
466 $ hg ci -m 10
467 $ hg graft 2 --tool internal:fail
467 $ hg graft 2 --tool internal:fail
468 grafting 2:5c095ad7e90f "2"
468 grafting 2:5c095ad7e90f "2"
469 abort: unresolved conflicts, can't continue
469 abort: unresolved conflicts, can't continue
470 (use hg resolve and hg graft --continue)
470 (use hg resolve and hg graft --continue)
471 [255]
471 [255]
472 $ hg resolve --all
472 $ hg resolve --all
473 merging a and b to b
473 merging a and b to b
474 (no more unresolved files)
474 (no more unresolved files)
475 continue: hg graft --continue
475 continue: hg graft --continue
476 $ hg graft -c
476 $ hg graft -c
477 grafting 2:5c095ad7e90f "2"
477 grafting 2:5c095ad7e90f "2"
478 $ hg export tip --git
478 $ hg export tip --git
479 # HG changeset patch
479 # HG changeset patch
480 # User test
480 # User test
481 # Date 0 0
481 # Date 0 0
482 # Thu Jan 01 00:00:00 1970 +0000
482 # Thu Jan 01 00:00:00 1970 +0000
483 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
483 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
484 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
484 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
485 2
485 2
486
486
487 diff --git a/a b/b
487 diff --git a/a b/b
488 rename from a
488 rename from a
489 rename to b
489 rename to b
490
490
491 Test simple origin(), with and without args
491 Test simple origin(), with and without args
492 $ hg log -r 'origin()'
492 $ hg log -r 'origin()'
493 changeset: 1:5d205f8b35b6
493 changeset: 1:5d205f8b35b6
494 user: bar
494 user: bar
495 date: Thu Jan 01 00:00:00 1970 +0000
495 date: Thu Jan 01 00:00:00 1970 +0000
496 summary: 1
496 summary: 1
497
497
498 changeset: 2:5c095ad7e90f
498 changeset: 2:5c095ad7e90f
499 user: test
499 user: test
500 date: Thu Jan 01 00:00:00 1970 +0000
500 date: Thu Jan 01 00:00:00 1970 +0000
501 summary: 2
501 summary: 2
502
502
503 changeset: 3:4c60f11aa304
503 changeset: 3:4c60f11aa304
504 user: baz
504 user: baz
505 date: Thu Jan 01 00:00:00 1970 +0000
505 date: Thu Jan 01 00:00:00 1970 +0000
506 summary: 3
506 summary: 3
507
507
508 changeset: 4:9c233e8e184d
508 changeset: 4:9c233e8e184d
509 user: test
509 user: test
510 date: Thu Jan 01 00:00:00 1970 +0000
510 date: Thu Jan 01 00:00:00 1970 +0000
511 summary: 4
511 summary: 4
512
512
513 changeset: 5:97f8bfe72746
513 changeset: 5:97f8bfe72746
514 branch: stable
514 branch: stable
515 parent: 3:4c60f11aa304
515 parent: 3:4c60f11aa304
516 user: test
516 user: test
517 date: Thu Jan 01 00:00:00 1970 +0000
517 date: Thu Jan 01 00:00:00 1970 +0000
518 summary: 5
518 summary: 5
519
519
520 $ hg log -r 'origin(7)'
520 $ hg log -r 'origin(7)'
521 changeset: 2:5c095ad7e90f
521 changeset: 2:5c095ad7e90f
522 user: test
522 user: test
523 date: Thu Jan 01 00:00:00 1970 +0000
523 date: Thu Jan 01 00:00:00 1970 +0000
524 summary: 2
524 summary: 2
525
525
526 Now transplant a graft to test following through copies
526 Now transplant a graft to test following through copies
527 $ hg up -q 0
527 $ hg up -q 0
528 $ hg branch -q dev
528 $ hg branch -q dev
529 $ hg ci -qm "dev branch"
529 $ hg ci -qm "dev branch"
530 $ hg --config extensions.transplant= transplant -q 7
530 $ hg --config extensions.transplant= transplant -q 7
531 $ hg log -r 'origin(.)'
531 $ hg log -r 'origin(.)'
532 changeset: 2:5c095ad7e90f
532 changeset: 2:5c095ad7e90f
533 user: test
533 user: test
534 date: Thu Jan 01 00:00:00 1970 +0000
534 date: Thu Jan 01 00:00:00 1970 +0000
535 summary: 2
535 summary: 2
536
536
537 Test that the graft and transplant markers in extra are converted, allowing
537 Test that the graft and transplant markers in extra are converted, allowing
538 origin() to still work. Note that these recheck the immediately preceeding two
538 origin() to still work. Note that these recheck the immediately preceeding two
539 tests.
539 tests.
540 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
540 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
541
541
542 The graft case
542 The graft case
543 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
543 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
544 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
544 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
545 branch=default
545 branch=default
546 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
546 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
547 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
547 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
548 $ hg -R ../converted log -r 'origin(7)'
548 $ hg -R ../converted log -r 'origin(7)'
549 changeset: 2:e0213322b2c1
549 changeset: 2:e0213322b2c1
550 user: test
550 user: test
551 date: Thu Jan 01 00:00:00 1970 +0000
551 date: Thu Jan 01 00:00:00 1970 +0000
552 summary: 2
552 summary: 2
553
553
554 Test that template correctly expands more than one 'extra' (issue4362), and that
554 Test that template correctly expands more than one 'extra' (issue4362), and that
555 'intermediate-source' is converted.
555 'intermediate-source' is converted.
556 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
556 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
557 Extra: branch=default
557 Extra: branch=default
558 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
558 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
559 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
559 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
560 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
560 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
561
561
562 The transplant case
562 The transplant case
563 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
563 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
564 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
564 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
565 branch=dev
565 branch=dev
566 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
566 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
567 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac (esc)
567 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac (esc)
568 `h\x9b (esc)
568 `h\x9b (esc)
569 $ hg -R ../converted log -r 'origin(tip)'
569 $ hg -R ../converted log -r 'origin(tip)'
570 changeset: 2:e0213322b2c1
570 changeset: 2:e0213322b2c1
571 user: test
571 user: test
572 date: Thu Jan 01 00:00:00 1970 +0000
572 date: Thu Jan 01 00:00:00 1970 +0000
573 summary: 2
573 summary: 2
574
574
575
575
576 Test simple destination
576 Test simple destination
577 $ hg log -r 'destination()'
577 $ hg log -r 'destination()'
578 changeset: 7:ef0ef43d49e7
578 changeset: 7:ef0ef43d49e7
579 parent: 0:68795b066622
579 parent: 0:68795b066622
580 user: foo
580 user: foo
581 date: Thu Jan 01 00:00:00 1970 +0000
581 date: Thu Jan 01 00:00:00 1970 +0000
582 summary: 2
582 summary: 2
583
583
584 changeset: 8:6b9e5368ca4e
584 changeset: 8:6b9e5368ca4e
585 user: bar
585 user: bar
586 date: Thu Jan 01 00:00:00 1970 +0000
586 date: Thu Jan 01 00:00:00 1970 +0000
587 summary: 1
587 summary: 1
588
588
589 changeset: 9:1905859650ec
589 changeset: 9:1905859650ec
590 user: test
590 user: test
591 date: Thu Jan 01 00:00:00 1970 +0000
591 date: Thu Jan 01 00:00:00 1970 +0000
592 summary: 5
592 summary: 5
593
593
594 changeset: 10:52dc0b4c6907
594 changeset: 10:52dc0b4c6907
595 user: test
595 user: test
596 date: Thu Jan 01 00:00:00 1970 +0000
596 date: Thu Jan 01 00:00:00 1970 +0000
597 summary: 4
597 summary: 4
598
598
599 changeset: 11:882b35362a6b
599 changeset: 11:882b35362a6b
600 user: test
600 user: test
601 date: Thu Jan 01 00:00:00 1970 +0000
601 date: Thu Jan 01 00:00:00 1970 +0000
602 summary: 3
602 summary: 3
603
603
604 changeset: 13:7a4785234d87
604 changeset: 13:7a4785234d87
605 user: foo
605 user: foo
606 date: Thu Jan 01 00:00:00 1970 +0000
606 date: Thu Jan 01 00:00:00 1970 +0000
607 summary: 2
607 summary: 2
608
608
609 changeset: 14:f64defefacee
609 changeset: 14:f64defefacee
610 parent: 1:5d205f8b35b6
610 parent: 1:5d205f8b35b6
611 user: foo
611 user: foo
612 date: Thu Jan 01 00:00:00 1970 +0000
612 date: Thu Jan 01 00:00:00 1970 +0000
613 summary: 3
613 summary: 3
614
614
615 changeset: 17:f67661df0c48
615 changeset: 17:f67661df0c48
616 user: bar
616 user: bar
617 date: Thu Jan 01 00:00:00 1970 +0000
617 date: Thu Jan 01 00:00:00 1970 +0000
618 summary: 1
618 summary: 1
619
619
620 changeset: 19:9627f653b421
620 changeset: 19:9627f653b421
621 user: test
621 user: test
622 date: Thu Jan 01 00:00:00 1970 +0000
622 date: Thu Jan 01 00:00:00 1970 +0000
623 summary: 2
623 summary: 2
624
624
625 changeset: 21:7e61b508e709
625 changeset: 21:7e61b508e709
626 branch: dev
626 branch: dev
627 tag: tip
627 tag: tip
628 user: foo
628 user: foo
629 date: Thu Jan 01 00:00:00 1970 +0000
629 date: Thu Jan 01 00:00:00 1970 +0000
630 summary: 2
630 summary: 2
631
631
632 $ hg log -r 'destination(2)'
632 $ hg log -r 'destination(2)'
633 changeset: 7:ef0ef43d49e7
633 changeset: 7:ef0ef43d49e7
634 parent: 0:68795b066622
634 parent: 0:68795b066622
635 user: foo
635 user: foo
636 date: Thu Jan 01 00:00:00 1970 +0000
636 date: Thu Jan 01 00:00:00 1970 +0000
637 summary: 2
637 summary: 2
638
638
639 changeset: 13:7a4785234d87
639 changeset: 13:7a4785234d87
640 user: foo
640 user: foo
641 date: Thu Jan 01 00:00:00 1970 +0000
641 date: Thu Jan 01 00:00:00 1970 +0000
642 summary: 2
642 summary: 2
643
643
644 changeset: 19:9627f653b421
644 changeset: 19:9627f653b421
645 user: test
645 user: test
646 date: Thu Jan 01 00:00:00 1970 +0000
646 date: Thu Jan 01 00:00:00 1970 +0000
647 summary: 2
647 summary: 2
648
648
649 changeset: 21:7e61b508e709
649 changeset: 21:7e61b508e709
650 branch: dev
650 branch: dev
651 tag: tip
651 tag: tip
652 user: foo
652 user: foo
653 date: Thu Jan 01 00:00:00 1970 +0000
653 date: Thu Jan 01 00:00:00 1970 +0000
654 summary: 2
654 summary: 2
655
655
656 Transplants of grafts can find a destination...
656 Transplants of grafts can find a destination...
657 $ hg log -r 'destination(7)'
657 $ hg log -r 'destination(7)'
658 changeset: 21:7e61b508e709
658 changeset: 21:7e61b508e709
659 branch: dev
659 branch: dev
660 tag: tip
660 tag: tip
661 user: foo
661 user: foo
662 date: Thu Jan 01 00:00:00 1970 +0000
662 date: Thu Jan 01 00:00:00 1970 +0000
663 summary: 2
663 summary: 2
664
664
665 ... grafts of grafts unfortunately can't
665 ... grafts of grafts unfortunately can't
666 $ hg graft -q 13
666 $ hg graft -q 13
667 warning: can't find ancestor for 'b' copied from 'a'!
667 warning: can't find ancestor for 'b' copied from 'a'!
668 $ hg log -r 'destination(13)'
668 $ hg log -r 'destination(13)'
669 All copies of a cset
669 All copies of a cset
670 $ hg log -r 'origin(13) or destination(origin(13))'
670 $ hg log -r 'origin(13) or destination(origin(13))'
671 changeset: 2:5c095ad7e90f
671 changeset: 2:5c095ad7e90f
672 user: test
672 user: test
673 date: Thu Jan 01 00:00:00 1970 +0000
673 date: Thu Jan 01 00:00:00 1970 +0000
674 summary: 2
674 summary: 2
675
675
676 changeset: 7:ef0ef43d49e7
676 changeset: 7:ef0ef43d49e7
677 parent: 0:68795b066622
677 parent: 0:68795b066622
678 user: foo
678 user: foo
679 date: Thu Jan 01 00:00:00 1970 +0000
679 date: Thu Jan 01 00:00:00 1970 +0000
680 summary: 2
680 summary: 2
681
681
682 changeset: 13:7a4785234d87
682 changeset: 13:7a4785234d87
683 user: foo
683 user: foo
684 date: Thu Jan 01 00:00:00 1970 +0000
684 date: Thu Jan 01 00:00:00 1970 +0000
685 summary: 2
685 summary: 2
686
686
687 changeset: 19:9627f653b421
687 changeset: 19:9627f653b421
688 user: test
688 user: test
689 date: Thu Jan 01 00:00:00 1970 +0000
689 date: Thu Jan 01 00:00:00 1970 +0000
690 summary: 2
690 summary: 2
691
691
692 changeset: 21:7e61b508e709
692 changeset: 21:7e61b508e709
693 branch: dev
693 branch: dev
694 user: foo
694 user: foo
695 date: Thu Jan 01 00:00:00 1970 +0000
695 date: Thu Jan 01 00:00:00 1970 +0000
696 summary: 2
696 summary: 2
697
697
698 changeset: 22:d1cb6591fa4b
698 changeset: 22:d1cb6591fa4b
699 branch: dev
699 branch: dev
700 tag: tip
700 tag: tip
701 user: foo
701 user: foo
702 date: Thu Jan 01 00:00:00 1970 +0000
702 date: Thu Jan 01 00:00:00 1970 +0000
703 summary: 2
703 summary: 2
704
704
705
705
706 graft works on complex revset
706 graft works on complex revset
707
707
708 $ hg graft 'origin(13) or destination(origin(13))'
708 $ hg graft 'origin(13) or destination(origin(13))'
709 skipping ancestor revision 21:7e61b508e709
709 skipping ancestor revision 21:7e61b508e709
710 skipping ancestor revision 22:d1cb6591fa4b
710 skipping ancestor revision 22:d1cb6591fa4b
711 skipping revision 2:5c095ad7e90f (already grafted to 22:d1cb6591fa4b)
711 skipping revision 2:5c095ad7e90f (already grafted to 22:d1cb6591fa4b)
712 grafting 7:ef0ef43d49e7 "2"
712 grafting 7:ef0ef43d49e7 "2"
713 warning: can't find ancestor for 'b' copied from 'a'!
713 warning: can't find ancestor for 'b' copied from 'a'!
714 grafting 13:7a4785234d87 "2"
714 grafting 13:7a4785234d87 "2"
715 warning: can't find ancestor for 'b' copied from 'a'!
715 warning: can't find ancestor for 'b' copied from 'a'!
716 grafting 19:9627f653b421 "2"
716 grafting 19:9627f653b421 "2"
717 merging b
717 merging b
718 warning: can't find ancestor for 'b' copied from 'a'!
718 warning: can't find ancestor for 'b' copied from 'a'!
719
719
720 graft with --force (still doesn't graft merges)
720 graft with --force (still doesn't graft merges)
721
721
722 $ hg graft 19 0 6
722 $ hg graft 19 0 6
723 skipping ungraftable merge revision 6
723 skipping ungraftable merge revision 6
724 skipping ancestor revision 0:68795b066622
724 skipping ancestor revision 0:68795b066622
725 skipping already grafted revision 19:9627f653b421 (22:d1cb6591fa4b also has origin 2:5c095ad7e90f)
725 skipping already grafted revision 19:9627f653b421 (22:d1cb6591fa4b also has origin 2:5c095ad7e90f)
726 [255]
726 [255]
727 $ hg graft 19 0 6 --force
727 $ hg graft 19 0 6 --force
728 skipping ungraftable merge revision 6
728 skipping ungraftable merge revision 6
729 grafting 19:9627f653b421 "2"
729 grafting 19:9627f653b421 "2"
730 merging b
730 merging b
731 warning: can't find ancestor for 'b' copied from 'a'!
731 warning: can't find ancestor for 'b' copied from 'a'!
732 grafting 0:68795b066622 "0"
732 grafting 0:68795b066622 "0"
733
733
734 graft --force after backout
734 graft --force after backout
735
735
736 $ echo abc > a
736 $ echo abc > a
737 $ hg ci -m 28
737 $ hg ci -m 28
738 $ hg backout 28
738 $ hg backout 28
739 reverting a
739 reverting a
740 changeset 29:53177ba928f6 backs out changeset 28:50a516bb8b57
740 changeset 29:53177ba928f6 backs out changeset 28:50a516bb8b57
741 $ hg graft 28
741 $ hg graft 28
742 skipping ancestor revision 28:50a516bb8b57
742 skipping ancestor revision 28:50a516bb8b57
743 [255]
743 [255]
744 $ hg graft 28 --force
744 $ hg graft 28 --force
745 grafting 28:50a516bb8b57 "28"
745 grafting 28:50a516bb8b57 "28"
746 merging a
746 merging a
747 $ cat a
747 $ cat a
748 abc
748 abc
749
749
750 graft --continue after --force
750 graft --continue after --force
751
751
752 $ echo def > a
752 $ echo def > a
753 $ hg ci -m 31
753 $ hg ci -m 31
754 $ hg graft 28 --force --tool internal:fail
754 $ hg graft 28 --force --tool internal:fail
755 grafting 28:50a516bb8b57 "28"
755 grafting 28:50a516bb8b57 "28"
756 abort: unresolved conflicts, can't continue
756 abort: unresolved conflicts, can't continue
757 (use hg resolve and hg graft --continue)
757 (use hg resolve and hg graft --continue)
758 [255]
758 [255]
759 $ hg resolve --all
759 $ hg resolve --all
760 merging a
760 merging a
761 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
761 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
762 [1]
762 [1]
763 $ echo abc > a
763 $ echo abc > a
764 $ hg resolve -m a
764 $ hg resolve -m a
765 (no more unresolved files)
765 (no more unresolved files)
766 continue: hg graft --continue
766 continue: hg graft --continue
767 $ hg graft -c
767 $ hg graft -c
768 grafting 28:50a516bb8b57 "28"
768 grafting 28:50a516bb8b57 "28"
769 $ cat a
769 $ cat a
770 abc
770 abc
771
771
772 Continue testing same origin policy, using revision numbers from test above
772 Continue testing same origin policy, using revision numbers from test above
773 but do some destructive editing of the repo:
773 but do some destructive editing of the repo:
774
774
775 $ hg up -qC 7
775 $ hg up -qC 7
776 $ hg tag -l -r 13 tmp
776 $ hg tag -l -r 13 tmp
777 $ hg --config extensions.strip= strip 2
777 $ hg --config extensions.strip= strip 2
778 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg (glob)
778 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg (glob)
779 $ hg graft tmp
779 $ hg graft tmp
780 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
780 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
781 [255]
781 [255]
782
782
783 Empty graft
783 Empty graft
784
784
785 $ hg up -qr 26
785 $ hg up -qr 26
786 $ hg tag -f something
786 $ hg tag -f something
787 $ hg graft -qr 27
787 $ hg graft -qr 27
788 $ hg graft -f 27
788 $ hg graft -f 27
789 grafting 27:ed6c7e54e319 "28"
789 grafting 27:ed6c7e54e319 "28"
790 note: graft of 27:ed6c7e54e319 created no changes to commit
790 note: graft of 27:ed6c7e54e319 created no changes to commit
791
791
792 $ cd ..
792 $ cd ..
793
793
794 Graft to duplicate a commit
794 Graft to duplicate a commit
795
795
796 $ hg init graftsibling
796 $ hg init graftsibling
797 $ cd graftsibling
797 $ cd graftsibling
798 $ touch a
798 $ touch a
799 $ hg commit -qAm a
799 $ hg commit -qAm a
800 $ touch b
800 $ touch b
801 $ hg commit -qAm b
801 $ hg commit -qAm b
802 $ hg log -G -T '{rev}\n'
802 $ hg log -G -T '{rev}\n'
803 @ 1
803 @ 1
804 |
804 |
805 o 0
805 o 0
806
806
807 $ hg up -q 0
807 $ hg up -q 0
808 $ hg graft -r 1
808 $ hg graft -r 1
809 grafting 1:0e067c57feba "b" (tip)
809 grafting 1:0e067c57feba "b" (tip)
810 $ hg log -G -T '{rev}\n'
810 $ hg log -G -T '{rev}\n'
811 @ 2
811 @ 2
812 |
812 |
813 | o 1
813 | o 1
814 |/
814 |/
815 o 0
815 o 0
816
816
817 Graft to duplicate a commit twice
817 Graft to duplicate a commit twice
818
818
819 $ hg up -q 0
819 $ hg up -q 0
820 $ hg graft -r 2
820 $ hg graft -r 2
821 grafting 2:044ec77f6389 "b" (tip)
821 grafting 2:044ec77f6389 "b" (tip)
822 $ hg log -G -T '{rev}\n'
822 $ hg log -G -T '{rev}\n'
823 @ 3
823 @ 3
824 |
824 |
825 | o 2
825 | o 2
826 |/
826 |/
827 | o 1
827 | o 1
828 |/
828 |/
829 o 0
829 o 0
830
830
@@ -1,157 +1,159 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > histedit=
5 > histedit=
6 > EOF
6 > EOF
7
7
8 $ initrepo ()
8 $ initrepo ()
9 > {
9 > {
10 > hg init r
10 > hg init r
11 > cd r
11 > cd r
12 > for x in a b c d e f ; do
12 > for x in a b c d e f ; do
13 > echo $x > $x
13 > echo $x > $x
14 > hg add $x
14 > hg add $x
15 > hg ci -m $x
15 > hg ci -m $x
16 > done
16 > done
17 > echo a >> e
17 > echo a >> e
18 > hg ci -m 'does not commute with e'
18 > hg ci -m 'does not commute with e'
19 > cd ..
19 > cd ..
20 > }
20 > }
21
21
22 $ initrepo
22 $ initrepo
23 $ cd r
23 $ cd r
24
24
25 log before edit
25 log before edit
26 $ hg log --graph
26 $ hg log --graph
27 @ changeset: 6:bfa474341cc9
27 @ changeset: 6:bfa474341cc9
28 | tag: tip
28 | tag: tip
29 | user: test
29 | user: test
30 | date: Thu Jan 01 00:00:00 1970 +0000
30 | date: Thu Jan 01 00:00:00 1970 +0000
31 | summary: does not commute with e
31 | summary: does not commute with e
32 |
32 |
33 o changeset: 5:652413bf663e
33 o changeset: 5:652413bf663e
34 | user: test
34 | user: test
35 | date: Thu Jan 01 00:00:00 1970 +0000
35 | date: Thu Jan 01 00:00:00 1970 +0000
36 | summary: f
36 | summary: f
37 |
37 |
38 o changeset: 4:e860deea161a
38 o changeset: 4:e860deea161a
39 | user: test
39 | user: test
40 | date: Thu Jan 01 00:00:00 1970 +0000
40 | date: Thu Jan 01 00:00:00 1970 +0000
41 | summary: e
41 | summary: e
42 |
42 |
43 o changeset: 3:055a42cdd887
43 o changeset: 3:055a42cdd887
44 | user: test
44 | user: test
45 | date: Thu Jan 01 00:00:00 1970 +0000
45 | date: Thu Jan 01 00:00:00 1970 +0000
46 | summary: d
46 | summary: d
47 |
47 |
48 o changeset: 2:177f92b77385
48 o changeset: 2:177f92b77385
49 | user: test
49 | user: test
50 | date: Thu Jan 01 00:00:00 1970 +0000
50 | date: Thu Jan 01 00:00:00 1970 +0000
51 | summary: c
51 | summary: c
52 |
52 |
53 o changeset: 1:d2ae7f538514
53 o changeset: 1:d2ae7f538514
54 | user: test
54 | user: test
55 | date: Thu Jan 01 00:00:00 1970 +0000
55 | date: Thu Jan 01 00:00:00 1970 +0000
56 | summary: b
56 | summary: b
57 |
57 |
58 o changeset: 0:cb9a9f314b8b
58 o changeset: 0:cb9a9f314b8b
59 user: test
59 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
60 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: a
61 summary: a
62
62
63
63
64 edit the history
64 edit the history
65 $ hg histedit 177f92b77385 --commands - 2>&1 <<EOF | fixbundle
65 $ hg histedit 177f92b77385 --commands - 2>&1 <<EOF | fixbundle
66 > pick 177f92b77385 c
66 > pick 177f92b77385 c
67 > pick 055a42cdd887 d
67 > pick 055a42cdd887 d
68 > pick bfa474341cc9 does not commute with e
68 > pick bfa474341cc9 does not commute with e
69 > pick e860deea161a e
69 > pick e860deea161a e
70 > pick 652413bf663e f
70 > pick 652413bf663e f
71 > EOF
71 > EOF
72 merging e
72 merging e
73 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
73 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
74 Fix up the change (pick e860deea161a)
74 Fix up the change (pick e860deea161a)
75 (hg histedit --continue to resume)
75 (hg histedit --continue to resume)
76
76
77 insert unsupported advisory merge record
77 insert unsupported advisory merge record
78 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
78 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
79 $ hg debugmergestate
79 $ hg debugmergestate
80 * version 2 records
80 * version 2 records
81 local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
81 local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
82 other: e860deea161a2f77de56603b340ebbb4536308ae
82 other: e860deea161a2f77de56603b340ebbb4536308ae
83 unrecognized entry: x advisory record
83 unrecognized entry: x advisory record
84 file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
84 file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
85 file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
85 local path: e (flags "")
86 local path: e (flags "")
86 ancestor path: e (node null)
87 ancestor path: e (node null)
87 other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
88 other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
88 $ hg resolve -l
89 $ hg resolve -l
89 U e
90 U e
90
91
91 insert unsupported mandatory merge record
92 insert unsupported mandatory merge record
92 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
93 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
93 $ hg debugmergestate
94 $ hg debugmergestate
94 * version 2 records
95 * version 2 records
95 local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
96 local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
96 other: e860deea161a2f77de56603b340ebbb4536308ae
97 other: e860deea161a2f77de56603b340ebbb4536308ae
98 file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
97 file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
99 file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
98 local path: e (flags "")
100 local path: e (flags "")
99 ancestor path: e (node null)
101 ancestor path: e (node null)
100 other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
102 other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
101 unrecognized entry: X mandatory record
103 unrecognized entry: X mandatory record
102 $ hg resolve -l
104 $ hg resolve -l
103 abort: unsupported merge state records: X
105 abort: unsupported merge state records: X
104 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
106 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
105 [255]
107 [255]
106 $ hg resolve -ma
108 $ hg resolve -ma
107 abort: unsupported merge state records: X
109 abort: unsupported merge state records: X
108 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
110 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
109 [255]
111 [255]
110
112
111 abort the edit (should clear out merge state)
113 abort the edit (should clear out merge state)
112 $ hg histedit --abort 2>&1 | fixbundle
114 $ hg histedit --abort 2>&1 | fixbundle
113 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
115 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
114 $ hg debugmergestate
116 $ hg debugmergestate
115 no merge state found
117 no merge state found
116
118
117 log after abort
119 log after abort
118 $ hg resolve -l
120 $ hg resolve -l
119 $ hg log --graph
121 $ hg log --graph
120 @ changeset: 6:bfa474341cc9
122 @ changeset: 6:bfa474341cc9
121 | tag: tip
123 | tag: tip
122 | user: test
124 | user: test
123 | date: Thu Jan 01 00:00:00 1970 +0000
125 | date: Thu Jan 01 00:00:00 1970 +0000
124 | summary: does not commute with e
126 | summary: does not commute with e
125 |
127 |
126 o changeset: 5:652413bf663e
128 o changeset: 5:652413bf663e
127 | user: test
129 | user: test
128 | date: Thu Jan 01 00:00:00 1970 +0000
130 | date: Thu Jan 01 00:00:00 1970 +0000
129 | summary: f
131 | summary: f
130 |
132 |
131 o changeset: 4:e860deea161a
133 o changeset: 4:e860deea161a
132 | user: test
134 | user: test
133 | date: Thu Jan 01 00:00:00 1970 +0000
135 | date: Thu Jan 01 00:00:00 1970 +0000
134 | summary: e
136 | summary: e
135 |
137 |
136 o changeset: 3:055a42cdd887
138 o changeset: 3:055a42cdd887
137 | user: test
139 | user: test
138 | date: Thu Jan 01 00:00:00 1970 +0000
140 | date: Thu Jan 01 00:00:00 1970 +0000
139 | summary: d
141 | summary: d
140 |
142 |
141 o changeset: 2:177f92b77385
143 o changeset: 2:177f92b77385
142 | user: test
144 | user: test
143 | date: Thu Jan 01 00:00:00 1970 +0000
145 | date: Thu Jan 01 00:00:00 1970 +0000
144 | summary: c
146 | summary: c
145 |
147 |
146 o changeset: 1:d2ae7f538514
148 o changeset: 1:d2ae7f538514
147 | user: test
149 | user: test
148 | date: Thu Jan 01 00:00:00 1970 +0000
150 | date: Thu Jan 01 00:00:00 1970 +0000
149 | summary: b
151 | summary: b
150 |
152 |
151 o changeset: 0:cb9a9f314b8b
153 o changeset: 0:cb9a9f314b8b
152 user: test
154 user: test
153 date: Thu Jan 01 00:00:00 1970 +0000
155 date: Thu Jan 01 00:00:00 1970 +0000
154 summary: a
156 summary: a
155
157
156
158
157 $ cd ..
159 $ cd ..
@@ -1,98 +1,98 b''
1 https://bz.mercurial-scm.org/672
1 https://bz.mercurial-scm.org/672
2
2
3 # 0-2-4
3 # 0-2-4
4 # \ \ \
4 # \ \ \
5 # 1-3-5
5 # 1-3-5
6 #
6 #
7 # rename in #1, content change in #4.
7 # rename in #1, content change in #4.
8
8
9 $ hg init
9 $ hg init
10
10
11 $ touch 1
11 $ touch 1
12 $ touch 2
12 $ touch 2
13 $ hg commit -Am init # 0
13 $ hg commit -Am init # 0
14 adding 1
14 adding 1
15 adding 2
15 adding 2
16
16
17 $ hg rename 1 1a
17 $ hg rename 1 1a
18 $ hg commit -m rename # 1
18 $ hg commit -m rename # 1
19
19
20 $ hg co -C 0
20 $ hg co -C 0
21 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
22
22
23 $ echo unrelated >> 2
23 $ echo unrelated >> 2
24 $ hg ci -m unrelated1 # 2
24 $ hg ci -m unrelated1 # 2
25 created new head
25 created new head
26
26
27 $ hg merge --debug 1
27 $ hg merge --debug 1
28 searching for copies back to rev 1
28 searching for copies back to rev 1
29 unmatched files in other:
29 unmatched files in other:
30 1a
30 1a
31 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
31 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
32 src: '1' -> dst: '1a'
32 src: '1' -> dst: '1a'
33 checking for directory renames
33 checking for directory renames
34 resolving manifests
34 resolving manifests
35 branchmerge: True, force: False, partial: False
35 branchmerge: True, force: False, partial: False
36 ancestor: 81f4b099af3d, local: c64f439569a9+, remote: c12dcd37c90a
36 ancestor: 81f4b099af3d, local: c64f439569a9+, remote: c12dcd37c90a
37 1: other deleted -> r
37 1: other deleted -> r
38 removing 1
38 removing 1
39 1a: remote created -> g
39 1a: remote created -> g
40 getting 1a
40 getting 1a
41 2: remote unchanged -> k
41 2: remote unchanged -> k
42 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
42 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
43 (branch merge, don't forget to commit)
43 (branch merge, don't forget to commit)
44
44
45 $ hg ci -m merge1 # 3
45 $ hg ci -m merge1 # 3
46
46
47 $ hg co -C 2
47 $ hg co -C 2
48 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
48 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
49
49
50 $ echo hello >> 1
50 $ echo hello >> 1
51 $ hg ci -m unrelated2 # 4
51 $ hg ci -m unrelated2 # 4
52 created new head
52 created new head
53
53
54 $ hg co -C 3
54 $ hg co -C 3
55 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
55 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
56
56
57 $ hg merge -y --debug 4
57 $ hg merge -y --debug 4
58 searching for copies back to rev 1
58 searching for copies back to rev 1
59 unmatched files in local:
59 unmatched files in local:
60 1a
60 1a
61 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
61 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
62 src: '1' -> dst: '1a' *
62 src: '1' -> dst: '1a' *
63 checking for directory renames
63 checking for directory renames
64 resolving manifests
64 resolving manifests
65 branchmerge: True, force: False, partial: False
65 branchmerge: True, force: False, partial: False
66 ancestor: c64f439569a9, local: e327dca35ac8+, remote: 746e9549ea96
66 ancestor: c64f439569a9, local: e327dca35ac8+, remote: 746e9549ea96
67 preserving 1a for resolve of 1a
67 preserving 1a for resolve of 1a
68 1a: local copied/moved from 1 -> m (premerge)
68 1a: local copied/moved from 1 -> m (premerge)
69 picked tool ':merge' for 1a (binary False symlink False changedelete False)
69 picked tool ':merge' for 1a (binary False symlink False changedelete False)
70 merging 1a and 1 to 1a
70 merging 1a and 1 to 1a
71 my 1a@e327dca35ac8+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
71 my 1a@e327dca35ac8+ other 1@746e9549ea96 ancestor 1@c64f439569a9
72 premerge successful
72 premerge successful
73 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
73 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
74 (branch merge, don't forget to commit)
74 (branch merge, don't forget to commit)
75
75
76 $ hg co -C 4
76 $ hg co -C 4
77 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
77 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
78
78
79 $ hg merge -y --debug 3
79 $ hg merge -y --debug 3
80 searching for copies back to rev 1
80 searching for copies back to rev 1
81 unmatched files in other:
81 unmatched files in other:
82 1a
82 1a
83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
84 src: '1' -> dst: '1a' *
84 src: '1' -> dst: '1a' *
85 checking for directory renames
85 checking for directory renames
86 resolving manifests
86 resolving manifests
87 branchmerge: True, force: False, partial: False
87 branchmerge: True, force: False, partial: False
88 ancestor: c64f439569a9, local: 746e9549ea96+, remote: e327dca35ac8
88 ancestor: c64f439569a9, local: 746e9549ea96+, remote: e327dca35ac8
89 preserving 1 for resolve of 1a
89 preserving 1 for resolve of 1a
90 removing 1
90 removing 1
91 1a: remote moved from 1 -> m (premerge)
91 1a: remote moved from 1 -> m (premerge)
92 picked tool ':merge' for 1a (binary False symlink False changedelete False)
92 picked tool ':merge' for 1a (binary False symlink False changedelete False)
93 merging 1 and 1a to 1a
93 merging 1 and 1a to 1a
94 my 1a@746e9549ea96+ other 1a@e327dca35ac8 ancestor 1@81f4b099af3d
94 my 1a@746e9549ea96+ other 1a@e327dca35ac8 ancestor 1@c64f439569a9
95 premerge successful
95 premerge successful
96 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
96 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
97 (branch merge, don't forget to commit)
97 (branch merge, don't forget to commit)
98
98
@@ -1,992 +1,1034 b''
1 Tests for change/delete conflicts, including:
1 Tests for change/delete conflicts, including:
2 b5605d88dc27: Make ui.prompt repeat on "unrecognized response" again
2 b5605d88dc27: Make ui.prompt repeat on "unrecognized response" again
3 (issue897)
3 (issue897)
4
4
5 840e2b315c1f: Fix misleading error and prompts during update/merge
5 840e2b315c1f: Fix misleading error and prompts during update/merge
6 (issue556)
6 (issue556)
7
7
8 Make sure HGMERGE doesn't interfere with the test
8 Make sure HGMERGE doesn't interfere with the test
9 $ unset HGMERGE
9 $ unset HGMERGE
10
10
11 $ status() {
11 $ status() {
12 > echo "--- status ---"
12 > echo "--- status ---"
13 > hg st -A file1 file2 file3
13 > hg st -A file1 file2 file3
14 > echo "--- resolve --list ---"
14 > echo "--- resolve --list ---"
15 > hg resolve --list file1 file2 file3
15 > hg resolve --list file1 file2 file3
16 > echo "--- debugmergestate ---"
16 > echo "--- debugmergestate ---"
17 > hg debugmergestate
17 > hg debugmergestate
18 > for file in file1 file2 file3; do
18 > for file in file1 file2 file3; do
19 > if [ -f $file ]; then
19 > if [ -f $file ]; then
20 > echo "--- $file ---"
20 > echo "--- $file ---"
21 > cat $file
21 > cat $file
22 > else
22 > else
23 > echo "*** $file does not exist"
23 > echo "*** $file does not exist"
24 > fi
24 > fi
25 > done
25 > done
26 > }
26 > }
27
27
28 $ hg init repo
28 $ hg init repo
29 $ cd repo
29 $ cd repo
30
30
31 $ echo 1 > file1
31 $ echo 1 > file1
32 $ echo 2 > file2
32 $ echo 2 > file2
33 $ echo 3 > file3
33 $ echo 3 > file3
34 $ hg ci -Am 'added files'
34 $ hg ci -Am 'added files'
35 adding file1
35 adding file1
36 adding file2
36 adding file2
37 adding file3
37 adding file3
38
38
39 $ hg rm file1
39 $ hg rm file1
40 $ echo changed >> file2
40 $ echo changed >> file2
41 $ echo changed1 >> file3
41 $ echo changed1 >> file3
42 $ hg ci -m 'removed file1, changed file2, changed file3'
42 $ hg ci -m 'removed file1, changed file2, changed file3'
43
43
44 $ hg co 0
44 $ hg co 0
45 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
45 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
46
46
47 $ echo changed >> file1
47 $ echo changed >> file1
48 $ hg rm file2
48 $ hg rm file2
49 $ echo changed2 >> file3
49 $ echo changed2 >> file3
50 $ hg ci -m 'changed file1, removed file2, changed file3'
50 $ hg ci -m 'changed file1, removed file2, changed file3'
51 created new head
51 created new head
52
52
53
53
54 Non-interactive merge:
54 Non-interactive merge:
55
55
56 $ hg merge -y
56 $ hg merge -y
57 local changed file1 which remote deleted
57 local changed file1 which remote deleted
58 use (c)hanged version, (d)elete, or leave (u)nresolved? u
58 use (c)hanged version, (d)elete, or leave (u)nresolved? u
59 remote changed file2 which local deleted
59 remote changed file2 which local deleted
60 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
60 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
61 merging file3
61 merging file3
62 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
62 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
63 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
63 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
64 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
64 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
65 [1]
65 [1]
66
66
67 $ status
67 $ status
68 --- status ---
68 --- status ---
69 M file2
69 M file2
70 M file3
70 M file3
71 C file1
71 C file1
72 --- resolve --list ---
72 --- resolve --list ---
73 U file1
73 U file1
74 U file2
74 U file2
75 U file3
75 U file3
76 --- debugmergestate ---
76 --- debugmergestate ---
77 * version 2 records
77 * version 2 records
78 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
78 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
79 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
79 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
80 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
80 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
81 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
81 local path: file1 (flags "")
82 local path: file1 (flags "")
82 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
83 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
83 other path: file1 (node null)
84 other path: file1 (node null)
85 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
84 file: file2 (record type "C", state "u", hash null)
86 file: file2 (record type "C", state "u", hash null)
85 local path: file2 (flags "")
87 local path: file2 (flags "")
86 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
88 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
87 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
89 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
90 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
88 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
91 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
89 local path: file3 (flags "")
92 local path: file3 (flags "")
90 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
93 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
91 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
94 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
92 --- file1 ---
95 --- file1 ---
93 1
96 1
94 changed
97 changed
95 --- file2 ---
98 --- file2 ---
96 2
99 2
97 changed
100 changed
98 --- file3 ---
101 --- file3 ---
99 3
102 3
100 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
103 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
101 changed2
104 changed2
102 =======
105 =======
103 changed1
106 changed1
104 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
107 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
105
108
106
109
107 Interactive merge:
110 Interactive merge:
108
111
109 $ hg co -C
112 $ hg co -C
110 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
113 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
111
114
112 $ hg merge --config ui.interactive=true <<EOF
115 $ hg merge --config ui.interactive=true <<EOF
113 > c
116 > c
114 > d
117 > d
115 > EOF
118 > EOF
116 local changed file1 which remote deleted
119 local changed file1 which remote deleted
117 use (c)hanged version, (d)elete, or leave (u)nresolved? c
120 use (c)hanged version, (d)elete, or leave (u)nresolved? c
118 remote changed file2 which local deleted
121 remote changed file2 which local deleted
119 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? d
122 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? d
120 merging file3
123 merging file3
121 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
124 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
122 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
125 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
123 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
126 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
124 [1]
127 [1]
125
128
126 $ status
129 $ status
127 --- status ---
130 --- status ---
128 file2: * (glob)
131 file2: * (glob)
129 M file3
132 M file3
130 C file1
133 C file1
131 --- resolve --list ---
134 --- resolve --list ---
132 R file1
135 R file1
133 R file2
136 R file2
134 U file3
137 U file3
135 --- debugmergestate ---
138 --- debugmergestate ---
136 * version 2 records
139 * version 2 records
137 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
140 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
138 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
141 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
142 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
139 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
143 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
140 local path: file1 (flags "")
144 local path: file1 (flags "")
141 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
145 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
142 other path: file1 (node null)
146 other path: file1 (node null)
147 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
143 file: file2 (record type "C", state "r", hash null)
148 file: file2 (record type "C", state "r", hash null)
144 local path: file2 (flags "")
149 local path: file2 (flags "")
145 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
150 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
146 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
151 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
152 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
147 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
153 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
148 local path: file3 (flags "")
154 local path: file3 (flags "")
149 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
155 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
150 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
156 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
151 --- file1 ---
157 --- file1 ---
152 1
158 1
153 changed
159 changed
154 *** file2 does not exist
160 *** file2 does not exist
155 --- file3 ---
161 --- file3 ---
156 3
162 3
157 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
163 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
158 changed2
164 changed2
159 =======
165 =======
160 changed1
166 changed1
161 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
167 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
162
168
163
169
164 Interactive merge with bad input:
170 Interactive merge with bad input:
165
171
166 $ hg co -C
172 $ hg co -C
167 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
173 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
168
174
169 $ hg merge --config ui.interactive=true <<EOF
175 $ hg merge --config ui.interactive=true <<EOF
170 > foo
176 > foo
171 > bar
177 > bar
172 > d
178 > d
173 > baz
179 > baz
174 > c
180 > c
175 > EOF
181 > EOF
176 local changed file1 which remote deleted
182 local changed file1 which remote deleted
177 use (c)hanged version, (d)elete, or leave (u)nresolved? foo
183 use (c)hanged version, (d)elete, or leave (u)nresolved? foo
178 unrecognized response
184 unrecognized response
179 local changed file1 which remote deleted
185 local changed file1 which remote deleted
180 use (c)hanged version, (d)elete, or leave (u)nresolved? bar
186 use (c)hanged version, (d)elete, or leave (u)nresolved? bar
181 unrecognized response
187 unrecognized response
182 local changed file1 which remote deleted
188 local changed file1 which remote deleted
183 use (c)hanged version, (d)elete, or leave (u)nresolved? d
189 use (c)hanged version, (d)elete, or leave (u)nresolved? d
184 remote changed file2 which local deleted
190 remote changed file2 which local deleted
185 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? baz
191 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? baz
186 unrecognized response
192 unrecognized response
187 remote changed file2 which local deleted
193 remote changed file2 which local deleted
188 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? c
194 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? c
189 merging file3
195 merging file3
190 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
196 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
191 0 files updated, 1 files merged, 1 files removed, 1 files unresolved
197 0 files updated, 1 files merged, 1 files removed, 1 files unresolved
192 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
198 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
193 [1]
199 [1]
194
200
195 $ status
201 $ status
196 --- status ---
202 --- status ---
197 M file2
203 M file2
198 M file3
204 M file3
199 R file1
205 R file1
200 --- resolve --list ---
206 --- resolve --list ---
201 R file1
207 R file1
202 R file2
208 R file2
203 U file3
209 U file3
204 --- debugmergestate ---
210 --- debugmergestate ---
205 * version 2 records
211 * version 2 records
206 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
212 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
207 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
213 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
214 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
208 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
215 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
209 local path: file1 (flags "")
216 local path: file1 (flags "")
210 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
217 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
211 other path: file1 (node null)
218 other path: file1 (node null)
219 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
212 file: file2 (record type "C", state "r", hash null)
220 file: file2 (record type "C", state "r", hash null)
213 local path: file2 (flags "")
221 local path: file2 (flags "")
214 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
222 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
215 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
223 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
224 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
216 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
225 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
217 local path: file3 (flags "")
226 local path: file3 (flags "")
218 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
227 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
219 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
228 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
220 *** file1 does not exist
229 *** file1 does not exist
221 --- file2 ---
230 --- file2 ---
222 2
231 2
223 changed
232 changed
224 --- file3 ---
233 --- file3 ---
225 3
234 3
226 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
235 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
227 changed2
236 changed2
228 =======
237 =======
229 changed1
238 changed1
230 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
239 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
231
240
232
241
233 Interactive merge with not enough input:
242 Interactive merge with not enough input:
234
243
235 $ hg co -C
244 $ hg co -C
236 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
245 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
237
246
238 $ hg merge --config ui.interactive=true <<EOF
247 $ hg merge --config ui.interactive=true <<EOF
239 > d
248 > d
240 > EOF
249 > EOF
241 local changed file1 which remote deleted
250 local changed file1 which remote deleted
242 use (c)hanged version, (d)elete, or leave (u)nresolved? d
251 use (c)hanged version, (d)elete, or leave (u)nresolved? d
243 remote changed file2 which local deleted
252 remote changed file2 which local deleted
244 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
253 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
245 merging file3
254 merging file3
246 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
255 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
247 0 files updated, 0 files merged, 1 files removed, 2 files unresolved
256 0 files updated, 0 files merged, 1 files removed, 2 files unresolved
248 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
257 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
249 [1]
258 [1]
250
259
251 $ status
260 $ status
252 --- status ---
261 --- status ---
253 M file2
262 M file2
254 M file3
263 M file3
255 R file1
264 R file1
256 --- resolve --list ---
265 --- resolve --list ---
257 R file1
266 R file1
258 U file2
267 U file2
259 U file3
268 U file3
260 --- debugmergestate ---
269 --- debugmergestate ---
261 * version 2 records
270 * version 2 records
262 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
271 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
263 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
272 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
273 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
264 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
274 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
265 local path: file1 (flags "")
275 local path: file1 (flags "")
266 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
276 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
267 other path: file1 (node null)
277 other path: file1 (node null)
278 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
268 file: file2 (record type "C", state "u", hash null)
279 file: file2 (record type "C", state "u", hash null)
269 local path: file2 (flags "")
280 local path: file2 (flags "")
270 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
281 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
271 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
282 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
283 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
272 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
284 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
273 local path: file3 (flags "")
285 local path: file3 (flags "")
274 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
286 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
275 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
287 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
276 *** file1 does not exist
288 *** file1 does not exist
277 --- file2 ---
289 --- file2 ---
278 2
290 2
279 changed
291 changed
280 --- file3 ---
292 --- file3 ---
281 3
293 3
282 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
294 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
283 changed2
295 changed2
284 =======
296 =======
285 changed1
297 changed1
286 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
298 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
287
299
288 Choose local versions of files
300 Choose local versions of files
289
301
290 $ hg co -C
302 $ hg co -C
291 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
303 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
292
304
293 $ hg merge --tool :local
305 $ hg merge --tool :local
294 0 files updated, 3 files merged, 0 files removed, 0 files unresolved
306 0 files updated, 3 files merged, 0 files removed, 0 files unresolved
295 (branch merge, don't forget to commit)
307 (branch merge, don't forget to commit)
296 $ status 2>&1 | tee $TESTTMP/local.status
308 $ status 2>&1 | tee $TESTTMP/local.status
297 --- status ---
309 --- status ---
298 file2: * (glob)
310 file2: * (glob)
299 M file3
311 M file3
300 C file1
312 C file1
301 --- resolve --list ---
313 --- resolve --list ---
302 R file1
314 R file1
303 R file2
315 R file2
304 R file3
316 R file3
305 --- debugmergestate ---
317 --- debugmergestate ---
306 * version 2 records
318 * version 2 records
307 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
319 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
308 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
320 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
321 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
309 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
322 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
310 local path: file1 (flags "")
323 local path: file1 (flags "")
311 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
324 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
312 other path: file1 (node null)
325 other path: file1 (node null)
326 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
313 file: file2 (record type "C", state "r", hash null)
327 file: file2 (record type "C", state "r", hash null)
314 local path: file2 (flags "")
328 local path: file2 (flags "")
315 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
329 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
316 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
330 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
331 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
317 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
332 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
318 local path: file3 (flags "")
333 local path: file3 (flags "")
319 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
334 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
320 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
335 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
321 --- file1 ---
336 --- file1 ---
322 1
337 1
323 changed
338 changed
324 *** file2 does not exist
339 *** file2 does not exist
325 --- file3 ---
340 --- file3 ---
326 3
341 3
327 changed2
342 changed2
328
343
329 Choose other versions of files
344 Choose other versions of files
330
345
331 $ hg co -C
346 $ hg co -C
332 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
347 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
333
348
334 $ hg merge --tool :other
349 $ hg merge --tool :other
335 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
350 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
336 (branch merge, don't forget to commit)
351 (branch merge, don't forget to commit)
337 $ status 2>&1 | tee $TESTTMP/other.status
352 $ status 2>&1 | tee $TESTTMP/other.status
338 --- status ---
353 --- status ---
339 M file2
354 M file2
340 M file3
355 M file3
341 R file1
356 R file1
342 --- resolve --list ---
357 --- resolve --list ---
343 R file1
358 R file1
344 R file2
359 R file2
345 R file3
360 R file3
346 --- debugmergestate ---
361 --- debugmergestate ---
347 * version 2 records
362 * version 2 records
348 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
363 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
349 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
364 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
365 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
350 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
366 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
351 local path: file1 (flags "")
367 local path: file1 (flags "")
352 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
368 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
353 other path: file1 (node null)
369 other path: file1 (node null)
370 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
354 file: file2 (record type "C", state "r", hash null)
371 file: file2 (record type "C", state "r", hash null)
355 local path: file2 (flags "")
372 local path: file2 (flags "")
356 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
373 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
357 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
374 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
375 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
358 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
376 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
359 local path: file3 (flags "")
377 local path: file3 (flags "")
360 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
378 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
361 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
379 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
362 *** file1 does not exist
380 *** file1 does not exist
363 --- file2 ---
381 --- file2 ---
364 2
382 2
365 changed
383 changed
366 --- file3 ---
384 --- file3 ---
367 3
385 3
368 changed1
386 changed1
369
387
370 Fail
388 Fail
371
389
372 $ hg co -C
390 $ hg co -C
373 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
391 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
374
392
375 $ hg merge --tool :fail
393 $ hg merge --tool :fail
376 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
394 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
377 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
395 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
378 [1]
396 [1]
379 $ status 2>&1 | tee $TESTTMP/fail.status
397 $ status 2>&1 | tee $TESTTMP/fail.status
380 --- status ---
398 --- status ---
381 M file2
399 M file2
382 M file3
400 M file3
383 C file1
401 C file1
384 --- resolve --list ---
402 --- resolve --list ---
385 U file1
403 U file1
386 U file2
404 U file2
387 U file3
405 U file3
388 --- debugmergestate ---
406 --- debugmergestate ---
389 * version 2 records
407 * version 2 records
390 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
408 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
391 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
409 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
410 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
392 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
411 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
393 local path: file1 (flags "")
412 local path: file1 (flags "")
394 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
413 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
395 other path: file1 (node null)
414 other path: file1 (node null)
415 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
396 file: file2 (record type "C", state "u", hash null)
416 file: file2 (record type "C", state "u", hash null)
397 local path: file2 (flags "")
417 local path: file2 (flags "")
398 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
418 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
399 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
419 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
420 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
400 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
421 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
401 local path: file3 (flags "")
422 local path: file3 (flags "")
402 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
423 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
403 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
424 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
404 --- file1 ---
425 --- file1 ---
405 1
426 1
406 changed
427 changed
407 --- file2 ---
428 --- file2 ---
408 2
429 2
409 changed
430 changed
410 --- file3 ---
431 --- file3 ---
411 3
432 3
412 changed2
433 changed2
413
434
414 Force prompts with no input (should be similar to :fail)
435 Force prompts with no input (should be similar to :fail)
415
436
416 $ hg co -C
437 $ hg co -C
417 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
438 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
418
439
419 $ hg merge --config ui.interactive=True --tool :prompt
440 $ hg merge --config ui.interactive=True --tool :prompt
420 local changed file1 which remote deleted
441 local changed file1 which remote deleted
421 use (c)hanged version, (d)elete, or leave (u)nresolved?
442 use (c)hanged version, (d)elete, or leave (u)nresolved?
422 remote changed file2 which local deleted
443 remote changed file2 which local deleted
423 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
444 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
424 no tool found to merge file3
445 no tool found to merge file3
425 keep (l)ocal, take (o)ther, or leave (u)nresolved?
446 keep (l)ocal, take (o)ther, or leave (u)nresolved?
426 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
447 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
427 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
448 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
428 [1]
449 [1]
429 $ status 2>&1 | tee $TESTTMP/prompt.status
450 $ status 2>&1 | tee $TESTTMP/prompt.status
430 --- status ---
451 --- status ---
431 M file2
452 M file2
432 M file3
453 M file3
433 C file1
454 C file1
434 --- resolve --list ---
455 --- resolve --list ---
435 U file1
456 U file1
436 U file2
457 U file2
437 U file3
458 U file3
438 --- debugmergestate ---
459 --- debugmergestate ---
439 * version 2 records
460 * version 2 records
440 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
461 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
441 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
462 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
463 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
442 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
464 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
443 local path: file1 (flags "")
465 local path: file1 (flags "")
444 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
466 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
445 other path: file1 (node null)
467 other path: file1 (node null)
468 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
446 file: file2 (record type "C", state "u", hash null)
469 file: file2 (record type "C", state "u", hash null)
447 local path: file2 (flags "")
470 local path: file2 (flags "")
448 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
471 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
449 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
472 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
473 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
450 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
474 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
451 local path: file3 (flags "")
475 local path: file3 (flags "")
452 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
476 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
453 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
477 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
454 --- file1 ---
478 --- file1 ---
455 1
479 1
456 changed
480 changed
457 --- file2 ---
481 --- file2 ---
458 2
482 2
459 changed
483 changed
460 --- file3 ---
484 --- file3 ---
461 3
485 3
462 changed2
486 changed2
463 $ cmp $TESTTMP/fail.status $TESTTMP/prompt.status || diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
487 $ cmp $TESTTMP/fail.status $TESTTMP/prompt.status || diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
464
488
465
489
466 Force prompts
490 Force prompts
467
491
468 $ hg co -C
492 $ hg co -C
469 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
493 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
470
494
471 $ hg merge --tool :prompt
495 $ hg merge --tool :prompt
472 local changed file1 which remote deleted
496 local changed file1 which remote deleted
473 use (c)hanged version, (d)elete, or leave (u)nresolved? u
497 use (c)hanged version, (d)elete, or leave (u)nresolved? u
474 remote changed file2 which local deleted
498 remote changed file2 which local deleted
475 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
499 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
476 no tool found to merge file3
500 no tool found to merge file3
477 keep (l)ocal, take (o)ther, or leave (u)nresolved? u
501 keep (l)ocal, take (o)ther, or leave (u)nresolved? u
478 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
502 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
479 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
503 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
480 [1]
504 [1]
481 $ status
505 $ status
482 --- status ---
506 --- status ---
483 M file2
507 M file2
484 M file3
508 M file3
485 C file1
509 C file1
486 --- resolve --list ---
510 --- resolve --list ---
487 U file1
511 U file1
488 U file2
512 U file2
489 U file3
513 U file3
490 --- debugmergestate ---
514 --- debugmergestate ---
491 * version 2 records
515 * version 2 records
492 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
516 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
493 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
517 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
518 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
494 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
519 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
495 local path: file1 (flags "")
520 local path: file1 (flags "")
496 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
521 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
497 other path: file1 (node null)
522 other path: file1 (node null)
523 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
498 file: file2 (record type "C", state "u", hash null)
524 file: file2 (record type "C", state "u", hash null)
499 local path: file2 (flags "")
525 local path: file2 (flags "")
500 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
526 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
501 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
527 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
528 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
502 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
529 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
503 local path: file3 (flags "")
530 local path: file3 (flags "")
504 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
531 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
505 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
532 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
506 --- file1 ---
533 --- file1 ---
507 1
534 1
508 changed
535 changed
509 --- file2 ---
536 --- file2 ---
510 2
537 2
511 changed
538 changed
512 --- file3 ---
539 --- file3 ---
513 3
540 3
514 changed2
541 changed2
515
542
516 Choose to merge all files
543 Choose to merge all files
517
544
518 $ hg co -C
545 $ hg co -C
519 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
546 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
520
547
521 $ hg merge --tool :merge3
548 $ hg merge --tool :merge3
522 local changed file1 which remote deleted
549 local changed file1 which remote deleted
523 use (c)hanged version, (d)elete, or leave (u)nresolved? u
550 use (c)hanged version, (d)elete, or leave (u)nresolved? u
524 remote changed file2 which local deleted
551 remote changed file2 which local deleted
525 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
552 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
526 merging file3
553 merging file3
527 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
554 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
528 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
555 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
529 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
556 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
530 [1]
557 [1]
531 $ status
558 $ status
532 --- status ---
559 --- status ---
533 M file2
560 M file2
534 M file3
561 M file3
535 C file1
562 C file1
536 --- resolve --list ---
563 --- resolve --list ---
537 U file1
564 U file1
538 U file2
565 U file2
539 U file3
566 U file3
540 --- debugmergestate ---
567 --- debugmergestate ---
541 * version 2 records
568 * version 2 records
542 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
569 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
543 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
570 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
571 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
544 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
572 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
545 local path: file1 (flags "")
573 local path: file1 (flags "")
546 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
574 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
547 other path: file1 (node null)
575 other path: file1 (node null)
576 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
548 file: file2 (record type "C", state "u", hash null)
577 file: file2 (record type "C", state "u", hash null)
549 local path: file2 (flags "")
578 local path: file2 (flags "")
550 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
579 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
551 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
580 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
581 file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
552 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
582 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
553 local path: file3 (flags "")
583 local path: file3 (flags "")
554 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
584 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
555 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
585 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
556 --- file1 ---
586 --- file1 ---
557 1
587 1
558 changed
588 changed
559 --- file2 ---
589 --- file2 ---
560 2
590 2
561 changed
591 changed
562 --- file3 ---
592 --- file3 ---
563 3
593 3
564 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
594 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
565 changed2
595 changed2
566 ||||||| base
596 ||||||| base
567 =======
597 =======
568 changed1
598 changed1
569 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
599 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
570
600
571 Exercise transitions between local, other, fail and prompt, and make sure the
601 Exercise transitions between local, other, fail and prompt, and make sure the
572 dirstate stays consistent. (Compare with each other and to the above
602 dirstate stays consistent. (Compare with each other and to the above
573 invocations.)
603 invocations.)
574
604
575 $ testtransitions() {
605 $ testtransitions() {
576 > # this traversal order covers every transition
606 > # this traversal order covers every transition
577 > tools="local other prompt local fail other local prompt other fail prompt fail local"
607 > tools="local other prompt local fail other local prompt other fail prompt fail local"
578 > lasttool="merge3"
608 > lasttool="merge3"
579 > for tool in $tools; do
609 > for tool in $tools; do
580 > echo "=== :$lasttool -> :$tool ==="
610 > echo "=== :$lasttool -> :$tool ==="
581 > ref="$TESTTMP/$tool.status"
611 > ref="$TESTTMP/$tool.status"
582 > hg resolve --unmark --all
612 > hg resolve --unmark --all
583 > hg resolve --tool ":$tool" --all --config ui.interactive=True
613 > hg resolve --tool ":$tool" --all --config ui.interactive=True
584 > status > "$TESTTMP/compare.status" 2>&1
614 > status > "$TESTTMP/compare.status" 2>&1
585 > echo '--- diff of status ---'
615 > echo '--- diff of status ---'
586 > if cmp "$TESTTMP/$tool.status" "$TESTTMP/compare.status" || diff -U8 "$TESTTMP/$tool.status" "$TESTTMP/compare.status"; then
616 > if cmp "$TESTTMP/$tool.status" "$TESTTMP/compare.status" || diff -U8 "$TESTTMP/$tool.status" "$TESTTMP/compare.status"; then
587 > echo '(status identical)'
617 > echo '(status identical)'
588 > fi
618 > fi
589 > lasttool="$tool"
619 > lasttool="$tool"
590 > echo
620 > echo
591 > done
621 > done
592 > }
622 > }
593
623
594 $ testtransitions
624 $ testtransitions
595 === :merge3 -> :local ===
625 === :merge3 -> :local ===
596 (no more unresolved files)
626 (no more unresolved files)
597 --- diff of status ---
627 --- diff of status ---
598 (status identical)
628 (status identical)
599
629
600 === :local -> :other ===
630 === :local -> :other ===
601 (no more unresolved files)
631 (no more unresolved files)
602 --- diff of status ---
632 --- diff of status ---
603 (status identical)
633 (status identical)
604
634
605 === :other -> :prompt ===
635 === :other -> :prompt ===
606 local changed file1 which remote deleted
636 local changed file1 which remote deleted
607 use (c)hanged version, (d)elete, or leave (u)nresolved?
637 use (c)hanged version, (d)elete, or leave (u)nresolved?
608 remote changed file2 which local deleted
638 remote changed file2 which local deleted
609 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
639 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
610 no tool found to merge file3
640 no tool found to merge file3
611 keep (l)ocal, take (o)ther, or leave (u)nresolved?
641 keep (l)ocal, take (o)ther, or leave (u)nresolved?
612 --- diff of status ---
642 --- diff of status ---
613 (status identical)
643 (status identical)
614
644
615 === :prompt -> :local ===
645 === :prompt -> :local ===
616 (no more unresolved files)
646 (no more unresolved files)
617 --- diff of status ---
647 --- diff of status ---
618 (status identical)
648 (status identical)
619
649
620 === :local -> :fail ===
650 === :local -> :fail ===
621 --- diff of status ---
651 --- diff of status ---
622 (status identical)
652 (status identical)
623
653
624 === :fail -> :other ===
654 === :fail -> :other ===
625 (no more unresolved files)
655 (no more unresolved files)
626 --- diff of status ---
656 --- diff of status ---
627 (status identical)
657 (status identical)
628
658
629 === :other -> :local ===
659 === :other -> :local ===
630 (no more unresolved files)
660 (no more unresolved files)
631 --- diff of status ---
661 --- diff of status ---
632 (status identical)
662 (status identical)
633
663
634 === :local -> :prompt ===
664 === :local -> :prompt ===
635 local changed file1 which remote deleted
665 local changed file1 which remote deleted
636 use (c)hanged version, (d)elete, or leave (u)nresolved?
666 use (c)hanged version, (d)elete, or leave (u)nresolved?
637 remote changed file2 which local deleted
667 remote changed file2 which local deleted
638 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
668 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
639 no tool found to merge file3
669 no tool found to merge file3
640 keep (l)ocal, take (o)ther, or leave (u)nresolved?
670 keep (l)ocal, take (o)ther, or leave (u)nresolved?
641 --- diff of status ---
671 --- diff of status ---
642 (status identical)
672 (status identical)
643
673
644 === :prompt -> :other ===
674 === :prompt -> :other ===
645 (no more unresolved files)
675 (no more unresolved files)
646 --- diff of status ---
676 --- diff of status ---
647 (status identical)
677 (status identical)
648
678
649 === :other -> :fail ===
679 === :other -> :fail ===
650 --- diff of status ---
680 --- diff of status ---
651 (status identical)
681 (status identical)
652
682
653 === :fail -> :prompt ===
683 === :fail -> :prompt ===
654 local changed file1 which remote deleted
684 local changed file1 which remote deleted
655 use (c)hanged version, (d)elete, or leave (u)nresolved?
685 use (c)hanged version, (d)elete, or leave (u)nresolved?
656 remote changed file2 which local deleted
686 remote changed file2 which local deleted
657 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
687 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
658 no tool found to merge file3
688 no tool found to merge file3
659 keep (l)ocal, take (o)ther, or leave (u)nresolved?
689 keep (l)ocal, take (o)ther, or leave (u)nresolved?
660 --- diff of status ---
690 --- diff of status ---
661 (status identical)
691 (status identical)
662
692
663 === :prompt -> :fail ===
693 === :prompt -> :fail ===
664 --- diff of status ---
694 --- diff of status ---
665 (status identical)
695 (status identical)
666
696
667 === :fail -> :local ===
697 === :fail -> :local ===
668 (no more unresolved files)
698 (no more unresolved files)
669 --- diff of status ---
699 --- diff of status ---
670 (status identical)
700 (status identical)
671
701
672
702
673
703
674 Non-interactive linear update
704 Non-interactive linear update
675
705
676 $ hg co -C 0
706 $ hg co -C 0
677 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
707 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
678 $ echo changed >> file1
708 $ echo changed >> file1
679 $ hg rm file2
709 $ hg rm file2
680 $ hg update 1 -y
710 $ hg update 1 -y
681 local changed file1 which remote deleted
711 local changed file1 which remote deleted
682 use (c)hanged version, (d)elete, or leave (u)nresolved? u
712 use (c)hanged version, (d)elete, or leave (u)nresolved? u
683 remote changed file2 which local deleted
713 remote changed file2 which local deleted
684 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
714 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
685 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
715 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
686 use 'hg resolve' to retry unresolved file merges
716 use 'hg resolve' to retry unresolved file merges
687 [1]
717 [1]
688 $ status
718 $ status
689 --- status ---
719 --- status ---
690 A file1
720 A file1
691 C file2
721 C file2
692 C file3
722 C file3
693 --- resolve --list ---
723 --- resolve --list ---
694 U file1
724 U file1
695 U file2
725 U file2
696 --- debugmergestate ---
726 --- debugmergestate ---
697 * version 2 records
727 * version 2 records
698 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
728 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
699 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
729 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
730 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
700 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
731 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
701 local path: file1 (flags "")
732 local path: file1 (flags "")
702 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
733 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
703 other path: file1 (node null)
734 other path: file1 (node null)
735 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
704 file: file2 (record type "C", state "u", hash null)
736 file: file2 (record type "C", state "u", hash null)
705 local path: file2 (flags "")
737 local path: file2 (flags "")
706 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
738 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
707 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
739 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
708 --- file1 ---
740 --- file1 ---
709 1
741 1
710 changed
742 changed
711 --- file2 ---
743 --- file2 ---
712 2
744 2
713 changed
745 changed
714 --- file3 ---
746 --- file3 ---
715 3
747 3
716 changed1
748 changed1
717
749
718 Choose local versions of files
750 Choose local versions of files
719
751
720 $ hg co -C 0
752 $ hg co -C 0
721 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
753 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
722 $ echo changed >> file1
754 $ echo changed >> file1
723 $ hg rm file2
755 $ hg rm file2
724 $ hg update 1 --tool :local
756 $ hg update 1 --tool :local
725 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
757 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
726 $ status 2>&1 | tee $TESTTMP/local.status
758 $ status 2>&1 | tee $TESTTMP/local.status
727 --- status ---
759 --- status ---
728 file2: * (glob)
760 file2: * (glob)
729 A file1
761 A file1
730 C file3
762 C file3
731 --- resolve --list ---
763 --- resolve --list ---
732 R file1
764 R file1
733 R file2
765 R file2
734 --- debugmergestate ---
766 --- debugmergestate ---
735 * version 2 records
767 * version 2 records
736 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
768 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
737 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
769 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
770 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
738 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
771 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
739 local path: file1 (flags "")
772 local path: file1 (flags "")
740 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
773 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
741 other path: file1 (node null)
774 other path: file1 (node null)
775 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
742 file: file2 (record type "C", state "r", hash null)
776 file: file2 (record type "C", state "r", hash null)
743 local path: file2 (flags "")
777 local path: file2 (flags "")
744 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
778 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
745 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
779 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
746 --- file1 ---
780 --- file1 ---
747 1
781 1
748 changed
782 changed
749 *** file2 does not exist
783 *** file2 does not exist
750 --- file3 ---
784 --- file3 ---
751 3
785 3
752 changed1
786 changed1
753
787
754 Choose other versions of files
788 Choose other versions of files
755
789
756 $ hg co -C 0
790 $ hg co -C 0
757 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
791 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
758 $ echo changed >> file1
792 $ echo changed >> file1
759 $ hg rm file2
793 $ hg rm file2
760 $ hg update 1 --tool :other
794 $ hg update 1 --tool :other
761 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
795 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
762 $ status 2>&1 | tee $TESTTMP/other.status
796 $ status 2>&1 | tee $TESTTMP/other.status
763 --- status ---
797 --- status ---
764 file1: * (glob)
798 file1: * (glob)
765 C file2
799 C file2
766 C file3
800 C file3
767 --- resolve --list ---
801 --- resolve --list ---
768 R file1
802 R file1
769 R file2
803 R file2
770 --- debugmergestate ---
804 --- debugmergestate ---
771 * version 2 records
805 * version 2 records
772 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
806 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
773 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
807 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
808 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
774 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
809 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
775 local path: file1 (flags "")
810 local path: file1 (flags "")
776 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
811 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
777 other path: file1 (node null)
812 other path: file1 (node null)
813 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
778 file: file2 (record type "C", state "r", hash null)
814 file: file2 (record type "C", state "r", hash null)
779 local path: file2 (flags "")
815 local path: file2 (flags "")
780 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
816 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
781 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
817 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
782 *** file1 does not exist
818 *** file1 does not exist
783 --- file2 ---
819 --- file2 ---
784 2
820 2
785 changed
821 changed
786 --- file3 ---
822 --- file3 ---
787 3
823 3
788 changed1
824 changed1
789
825
790 Fail
826 Fail
791
827
792 $ hg co -C 0
828 $ hg co -C 0
793 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
829 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
794 $ echo changed >> file1
830 $ echo changed >> file1
795 $ hg rm file2
831 $ hg rm file2
796 $ hg update 1 --tool :fail
832 $ hg update 1 --tool :fail
797 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
833 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
798 use 'hg resolve' to retry unresolved file merges
834 use 'hg resolve' to retry unresolved file merges
799 [1]
835 [1]
800 $ status 2>&1 | tee $TESTTMP/fail.status
836 $ status 2>&1 | tee $TESTTMP/fail.status
801 --- status ---
837 --- status ---
802 A file1
838 A file1
803 C file2
839 C file2
804 C file3
840 C file3
805 --- resolve --list ---
841 --- resolve --list ---
806 U file1
842 U file1
807 U file2
843 U file2
808 --- debugmergestate ---
844 --- debugmergestate ---
809 * version 2 records
845 * version 2 records
810 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
846 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
811 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
847 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
848 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
812 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
849 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
813 local path: file1 (flags "")
850 local path: file1 (flags "")
814 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
851 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
815 other path: file1 (node null)
852 other path: file1 (node null)
853 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
816 file: file2 (record type "C", state "u", hash null)
854 file: file2 (record type "C", state "u", hash null)
817 local path: file2 (flags "")
855 local path: file2 (flags "")
818 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
856 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
819 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
857 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
820 --- file1 ---
858 --- file1 ---
821 1
859 1
822 changed
860 changed
823 --- file2 ---
861 --- file2 ---
824 2
862 2
825 changed
863 changed
826 --- file3 ---
864 --- file3 ---
827 3
865 3
828 changed1
866 changed1
829
867
830 Force prompts with no input
868 Force prompts with no input
831
869
832 $ hg co -C 0
870 $ hg co -C 0
833 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
871 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
834 $ echo changed >> file1
872 $ echo changed >> file1
835 $ hg rm file2
873 $ hg rm file2
836 $ hg update 1 --config ui.interactive=True --tool :prompt
874 $ hg update 1 --config ui.interactive=True --tool :prompt
837 local changed file1 which remote deleted
875 local changed file1 which remote deleted
838 use (c)hanged version, (d)elete, or leave (u)nresolved?
876 use (c)hanged version, (d)elete, or leave (u)nresolved?
839 remote changed file2 which local deleted
877 remote changed file2 which local deleted
840 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
878 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
841 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
879 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
842 use 'hg resolve' to retry unresolved file merges
880 use 'hg resolve' to retry unresolved file merges
843 [1]
881 [1]
844 $ status 2>&1 | tee $TESTTMP/prompt.status
882 $ status 2>&1 | tee $TESTTMP/prompt.status
845 --- status ---
883 --- status ---
846 A file1
884 A file1
847 C file2
885 C file2
848 C file3
886 C file3
849 --- resolve --list ---
887 --- resolve --list ---
850 U file1
888 U file1
851 U file2
889 U file2
852 --- debugmergestate ---
890 --- debugmergestate ---
853 * version 2 records
891 * version 2 records
854 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
892 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
855 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
893 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
894 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
856 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
895 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
857 local path: file1 (flags "")
896 local path: file1 (flags "")
858 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
897 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
859 other path: file1 (node null)
898 other path: file1 (node null)
899 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
860 file: file2 (record type "C", state "u", hash null)
900 file: file2 (record type "C", state "u", hash null)
861 local path: file2 (flags "")
901 local path: file2 (flags "")
862 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
902 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
863 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
903 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
864 --- file1 ---
904 --- file1 ---
865 1
905 1
866 changed
906 changed
867 --- file2 ---
907 --- file2 ---
868 2
908 2
869 changed
909 changed
870 --- file3 ---
910 --- file3 ---
871 3
911 3
872 changed1
912 changed1
873 $ cmp $TESTTMP/fail.status $TESTTMP/prompt.status || diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
913 $ cmp $TESTTMP/fail.status $TESTTMP/prompt.status || diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
874
914
875 Choose to merge all files
915 Choose to merge all files
876
916
877 $ hg co -C 0
917 $ hg co -C 0
878 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
918 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
879 $ echo changed >> file1
919 $ echo changed >> file1
880 $ hg rm file2
920 $ hg rm file2
881 $ hg update 1 --tool :merge3
921 $ hg update 1 --tool :merge3
882 local changed file1 which remote deleted
922 local changed file1 which remote deleted
883 use (c)hanged version, (d)elete, or leave (u)nresolved? u
923 use (c)hanged version, (d)elete, or leave (u)nresolved? u
884 remote changed file2 which local deleted
924 remote changed file2 which local deleted
885 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
925 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
886 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
926 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
887 use 'hg resolve' to retry unresolved file merges
927 use 'hg resolve' to retry unresolved file merges
888 [1]
928 [1]
889 $ status
929 $ status
890 --- status ---
930 --- status ---
891 A file1
931 A file1
892 C file2
932 C file2
893 C file3
933 C file3
894 --- resolve --list ---
934 --- resolve --list ---
895 U file1
935 U file1
896 U file2
936 U file2
897 --- debugmergestate ---
937 --- debugmergestate ---
898 * version 2 records
938 * version 2 records
899 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
939 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
900 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
940 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
941 file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
901 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
942 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
902 local path: file1 (flags "")
943 local path: file1 (flags "")
903 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
944 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
904 other path: file1 (node null)
945 other path: file1 (node null)
946 file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
905 file: file2 (record type "C", state "u", hash null)
947 file: file2 (record type "C", state "u", hash null)
906 local path: file2 (flags "")
948 local path: file2 (flags "")
907 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
949 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
908 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
950 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
909 --- file1 ---
951 --- file1 ---
910 1
952 1
911 changed
953 changed
912 --- file2 ---
954 --- file2 ---
913 2
955 2
914 changed
956 changed
915 --- file3 ---
957 --- file3 ---
916 3
958 3
917 changed1
959 changed1
918
960
919 Test transitions between different merge tools
961 Test transitions between different merge tools
920
962
921 $ testtransitions
963 $ testtransitions
922 === :merge3 -> :local ===
964 === :merge3 -> :local ===
923 (no more unresolved files)
965 (no more unresolved files)
924 --- diff of status ---
966 --- diff of status ---
925 (status identical)
967 (status identical)
926
968
927 === :local -> :other ===
969 === :local -> :other ===
928 (no more unresolved files)
970 (no more unresolved files)
929 --- diff of status ---
971 --- diff of status ---
930 (status identical)
972 (status identical)
931
973
932 === :other -> :prompt ===
974 === :other -> :prompt ===
933 local changed file1 which remote deleted
975 local changed file1 which remote deleted
934 use (c)hanged version, (d)elete, or leave (u)nresolved?
976 use (c)hanged version, (d)elete, or leave (u)nresolved?
935 remote changed file2 which local deleted
977 remote changed file2 which local deleted
936 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
978 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
937 --- diff of status ---
979 --- diff of status ---
938 (status identical)
980 (status identical)
939
981
940 === :prompt -> :local ===
982 === :prompt -> :local ===
941 (no more unresolved files)
983 (no more unresolved files)
942 --- diff of status ---
984 --- diff of status ---
943 (status identical)
985 (status identical)
944
986
945 === :local -> :fail ===
987 === :local -> :fail ===
946 --- diff of status ---
988 --- diff of status ---
947 (status identical)
989 (status identical)
948
990
949 === :fail -> :other ===
991 === :fail -> :other ===
950 (no more unresolved files)
992 (no more unresolved files)
951 --- diff of status ---
993 --- diff of status ---
952 (status identical)
994 (status identical)
953
995
954 === :other -> :local ===
996 === :other -> :local ===
955 (no more unresolved files)
997 (no more unresolved files)
956 --- diff of status ---
998 --- diff of status ---
957 (status identical)
999 (status identical)
958
1000
959 === :local -> :prompt ===
1001 === :local -> :prompt ===
960 local changed file1 which remote deleted
1002 local changed file1 which remote deleted
961 use (c)hanged version, (d)elete, or leave (u)nresolved?
1003 use (c)hanged version, (d)elete, or leave (u)nresolved?
962 remote changed file2 which local deleted
1004 remote changed file2 which local deleted
963 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
1005 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
964 --- diff of status ---
1006 --- diff of status ---
965 (status identical)
1007 (status identical)
966
1008
967 === :prompt -> :other ===
1009 === :prompt -> :other ===
968 (no more unresolved files)
1010 (no more unresolved files)
969 --- diff of status ---
1011 --- diff of status ---
970 (status identical)
1012 (status identical)
971
1013
972 === :other -> :fail ===
1014 === :other -> :fail ===
973 --- diff of status ---
1015 --- diff of status ---
974 (status identical)
1016 (status identical)
975
1017
976 === :fail -> :prompt ===
1018 === :fail -> :prompt ===
977 local changed file1 which remote deleted
1019 local changed file1 which remote deleted
978 use (c)hanged version, (d)elete, or leave (u)nresolved?
1020 use (c)hanged version, (d)elete, or leave (u)nresolved?
979 remote changed file2 which local deleted
1021 remote changed file2 which local deleted
980 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
1022 use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
981 --- diff of status ---
1023 --- diff of status ---
982 (status identical)
1024 (status identical)
983
1025
984 === :prompt -> :fail ===
1026 === :prompt -> :fail ===
985 --- diff of status ---
1027 --- diff of status ---
986 (status identical)
1028 (status identical)
987
1029
988 === :fail -> :local ===
1030 === :fail -> :local ===
989 (no more unresolved files)
1031 (no more unresolved files)
990 --- diff of status ---
1032 --- diff of status ---
991 (status identical)
1033 (status identical)
992
1034
@@ -1,352 +1,352 b''
1 Criss cross merging
1 Criss cross merging
2
2
3 $ hg init criss-cross
3 $ hg init criss-cross
4 $ cd criss-cross
4 $ cd criss-cross
5 $ echo '0 base' > f1
5 $ echo '0 base' > f1
6 $ echo '0 base' > f2
6 $ echo '0 base' > f2
7 $ hg ci -Aqm '0 base'
7 $ hg ci -Aqm '0 base'
8
8
9 $ echo '1 first change' > f1
9 $ echo '1 first change' > f1
10 $ hg ci -m '1 first change f1'
10 $ hg ci -m '1 first change f1'
11
11
12 $ hg up -qr0
12 $ hg up -qr0
13 $ echo '2 first change' > f2
13 $ echo '2 first change' > f2
14 $ hg ci -qm '2 first change f2'
14 $ hg ci -qm '2 first change f2'
15
15
16 $ hg merge -qr 1
16 $ hg merge -qr 1
17 $ hg ci -m '3 merge'
17 $ hg ci -m '3 merge'
18
18
19 $ hg up -qr2
19 $ hg up -qr2
20 $ hg merge -qr1
20 $ hg merge -qr1
21 $ hg ci -qm '4 merge'
21 $ hg ci -qm '4 merge'
22
22
23 $ echo '5 second change' > f1
23 $ echo '5 second change' > f1
24 $ hg ci -m '5 second change f1'
24 $ hg ci -m '5 second change f1'
25
25
26 $ hg up -r3
26 $ hg up -r3
27 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
27 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 $ echo '6 second change' > f2
28 $ echo '6 second change' > f2
29 $ hg ci -m '6 second change f2'
29 $ hg ci -m '6 second change f2'
30
30
31 $ hg log -G
31 $ hg log -G
32 @ changeset: 6:3b08d01b0ab5
32 @ changeset: 6:3b08d01b0ab5
33 | tag: tip
33 | tag: tip
34 | parent: 3:cf89f02107e5
34 | parent: 3:cf89f02107e5
35 | user: test
35 | user: test
36 | date: Thu Jan 01 00:00:00 1970 +0000
36 | date: Thu Jan 01 00:00:00 1970 +0000
37 | summary: 6 second change f2
37 | summary: 6 second change f2
38 |
38 |
39 | o changeset: 5:adfe50279922
39 | o changeset: 5:adfe50279922
40 | | user: test
40 | | user: test
41 | | date: Thu Jan 01 00:00:00 1970 +0000
41 | | date: Thu Jan 01 00:00:00 1970 +0000
42 | | summary: 5 second change f1
42 | | summary: 5 second change f1
43 | |
43 | |
44 | o changeset: 4:7d3e55501ae6
44 | o changeset: 4:7d3e55501ae6
45 | |\ parent: 2:40663881a6dd
45 | |\ parent: 2:40663881a6dd
46 | | | parent: 1:0f6b37dbe527
46 | | | parent: 1:0f6b37dbe527
47 | | | user: test
47 | | | user: test
48 | | | date: Thu Jan 01 00:00:00 1970 +0000
48 | | | date: Thu Jan 01 00:00:00 1970 +0000
49 | | | summary: 4 merge
49 | | | summary: 4 merge
50 | | |
50 | | |
51 o---+ changeset: 3:cf89f02107e5
51 o---+ changeset: 3:cf89f02107e5
52 | | | parent: 2:40663881a6dd
52 | | | parent: 2:40663881a6dd
53 |/ / parent: 1:0f6b37dbe527
53 |/ / parent: 1:0f6b37dbe527
54 | | user: test
54 | | user: test
55 | | date: Thu Jan 01 00:00:00 1970 +0000
55 | | date: Thu Jan 01 00:00:00 1970 +0000
56 | | summary: 3 merge
56 | | summary: 3 merge
57 | |
57 | |
58 | o changeset: 2:40663881a6dd
58 | o changeset: 2:40663881a6dd
59 | | parent: 0:40494bf2444c
59 | | parent: 0:40494bf2444c
60 | | user: test
60 | | user: test
61 | | date: Thu Jan 01 00:00:00 1970 +0000
61 | | date: Thu Jan 01 00:00:00 1970 +0000
62 | | summary: 2 first change f2
62 | | summary: 2 first change f2
63 | |
63 | |
64 o | changeset: 1:0f6b37dbe527
64 o | changeset: 1:0f6b37dbe527
65 |/ user: test
65 |/ user: test
66 | date: Thu Jan 01 00:00:00 1970 +0000
66 | date: Thu Jan 01 00:00:00 1970 +0000
67 | summary: 1 first change f1
67 | summary: 1 first change f1
68 |
68 |
69 o changeset: 0:40494bf2444c
69 o changeset: 0:40494bf2444c
70 user: test
70 user: test
71 date: Thu Jan 01 00:00:00 1970 +0000
71 date: Thu Jan 01 00:00:00 1970 +0000
72 summary: 0 base
72 summary: 0 base
73
73
74
74
75 $ hg merge -v --debug --tool internal:dump 5 --config merge.preferancestor='!'
75 $ hg merge -v --debug --tool internal:dump 5 --config merge.preferancestor='!'
76 note: using 0f6b37dbe527 as ancestor of 3b08d01b0ab5 and adfe50279922
76 note: using 0f6b37dbe527 as ancestor of 3b08d01b0ab5 and adfe50279922
77 alternatively, use --config merge.preferancestor=40663881a6dd
77 alternatively, use --config merge.preferancestor=40663881a6dd
78 searching for copies back to rev 3
78 searching for copies back to rev 3
79 resolving manifests
79 resolving manifests
80 branchmerge: True, force: False, partial: False
80 branchmerge: True, force: False, partial: False
81 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
81 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
82 preserving f2 for resolve of f2
82 preserving f2 for resolve of f2
83 f1: remote is newer -> g
83 f1: remote is newer -> g
84 getting f1
84 getting f1
85 f2: versions differ -> m (premerge)
85 f2: versions differ -> m (premerge)
86 picked tool ':dump' for f2 (binary False symlink False changedelete False)
86 picked tool ':dump' for f2 (binary False symlink False changedelete False)
87 merging f2
87 merging f2
88 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@40494bf2444c
88 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
89 f2: versions differ -> m (merge)
89 f2: versions differ -> m (merge)
90 picked tool ':dump' for f2 (binary False symlink False changedelete False)
90 picked tool ':dump' for f2 (binary False symlink False changedelete False)
91 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@40494bf2444c
91 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
92 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
92 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
93 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
93 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
94 [1]
94 [1]
95
95
96 $ head *
96 $ head *
97 ==> f1 <==
97 ==> f1 <==
98 5 second change
98 5 second change
99
99
100 ==> f2 <==
100 ==> f2 <==
101 6 second change
101 6 second change
102
102
103 ==> f2.base <==
103 ==> f2.base <==
104 0 base
104 0 base
105
105
106 ==> f2.local <==
106 ==> f2.local <==
107 6 second change
107 6 second change
108
108
109 ==> f2.orig <==
109 ==> f2.orig <==
110 6 second change
110 6 second change
111
111
112 ==> f2.other <==
112 ==> f2.other <==
113 2 first change
113 2 first change
114
114
115 $ hg up -qC .
115 $ hg up -qC .
116 $ hg merge -v --tool internal:dump 5 --config merge.preferancestor="null 40663881 3b08d"
116 $ hg merge -v --tool internal:dump 5 --config merge.preferancestor="null 40663881 3b08d"
117 note: using 40663881a6dd as ancestor of 3b08d01b0ab5 and adfe50279922
117 note: using 40663881a6dd as ancestor of 3b08d01b0ab5 and adfe50279922
118 alternatively, use --config merge.preferancestor=0f6b37dbe527
118 alternatively, use --config merge.preferancestor=0f6b37dbe527
119 resolving manifests
119 resolving manifests
120 merging f1
120 merging f1
121 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
121 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
122 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
122 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
123 [1]
123 [1]
124
124
125 Redo merge with merge.preferancestor="*" to enable bid merge
125 Redo merge with merge.preferancestor="*" to enable bid merge
126
126
127 $ rm f*
127 $ rm f*
128 $ hg up -qC .
128 $ hg up -qC .
129 $ hg merge -v --debug --tool internal:dump 5 --config merge.preferancestor="*"
129 $ hg merge -v --debug --tool internal:dump 5 --config merge.preferancestor="*"
130 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
130 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
131
131
132 calculating bids for ancestor 0f6b37dbe527
132 calculating bids for ancestor 0f6b37dbe527
133 searching for copies back to rev 3
133 searching for copies back to rev 3
134 resolving manifests
134 resolving manifests
135 branchmerge: True, force: False, partial: False
135 branchmerge: True, force: False, partial: False
136 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
136 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
137 f1: remote is newer -> g
137 f1: remote is newer -> g
138 f2: versions differ -> m
138 f2: versions differ -> m
139
139
140 calculating bids for ancestor 40663881a6dd
140 calculating bids for ancestor 40663881a6dd
141 searching for copies back to rev 3
141 searching for copies back to rev 3
142 resolving manifests
142 resolving manifests
143 branchmerge: True, force: False, partial: False
143 branchmerge: True, force: False, partial: False
144 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
144 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
145 f1: versions differ -> m
145 f1: versions differ -> m
146 f2: remote unchanged -> k
146 f2: remote unchanged -> k
147
147
148 auction for merging merge bids
148 auction for merging merge bids
149 f1: picking 'get' action
149 f1: picking 'get' action
150 f2: picking 'keep' action
150 f2: picking 'keep' action
151 end of auction
151 end of auction
152
152
153 f1: remote is newer -> g
153 f1: remote is newer -> g
154 getting f1
154 getting f1
155 f2: remote unchanged -> k
155 f2: remote unchanged -> k
156 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
156 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
157 (branch merge, don't forget to commit)
157 (branch merge, don't forget to commit)
158
158
159 $ head *
159 $ head *
160 ==> f1 <==
160 ==> f1 <==
161 5 second change
161 5 second change
162
162
163 ==> f2 <==
163 ==> f2 <==
164 6 second change
164 6 second change
165
165
166
166
167 The other way around:
167 The other way around:
168
168
169 $ hg up -C -r5
169 $ hg up -C -r5
170 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
170 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
171 $ hg merge -v --debug --config merge.preferancestor="*"
171 $ hg merge -v --debug --config merge.preferancestor="*"
172 note: merging adfe50279922+ and 3b08d01b0ab5 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
172 note: merging adfe50279922+ and 3b08d01b0ab5 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
173
173
174 calculating bids for ancestor 0f6b37dbe527
174 calculating bids for ancestor 0f6b37dbe527
175 searching for copies back to rev 3
175 searching for copies back to rev 3
176 resolving manifests
176 resolving manifests
177 branchmerge: True, force: False, partial: False
177 branchmerge: True, force: False, partial: False
178 ancestor: 0f6b37dbe527, local: adfe50279922+, remote: 3b08d01b0ab5
178 ancestor: 0f6b37dbe527, local: adfe50279922+, remote: 3b08d01b0ab5
179 f1: remote unchanged -> k
179 f1: remote unchanged -> k
180 f2: versions differ -> m
180 f2: versions differ -> m
181
181
182 calculating bids for ancestor 40663881a6dd
182 calculating bids for ancestor 40663881a6dd
183 searching for copies back to rev 3
183 searching for copies back to rev 3
184 resolving manifests
184 resolving manifests
185 branchmerge: True, force: False, partial: False
185 branchmerge: True, force: False, partial: False
186 ancestor: 40663881a6dd, local: adfe50279922+, remote: 3b08d01b0ab5
186 ancestor: 40663881a6dd, local: adfe50279922+, remote: 3b08d01b0ab5
187 f1: versions differ -> m
187 f1: versions differ -> m
188 f2: remote is newer -> g
188 f2: remote is newer -> g
189
189
190 auction for merging merge bids
190 auction for merging merge bids
191 f1: picking 'keep' action
191 f1: picking 'keep' action
192 f2: picking 'get' action
192 f2: picking 'get' action
193 end of auction
193 end of auction
194
194
195 f2: remote is newer -> g
195 f2: remote is newer -> g
196 getting f2
196 getting f2
197 f1: remote unchanged -> k
197 f1: remote unchanged -> k
198 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
198 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
199 (branch merge, don't forget to commit)
199 (branch merge, don't forget to commit)
200
200
201 $ head *
201 $ head *
202 ==> f1 <==
202 ==> f1 <==
203 5 second change
203 5 second change
204
204
205 ==> f2 <==
205 ==> f2 <==
206 6 second change
206 6 second change
207
207
208 Verify how the output looks and and how verbose it is:
208 Verify how the output looks and and how verbose it is:
209
209
210 $ hg up -qC
210 $ hg up -qC
211 $ hg merge
211 $ hg merge
212 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
213 (branch merge, don't forget to commit)
213 (branch merge, don't forget to commit)
214
214
215 $ hg up -qC
215 $ hg up -qC
216 $ hg merge -v
216 $ hg merge -v
217 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
217 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
218
218
219 calculating bids for ancestor 0f6b37dbe527
219 calculating bids for ancestor 0f6b37dbe527
220 resolving manifests
220 resolving manifests
221
221
222 calculating bids for ancestor 40663881a6dd
222 calculating bids for ancestor 40663881a6dd
223 resolving manifests
223 resolving manifests
224
224
225 auction for merging merge bids
225 auction for merging merge bids
226 f1: picking 'get' action
226 f1: picking 'get' action
227 f2: picking 'keep' action
227 f2: picking 'keep' action
228 end of auction
228 end of auction
229
229
230 getting f1
230 getting f1
231 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
232 (branch merge, don't forget to commit)
232 (branch merge, don't forget to commit)
233
233
234 $ hg up -qC
234 $ hg up -qC
235 $ hg merge -v --debug --config merge.preferancestor="*"
235 $ hg merge -v --debug --config merge.preferancestor="*"
236 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
236 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
237
237
238 calculating bids for ancestor 0f6b37dbe527
238 calculating bids for ancestor 0f6b37dbe527
239 searching for copies back to rev 3
239 searching for copies back to rev 3
240 resolving manifests
240 resolving manifests
241 branchmerge: True, force: False, partial: False
241 branchmerge: True, force: False, partial: False
242 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
242 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
243 f1: remote is newer -> g
243 f1: remote is newer -> g
244 f2: versions differ -> m
244 f2: versions differ -> m
245
245
246 calculating bids for ancestor 40663881a6dd
246 calculating bids for ancestor 40663881a6dd
247 searching for copies back to rev 3
247 searching for copies back to rev 3
248 resolving manifests
248 resolving manifests
249 branchmerge: True, force: False, partial: False
249 branchmerge: True, force: False, partial: False
250 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
250 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
251 f1: versions differ -> m
251 f1: versions differ -> m
252 f2: remote unchanged -> k
252 f2: remote unchanged -> k
253
253
254 auction for merging merge bids
254 auction for merging merge bids
255 f1: picking 'get' action
255 f1: picking 'get' action
256 f2: picking 'keep' action
256 f2: picking 'keep' action
257 end of auction
257 end of auction
258
258
259 f1: remote is newer -> g
259 f1: remote is newer -> g
260 getting f1
260 getting f1
261 f2: remote unchanged -> k
261 f2: remote unchanged -> k
262 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
262 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
263 (branch merge, don't forget to commit)
263 (branch merge, don't forget to commit)
264
264
265 $ cd ..
265 $ cd ..
266
266
267 http://stackoverflow.com/questions/9350005/how-do-i-specify-a-merge-base-to-use-in-a-hg-merge/9430810
267 http://stackoverflow.com/questions/9350005/how-do-i-specify-a-merge-base-to-use-in-a-hg-merge/9430810
268
268
269 $ hg init ancestor-merging
269 $ hg init ancestor-merging
270 $ cd ancestor-merging
270 $ cd ancestor-merging
271 $ echo a > x
271 $ echo a > x
272 $ hg commit -A -m a x
272 $ hg commit -A -m a x
273 $ hg update -q 0
273 $ hg update -q 0
274 $ echo b >> x
274 $ echo b >> x
275 $ hg commit -m b
275 $ hg commit -m b
276 $ hg update -q 0
276 $ hg update -q 0
277 $ echo c >> x
277 $ echo c >> x
278 $ hg commit -qm c
278 $ hg commit -qm c
279 $ hg update -q 1
279 $ hg update -q 1
280 $ hg merge -q --tool internal:local 2
280 $ hg merge -q --tool internal:local 2
281 $ echo c >> x
281 $ echo c >> x
282 $ hg commit -m bc
282 $ hg commit -m bc
283 $ hg update -q 2
283 $ hg update -q 2
284 $ hg merge -q --tool internal:local 1
284 $ hg merge -q --tool internal:local 1
285 $ echo b >> x
285 $ echo b >> x
286 $ hg commit -qm cb
286 $ hg commit -qm cb
287
287
288 $ hg merge --config merge.preferancestor='!'
288 $ hg merge --config merge.preferancestor='!'
289 note: using 70008a2163f6 as ancestor of 0d355fdef312 and 4b8b546a3eef
289 note: using 70008a2163f6 as ancestor of 0d355fdef312 and 4b8b546a3eef
290 alternatively, use --config merge.preferancestor=b211bbc6eb3c
290 alternatively, use --config merge.preferancestor=b211bbc6eb3c
291 merging x
291 merging x
292 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
292 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
293 (branch merge, don't forget to commit)
293 (branch merge, don't forget to commit)
294 $ cat x
294 $ cat x
295 a
295 a
296 c
296 c
297 b
297 b
298 c
298 c
299
299
300 $ hg up -qC .
300 $ hg up -qC .
301
301
302 $ hg merge --config merge.preferancestor=b211bbc6eb3c
302 $ hg merge --config merge.preferancestor=b211bbc6eb3c
303 note: using b211bbc6eb3c as ancestor of 0d355fdef312 and 4b8b546a3eef
303 note: using b211bbc6eb3c as ancestor of 0d355fdef312 and 4b8b546a3eef
304 alternatively, use --config merge.preferancestor=70008a2163f6
304 alternatively, use --config merge.preferancestor=70008a2163f6
305 merging x
305 merging x
306 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
306 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
307 (branch merge, don't forget to commit)
307 (branch merge, don't forget to commit)
308 $ cat x
308 $ cat x
309 a
309 a
310 b
310 b
311 c
311 c
312 b
312 b
313
313
314 $ hg up -qC .
314 $ hg up -qC .
315
315
316 $ hg merge -v --config merge.preferancestor="*"
316 $ hg merge -v --config merge.preferancestor="*"
317 note: merging 0d355fdef312+ and 4b8b546a3eef using bids from ancestors 70008a2163f6 and b211bbc6eb3c
317 note: merging 0d355fdef312+ and 4b8b546a3eef using bids from ancestors 70008a2163f6 and b211bbc6eb3c
318
318
319 calculating bids for ancestor 70008a2163f6
319 calculating bids for ancestor 70008a2163f6
320 resolving manifests
320 resolving manifests
321
321
322 calculating bids for ancestor b211bbc6eb3c
322 calculating bids for ancestor b211bbc6eb3c
323 resolving manifests
323 resolving manifests
324
324
325 auction for merging merge bids
325 auction for merging merge bids
326 x: multiple bids for merge action:
326 x: multiple bids for merge action:
327 versions differ -> m
327 versions differ -> m
328 versions differ -> m
328 versions differ -> m
329 x: ambiguous merge - picked m action
329 x: ambiguous merge - picked m action
330 end of auction
330 end of auction
331
331
332 merging x
332 merging x
333 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
333 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
334 (branch merge, don't forget to commit)
334 (branch merge, don't forget to commit)
335 $ cat x
335 $ cat x
336 a
336 a
337 c
337 c
338 b
338 b
339 c
339 c
340
340
341 Verify that the old context ancestor works with / despite preferancestor:
341 Verify that the old context ancestor works with / despite preferancestor:
342
342
343 $ hg log -r 'ancestor(head())' --config merge.preferancestor=1 -T '{rev}\n'
343 $ hg log -r 'ancestor(head())' --config merge.preferancestor=1 -T '{rev}\n'
344 1
344 1
345 $ hg log -r 'ancestor(head())' --config merge.preferancestor=2 -T '{rev}\n'
345 $ hg log -r 'ancestor(head())' --config merge.preferancestor=2 -T '{rev}\n'
346 2
346 2
347 $ hg log -r 'ancestor(head())' --config merge.preferancestor=3 -T '{rev}\n'
347 $ hg log -r 'ancestor(head())' --config merge.preferancestor=3 -T '{rev}\n'
348 1
348 1
349 $ hg log -r 'ancestor(head())' --config merge.preferancestor='1337 * - 2' -T '{rev}\n'
349 $ hg log -r 'ancestor(head())' --config merge.preferancestor='1337 * - 2' -T '{rev}\n'
350 2
350 2
351
351
352 $ cd ..
352 $ cd ..
@@ -1,394 +1,396 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > rebase=
3 > rebase=
4 >
4 >
5 > [phases]
5 > [phases]
6 > publish=False
6 > publish=False
7 >
7 >
8 > [alias]
8 > [alias]
9 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
9 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
10 > EOF
10 > EOF
11
11
12
12
13 $ hg init a
13 $ hg init a
14 $ cd a
14 $ cd a
15
15
16 $ touch .hg/rebasestate
16 $ touch .hg/rebasestate
17 $ hg sum
17 $ hg sum
18 parent: -1:000000000000 tip (empty repository)
18 parent: -1:000000000000 tip (empty repository)
19 branch: default
19 branch: default
20 commit: (clean)
20 commit: (clean)
21 update: (current)
21 update: (current)
22 abort: .hg/rebasestate is incomplete
22 abort: .hg/rebasestate is incomplete
23 [255]
23 [255]
24 $ rm .hg/rebasestate
24 $ rm .hg/rebasestate
25
25
26 $ echo c1 > common
26 $ echo c1 > common
27 $ hg add common
27 $ hg add common
28 $ hg ci -m C1
28 $ hg ci -m C1
29
29
30 $ echo c2 >> common
30 $ echo c2 >> common
31 $ hg ci -m C2
31 $ hg ci -m C2
32
32
33 $ echo c3 >> common
33 $ echo c3 >> common
34 $ hg ci -m C3
34 $ hg ci -m C3
35
35
36 $ hg up -q -C 1
36 $ hg up -q -C 1
37
37
38 $ echo l1 >> extra
38 $ echo l1 >> extra
39 $ hg add extra
39 $ hg add extra
40 $ hg ci -m L1
40 $ hg ci -m L1
41 created new head
41 created new head
42
42
43 $ sed -e 's/c2/l2/' common > common.new
43 $ sed -e 's/c2/l2/' common > common.new
44 $ mv common.new common
44 $ mv common.new common
45 $ hg ci -m L2
45 $ hg ci -m L2
46
46
47 $ hg phase --force --secret 2
47 $ hg phase --force --secret 2
48
48
49 $ hg tglog
49 $ hg tglog
50 @ 4:draft 'L2'
50 @ 4:draft 'L2'
51 |
51 |
52 o 3:draft 'L1'
52 o 3:draft 'L1'
53 |
53 |
54 | o 2:secret 'C3'
54 | o 2:secret 'C3'
55 |/
55 |/
56 o 1:draft 'C2'
56 o 1:draft 'C2'
57 |
57 |
58 o 0:draft 'C1'
58 o 0:draft 'C1'
59
59
60
60
61 Conflicting rebase:
61 Conflicting rebase:
62
62
63 $ hg rebase -s 3 -d 2
63 $ hg rebase -s 3 -d 2
64 rebasing 3:3163e20567cc "L1"
64 rebasing 3:3163e20567cc "L1"
65 rebasing 4:46f0b057b5c0 "L2" (tip)
65 rebasing 4:46f0b057b5c0 "L2" (tip)
66 merging common
66 merging common
67 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
67 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
68 unresolved conflicts (see hg resolve, then hg rebase --continue)
68 unresolved conflicts (see hg resolve, then hg rebase --continue)
69 [1]
69 [1]
70
70
71 Insert unsupported advisory merge record:
71 Insert unsupported advisory merge record:
72
72
73 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
73 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
74 $ hg debugmergestate
74 $ hg debugmergestate
75 * version 2 records
75 * version 2 records
76 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
76 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
77 other: 46f0b057b5c061d276b91491c22151f78698abd2
77 other: 46f0b057b5c061d276b91491c22151f78698abd2
78 unrecognized entry: x advisory record
78 unrecognized entry: x advisory record
79 file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
79 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
80 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
80 local path: common (flags "")
81 local path: common (flags "")
81 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
82 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
82 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
83 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
83 $ hg resolve -l
84 $ hg resolve -l
84 U common
85 U common
85
86
86 Insert unsupported mandatory merge record:
87 Insert unsupported mandatory merge record:
87
88
88 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
89 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
89 $ hg debugmergestate
90 $ hg debugmergestate
90 * version 2 records
91 * version 2 records
91 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
92 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
92 other: 46f0b057b5c061d276b91491c22151f78698abd2
93 other: 46f0b057b5c061d276b91491c22151f78698abd2
94 file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
93 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
95 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
94 local path: common (flags "")
96 local path: common (flags "")
95 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
97 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
96 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
98 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
97 unrecognized entry: X mandatory record
99 unrecognized entry: X mandatory record
98 $ hg resolve -l
100 $ hg resolve -l
99 abort: unsupported merge state records: X
101 abort: unsupported merge state records: X
100 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
102 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
101 [255]
103 [255]
102 $ hg resolve -ma
104 $ hg resolve -ma
103 abort: unsupported merge state records: X
105 abort: unsupported merge state records: X
104 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
106 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
105 [255]
107 [255]
106
108
107 Abort (should clear out unsupported merge state):
109 Abort (should clear out unsupported merge state):
108
110
109 $ hg rebase --abort
111 $ hg rebase --abort
110 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3e046f2ecedb-6beef7d5-backup.hg (glob)
112 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3e046f2ecedb-6beef7d5-backup.hg (glob)
111 rebase aborted
113 rebase aborted
112 $ hg debugmergestate
114 $ hg debugmergestate
113 no merge state found
115 no merge state found
114
116
115 $ hg tglog
117 $ hg tglog
116 @ 4:draft 'L2'
118 @ 4:draft 'L2'
117 |
119 |
118 o 3:draft 'L1'
120 o 3:draft 'L1'
119 |
121 |
120 | o 2:secret 'C3'
122 | o 2:secret 'C3'
121 |/
123 |/
122 o 1:draft 'C2'
124 o 1:draft 'C2'
123 |
125 |
124 o 0:draft 'C1'
126 o 0:draft 'C1'
125
127
126 Test safety for inconsistent rebase state, which may be created (and
128 Test safety for inconsistent rebase state, which may be created (and
127 forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
129 forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
128 earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
130 earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
129
131
130 $ hg rebase -s 3 -d 2
132 $ hg rebase -s 3 -d 2
131 rebasing 3:3163e20567cc "L1"
133 rebasing 3:3163e20567cc "L1"
132 rebasing 4:46f0b057b5c0 "L2" (tip)
134 rebasing 4:46f0b057b5c0 "L2" (tip)
133 merging common
135 merging common
134 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
136 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
135 unresolved conflicts (see hg resolve, then hg rebase --continue)
137 unresolved conflicts (see hg resolve, then hg rebase --continue)
136 [1]
138 [1]
137
139
138 $ mv .hg/rebasestate .hg/rebasestate.back
140 $ mv .hg/rebasestate .hg/rebasestate.back
139 $ hg update --quiet --clean 2
141 $ hg update --quiet --clean 2
140 $ hg --config extensions.mq= strip --quiet "destination()"
142 $ hg --config extensions.mq= strip --quiet "destination()"
141 $ mv .hg/rebasestate.back .hg/rebasestate
143 $ mv .hg/rebasestate.back .hg/rebasestate
142
144
143 $ hg rebase --continue
145 $ hg rebase --continue
144 abort: cannot continue inconsistent rebase
146 abort: cannot continue inconsistent rebase
145 (use "hg rebase --abort" to clear broken state)
147 (use "hg rebase --abort" to clear broken state)
146 [255]
148 [255]
147 $ hg summary | grep '^rebase: '
149 $ hg summary | grep '^rebase: '
148 rebase: (use "hg rebase --abort" to clear broken state)
150 rebase: (use "hg rebase --abort" to clear broken state)
149 $ hg rebase --abort
151 $ hg rebase --abort
150 rebase aborted (no revision is removed, only broken state is cleared)
152 rebase aborted (no revision is removed, only broken state is cleared)
151
153
152 $ cd ..
154 $ cd ..
153
155
154
156
155 Construct new repo:
157 Construct new repo:
156
158
157 $ hg init b
159 $ hg init b
158 $ cd b
160 $ cd b
159
161
160 $ echo a > a
162 $ echo a > a
161 $ hg ci -Am A
163 $ hg ci -Am A
162 adding a
164 adding a
163
165
164 $ echo b > b
166 $ echo b > b
165 $ hg ci -Am B
167 $ hg ci -Am B
166 adding b
168 adding b
167
169
168 $ echo c > c
170 $ echo c > c
169 $ hg ci -Am C
171 $ hg ci -Am C
170 adding c
172 adding c
171
173
172 $ hg up -q 0
174 $ hg up -q 0
173
175
174 $ echo b > b
176 $ echo b > b
175 $ hg ci -Am 'B bis'
177 $ hg ci -Am 'B bis'
176 adding b
178 adding b
177 created new head
179 created new head
178
180
179 $ echo c1 > c
181 $ echo c1 > c
180 $ hg ci -Am C1
182 $ hg ci -Am C1
181 adding c
183 adding c
182
184
183 $ hg phase --force --secret 1
185 $ hg phase --force --secret 1
184 $ hg phase --public 1
186 $ hg phase --public 1
185
187
186 Rebase and abort without generating new changesets:
188 Rebase and abort without generating new changesets:
187
189
188 $ hg tglog
190 $ hg tglog
189 @ 4:draft 'C1'
191 @ 4:draft 'C1'
190 |
192 |
191 o 3:draft 'B bis'
193 o 3:draft 'B bis'
192 |
194 |
193 | o 2:secret 'C'
195 | o 2:secret 'C'
194 | |
196 | |
195 | o 1:public 'B'
197 | o 1:public 'B'
196 |/
198 |/
197 o 0:public 'A'
199 o 0:public 'A'
198
200
199 $ hg rebase -b 4 -d 2
201 $ hg rebase -b 4 -d 2
200 rebasing 3:a6484957d6b9 "B bis"
202 rebasing 3:a6484957d6b9 "B bis"
201 note: rebase of 3:a6484957d6b9 created no changes to commit
203 note: rebase of 3:a6484957d6b9 created no changes to commit
202 rebasing 4:145842775fec "C1" (tip)
204 rebasing 4:145842775fec "C1" (tip)
203 merging c
205 merging c
204 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
206 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
205 unresolved conflicts (see hg resolve, then hg rebase --continue)
207 unresolved conflicts (see hg resolve, then hg rebase --continue)
206 [1]
208 [1]
207
209
208 $ hg tglog
210 $ hg tglog
209 @ 4:draft 'C1'
211 @ 4:draft 'C1'
210 |
212 |
211 o 3:draft 'B bis'
213 o 3:draft 'B bis'
212 |
214 |
213 | @ 2:secret 'C'
215 | @ 2:secret 'C'
214 | |
216 | |
215 | o 1:public 'B'
217 | o 1:public 'B'
216 |/
218 |/
217 o 0:public 'A'
219 o 0:public 'A'
218
220
219 $ hg rebase -a
221 $ hg rebase -a
220 rebase aborted
222 rebase aborted
221
223
222 $ hg tglog
224 $ hg tglog
223 @ 4:draft 'C1'
225 @ 4:draft 'C1'
224 |
226 |
225 o 3:draft 'B bis'
227 o 3:draft 'B bis'
226 |
228 |
227 | o 2:secret 'C'
229 | o 2:secret 'C'
228 | |
230 | |
229 | o 1:public 'B'
231 | o 1:public 'B'
230 |/
232 |/
231 o 0:public 'A'
233 o 0:public 'A'
232
234
233
235
234 $ cd ..
236 $ cd ..
235
237
236 rebase abort should not leave working copy in a merge state if tip-1 is public
238 rebase abort should not leave working copy in a merge state if tip-1 is public
237 (issue4082)
239 (issue4082)
238
240
239 $ hg init abortpublic
241 $ hg init abortpublic
240 $ cd abortpublic
242 $ cd abortpublic
241 $ echo a > a && hg ci -Aqm a
243 $ echo a > a && hg ci -Aqm a
242 $ hg book master
244 $ hg book master
243 $ hg book foo
245 $ hg book foo
244 $ echo b > b && hg ci -Aqm b
246 $ echo b > b && hg ci -Aqm b
245 $ hg up -q master
247 $ hg up -q master
246 $ echo c > c && hg ci -Aqm c
248 $ echo c > c && hg ci -Aqm c
247 $ hg phase -p -r .
249 $ hg phase -p -r .
248 $ hg up -q foo
250 $ hg up -q foo
249 $ echo C > c && hg ci -Aqm C
251 $ echo C > c && hg ci -Aqm C
250 $ hg log -G --template "{rev} {desc} {bookmarks}"
252 $ hg log -G --template "{rev} {desc} {bookmarks}"
251 @ 3 C foo
253 @ 3 C foo
252 |
254 |
253 | o 2 c master
255 | o 2 c master
254 | |
256 | |
255 o | 1 b
257 o | 1 b
256 |/
258 |/
257 o 0 a
259 o 0 a
258
260
259
261
260 $ hg rebase -d master -r foo
262 $ hg rebase -d master -r foo
261 rebasing 3:6c0f977a22d8 "C" (tip foo)
263 rebasing 3:6c0f977a22d8 "C" (tip foo)
262 merging c
264 merging c
263 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
265 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
264 unresolved conflicts (see hg resolve, then hg rebase --continue)
266 unresolved conflicts (see hg resolve, then hg rebase --continue)
265 [1]
267 [1]
266 $ hg rebase --abort
268 $ hg rebase --abort
267 rebase aborted
269 rebase aborted
268 $ hg log -G --template "{rev} {desc} {bookmarks}"
270 $ hg log -G --template "{rev} {desc} {bookmarks}"
269 @ 3 C foo
271 @ 3 C foo
270 |
272 |
271 | o 2 c master
273 | o 2 c master
272 | |
274 | |
273 o | 1 b
275 o | 1 b
274 |/
276 |/
275 o 0 a
277 o 0 a
276
278
277 $ cd ..
279 $ cd ..
278
280
279 Make sure we don't clobber changes in the working directory when the
281 Make sure we don't clobber changes in the working directory when the
280 user has somehow managed to update to a different revision (issue4009)
282 user has somehow managed to update to a different revision (issue4009)
281
283
282 $ hg init noupdate
284 $ hg init noupdate
283 $ cd noupdate
285 $ cd noupdate
284 $ hg book @
286 $ hg book @
285 $ echo original > a
287 $ echo original > a
286 $ hg add a
288 $ hg add a
287 $ hg commit -m a
289 $ hg commit -m a
288 $ echo x > b
290 $ echo x > b
289 $ hg add b
291 $ hg add b
290 $ hg commit -m b1
292 $ hg commit -m b1
291 $ hg up 0
293 $ hg up 0
292 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
294 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
293 (leaving bookmark @)
295 (leaving bookmark @)
294 $ hg book foo
296 $ hg book foo
295 $ echo y > b
297 $ echo y > b
296 $ hg add b
298 $ hg add b
297 $ hg commit -m b2
299 $ hg commit -m b2
298 created new head
300 created new head
299
301
300 $ hg rebase -d @ -b foo --tool=internal:fail
302 $ hg rebase -d @ -b foo --tool=internal:fail
301 rebasing 2:070cf4580bb5 "b2" (tip foo)
303 rebasing 2:070cf4580bb5 "b2" (tip foo)
302 unresolved conflicts (see hg resolve, then hg rebase --continue)
304 unresolved conflicts (see hg resolve, then hg rebase --continue)
303 [1]
305 [1]
304
306
305 $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
307 $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
306 $ hg up -C 0 # user does other stuff in the repo
308 $ hg up -C 0 # user does other stuff in the repo
307 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
309 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
308
310
309 $ mv rebasestate .hg/ # user upgrades to 2.7
311 $ mv rebasestate .hg/ # user upgrades to 2.7
310
312
311 $ echo new > a
313 $ echo new > a
312 $ hg up 1 # user gets an error saying to run hg rebase --abort
314 $ hg up 1 # user gets an error saying to run hg rebase --abort
313 abort: rebase in progress
315 abort: rebase in progress
314 (use 'hg rebase --continue' or 'hg rebase --abort')
316 (use 'hg rebase --continue' or 'hg rebase --abort')
315 [255]
317 [255]
316
318
317 $ cat a
319 $ cat a
318 new
320 new
319 $ hg rebase --abort
321 $ hg rebase --abort
320 rebase aborted
322 rebase aborted
321 $ cat a
323 $ cat a
322 new
324 new
323
325
324 $ cd ..
326 $ cd ..
325
327
326 On the other hand, make sure we *do* clobber changes whenever we
328 On the other hand, make sure we *do* clobber changes whenever we
327 haven't somehow managed to update the repo to a different revision
329 haven't somehow managed to update the repo to a different revision
328 during a rebase (issue4661)
330 during a rebase (issue4661)
329
331
330 $ hg ini yesupdate
332 $ hg ini yesupdate
331 $ cd yesupdate
333 $ cd yesupdate
332 $ echo "initial data" > foo.txt
334 $ echo "initial data" > foo.txt
333 $ hg add
335 $ hg add
334 adding foo.txt
336 adding foo.txt
335 $ hg ci -m "initial checkin"
337 $ hg ci -m "initial checkin"
336 $ echo "change 1" > foo.txt
338 $ echo "change 1" > foo.txt
337 $ hg ci -m "change 1"
339 $ hg ci -m "change 1"
338 $ hg up 0
340 $ hg up 0
339 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
341 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 $ echo "conflicting change 1" > foo.txt
342 $ echo "conflicting change 1" > foo.txt
341 $ hg ci -m "conflicting 1"
343 $ hg ci -m "conflicting 1"
342 created new head
344 created new head
343 $ echo "conflicting change 2" > foo.txt
345 $ echo "conflicting change 2" > foo.txt
344 $ hg ci -m "conflicting 2"
346 $ hg ci -m "conflicting 2"
345
347
346 $ hg rebase -d 1 --tool 'internal:fail'
348 $ hg rebase -d 1 --tool 'internal:fail'
347 rebasing 2:e4ea5cdc9789 "conflicting 1"
349 rebasing 2:e4ea5cdc9789 "conflicting 1"
348 unresolved conflicts (see hg resolve, then hg rebase --continue)
350 unresolved conflicts (see hg resolve, then hg rebase --continue)
349 [1]
351 [1]
350 $ hg rebase --abort
352 $ hg rebase --abort
351 rebase aborted
353 rebase aborted
352 $ hg summary
354 $ hg summary
353 parent: 3:b16646383533 tip
355 parent: 3:b16646383533 tip
354 conflicting 2
356 conflicting 2
355 branch: default
357 branch: default
356 commit: (clean)
358 commit: (clean)
357 update: 1 new changesets, 2 branch heads (merge)
359 update: 1 new changesets, 2 branch heads (merge)
358 phases: 4 draft
360 phases: 4 draft
359 $ cd ..
361 $ cd ..
360
362
361 test aborting a rebase succeeds after rebasing with skipped commits onto a
363 test aborting a rebase succeeds after rebasing with skipped commits onto a
362 public changeset (issue4896)
364 public changeset (issue4896)
363
365
364 $ hg init succeedonpublic
366 $ hg init succeedonpublic
365 $ cd succeedonpublic
367 $ cd succeedonpublic
366 $ echo 'content' > root
368 $ echo 'content' > root
367 $ hg commit -A -m 'root' -q
369 $ hg commit -A -m 'root' -q
368
370
369 set up public branch
371 set up public branch
370 $ echo 'content' > disappear
372 $ echo 'content' > disappear
371 $ hg commit -A -m 'disappear public' -q
373 $ hg commit -A -m 'disappear public' -q
372 commit will cause merge conflict on rebase
374 commit will cause merge conflict on rebase
373 $ echo '' > root
375 $ echo '' > root
374 $ hg commit -m 'remove content public' -q
376 $ hg commit -m 'remove content public' -q
375 $ hg phase --public
377 $ hg phase --public
376
378
377 setup the draft branch that will be rebased onto public commit
379 setup the draft branch that will be rebased onto public commit
378 $ hg up -r 0 -q
380 $ hg up -r 0 -q
379 $ echo 'content' > disappear
381 $ echo 'content' > disappear
380 commit will disappear
382 commit will disappear
381 $ hg commit -A -m 'disappear draft' -q
383 $ hg commit -A -m 'disappear draft' -q
382 $ echo 'addedcontADDEDentadded' > root
384 $ echo 'addedcontADDEDentadded' > root
383 commit will cause merge conflict on rebase
385 commit will cause merge conflict on rebase
384 $ hg commit -m 'add content draft' -q
386 $ hg commit -m 'add content draft' -q
385
387
386 $ hg rebase -d 'public()' --tool :merge -q
388 $ hg rebase -d 'public()' --tool :merge -q
387 note: rebase of 3:0682fd3dabf5 created no changes to commit
389 note: rebase of 3:0682fd3dabf5 created no changes to commit
388 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
390 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
389 unresolved conflicts (see hg resolve, then hg rebase --continue)
391 unresolved conflicts (see hg resolve, then hg rebase --continue)
390 [1]
392 [1]
391 $ hg rebase --abort
393 $ hg rebase --abort
392 rebase aborted
394 rebase aborted
393 $ cd ..
395 $ cd ..
394
396
@@ -1,328 +1,332 b''
1 test that a commit clears the merge state.
1 test that a commit clears the merge state.
2
2
3 $ hg init repo
3 $ hg init repo
4 $ cd repo
4 $ cd repo
5
5
6 $ echo foo > file1
6 $ echo foo > file1
7 $ echo foo > file2
7 $ echo foo > file2
8 $ hg commit -Am 'add files'
8 $ hg commit -Am 'add files'
9 adding file1
9 adding file1
10 adding file2
10 adding file2
11
11
12 $ echo bar >> file1
12 $ echo bar >> file1
13 $ echo bar >> file2
13 $ echo bar >> file2
14 $ hg commit -Am 'append bar to files'
14 $ hg commit -Am 'append bar to files'
15
15
16 create a second head with conflicting edits
16 create a second head with conflicting edits
17
17
18 $ hg up -C 0
18 $ hg up -C 0
19 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
19 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 $ echo baz >> file1
20 $ echo baz >> file1
21 $ echo baz >> file2
21 $ echo baz >> file2
22 $ hg commit -Am 'append baz to files'
22 $ hg commit -Am 'append baz to files'
23 created new head
23 created new head
24
24
25 create a third head with no conflicting edits
25 create a third head with no conflicting edits
26 $ hg up -qC 0
26 $ hg up -qC 0
27 $ echo foo > file3
27 $ echo foo > file3
28 $ hg commit -Am 'add non-conflicting file'
28 $ hg commit -Am 'add non-conflicting file'
29 adding file3
29 adding file3
30 created new head
30 created new head
31
31
32 failing merge
32 failing merge
33
33
34 $ hg up -qC 2
34 $ hg up -qC 2
35 $ hg merge --tool=internal:fail 1
35 $ hg merge --tool=internal:fail 1
36 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
36 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
37 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
37 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
38 [1]
38 [1]
39
39
40 resolve -l should contain unresolved entries
40 resolve -l should contain unresolved entries
41
41
42 $ hg resolve -l
42 $ hg resolve -l
43 U file1
43 U file1
44 U file2
44 U file2
45
45
46 $ hg resolve -l --no-status
46 $ hg resolve -l --no-status
47 file1
47 file1
48 file2
48 file2
49
49
50 resolving an unknown path should emit a warning, but not for -l
50 resolving an unknown path should emit a warning, but not for -l
51
51
52 $ hg resolve -m does-not-exist
52 $ hg resolve -m does-not-exist
53 arguments do not match paths that need resolving
53 arguments do not match paths that need resolving
54 $ hg resolve -l does-not-exist
54 $ hg resolve -l does-not-exist
55
55
56 don't allow marking or unmarking driver-resolved files
56 don't allow marking or unmarking driver-resolved files
57
57
58 $ cat > $TESTTMP/markdriver.py << EOF
58 $ cat > $TESTTMP/markdriver.py << EOF
59 > '''mark and unmark files as driver-resolved'''
59 > '''mark and unmark files as driver-resolved'''
60 > from mercurial import cmdutil, merge, scmutil
60 > from mercurial import cmdutil, merge, scmutil
61 > cmdtable = {}
61 > cmdtable = {}
62 > command = cmdutil.command(cmdtable)
62 > command = cmdutil.command(cmdtable)
63 > @command('markdriver',
63 > @command('markdriver',
64 > [('u', 'unmark', None, '')],
64 > [('u', 'unmark', None, '')],
65 > 'FILE...')
65 > 'FILE...')
66 > def markdriver(ui, repo, *pats, **opts):
66 > def markdriver(ui, repo, *pats, **opts):
67 > wlock = repo.wlock()
67 > wlock = repo.wlock()
68 > try:
68 > try:
69 > ms = merge.mergestate.read(repo)
69 > ms = merge.mergestate.read(repo)
70 > m = scmutil.match(repo[None], pats, opts)
70 > m = scmutil.match(repo[None], pats, opts)
71 > for f in ms:
71 > for f in ms:
72 > if not m(f):
72 > if not m(f):
73 > continue
73 > continue
74 > if not opts['unmark']:
74 > if not opts['unmark']:
75 > ms.mark(f, 'd')
75 > ms.mark(f, 'd')
76 > else:
76 > else:
77 > ms.mark(f, 'u')
77 > ms.mark(f, 'u')
78 > ms.commit()
78 > ms.commit()
79 > finally:
79 > finally:
80 > wlock.release()
80 > wlock.release()
81 > EOF
81 > EOF
82 $ hg --config extensions.markdriver=$TESTTMP/markdriver.py markdriver file1
82 $ hg --config extensions.markdriver=$TESTTMP/markdriver.py markdriver file1
83 $ hg resolve --list
83 $ hg resolve --list
84 D file1
84 D file1
85 U file2
85 U file2
86 $ hg resolve --mark file1
86 $ hg resolve --mark file1
87 not marking file1 as it is driver-resolved
87 not marking file1 as it is driver-resolved
88 this should not print out file1
88 this should not print out file1
89 $ hg resolve --mark --all
89 $ hg resolve --mark --all
90 (no more unresolved files -- run "hg resolve --all" to conclude)
90 (no more unresolved files -- run "hg resolve --all" to conclude)
91 $ hg resolve --mark 'glob:file*'
91 $ hg resolve --mark 'glob:file*'
92 (no more unresolved files -- run "hg resolve --all" to conclude)
92 (no more unresolved files -- run "hg resolve --all" to conclude)
93 $ hg resolve --list
93 $ hg resolve --list
94 D file1
94 D file1
95 R file2
95 R file2
96 $ hg resolve --unmark file1
96 $ hg resolve --unmark file1
97 not unmarking file1 as it is driver-resolved
97 not unmarking file1 as it is driver-resolved
98 (no more unresolved files -- run "hg resolve --all" to conclude)
98 (no more unresolved files -- run "hg resolve --all" to conclude)
99 $ hg resolve --unmark --all
99 $ hg resolve --unmark --all
100 $ hg resolve --list
100 $ hg resolve --list
101 D file1
101 D file1
102 U file2
102 U file2
103 $ hg --config extensions.markdriver=$TESTTMP/markdriver.py markdriver --unmark file1
103 $ hg --config extensions.markdriver=$TESTTMP/markdriver.py markdriver --unmark file1
104 $ hg resolve --list
104 $ hg resolve --list
105 U file1
105 U file1
106 U file2
106 U file2
107
107
108 resolve the failure
108 resolve the failure
109
109
110 $ echo resolved > file1
110 $ echo resolved > file1
111 $ hg resolve -m file1
111 $ hg resolve -m file1
112
112
113 resolve -l should show resolved file as resolved
113 resolve -l should show resolved file as resolved
114
114
115 $ hg resolve -l
115 $ hg resolve -l
116 R file1
116 R file1
117 U file2
117 U file2
118
118
119 $ hg resolve -l -Tjson
119 $ hg resolve -l -Tjson
120 [
120 [
121 {
121 {
122 "path": "file1",
122 "path": "file1",
123 "status": "R"
123 "status": "R"
124 },
124 },
125 {
125 {
126 "path": "file2",
126 "path": "file2",
127 "status": "U"
127 "status": "U"
128 }
128 }
129 ]
129 ]
130
130
131 resolve -m without paths should mark all resolved
131 resolve -m without paths should mark all resolved
132
132
133 $ hg resolve -m
133 $ hg resolve -m
134 (no more unresolved files)
134 (no more unresolved files)
135 $ hg commit -m 'resolved'
135 $ hg commit -m 'resolved'
136
136
137 resolve -l should be empty after commit
137 resolve -l should be empty after commit
138
138
139 $ hg resolve -l
139 $ hg resolve -l
140
140
141 $ hg resolve -l -Tjson
141 $ hg resolve -l -Tjson
142 [
142 [
143 ]
143 ]
144
144
145 resolve --all should abort when no merge in progress
145 resolve --all should abort when no merge in progress
146
146
147 $ hg resolve --all
147 $ hg resolve --all
148 abort: resolve command not applicable when not merging
148 abort: resolve command not applicable when not merging
149 [255]
149 [255]
150
150
151 resolve -m should abort when no merge in progress
151 resolve -m should abort when no merge in progress
152
152
153 $ hg resolve -m
153 $ hg resolve -m
154 abort: resolve command not applicable when not merging
154 abort: resolve command not applicable when not merging
155 [255]
155 [255]
156
156
157 can not update or merge when there are unresolved conflicts
157 can not update or merge when there are unresolved conflicts
158
158
159 $ hg up -qC 0
159 $ hg up -qC 0
160 $ echo quux >> file1
160 $ echo quux >> file1
161 $ hg up 1
161 $ hg up 1
162 merging file1
162 merging file1
163 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
163 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
164 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
164 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
165 use 'hg resolve' to retry unresolved file merges
165 use 'hg resolve' to retry unresolved file merges
166 [1]
166 [1]
167 $ hg up 0
167 $ hg up 0
168 abort: outstanding merge conflicts
168 abort: outstanding merge conflicts
169 [255]
169 [255]
170 $ hg merge 2
170 $ hg merge 2
171 abort: outstanding merge conflicts
171 abort: outstanding merge conflicts
172 [255]
172 [255]
173 $ hg merge --force 2
173 $ hg merge --force 2
174 abort: outstanding merge conflicts
174 abort: outstanding merge conflicts
175 [255]
175 [255]
176
176
177 set up conflict-free merge
177 set up conflict-free merge
178
178
179 $ hg up -qC 3
179 $ hg up -qC 3
180 $ hg merge 1
180 $ hg merge 1
181 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
181 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
182 (branch merge, don't forget to commit)
182 (branch merge, don't forget to commit)
183
183
184 resolve --all should do nothing in merge without conflicts
184 resolve --all should do nothing in merge without conflicts
185 $ hg resolve --all
185 $ hg resolve --all
186 (no more unresolved files)
186 (no more unresolved files)
187
187
188 resolve -m should do nothing in merge without conflicts
188 resolve -m should do nothing in merge without conflicts
189
189
190 $ hg resolve -m
190 $ hg resolve -m
191 (no more unresolved files)
191 (no more unresolved files)
192
192
193 get back to conflicting state
193 get back to conflicting state
194
194
195 $ hg up -qC 2
195 $ hg up -qC 2
196 $ hg merge --tool=internal:fail 1
196 $ hg merge --tool=internal:fail 1
197 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
197 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
198 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
198 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
199 [1]
199 [1]
200
200
201 resolve without arguments should suggest --all
201 resolve without arguments should suggest --all
202 $ hg resolve
202 $ hg resolve
203 abort: no files or directories specified
203 abort: no files or directories specified
204 (use --all to re-merge all unresolved files)
204 (use --all to re-merge all unresolved files)
205 [255]
205 [255]
206
206
207 resolve --all should re-merge all unresolved files
207 resolve --all should re-merge all unresolved files
208 $ hg resolve --all
208 $ hg resolve --all
209 merging file1
209 merging file1
210 merging file2
210 merging file2
211 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
211 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
212 warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
212 warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
213 [1]
213 [1]
214 $ cat file1.orig
214 $ cat file1.orig
215 foo
215 foo
216 baz
216 baz
217 $ cat file2.orig
217 $ cat file2.orig
218 foo
218 foo
219 baz
219 baz
220
220
221 .orig files should exists where specified
221 .orig files should exists where specified
222 $ hg resolve --all --verbose --config 'ui.origbackuppath=.hg/origbackups'
222 $ hg resolve --all --verbose --config 'ui.origbackuppath=.hg/origbackups'
223 merging file1
223 merging file1
224 creating directory: $TESTTMP/repo/.hg/origbackups (glob)
224 creating directory: $TESTTMP/repo/.hg/origbackups (glob)
225 merging file2
225 merging file2
226 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
226 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
227 warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
227 warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
228 [1]
228 [1]
229 $ ls .hg/origbackups
229 $ ls .hg/origbackups
230 file1.orig
230 file1.orig
231 file2.orig
231 file2.orig
232 $ grep '<<<' file1 > /dev/null
232 $ grep '<<<' file1 > /dev/null
233 $ grep '<<<' file2 > /dev/null
233 $ grep '<<<' file2 > /dev/null
234
234
235 resolve <file> should re-merge file
235 resolve <file> should re-merge file
236 $ echo resolved > file1
236 $ echo resolved > file1
237 $ hg resolve -q file1
237 $ hg resolve -q file1
238 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
238 warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
239 [1]
239 [1]
240 $ grep '<<<' file1 > /dev/null
240 $ grep '<<<' file1 > /dev/null
241
241
242 test .orig behavior with resolve
242 test .orig behavior with resolve
243
243
244 $ hg resolve -q file1 --tool "sh -c 'f --dump \"$TESTTMP/repo/file1.orig\"'"
244 $ hg resolve -q file1 --tool "sh -c 'f --dump \"$TESTTMP/repo/file1.orig\"'"
245 $TESTTMP/repo/file1.orig: (glob)
245 $TESTTMP/repo/file1.orig: (glob)
246 >>>
246 >>>
247 foo
247 foo
248 baz
248 baz
249 <<<
249 <<<
250
250
251 resolve <file> should do nothing if 'file' was marked resolved
251 resolve <file> should do nothing if 'file' was marked resolved
252 $ echo resolved > file1
252 $ echo resolved > file1
253 $ hg resolve -m file1
253 $ hg resolve -m file1
254 $ hg resolve -q file1
254 $ hg resolve -q file1
255 $ cat file1
255 $ cat file1
256 resolved
256 resolved
257
257
258 insert unsupported advisory merge record
258 insert unsupported advisory merge record
259
259
260 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
260 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
261 $ hg debugmergestate
261 $ hg debugmergestate
262 * version 2 records
262 * version 2 records
263 local: 57653b9f834a4493f7240b0681efcb9ae7cab745
263 local: 57653b9f834a4493f7240b0681efcb9ae7cab745
264 other: dc77451844e37f03f5c559e3b8529b2b48d381d1
264 other: dc77451844e37f03f5c559e3b8529b2b48d381d1
265 unrecognized entry: x advisory record
265 unrecognized entry: x advisory record
266 file extras: file1 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
266 file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
267 file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
267 local path: file1 (flags "")
268 local path: file1 (flags "")
268 ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
269 ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
269 other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
270 other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
271 file extras: file2 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
270 file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
272 file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
271 local path: file2 (flags "")
273 local path: file2 (flags "")
272 ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
274 ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
273 other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
275 other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
274 $ hg resolve -l
276 $ hg resolve -l
275 R file1
277 R file1
276 U file2
278 U file2
277
279
278 insert unsupported mandatory merge record
280 insert unsupported mandatory merge record
279
281
280 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
282 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
281 $ hg debugmergestate
283 $ hg debugmergestate
282 * version 2 records
284 * version 2 records
283 local: 57653b9f834a4493f7240b0681efcb9ae7cab745
285 local: 57653b9f834a4493f7240b0681efcb9ae7cab745
284 other: dc77451844e37f03f5c559e3b8529b2b48d381d1
286 other: dc77451844e37f03f5c559e3b8529b2b48d381d1
287 file extras: file1 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
285 file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
288 file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
286 local path: file1 (flags "")
289 local path: file1 (flags "")
287 ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
290 ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
288 other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
291 other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
292 file extras: file2 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
289 file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
293 file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
290 local path: file2 (flags "")
294 local path: file2 (flags "")
291 ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
295 ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
292 other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
296 other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
293 unrecognized entry: X mandatory record
297 unrecognized entry: X mandatory record
294 $ hg resolve -l
298 $ hg resolve -l
295 abort: unsupported merge state records: X
299 abort: unsupported merge state records: X
296 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
300 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
297 [255]
301 [255]
298 $ hg resolve -ma
302 $ hg resolve -ma
299 abort: unsupported merge state records: X
303 abort: unsupported merge state records: X
300 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
304 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
301 [255]
305 [255]
302 $ hg summary
306 $ hg summary
303 parent: 2:57653b9f834a
307 parent: 2:57653b9f834a
304 append baz to files
308 append baz to files
305 parent: 1:dc77451844e3
309 parent: 1:dc77451844e3
306 append bar to files
310 append bar to files
307 branch: default
311 branch: default
308 warning: merge state has unsupported record types: X
312 warning: merge state has unsupported record types: X
309 commit: 2 modified, 2 unknown (merge)
313 commit: 2 modified, 2 unknown (merge)
310 update: 2 new changesets (update)
314 update: 2 new changesets (update)
311 phases: 5 draft
315 phases: 5 draft
312
316
313 update --clean shouldn't abort on unsupported records
317 update --clean shouldn't abort on unsupported records
314
318
315 $ hg up -qC 1
319 $ hg up -qC 1
316 $ hg debugmergestate
320 $ hg debugmergestate
317 no merge state found
321 no merge state found
318
322
319 test crashed merge with empty mergestate
323 test crashed merge with empty mergestate
320
324
321 $ mkdir .hg/merge
325 $ mkdir .hg/merge
322 $ touch .hg/merge/state
326 $ touch .hg/merge/state
323
327
324 resolve -l should be empty
328 resolve -l should be empty
325
329
326 $ hg resolve -l
330 $ hg resolve -l
327
331
328 $ cd ..
332 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now