##// END OF EJS Templates
filemerge: break overall filemerge into separate premerge and merge steps...
Siddharth Agarwal -
r26611:a5ff66e6 default
parent child Browse files
Show More
@@ -1,583 +1,583 b''
1 # filemerge.py - file-level merge handling for Mercurial
1 # filemerge.py - file-level merge handling for Mercurial
2 #
2 #
3 # Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007, 2008 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 filecmp
10 import filecmp
11 import os
11 import os
12 import re
12 import re
13 import tempfile
13 import tempfile
14
14
15 from .i18n import _
15 from .i18n import _
16 from .node import short
16 from .node import short
17
17
18 from . import (
18 from . import (
19 error,
19 error,
20 match,
20 match,
21 simplemerge,
21 simplemerge,
22 tagmerge,
22 tagmerge,
23 templatekw,
23 templatekw,
24 templater,
24 templater,
25 util,
25 util,
26 )
26 )
27
27
28 def _toolstr(ui, tool, part, default=""):
28 def _toolstr(ui, tool, part, default=""):
29 return ui.config("merge-tools", tool + "." + part, default)
29 return ui.config("merge-tools", tool + "." + part, default)
30
30
31 def _toolbool(ui, tool, part, default=False):
31 def _toolbool(ui, tool, part, default=False):
32 return ui.configbool("merge-tools", tool + "." + part, default)
32 return ui.configbool("merge-tools", tool + "." + part, default)
33
33
34 def _toollist(ui, tool, part, default=[]):
34 def _toollist(ui, tool, part, default=[]):
35 return ui.configlist("merge-tools", tool + "." + part, default)
35 return ui.configlist("merge-tools", tool + "." + part, default)
36
36
37 internals = {}
37 internals = {}
38 # Merge tools to document.
38 # Merge tools to document.
39 internalsdoc = {}
39 internalsdoc = {}
40
40
41 # internal tool merge types
41 # internal tool merge types
42 nomerge = None
42 nomerge = None
43 mergeonly = 'mergeonly' # just the full merge, no premerge
43 mergeonly = 'mergeonly' # just the full merge, no premerge
44 fullmerge = 'fullmerge' # both premerge and merge
44 fullmerge = 'fullmerge' # both premerge and merge
45
45
46 def internaltool(name, mergetype, onfailure=None, precheck=None):
46 def internaltool(name, mergetype, onfailure=None, precheck=None):
47 '''return a decorator for populating internal merge tool table'''
47 '''return a decorator for populating internal merge tool table'''
48 def decorator(func):
48 def decorator(func):
49 fullname = ':' + name
49 fullname = ':' + name
50 func.__doc__ = "``%s``\n" % fullname + func.__doc__.strip()
50 func.__doc__ = "``%s``\n" % fullname + func.__doc__.strip()
51 internals[fullname] = func
51 internals[fullname] = func
52 internals['internal:' + name] = func
52 internals['internal:' + name] = func
53 internalsdoc[fullname] = func
53 internalsdoc[fullname] = func
54 func.mergetype = mergetype
54 func.mergetype = mergetype
55 func.onfailure = onfailure
55 func.onfailure = onfailure
56 func.precheck = precheck
56 func.precheck = precheck
57 return func
57 return func
58 return decorator
58 return decorator
59
59
60 def _findtool(ui, tool):
60 def _findtool(ui, tool):
61 if tool in internals:
61 if tool in internals:
62 return tool
62 return tool
63 return findexternaltool(ui, tool)
63 return findexternaltool(ui, tool)
64
64
65 def findexternaltool(ui, tool):
65 def findexternaltool(ui, tool):
66 for kn in ("regkey", "regkeyalt"):
66 for kn in ("regkey", "regkeyalt"):
67 k = _toolstr(ui, tool, kn)
67 k = _toolstr(ui, tool, kn)
68 if not k:
68 if not k:
69 continue
69 continue
70 p = util.lookupreg(k, _toolstr(ui, tool, "regname"))
70 p = util.lookupreg(k, _toolstr(ui, tool, "regname"))
71 if p:
71 if p:
72 p = util.findexe(p + _toolstr(ui, tool, "regappend"))
72 p = util.findexe(p + _toolstr(ui, tool, "regappend"))
73 if p:
73 if p:
74 return p
74 return p
75 exe = _toolstr(ui, tool, "executable", tool)
75 exe = _toolstr(ui, tool, "executable", tool)
76 return util.findexe(util.expandpath(exe))
76 return util.findexe(util.expandpath(exe))
77
77
78 def _picktool(repo, ui, path, binary, symlink):
78 def _picktool(repo, ui, path, binary, symlink):
79 def check(tool, pat, symlink, binary):
79 def check(tool, pat, symlink, binary):
80 tmsg = tool
80 tmsg = tool
81 if pat:
81 if pat:
82 tmsg += " specified for " + pat
82 tmsg += " specified for " + pat
83 if not _findtool(ui, tool):
83 if not _findtool(ui, tool):
84 if pat: # explicitly requested tool deserves a warning
84 if pat: # explicitly requested tool deserves a warning
85 ui.warn(_("couldn't find merge tool %s\n") % tmsg)
85 ui.warn(_("couldn't find merge tool %s\n") % tmsg)
86 else: # configured but non-existing tools are more silent
86 else: # configured but non-existing tools are more silent
87 ui.note(_("couldn't find merge tool %s\n") % tmsg)
87 ui.note(_("couldn't find merge tool %s\n") % tmsg)
88 elif symlink and not _toolbool(ui, tool, "symlink"):
88 elif symlink and not _toolbool(ui, tool, "symlink"):
89 ui.warn(_("tool %s can't handle symlinks\n") % tmsg)
89 ui.warn(_("tool %s can't handle symlinks\n") % tmsg)
90 elif binary and not _toolbool(ui, tool, "binary"):
90 elif binary and not _toolbool(ui, tool, "binary"):
91 ui.warn(_("tool %s can't handle binary\n") % tmsg)
91 ui.warn(_("tool %s can't handle binary\n") % tmsg)
92 elif not util.gui() and _toolbool(ui, tool, "gui"):
92 elif not util.gui() and _toolbool(ui, tool, "gui"):
93 ui.warn(_("tool %s requires a GUI\n") % tmsg)
93 ui.warn(_("tool %s requires a GUI\n") % tmsg)
94 else:
94 else:
95 return True
95 return True
96 return False
96 return False
97
97
98 # internal config: ui.forcemerge
98 # internal config: ui.forcemerge
99 # forcemerge comes from command line arguments, highest priority
99 # forcemerge comes from command line arguments, highest priority
100 force = ui.config('ui', 'forcemerge')
100 force = ui.config('ui', 'forcemerge')
101 if force:
101 if force:
102 toolpath = _findtool(ui, force)
102 toolpath = _findtool(ui, force)
103 if toolpath:
103 if toolpath:
104 return (force, util.shellquote(toolpath))
104 return (force, util.shellquote(toolpath))
105 else:
105 else:
106 # mimic HGMERGE if given tool not found
106 # mimic HGMERGE if given tool not found
107 return (force, force)
107 return (force, force)
108
108
109 # HGMERGE takes next precedence
109 # HGMERGE takes next precedence
110 hgmerge = os.environ.get("HGMERGE")
110 hgmerge = os.environ.get("HGMERGE")
111 if hgmerge:
111 if hgmerge:
112 return (hgmerge, hgmerge)
112 return (hgmerge, hgmerge)
113
113
114 # then patterns
114 # then patterns
115 for pat, tool in ui.configitems("merge-patterns"):
115 for pat, tool in ui.configitems("merge-patterns"):
116 mf = match.match(repo.root, '', [pat])
116 mf = match.match(repo.root, '', [pat])
117 if mf(path) and check(tool, pat, symlink, False):
117 if mf(path) and check(tool, pat, symlink, False):
118 toolpath = _findtool(ui, tool)
118 toolpath = _findtool(ui, tool)
119 return (tool, util.shellquote(toolpath))
119 return (tool, util.shellquote(toolpath))
120
120
121 # then merge tools
121 # then merge tools
122 tools = {}
122 tools = {}
123 for k, v in ui.configitems("merge-tools"):
123 for k, v in ui.configitems("merge-tools"):
124 t = k.split('.')[0]
124 t = k.split('.')[0]
125 if t not in tools:
125 if t not in tools:
126 tools[t] = int(_toolstr(ui, t, "priority", "0"))
126 tools[t] = int(_toolstr(ui, t, "priority", "0"))
127 names = tools.keys()
127 names = tools.keys()
128 tools = sorted([(-p, t) for t, p in tools.items()])
128 tools = sorted([(-p, t) for t, p in tools.items()])
129 uimerge = ui.config("ui", "merge")
129 uimerge = ui.config("ui", "merge")
130 if uimerge:
130 if uimerge:
131 if uimerge not in names:
131 if uimerge not in names:
132 return (uimerge, uimerge)
132 return (uimerge, uimerge)
133 tools.insert(0, (None, uimerge)) # highest priority
133 tools.insert(0, (None, uimerge)) # highest priority
134 tools.append((None, "hgmerge")) # the old default, if found
134 tools.append((None, "hgmerge")) # the old default, if found
135 for p, t in tools:
135 for p, t in tools:
136 if check(t, None, symlink, binary):
136 if check(t, None, symlink, binary):
137 toolpath = _findtool(ui, t)
137 toolpath = _findtool(ui, t)
138 return (t, util.shellquote(toolpath))
138 return (t, util.shellquote(toolpath))
139
139
140 # internal merge or prompt as last resort
140 # internal merge or prompt as last resort
141 if symlink or binary:
141 if symlink or binary:
142 return ":prompt", None
142 return ":prompt", None
143 return ":merge", None
143 return ":merge", None
144
144
145 def _eoltype(data):
145 def _eoltype(data):
146 "Guess the EOL type of a file"
146 "Guess the EOL type of a file"
147 if '\0' in data: # binary
147 if '\0' in data: # binary
148 return None
148 return None
149 if '\r\n' in data: # Windows
149 if '\r\n' in data: # Windows
150 return '\r\n'
150 return '\r\n'
151 if '\r' in data: # Old Mac
151 if '\r' in data: # Old Mac
152 return '\r'
152 return '\r'
153 if '\n' in data: # UNIX
153 if '\n' in data: # UNIX
154 return '\n'
154 return '\n'
155 return None # unknown
155 return None # unknown
156
156
157 def _matcheol(file, origfile):
157 def _matcheol(file, origfile):
158 "Convert EOL markers in a file to match origfile"
158 "Convert EOL markers in a file to match origfile"
159 tostyle = _eoltype(util.readfile(origfile))
159 tostyle = _eoltype(util.readfile(origfile))
160 if tostyle:
160 if tostyle:
161 data = util.readfile(file)
161 data = util.readfile(file)
162 style = _eoltype(data)
162 style = _eoltype(data)
163 if style:
163 if style:
164 newdata = data.replace(style, tostyle)
164 newdata = data.replace(style, tostyle)
165 if newdata != data:
165 if newdata != data:
166 util.writefile(file, newdata)
166 util.writefile(file, newdata)
167
167
168 @internaltool('prompt', nomerge)
168 @internaltool('prompt', nomerge)
169 def _iprompt(repo, mynode, orig, fcd, fco, fca, toolconf):
169 def _iprompt(repo, mynode, orig, fcd, fco, fca, toolconf):
170 """Asks the user which of the local or the other version to keep as
170 """Asks the user which of the local or the other version to keep as
171 the merged version."""
171 the merged version."""
172 ui = repo.ui
172 ui = repo.ui
173 fd = fcd.path()
173 fd = fcd.path()
174
174
175 if ui.promptchoice(_(" no tool found to merge %s\n"
175 if ui.promptchoice(_(" no tool found to merge %s\n"
176 "keep (l)ocal or take (o)ther?"
176 "keep (l)ocal or take (o)ther?"
177 "$$ &Local $$ &Other") % fd, 0):
177 "$$ &Local $$ &Other") % fd, 0):
178 return _iother(repo, mynode, orig, fcd, fco, fca, toolconf)
178 return _iother(repo, mynode, orig, fcd, fco, fca, toolconf)
179 else:
179 else:
180 return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf)
180 return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf)
181
181
182 @internaltool('local', nomerge)
182 @internaltool('local', nomerge)
183 def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf):
183 def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf):
184 """Uses the local version of files as the merged version."""
184 """Uses the local version of files as the merged version."""
185 return 0
185 return 0
186
186
187 @internaltool('other', nomerge)
187 @internaltool('other', nomerge)
188 def _iother(repo, mynode, orig, fcd, fco, fca, toolconf):
188 def _iother(repo, mynode, orig, fcd, fco, fca, toolconf):
189 """Uses the other version of files as the merged version."""
189 """Uses the other version of files as the merged version."""
190 repo.wwrite(fcd.path(), fco.data(), fco.flags())
190 repo.wwrite(fcd.path(), fco.data(), fco.flags())
191 return 0
191 return 0
192
192
193 @internaltool('fail', nomerge)
193 @internaltool('fail', nomerge)
194 def _ifail(repo, mynode, orig, fcd, fco, fca, toolconf):
194 def _ifail(repo, mynode, orig, fcd, fco, fca, toolconf):
195 """
195 """
196 Rather than attempting to merge files that were modified on both
196 Rather than attempting to merge files that were modified on both
197 branches, it marks them as unresolved. The resolve command must be
197 branches, it marks them as unresolved. The resolve command must be
198 used to resolve these conflicts."""
198 used to resolve these conflicts."""
199 return 1
199 return 1
200
200
201 def _premerge(repo, toolconf, files, labels=None):
201 def _premerge(repo, toolconf, files, labels=None):
202 tool, toolpath, binary, symlink = toolconf
202 tool, toolpath, binary, symlink = toolconf
203 if symlink:
203 if symlink:
204 return 1
204 return 1
205 a, b, c, back = files
205 a, b, c, back = files
206
206
207 ui = repo.ui
207 ui = repo.ui
208
208
209 validkeep = ['keep', 'keep-merge3']
209 validkeep = ['keep', 'keep-merge3']
210
210
211 # do we attempt to simplemerge first?
211 # do we attempt to simplemerge first?
212 try:
212 try:
213 premerge = _toolbool(ui, tool, "premerge", not binary)
213 premerge = _toolbool(ui, tool, "premerge", not binary)
214 except error.ConfigError:
214 except error.ConfigError:
215 premerge = _toolstr(ui, tool, "premerge").lower()
215 premerge = _toolstr(ui, tool, "premerge").lower()
216 if premerge not in validkeep:
216 if premerge not in validkeep:
217 _valid = ', '.join(["'" + v + "'" for v in validkeep])
217 _valid = ', '.join(["'" + v + "'" for v in validkeep])
218 raise error.ConfigError(_("%s.premerge not valid "
218 raise error.ConfigError(_("%s.premerge not valid "
219 "('%s' is neither boolean nor %s)") %
219 "('%s' is neither boolean nor %s)") %
220 (tool, premerge, _valid))
220 (tool, premerge, _valid))
221
221
222 if premerge:
222 if premerge:
223 if premerge == 'keep-merge3':
223 if premerge == 'keep-merge3':
224 if not labels:
224 if not labels:
225 labels = _defaultconflictlabels
225 labels = _defaultconflictlabels
226 if len(labels) < 3:
226 if len(labels) < 3:
227 labels.append('base')
227 labels.append('base')
228 r = simplemerge.simplemerge(ui, a, b, c, quiet=True, label=labels)
228 r = simplemerge.simplemerge(ui, a, b, c, quiet=True, label=labels)
229 if not r:
229 if not r:
230 ui.debug(" premerge successful\n")
230 ui.debug(" premerge successful\n")
231 return 0
231 return 0
232 if premerge not in validkeep:
232 if premerge not in validkeep:
233 util.copyfile(back, a) # restore from backup and try again
233 util.copyfile(back, a) # restore from backup and try again
234 return 1 # continue merging
234 return 1 # continue merging
235
235
236 def _symlinkcheck(repo, mynode, orig, fcd, fco, fca, toolconf):
236 def _symlinkcheck(repo, mynode, orig, fcd, fco, fca, toolconf):
237 tool, toolpath, binary, symlink = toolconf
237 tool, toolpath, binary, symlink = toolconf
238 if symlink:
238 if symlink:
239 repo.ui.warn(_('warning: internal %s cannot merge symlinks '
239 repo.ui.warn(_('warning: internal %s cannot merge symlinks '
240 'for %s\n') % (tool, fcd.path()))
240 'for %s\n') % (tool, fcd.path()))
241 return False
241 return False
242 return True
242 return True
243
243
244 def _merge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels, mode):
244 def _merge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels, mode):
245 """
245 """
246 Uses the internal non-interactive simple merge algorithm for merging
246 Uses the internal non-interactive simple merge algorithm for merging
247 files. It will fail if there are any conflicts and leave markers in
247 files. It will fail if there are any conflicts and leave markers in
248 the partially merged file. Markers will have two sections, one for each side
248 the partially merged file. Markers will have two sections, one for each side
249 of merge, unless mode equals 'union' which suppresses the markers."""
249 of merge, unless mode equals 'union' which suppresses the markers."""
250 a, b, c, back = files
250 a, b, c, back = files
251
251
252 ui = repo.ui
252 ui = repo.ui
253
253
254 r = simplemerge.simplemerge(ui, a, b, c, label=labels, mode=mode)
254 r = simplemerge.simplemerge(ui, a, b, c, label=labels, mode=mode)
255 return True, r
255 return True, r
256
256
257 @internaltool('union', fullmerge,
257 @internaltool('union', fullmerge,
258 _("merging %s incomplete! "
258 _("merging %s incomplete! "
259 "(edit conflicts, then use 'hg resolve --mark')\n"),
259 "(edit conflicts, then use 'hg resolve --mark')\n"),
260 precheck=_symlinkcheck)
260 precheck=_symlinkcheck)
261 def _iunion(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
261 def _iunion(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
262 """
262 """
263 Uses the internal non-interactive simple merge algorithm for merging
263 Uses the internal non-interactive simple merge algorithm for merging
264 files. It will use both left and right sides for conflict regions.
264 files. It will use both left and right sides for conflict regions.
265 No markers are inserted."""
265 No markers are inserted."""
266 return _merge(repo, mynode, orig, fcd, fco, fca, toolconf,
266 return _merge(repo, mynode, orig, fcd, fco, fca, toolconf,
267 files, labels, 'union')
267 files, labels, 'union')
268
268
269 @internaltool('merge', fullmerge,
269 @internaltool('merge', fullmerge,
270 _("merging %s incomplete! "
270 _("merging %s incomplete! "
271 "(edit conflicts, then use 'hg resolve --mark')\n"),
271 "(edit conflicts, then use 'hg resolve --mark')\n"),
272 precheck=_symlinkcheck)
272 precheck=_symlinkcheck)
273 def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
273 def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
274 """
274 """
275 Uses the internal non-interactive simple merge algorithm for merging
275 Uses the internal non-interactive simple merge algorithm for merging
276 files. It will fail if there are any conflicts and leave markers in
276 files. It will fail if there are any conflicts and leave markers in
277 the partially merged file. Markers will have two sections, one for each side
277 the partially merged file. Markers will have two sections, one for each side
278 of merge."""
278 of merge."""
279 return _merge(repo, mynode, orig, fcd, fco, fca, toolconf,
279 return _merge(repo, mynode, orig, fcd, fco, fca, toolconf,
280 files, labels, 'merge')
280 files, labels, 'merge')
281
281
282 @internaltool('merge3', fullmerge,
282 @internaltool('merge3', fullmerge,
283 _("merging %s incomplete! "
283 _("merging %s incomplete! "
284 "(edit conflicts, then use 'hg resolve --mark')\n"),
284 "(edit conflicts, then use 'hg resolve --mark')\n"),
285 precheck=_symlinkcheck)
285 precheck=_symlinkcheck)
286 def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
286 def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
287 """
287 """
288 Uses the internal non-interactive simple merge algorithm for merging
288 Uses the internal non-interactive simple merge algorithm for merging
289 files. It will fail if there are any conflicts and leave markers in
289 files. It will fail if there are any conflicts and leave markers in
290 the partially merged file. Marker will have three sections, one from each
290 the partially merged file. Marker will have three sections, one from each
291 side of the merge and one for the base content."""
291 side of the merge and one for the base content."""
292 if not labels:
292 if not labels:
293 labels = _defaultconflictlabels
293 labels = _defaultconflictlabels
294 if len(labels) < 3:
294 if len(labels) < 3:
295 labels.append('base')
295 labels.append('base')
296 return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels)
296 return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels)
297
297
298 def _imergeauto(repo, mynode, orig, fcd, fco, fca, toolconf, files,
298 def _imergeauto(repo, mynode, orig, fcd, fco, fca, toolconf, files,
299 labels=None, localorother=None):
299 labels=None, localorother=None):
300 """
300 """
301 Generic driver for _imergelocal and _imergeother
301 Generic driver for _imergelocal and _imergeother
302 """
302 """
303 assert localorother is not None
303 assert localorother is not None
304 tool, toolpath, binary, symlink = toolconf
304 tool, toolpath, binary, symlink = toolconf
305 if symlink:
305 if symlink:
306 repo.ui.warn(_('warning: :merge-%s cannot merge symlinks '
306 repo.ui.warn(_('warning: :merge-%s cannot merge symlinks '
307 'for %s\n') % (localorother, fcd.path()))
307 'for %s\n') % (localorother, fcd.path()))
308 return False, 1
308 return False, 1
309 a, b, c, back = files
309 a, b, c, back = files
310 r = simplemerge.simplemerge(repo.ui, a, b, c, label=labels,
310 r = simplemerge.simplemerge(repo.ui, a, b, c, label=labels,
311 localorother=localorother)
311 localorother=localorother)
312 return True, r
312 return True, r
313
313
314 @internaltool('merge-local', mergeonly)
314 @internaltool('merge-local', mergeonly)
315 def _imergelocal(*args, **kwargs):
315 def _imergelocal(*args, **kwargs):
316 """
316 """
317 Like :merge, but resolve all conflicts non-interactively in favor
317 Like :merge, but resolve all conflicts non-interactively in favor
318 of the local changes."""
318 of the local changes."""
319 success, status = _imergeauto(localorother='local', *args, **kwargs)
319 success, status = _imergeauto(localorother='local', *args, **kwargs)
320 return success, status
320 return success, status
321
321
322 @internaltool('merge-other', mergeonly)
322 @internaltool('merge-other', mergeonly)
323 def _imergeother(*args, **kwargs):
323 def _imergeother(*args, **kwargs):
324 """
324 """
325 Like :merge, but resolve all conflicts non-interactively in favor
325 Like :merge, but resolve all conflicts non-interactively in favor
326 of the other changes."""
326 of the other changes."""
327 success, status = _imergeauto(localorother='other', *args, **kwargs)
327 success, status = _imergeauto(localorother='other', *args, **kwargs)
328 return success, status
328 return success, status
329
329
330 @internaltool('tagmerge', mergeonly,
330 @internaltool('tagmerge', mergeonly,
331 _("automatic tag merging of %s failed! "
331 _("automatic tag merging of %s failed! "
332 "(use 'hg resolve --tool :merge' or another merge "
332 "(use 'hg resolve --tool :merge' or another merge "
333 "tool of your choice)\n"))
333 "tool of your choice)\n"))
334 def _itagmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
334 def _itagmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
335 """
335 """
336 Uses the internal tag merge algorithm (experimental).
336 Uses the internal tag merge algorithm (experimental).
337 """
337 """
338 return tagmerge.merge(repo, fcd, fco, fca)
338 return tagmerge.merge(repo, fcd, fco, fca)
339
339
340 @internaltool('dump', fullmerge)
340 @internaltool('dump', fullmerge)
341 def _idump(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
341 def _idump(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
342 """
342 """
343 Creates three versions of the files to merge, containing the
343 Creates three versions of the files to merge, containing the
344 contents of local, other and base. These files can then be used to
344 contents of local, other and base. These files can then be used to
345 perform a merge manually. If the file to be merged is named
345 perform a merge manually. If the file to be merged is named
346 ``a.txt``, these files will accordingly be named ``a.txt.local``,
346 ``a.txt``, these files will accordingly be named ``a.txt.local``,
347 ``a.txt.other`` and ``a.txt.base`` and they will be placed in the
347 ``a.txt.other`` and ``a.txt.base`` and they will be placed in the
348 same directory as ``a.txt``."""
348 same directory as ``a.txt``."""
349 a, b, c, back = files
349 a, b, c, back = files
350
350
351 fd = fcd.path()
351 fd = fcd.path()
352
352
353 util.copyfile(a, a + ".local")
353 util.copyfile(a, a + ".local")
354 repo.wwrite(fd + ".other", fco.data(), fco.flags())
354 repo.wwrite(fd + ".other", fco.data(), fco.flags())
355 repo.wwrite(fd + ".base", fca.data(), fca.flags())
355 repo.wwrite(fd + ".base", fca.data(), fca.flags())
356 return False, 1
356 return False, 1
357
357
358 def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
358 def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
359 tool, toolpath, binary, symlink = toolconf
359 tool, toolpath, binary, symlink = toolconf
360 a, b, c, back = files
360 a, b, c, back = files
361 out = ""
361 out = ""
362 env = {'HG_FILE': fcd.path(),
362 env = {'HG_FILE': fcd.path(),
363 'HG_MY_NODE': short(mynode),
363 'HG_MY_NODE': short(mynode),
364 'HG_OTHER_NODE': str(fco.changectx()),
364 'HG_OTHER_NODE': str(fco.changectx()),
365 'HG_BASE_NODE': str(fca.changectx()),
365 'HG_BASE_NODE': str(fca.changectx()),
366 'HG_MY_ISLINK': 'l' in fcd.flags(),
366 'HG_MY_ISLINK': 'l' in fcd.flags(),
367 'HG_OTHER_ISLINK': 'l' in fco.flags(),
367 'HG_OTHER_ISLINK': 'l' in fco.flags(),
368 'HG_BASE_ISLINK': 'l' in fca.flags(),
368 'HG_BASE_ISLINK': 'l' in fca.flags(),
369 }
369 }
370
370
371 ui = repo.ui
371 ui = repo.ui
372
372
373 args = _toolstr(ui, tool, "args", '$local $base $other')
373 args = _toolstr(ui, tool, "args", '$local $base $other')
374 if "$output" in args:
374 if "$output" in args:
375 out, a = a, back # read input from backup, write to original
375 out, a = a, back # read input from backup, write to original
376 replace = {'local': a, 'base': b, 'other': c, 'output': out}
376 replace = {'local': a, 'base': b, 'other': c, 'output': out}
377 args = util.interpolate(r'\$', replace, args,
377 args = util.interpolate(r'\$', replace, args,
378 lambda s: util.shellquote(util.localpath(s)))
378 lambda s: util.shellquote(util.localpath(s)))
379 cmd = toolpath + ' ' + args
379 cmd = toolpath + ' ' + args
380 repo.ui.debug('launching merge tool: %s\n' % cmd)
380 repo.ui.debug('launching merge tool: %s\n' % cmd)
381 r = ui.system(cmd, cwd=repo.root, environ=env)
381 r = ui.system(cmd, cwd=repo.root, environ=env)
382 repo.ui.debug('merge tool returned: %s\n' % r)
382 repo.ui.debug('merge tool returned: %s\n' % r)
383 return True, r
383 return True, r
384
384
385 def _formatconflictmarker(repo, ctx, template, label, pad):
385 def _formatconflictmarker(repo, ctx, template, label, pad):
386 """Applies the given template to the ctx, prefixed by the label.
386 """Applies the given template to the ctx, prefixed by the label.
387
387
388 Pad is the minimum width of the label prefix, so that multiple markers
388 Pad is the minimum width of the label prefix, so that multiple markers
389 can have aligned templated parts.
389 can have aligned templated parts.
390 """
390 """
391 if ctx.node() is None:
391 if ctx.node() is None:
392 ctx = ctx.p1()
392 ctx = ctx.p1()
393
393
394 props = templatekw.keywords.copy()
394 props = templatekw.keywords.copy()
395 props['templ'] = template
395 props['templ'] = template
396 props['ctx'] = ctx
396 props['ctx'] = ctx
397 props['repo'] = repo
397 props['repo'] = repo
398 templateresult = template('conflictmarker', **props)
398 templateresult = template('conflictmarker', **props)
399
399
400 label = ('%s:' % label).ljust(pad + 1)
400 label = ('%s:' % label).ljust(pad + 1)
401 mark = '%s %s' % (label, templater.stringify(templateresult))
401 mark = '%s %s' % (label, templater.stringify(templateresult))
402
402
403 if mark:
403 if mark:
404 mark = mark.splitlines()[0] # split for safety
404 mark = mark.splitlines()[0] # split for safety
405
405
406 # 8 for the prefix of conflict marker lines (e.g. '<<<<<<< ')
406 # 8 for the prefix of conflict marker lines (e.g. '<<<<<<< ')
407 return util.ellipsis(mark, 80 - 8)
407 return util.ellipsis(mark, 80 - 8)
408
408
409 _defaultconflictmarker = ('{node|short} ' +
409 _defaultconflictmarker = ('{node|short} ' +
410 '{ifeq(tags, "tip", "", "{tags} ")}' +
410 '{ifeq(tags, "tip", "", "{tags} ")}' +
411 '{if(bookmarks, "{bookmarks} ")}' +
411 '{if(bookmarks, "{bookmarks} ")}' +
412 '{ifeq(branch, "default", "", "{branch} ")}' +
412 '{ifeq(branch, "default", "", "{branch} ")}' +
413 '- {author|user}: {desc|firstline}')
413 '- {author|user}: {desc|firstline}')
414
414
415 _defaultconflictlabels = ['local', 'other']
415 _defaultconflictlabels = ['local', 'other']
416
416
417 def _formatlabels(repo, fcd, fco, fca, labels):
417 def _formatlabels(repo, fcd, fco, fca, labels):
418 """Formats the given labels using the conflict marker template.
418 """Formats the given labels using the conflict marker template.
419
419
420 Returns a list of formatted labels.
420 Returns a list of formatted labels.
421 """
421 """
422 cd = fcd.changectx()
422 cd = fcd.changectx()
423 co = fco.changectx()
423 co = fco.changectx()
424 ca = fca.changectx()
424 ca = fca.changectx()
425
425
426 ui = repo.ui
426 ui = repo.ui
427 template = ui.config('ui', 'mergemarkertemplate', _defaultconflictmarker)
427 template = ui.config('ui', 'mergemarkertemplate', _defaultconflictmarker)
428 tmpl = templater.templater(None, cache={'conflictmarker': template})
428 tmpl = templater.templater(None, cache={'conflictmarker': template})
429
429
430 pad = max(len(l) for l in labels)
430 pad = max(len(l) for l in labels)
431
431
432 newlabels = [_formatconflictmarker(repo, cd, tmpl, labels[0], pad),
432 newlabels = [_formatconflictmarker(repo, cd, tmpl, labels[0], pad),
433 _formatconflictmarker(repo, co, tmpl, labels[1], pad)]
433 _formatconflictmarker(repo, co, tmpl, labels[1], pad)]
434 if len(labels) > 2:
434 if len(labels) > 2:
435 newlabels.append(_formatconflictmarker(repo, ca, tmpl, labels[2], pad))
435 newlabels.append(_formatconflictmarker(repo, ca, tmpl, labels[2], pad))
436 return newlabels
436 return newlabels
437
437
438 def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None):
438 def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None):
439 """perform a 3-way merge in the working directory
439 """perform a 3-way merge in the working directory
440
440
441 premerge = whether this is a premerge
441 premerge = whether this is a premerge
442 mynode = parent node before merge
442 mynode = parent node before merge
443 orig = original local filename before merge
443 orig = original local filename before merge
444 fco = other file context
444 fco = other file context
445 fca = ancestor file context
445 fca = ancestor file context
446 fcd = local file context for current/destination file
446 fcd = local file context for current/destination file
447
447
448 Returns whether the merge is complete, and the return value of the merge.
448 Returns whether the merge is complete, and the return value of the merge.
449 """
449 """
450
450
451 def temp(prefix, ctx):
451 def temp(prefix, ctx):
452 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
452 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
453 (fd, name) = tempfile.mkstemp(prefix=pre)
453 (fd, name) = tempfile.mkstemp(prefix=pre)
454 data = repo.wwritedata(ctx.path(), ctx.data())
454 data = repo.wwritedata(ctx.path(), ctx.data())
455 f = os.fdopen(fd, "wb")
455 f = os.fdopen(fd, "wb")
456 f.write(data)
456 f.write(data)
457 f.close()
457 f.close()
458 return name
458 return name
459
459
460 if not fco.cmp(fcd): # files identical?
460 if not fco.cmp(fcd): # files identical?
461 return True, None
461 return True, None
462
462
463 ui = repo.ui
463 ui = repo.ui
464 fd = fcd.path()
464 fd = fcd.path()
465 binary = fcd.isbinary() or fco.isbinary() or fca.isbinary()
465 binary = fcd.isbinary() or fco.isbinary() or fca.isbinary()
466 symlink = 'l' in fcd.flags() + fco.flags()
466 symlink = 'l' in fcd.flags() + fco.flags()
467 tool, toolpath = _picktool(repo, ui, fd, binary, symlink)
467 tool, toolpath = _picktool(repo, ui, fd, binary, symlink)
468 if tool in internals and tool.startswith('internal:'):
468 if tool in internals and tool.startswith('internal:'):
469 # normalize to new-style names (':merge' etc)
469 # normalize to new-style names (':merge' etc)
470 tool = tool[len('internal'):]
470 tool = tool[len('internal'):]
471 ui.debug("picked tool '%s' for %s (binary %s symlink %s)\n" %
471 ui.debug("picked tool '%s' for %s (binary %s symlink %s)\n" %
472 (tool, fd, binary, symlink))
472 (tool, fd, binary, symlink))
473
473
474 if tool in internals:
474 if tool in internals:
475 func = internals[tool]
475 func = internals[tool]
476 mergetype = func.mergetype
476 mergetype = func.mergetype
477 onfailure = func.onfailure
477 onfailure = func.onfailure
478 precheck = func.precheck
478 precheck = func.precheck
479 else:
479 else:
480 func = _xmerge
480 func = _xmerge
481 mergetype = fullmerge
481 mergetype = fullmerge
482 onfailure = _("merging %s failed!\n")
482 onfailure = _("merging %s failed!\n")
483 precheck = None
483 precheck = None
484
484
485 toolconf = tool, toolpath, binary, symlink
485 toolconf = tool, toolpath, binary, symlink
486
486
487 if mergetype == nomerge:
487 if mergetype == nomerge:
488 return True, func(repo, mynode, orig, fcd, fco, fca, toolconf)
488 return True, func(repo, mynode, orig, fcd, fco, fca, toolconf)
489
489
490 if premerge:
490 if premerge:
491 if orig != fco.path():
491 if orig != fco.path():
492 ui.status(_("merging %s and %s to %s\n") % (orig, fco.path(), fd))
492 ui.status(_("merging %s and %s to %s\n") % (orig, fco.path(), fd))
493 else:
493 else:
494 ui.status(_("merging %s\n") % fd)
494 ui.status(_("merging %s\n") % fd)
495
495
496 ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca))
496 ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca))
497
497
498 if precheck and not precheck(repo, mynode, orig, fcd, fco, fca,
498 if precheck and not precheck(repo, mynode, orig, fcd, fco, fca,
499 toolconf):
499 toolconf):
500 if onfailure:
500 if onfailure:
501 ui.warn(onfailure % fd)
501 ui.warn(onfailure % fd)
502 return True, 1
502 return True, 1
503
503
504 a = repo.wjoin(fd)
504 a = repo.wjoin(fd)
505 b = temp("base", fca)
505 b = temp("base", fca)
506 c = temp("other", fco)
506 c = temp("other", fco)
507 back = a + ".orig"
507 back = a + ".orig"
508 if premerge:
508 if premerge:
509 util.copyfile(a, back)
509 util.copyfile(a, back)
510 files = (a, b, c, back)
510 files = (a, b, c, back)
511
511
512 r = 1
512 r = 1
513 try:
513 try:
514 markerstyle = ui.config('ui', 'mergemarkers', 'basic')
514 markerstyle = ui.config('ui', 'mergemarkers', 'basic')
515 if not labels:
515 if not labels:
516 labels = _defaultconflictlabels
516 labels = _defaultconflictlabels
517 if markerstyle != 'basic':
517 if markerstyle != 'basic':
518 labels = _formatlabels(repo, fcd, fco, fca, labels)
518 labels = _formatlabels(repo, fcd, fco, fca, labels)
519
519
520 if premerge and mergetype == fullmerge:
520 if premerge and mergetype == fullmerge:
521 r = _premerge(repo, toolconf, files, labels=labels)
521 r = _premerge(repo, toolconf, files, labels=labels)
522 # complete if premerge successful (r is 0)
523 return not r, r
522
524
523 if not r: # premerge successfully merged the file
525 if not r: # premerge successfully merged the file
524 needcheck = False
526 needcheck = False
525 else:
527 else:
526 needcheck, r = func(repo, mynode, orig, fcd, fco, fca, toolconf,
528 needcheck, r = func(repo, mynode, orig, fcd, fco, fca, toolconf,
527 files, labels=labels)
529 files, labels=labels)
528
530
529 if needcheck:
531 if needcheck:
530 r = _check(r, ui, tool, fcd, files)
532 r = _check(r, ui, tool, fcd, files)
531
533
532 if r:
534 if r:
533 if onfailure:
535 if onfailure:
534 ui.warn(onfailure % fd)
536 ui.warn(onfailure % fd)
535
537
536 return True, r
538 return True, r
537 finally:
539 finally:
538 if not r:
540 if not r:
539 util.unlink(back)
541 util.unlink(back)
540 util.unlink(b)
542 util.unlink(b)
541 util.unlink(c)
543 util.unlink(c)
542
544
543 def _check(r, ui, tool, fcd, files):
545 def _check(r, ui, tool, fcd, files):
544 fd = fcd.path()
546 fd = fcd.path()
545 a, b, c, back = files
547 a, b, c, back = files
546
548
547 if not r and (_toolbool(ui, tool, "checkconflicts") or
549 if not r and (_toolbool(ui, tool, "checkconflicts") or
548 'conflicts' in _toollist(ui, tool, "check")):
550 'conflicts' in _toollist(ui, tool, "check")):
549 if re.search("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data(),
551 if re.search("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data(),
550 re.MULTILINE):
552 re.MULTILINE):
551 r = 1
553 r = 1
552
554
553 checked = False
555 checked = False
554 if 'prompt' in _toollist(ui, tool, "check"):
556 if 'prompt' in _toollist(ui, tool, "check"):
555 checked = True
557 checked = True
556 if ui.promptchoice(_("was merge of '%s' successful (yn)?"
558 if ui.promptchoice(_("was merge of '%s' successful (yn)?"
557 "$$ &Yes $$ &No") % fd, 1):
559 "$$ &Yes $$ &No") % fd, 1):
558 r = 1
560 r = 1
559
561
560 if not r and not checked and (_toolbool(ui, tool, "checkchanged") or
562 if not r and not checked and (_toolbool(ui, tool, "checkchanged") or
561 'changed' in
563 'changed' in
562 _toollist(ui, tool, "check")):
564 _toollist(ui, tool, "check")):
563 if filecmp.cmp(a, back):
565 if filecmp.cmp(a, back):
564 if ui.promptchoice(_(" output file %s appears unchanged\n"
566 if ui.promptchoice(_(" output file %s appears unchanged\n"
565 "was merge successful (yn)?"
567 "was merge successful (yn)?"
566 "$$ &Yes $$ &No") % fd, 1):
568 "$$ &Yes $$ &No") % fd, 1):
567 r = 1
569 r = 1
568
570
569 if _toolbool(ui, tool, "fixeol"):
571 if _toolbool(ui, tool, "fixeol"):
570 _matcheol(a, back)
572 _matcheol(a, back)
571
573
572 return r
574 return r
573
575
574 def premerge(repo, mynode, orig, fcd, fco, fca, labels=None):
576 def premerge(repo, mynode, orig, fcd, fco, fca, labels=None):
575 return _filemerge(True, repo, mynode, orig, fcd, fco, fca, labels=labels)
577 return _filemerge(True, repo, mynode, orig, fcd, fco, fca, labels=labels)
576
578
577 def filemerge(repo, mynode, orig, fcd, fco, fca, labels=None):
579 def filemerge(repo, mynode, orig, fcd, fco, fca, labels=None):
578 # premerge = True is temporary -- will be changed to False once premerge
580 return _filemerge(False, repo, mynode, orig, fcd, fco, fca, labels=labels)
579 # function above is ready
580 return _filemerge(True, repo, mynode, orig, fcd, fco, fca, labels=labels)
581
581
582 # tell hggettext to extract docstrings from these functions:
582 # tell hggettext to extract docstrings from these functions:
583 i18nfunctions = internals.values()
583 i18nfunctions = internals.values()
@@ -1,1189 +1,1192 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 nullid,
19 nullid,
20 nullrev,
20 nullrev,
21 )
21 )
22 from . import (
22 from . import (
23 copies,
23 copies,
24 destutil,
24 destutil,
25 error,
25 error,
26 filemerge,
26 filemerge,
27 obsolete,
27 obsolete,
28 subrepo,
28 subrepo,
29 util,
29 util,
30 worker,
30 worker,
31 )
31 )
32
32
33 _pack = struct.pack
33 _pack = struct.pack
34 _unpack = struct.unpack
34 _unpack = struct.unpack
35
35
36 def _droponode(data):
36 def _droponode(data):
37 # used for compatibility for v1
37 # used for compatibility for v1
38 bits = data.split('\0')
38 bits = data.split('\0')
39 bits = bits[:-2] + bits[-1:]
39 bits = bits[:-2] + bits[-1:]
40 return '\0'.join(bits)
40 return '\0'.join(bits)
41
41
42 class mergestate(object):
42 class mergestate(object):
43 '''track 3-way merge state of individual files
43 '''track 3-way merge state of individual files
44
44
45 it is stored on disk when needed. Two file are used, one with an old
45 it is stored on disk when needed. Two file are used, one with an old
46 format, one with a new format. Both contains similar data, but the new
46 format, one with a new format. Both contains similar data, but the new
47 format can store new kinds of field.
47 format can store new kinds of field.
48
48
49 Current new format is a list of arbitrary record of the form:
49 Current new format is a list of arbitrary record of the form:
50
50
51 [type][length][content]
51 [type][length][content]
52
52
53 Type is a single character, length is a 4 bytes integer, content is an
53 Type is a single character, length is a 4 bytes integer, content is an
54 arbitrary suites of bytes of length `length`.
54 arbitrary suites of bytes of length `length`.
55
55
56 Type should be a letter. Capital letter are mandatory record, Mercurial
56 Type should be a letter. Capital letter are mandatory record, Mercurial
57 should abort if they are unknown. lower case record can be safely ignored.
57 should abort if they are unknown. lower case record can be safely ignored.
58
58
59 Currently known record:
59 Currently known record:
60
60
61 L: the node of the "local" part of the merge (hexified version)
61 L: the node of the "local" part of the merge (hexified version)
62 O: the node of the "other" part of the merge (hexified version)
62 O: the node of the "other" part of the merge (hexified version)
63 F: a file to be merged entry
63 F: a file to be merged entry
64 '''
64 '''
65 statepathv1 = 'merge/state'
65 statepathv1 = 'merge/state'
66 statepathv2 = 'merge/state2'
66 statepathv2 = 'merge/state2'
67
67
68 def __init__(self, repo):
68 def __init__(self, repo):
69 self._repo = repo
69 self._repo = repo
70 self._dirty = False
70 self._dirty = False
71 self._read()
71 self._read()
72
72
73 def reset(self, node=None, other=None):
73 def reset(self, node=None, other=None):
74 self._state = {}
74 self._state = {}
75 self._local = None
75 self._local = None
76 self._other = None
76 self._other = None
77 if node:
77 if node:
78 self._local = node
78 self._local = node
79 self._other = other
79 self._other = other
80 shutil.rmtree(self._repo.join('merge'), True)
80 shutil.rmtree(self._repo.join('merge'), True)
81 self._dirty = False
81 self._dirty = False
82
82
83 def _read(self):
83 def _read(self):
84 """Analyse each record content to restore a serialized state from disk
84 """Analyse each record content to restore a serialized state from disk
85
85
86 This function process "record" entry produced by the de-serialization
86 This function process "record" entry produced by the de-serialization
87 of on disk file.
87 of on disk file.
88 """
88 """
89 self._state = {}
89 self._state = {}
90 self._local = None
90 self._local = None
91 self._other = None
91 self._other = None
92 records = self._readrecords()
92 records = self._readrecords()
93 for rtype, record in records:
93 for rtype, record in records:
94 if rtype == 'L':
94 if rtype == 'L':
95 self._local = bin(record)
95 self._local = bin(record)
96 elif rtype == 'O':
96 elif rtype == 'O':
97 self._other = bin(record)
97 self._other = bin(record)
98 elif rtype == 'F':
98 elif rtype == 'F':
99 bits = record.split('\0')
99 bits = record.split('\0')
100 self._state[bits[0]] = bits[1:]
100 self._state[bits[0]] = bits[1:]
101 elif not rtype.islower():
101 elif not rtype.islower():
102 raise error.Abort(_('unsupported merge state record: %s')
102 raise error.Abort(_('unsupported merge state record: %s')
103 % rtype)
103 % rtype)
104 self._dirty = False
104 self._dirty = False
105
105
106 def _readrecords(self):
106 def _readrecords(self):
107 """Read merge state from disk and return a list of record (TYPE, data)
107 """Read merge state from disk and return a list of record (TYPE, data)
108
108
109 We read data from both v1 and v2 files and decide which one to use.
109 We read data from both v1 and v2 files and decide which one to use.
110
110
111 V1 has been used by version prior to 2.9.1 and contains less data than
111 V1 has been used by version prior to 2.9.1 and contains less data than
112 v2. We read both versions and check if no data in v2 contradicts
112 v2. We read both versions and check if no data in v2 contradicts
113 v1. If there is not contradiction we can safely assume that both v1
113 v1. If there is not contradiction we can safely assume that both v1
114 and v2 were written at the same time and use the extract data in v2. If
114 and v2 were written at the same time and use the extract data in v2. If
115 there is contradiction we ignore v2 content as we assume an old version
115 there is contradiction we ignore v2 content as we assume an old version
116 of Mercurial has overwritten the mergestate file and left an old v2
116 of Mercurial has overwritten the mergestate file and left an old v2
117 file around.
117 file around.
118
118
119 returns list of record [(TYPE, data), ...]"""
119 returns list of record [(TYPE, data), ...]"""
120 v1records = self._readrecordsv1()
120 v1records = self._readrecordsv1()
121 v2records = self._readrecordsv2()
121 v2records = self._readrecordsv2()
122 if self._v1v2match(v1records, v2records):
122 if self._v1v2match(v1records, v2records):
123 return v2records
123 return v2records
124 else:
124 else:
125 # v1 file is newer than v2 file, use it
125 # v1 file is newer than v2 file, use it
126 # we have to infer the "other" changeset of the merge
126 # we have to infer the "other" changeset of the merge
127 # we cannot do better than that with v1 of the format
127 # we cannot do better than that with v1 of the format
128 mctx = self._repo[None].parents()[-1]
128 mctx = self._repo[None].parents()[-1]
129 v1records.append(('O', mctx.hex()))
129 v1records.append(('O', mctx.hex()))
130 # add place holder "other" file node information
130 # add place holder "other" file node information
131 # nobody is using it yet so we do no need to fetch the data
131 # nobody is using it yet so we do no need to fetch the data
132 # if mctx was wrong `mctx[bits[-2]]` may fails.
132 # if mctx was wrong `mctx[bits[-2]]` may fails.
133 for idx, r in enumerate(v1records):
133 for idx, r in enumerate(v1records):
134 if r[0] == 'F':
134 if r[0] == 'F':
135 bits = r[1].split('\0')
135 bits = r[1].split('\0')
136 bits.insert(-2, '')
136 bits.insert(-2, '')
137 v1records[idx] = (r[0], '\0'.join(bits))
137 v1records[idx] = (r[0], '\0'.join(bits))
138 return v1records
138 return v1records
139
139
140 def _v1v2match(self, v1records, v2records):
140 def _v1v2match(self, v1records, v2records):
141 oldv2 = set() # old format version of v2 record
141 oldv2 = set() # old format version of v2 record
142 for rec in v2records:
142 for rec in v2records:
143 if rec[0] == 'L':
143 if rec[0] == 'L':
144 oldv2.add(rec)
144 oldv2.add(rec)
145 elif rec[0] == 'F':
145 elif rec[0] == 'F':
146 # drop the onode data (not contained in v1)
146 # drop the onode data (not contained in v1)
147 oldv2.add(('F', _droponode(rec[1])))
147 oldv2.add(('F', _droponode(rec[1])))
148 for rec in v1records:
148 for rec in v1records:
149 if rec not in oldv2:
149 if rec not in oldv2:
150 return False
150 return False
151 else:
151 else:
152 return True
152 return True
153
153
154 def _readrecordsv1(self):
154 def _readrecordsv1(self):
155 """read on disk merge state for version 1 file
155 """read on disk merge state for version 1 file
156
156
157 returns list of record [(TYPE, data), ...]
157 returns list of record [(TYPE, data), ...]
158
158
159 Note: the "F" data from this file are one entry short
159 Note: the "F" data from this file are one entry short
160 (no "other file node" entry)
160 (no "other file node" entry)
161 """
161 """
162 records = []
162 records = []
163 try:
163 try:
164 f = self._repo.vfs(self.statepathv1)
164 f = self._repo.vfs(self.statepathv1)
165 for i, l in enumerate(f):
165 for i, l in enumerate(f):
166 if i == 0:
166 if i == 0:
167 records.append(('L', l[:-1]))
167 records.append(('L', l[:-1]))
168 else:
168 else:
169 records.append(('F', l[:-1]))
169 records.append(('F', l[:-1]))
170 f.close()
170 f.close()
171 except IOError as err:
171 except IOError as err:
172 if err.errno != errno.ENOENT:
172 if err.errno != errno.ENOENT:
173 raise
173 raise
174 return records
174 return records
175
175
176 def _readrecordsv2(self):
176 def _readrecordsv2(self):
177 """read on disk merge state for version 2 file
177 """read on disk merge state for version 2 file
178
178
179 returns list of record [(TYPE, data), ...]
179 returns list of record [(TYPE, data), ...]
180 """
180 """
181 records = []
181 records = []
182 try:
182 try:
183 f = self._repo.vfs(self.statepathv2)
183 f = self._repo.vfs(self.statepathv2)
184 data = f.read()
184 data = f.read()
185 off = 0
185 off = 0
186 end = len(data)
186 end = len(data)
187 while off < end:
187 while off < end:
188 rtype = data[off]
188 rtype = data[off]
189 off += 1
189 off += 1
190 length = _unpack('>I', data[off:(off + 4)])[0]
190 length = _unpack('>I', data[off:(off + 4)])[0]
191 off += 4
191 off += 4
192 record = data[off:(off + length)]
192 record = data[off:(off + length)]
193 off += length
193 off += length
194 records.append((rtype, record))
194 records.append((rtype, record))
195 f.close()
195 f.close()
196 except IOError as err:
196 except IOError as err:
197 if err.errno != errno.ENOENT:
197 if err.errno != errno.ENOENT:
198 raise
198 raise
199 return records
199 return records
200
200
201 def active(self):
201 def active(self):
202 """Whether mergestate is active.
202 """Whether mergestate is active.
203
203
204 Returns True if there appears to be mergestate. This is a rough proxy
204 Returns True if there appears to be mergestate. This is a rough proxy
205 for "is a merge in progress."
205 for "is a merge in progress."
206 """
206 """
207 # Check local variables before looking at filesystem for performance
207 # Check local variables before looking at filesystem for performance
208 # reasons.
208 # reasons.
209 return bool(self._local) or bool(self._state) or \
209 return bool(self._local) or bool(self._state) or \
210 self._repo.vfs.exists(self.statepathv1) or \
210 self._repo.vfs.exists(self.statepathv1) or \
211 self._repo.vfs.exists(self.statepathv2)
211 self._repo.vfs.exists(self.statepathv2)
212
212
213 def commit(self):
213 def commit(self):
214 """Write current state on disk (if necessary)"""
214 """Write current state on disk (if necessary)"""
215 if self._dirty:
215 if self._dirty:
216 records = []
216 records = []
217 records.append(('L', hex(self._local)))
217 records.append(('L', hex(self._local)))
218 records.append(('O', hex(self._other)))
218 records.append(('O', hex(self._other)))
219 for d, v in self._state.iteritems():
219 for d, v in self._state.iteritems():
220 records.append(('F', '\0'.join([d] + v)))
220 records.append(('F', '\0'.join([d] + v)))
221 self._writerecords(records)
221 self._writerecords(records)
222 self._dirty = False
222 self._dirty = False
223
223
224 def _writerecords(self, records):
224 def _writerecords(self, records):
225 """Write current state on disk (both v1 and v2)"""
225 """Write current state on disk (both v1 and v2)"""
226 self._writerecordsv1(records)
226 self._writerecordsv1(records)
227 self._writerecordsv2(records)
227 self._writerecordsv2(records)
228
228
229 def _writerecordsv1(self, records):
229 def _writerecordsv1(self, records):
230 """Write current state on disk in a version 1 file"""
230 """Write current state on disk in a version 1 file"""
231 f = self._repo.vfs(self.statepathv1, 'w')
231 f = self._repo.vfs(self.statepathv1, 'w')
232 irecords = iter(records)
232 irecords = iter(records)
233 lrecords = irecords.next()
233 lrecords = irecords.next()
234 assert lrecords[0] == 'L'
234 assert lrecords[0] == 'L'
235 f.write(hex(self._local) + '\n')
235 f.write(hex(self._local) + '\n')
236 for rtype, data in irecords:
236 for rtype, data in irecords:
237 if rtype == 'F':
237 if rtype == 'F':
238 f.write('%s\n' % _droponode(data))
238 f.write('%s\n' % _droponode(data))
239 f.close()
239 f.close()
240
240
241 def _writerecordsv2(self, records):
241 def _writerecordsv2(self, records):
242 """Write current state on disk in a version 2 file"""
242 """Write current state on disk in a version 2 file"""
243 f = self._repo.vfs(self.statepathv2, 'w')
243 f = self._repo.vfs(self.statepathv2, 'w')
244 for key, data in records:
244 for key, data in records:
245 assert len(key) == 1
245 assert len(key) == 1
246 format = '>sI%is' % len(data)
246 format = '>sI%is' % len(data)
247 f.write(_pack(format, key, len(data), data))
247 f.write(_pack(format, key, len(data), data))
248 f.close()
248 f.close()
249
249
250 def add(self, fcl, fco, fca, fd):
250 def add(self, fcl, fco, fca, fd):
251 """add a new (potentially?) conflicting file the merge state
251 """add a new (potentially?) conflicting file the merge state
252 fcl: file context for local,
252 fcl: file context for local,
253 fco: file context for remote,
253 fco: file context for remote,
254 fca: file context for ancestors,
254 fca: file context for ancestors,
255 fd: file path of the resulting merge.
255 fd: file path of the resulting merge.
256
256
257 note: also write the local version to the `.hg/merge` directory.
257 note: also write the local version to the `.hg/merge` directory.
258 """
258 """
259 hash = util.sha1(fcl.path()).hexdigest()
259 hash = util.sha1(fcl.path()).hexdigest()
260 self._repo.vfs.write('merge/' + hash, fcl.data())
260 self._repo.vfs.write('merge/' + hash, fcl.data())
261 self._state[fd] = ['u', hash, fcl.path(),
261 self._state[fd] = ['u', hash, fcl.path(),
262 fca.path(), hex(fca.filenode()),
262 fca.path(), hex(fca.filenode()),
263 fco.path(), hex(fco.filenode()),
263 fco.path(), hex(fco.filenode()),
264 fcl.flags()]
264 fcl.flags()]
265 self._dirty = True
265 self._dirty = True
266
266
267 def __contains__(self, dfile):
267 def __contains__(self, dfile):
268 return dfile in self._state
268 return dfile in self._state
269
269
270 def __getitem__(self, dfile):
270 def __getitem__(self, dfile):
271 return self._state[dfile][0]
271 return self._state[dfile][0]
272
272
273 def __iter__(self):
273 def __iter__(self):
274 return iter(sorted(self._state))
274 return iter(sorted(self._state))
275
275
276 def files(self):
276 def files(self):
277 return self._state.keys()
277 return self._state.keys()
278
278
279 def mark(self, dfile, state):
279 def mark(self, dfile, state):
280 self._state[dfile][0] = state
280 self._state[dfile][0] = state
281 self._dirty = True
281 self._dirty = True
282
282
283 def unresolved(self):
283 def unresolved(self):
284 """Obtain the paths of unresolved files."""
284 """Obtain the paths of unresolved files."""
285
285
286 for f, entry in self._state.items():
286 for f, entry in self._state.items():
287 if entry[0] == 'u':
287 if entry[0] == 'u':
288 yield f
288 yield f
289
289
290 def resolve(self, dfile, wctx, labels=None):
290 def resolve(self, dfile, wctx, labels=None):
291 """rerun merge process for file path `dfile`"""
291 """rerun merge process for file path `dfile`"""
292 if self[dfile] == 'r':
292 if self[dfile] == 'r':
293 return 0
293 return 0
294 stateentry = self._state[dfile]
294 stateentry = self._state[dfile]
295 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
295 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
296 octx = self._repo[self._other]
296 octx = self._repo[self._other]
297 fcd = wctx[dfile]
297 fcd = wctx[dfile]
298 fco = octx[ofile]
298 fco = octx[ofile]
299 fca = self._repo.filectx(afile, fileid=anode)
299 fca = self._repo.filectx(afile, fileid=anode)
300 # "premerge" x flags
300 # "premerge" x flags
301 flo = fco.flags()
301 flo = fco.flags()
302 fla = fca.flags()
302 fla = fca.flags()
303 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
303 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
304 if fca.node() == nullid:
304 if fca.node() == nullid:
305 self._repo.ui.warn(_('warning: cannot merge flags for %s\n') %
305 self._repo.ui.warn(_('warning: cannot merge flags for %s\n') %
306 afile)
306 afile)
307 elif flags == fla:
307 elif flags == fla:
308 flags = flo
308 flags = flo
309 # restore local
309 # restore local
310 f = self._repo.vfs('merge/' + hash)
310 f = self._repo.vfs('merge/' + hash)
311 self._repo.wwrite(dfile, f.read(), flags)
311 self._repo.wwrite(dfile, f.read(), flags)
312 f.close()
312 f.close()
313 complete, r = filemerge.filemerge(self._repo, self._local, lfile, fcd,
313 complete, r = filemerge.premerge(self._repo, self._local, lfile, fcd,
314 fco, fca, labels=labels)
314 fco, fca, labels=labels)
315 if not complete:
316 complete, r = filemerge.filemerge(self._repo, self._local, lfile,
317 fcd, fco, fca, labels=labels)
315 if r is None:
318 if r is None:
316 # no real conflict
319 # no real conflict
317 del self._state[dfile]
320 del self._state[dfile]
318 self._dirty = True
321 self._dirty = True
319 elif not r:
322 elif not r:
320 self.mark(dfile, 'r')
323 self.mark(dfile, 'r')
321 return r
324 return r
322
325
323 def _checkunknownfile(repo, wctx, mctx, f, f2=None):
326 def _checkunknownfile(repo, wctx, mctx, f, f2=None):
324 if f2 is None:
327 if f2 is None:
325 f2 = f
328 f2 = f
326 return (os.path.isfile(repo.wjoin(f))
329 return (os.path.isfile(repo.wjoin(f))
327 and repo.wvfs.audit.check(f)
330 and repo.wvfs.audit.check(f)
328 and repo.dirstate.normalize(f) not in repo.dirstate
331 and repo.dirstate.normalize(f) not in repo.dirstate
329 and mctx[f2].cmp(wctx[f]))
332 and mctx[f2].cmp(wctx[f]))
330
333
331 def _checkunknownfiles(repo, wctx, mctx, force, actions):
334 def _checkunknownfiles(repo, wctx, mctx, force, actions):
332 """
335 """
333 Considers any actions that care about the presence of conflicting unknown
336 Considers any actions that care about the presence of conflicting unknown
334 files. For some actions, the result is to abort; for others, it is to
337 files. For some actions, the result is to abort; for others, it is to
335 choose a different action.
338 choose a different action.
336 """
339 """
337 aborts = []
340 aborts = []
338 if not force:
341 if not force:
339 for f, (m, args, msg) in actions.iteritems():
342 for f, (m, args, msg) in actions.iteritems():
340 if m in ('c', 'dc'):
343 if m in ('c', 'dc'):
341 if _checkunknownfile(repo, wctx, mctx, f):
344 if _checkunknownfile(repo, wctx, mctx, f):
342 aborts.append(f)
345 aborts.append(f)
343 elif m == 'dg':
346 elif m == 'dg':
344 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
347 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
345 aborts.append(f)
348 aborts.append(f)
346
349
347 for f in sorted(aborts):
350 for f in sorted(aborts):
348 repo.ui.warn(_("%s: untracked file differs\n") % f)
351 repo.ui.warn(_("%s: untracked file differs\n") % f)
349 if aborts:
352 if aborts:
350 raise error.Abort(_("untracked files in working directory differ "
353 raise error.Abort(_("untracked files in working directory differ "
351 "from files in requested revision"))
354 "from files in requested revision"))
352
355
353 for f, (m, args, msg) in actions.iteritems():
356 for f, (m, args, msg) in actions.iteritems():
354 if m == 'c':
357 if m == 'c':
355 actions[f] = ('g', args, msg)
358 actions[f] = ('g', args, msg)
356 elif m == 'cm':
359 elif m == 'cm':
357 fl2, anc = args
360 fl2, anc = args
358 different = _checkunknownfile(repo, wctx, mctx, f)
361 different = _checkunknownfile(repo, wctx, mctx, f)
359 if different:
362 if different:
360 actions[f] = ('m', (f, f, None, False, anc),
363 actions[f] = ('m', (f, f, None, False, anc),
361 "remote differs from untracked local")
364 "remote differs from untracked local")
362 else:
365 else:
363 actions[f] = ('g', (fl2,), "remote created")
366 actions[f] = ('g', (fl2,), "remote created")
364
367
365 def _forgetremoved(wctx, mctx, branchmerge):
368 def _forgetremoved(wctx, mctx, branchmerge):
366 """
369 """
367 Forget removed files
370 Forget removed files
368
371
369 If we're jumping between revisions (as opposed to merging), and if
372 If we're jumping between revisions (as opposed to merging), and if
370 neither the working directory nor the target rev has the file,
373 neither the working directory nor the target rev has the file,
371 then we need to remove it from the dirstate, to prevent the
374 then we need to remove it from the dirstate, to prevent the
372 dirstate from listing the file when it is no longer in the
375 dirstate from listing the file when it is no longer in the
373 manifest.
376 manifest.
374
377
375 If we're merging, and the other revision has removed a file
378 If we're merging, and the other revision has removed a file
376 that is not present in the working directory, we need to mark it
379 that is not present in the working directory, we need to mark it
377 as removed.
380 as removed.
378 """
381 """
379
382
380 actions = {}
383 actions = {}
381 m = 'f'
384 m = 'f'
382 if branchmerge:
385 if branchmerge:
383 m = 'r'
386 m = 'r'
384 for f in wctx.deleted():
387 for f in wctx.deleted():
385 if f not in mctx:
388 if f not in mctx:
386 actions[f] = m, None, "forget deleted"
389 actions[f] = m, None, "forget deleted"
387
390
388 if not branchmerge:
391 if not branchmerge:
389 for f in wctx.removed():
392 for f in wctx.removed():
390 if f not in mctx:
393 if f not in mctx:
391 actions[f] = 'f', None, "forget removed"
394 actions[f] = 'f', None, "forget removed"
392
395
393 return actions
396 return actions
394
397
395 def _checkcollision(repo, wmf, actions):
398 def _checkcollision(repo, wmf, actions):
396 # build provisional merged manifest up
399 # build provisional merged manifest up
397 pmmf = set(wmf)
400 pmmf = set(wmf)
398
401
399 if actions:
402 if actions:
400 # k, dr, e and rd are no-op
403 # k, dr, e and rd are no-op
401 for m in 'a', 'f', 'g', 'cd', 'dc':
404 for m in 'a', 'f', 'g', 'cd', 'dc':
402 for f, args, msg in actions[m]:
405 for f, args, msg in actions[m]:
403 pmmf.add(f)
406 pmmf.add(f)
404 for f, args, msg in actions['r']:
407 for f, args, msg in actions['r']:
405 pmmf.discard(f)
408 pmmf.discard(f)
406 for f, args, msg in actions['dm']:
409 for f, args, msg in actions['dm']:
407 f2, flags = args
410 f2, flags = args
408 pmmf.discard(f2)
411 pmmf.discard(f2)
409 pmmf.add(f)
412 pmmf.add(f)
410 for f, args, msg in actions['dg']:
413 for f, args, msg in actions['dg']:
411 pmmf.add(f)
414 pmmf.add(f)
412 for f, args, msg in actions['m']:
415 for f, args, msg in actions['m']:
413 f1, f2, fa, move, anc = args
416 f1, f2, fa, move, anc = args
414 if move:
417 if move:
415 pmmf.discard(f1)
418 pmmf.discard(f1)
416 pmmf.add(f)
419 pmmf.add(f)
417
420
418 # check case-folding collision in provisional merged manifest
421 # check case-folding collision in provisional merged manifest
419 foldmap = {}
422 foldmap = {}
420 for f in sorted(pmmf):
423 for f in sorted(pmmf):
421 fold = util.normcase(f)
424 fold = util.normcase(f)
422 if fold in foldmap:
425 if fold in foldmap:
423 raise error.Abort(_("case-folding collision between %s and %s")
426 raise error.Abort(_("case-folding collision between %s and %s")
424 % (f, foldmap[fold]))
427 % (f, foldmap[fold]))
425 foldmap[fold] = f
428 foldmap[fold] = f
426
429
427 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial,
430 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial,
428 acceptremote, followcopies):
431 acceptremote, followcopies):
429 """
432 """
430 Merge p1 and p2 with ancestor pa and generate merge action list
433 Merge p1 and p2 with ancestor pa and generate merge action list
431
434
432 branchmerge and force are as passed in to update
435 branchmerge and force are as passed in to update
433 partial = function to filter file lists
436 partial = function to filter file lists
434 acceptremote = accept the incoming changes without prompting
437 acceptremote = accept the incoming changes without prompting
435 """
438 """
436
439
437 copy, movewithdir, diverge, renamedelete = {}, {}, {}, {}
440 copy, movewithdir, diverge, renamedelete = {}, {}, {}, {}
438
441
439 # manifests fetched in order are going to be faster, so prime the caches
442 # manifests fetched in order are going to be faster, so prime the caches
440 [x.manifest() for x in
443 [x.manifest() for x in
441 sorted(wctx.parents() + [p2, pa], key=lambda x: x.rev())]
444 sorted(wctx.parents() + [p2, pa], key=lambda x: x.rev())]
442
445
443 if followcopies:
446 if followcopies:
444 ret = copies.mergecopies(repo, wctx, p2, pa)
447 ret = copies.mergecopies(repo, wctx, p2, pa)
445 copy, movewithdir, diverge, renamedelete = ret
448 copy, movewithdir, diverge, renamedelete = ret
446
449
447 repo.ui.note(_("resolving manifests\n"))
450 repo.ui.note(_("resolving manifests\n"))
448 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
451 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
449 % (bool(branchmerge), bool(force), bool(partial)))
452 % (bool(branchmerge), bool(force), bool(partial)))
450 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
453 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
451
454
452 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
455 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
453 copied = set(copy.values())
456 copied = set(copy.values())
454 copied.update(movewithdir.values())
457 copied.update(movewithdir.values())
455
458
456 if '.hgsubstate' in m1:
459 if '.hgsubstate' in m1:
457 # check whether sub state is modified
460 # check whether sub state is modified
458 for s in sorted(wctx.substate):
461 for s in sorted(wctx.substate):
459 if wctx.sub(s).dirty():
462 if wctx.sub(s).dirty():
460 m1['.hgsubstate'] += '+'
463 m1['.hgsubstate'] += '+'
461 break
464 break
462
465
463 # Compare manifests
466 # Compare manifests
464 diff = m1.diff(m2)
467 diff = m1.diff(m2)
465
468
466 actions = {}
469 actions = {}
467 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems():
470 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems():
468 if partial and not partial(f):
471 if partial and not partial(f):
469 continue
472 continue
470 if n1 and n2: # file exists on both local and remote side
473 if n1 and n2: # file exists on both local and remote side
471 if f not in ma:
474 if f not in ma:
472 fa = copy.get(f, None)
475 fa = copy.get(f, None)
473 if fa is not None:
476 if fa is not None:
474 actions[f] = ('m', (f, f, fa, False, pa.node()),
477 actions[f] = ('m', (f, f, fa, False, pa.node()),
475 "both renamed from " + fa)
478 "both renamed from " + fa)
476 else:
479 else:
477 actions[f] = ('m', (f, f, None, False, pa.node()),
480 actions[f] = ('m', (f, f, None, False, pa.node()),
478 "both created")
481 "both created")
479 else:
482 else:
480 a = ma[f]
483 a = ma[f]
481 fla = ma.flags(f)
484 fla = ma.flags(f)
482 nol = 'l' not in fl1 + fl2 + fla
485 nol = 'l' not in fl1 + fl2 + fla
483 if n2 == a and fl2 == fla:
486 if n2 == a and fl2 == fla:
484 actions[f] = ('k' , (), "remote unchanged")
487 actions[f] = ('k' , (), "remote unchanged")
485 elif n1 == a and fl1 == fla: # local unchanged - use remote
488 elif n1 == a and fl1 == fla: # local unchanged - use remote
486 if n1 == n2: # optimization: keep local content
489 if n1 == n2: # optimization: keep local content
487 actions[f] = ('e', (fl2,), "update permissions")
490 actions[f] = ('e', (fl2,), "update permissions")
488 else:
491 else:
489 actions[f] = ('g', (fl2,), "remote is newer")
492 actions[f] = ('g', (fl2,), "remote is newer")
490 elif nol and n2 == a: # remote only changed 'x'
493 elif nol and n2 == a: # remote only changed 'x'
491 actions[f] = ('e', (fl2,), "update permissions")
494 actions[f] = ('e', (fl2,), "update permissions")
492 elif nol and n1 == a: # local only changed 'x'
495 elif nol and n1 == a: # local only changed 'x'
493 actions[f] = ('g', (fl1,), "remote is newer")
496 actions[f] = ('g', (fl1,), "remote is newer")
494 else: # both changed something
497 else: # both changed something
495 actions[f] = ('m', (f, f, f, False, pa.node()),
498 actions[f] = ('m', (f, f, f, False, pa.node()),
496 "versions differ")
499 "versions differ")
497 elif n1: # file exists only on local side
500 elif n1: # file exists only on local side
498 if f in copied:
501 if f in copied:
499 pass # we'll deal with it on m2 side
502 pass # we'll deal with it on m2 side
500 elif f in movewithdir: # directory rename, move local
503 elif f in movewithdir: # directory rename, move local
501 f2 = movewithdir[f]
504 f2 = movewithdir[f]
502 if f2 in m2:
505 if f2 in m2:
503 actions[f2] = ('m', (f, f2, None, True, pa.node()),
506 actions[f2] = ('m', (f, f2, None, True, pa.node()),
504 "remote directory rename, both created")
507 "remote directory rename, both created")
505 else:
508 else:
506 actions[f2] = ('dm', (f, fl1),
509 actions[f2] = ('dm', (f, fl1),
507 "remote directory rename - move from " + f)
510 "remote directory rename - move from " + f)
508 elif f in copy:
511 elif f in copy:
509 f2 = copy[f]
512 f2 = copy[f]
510 actions[f] = ('m', (f, f2, f2, False, pa.node()),
513 actions[f] = ('m', (f, f2, f2, False, pa.node()),
511 "local copied/moved from " + f2)
514 "local copied/moved from " + f2)
512 elif f in ma: # clean, a different, no remote
515 elif f in ma: # clean, a different, no remote
513 if n1 != ma[f]:
516 if n1 != ma[f]:
514 if acceptremote:
517 if acceptremote:
515 actions[f] = ('r', None, "remote delete")
518 actions[f] = ('r', None, "remote delete")
516 else:
519 else:
517 actions[f] = ('cd', None, "prompt changed/deleted")
520 actions[f] = ('cd', None, "prompt changed/deleted")
518 elif n1[20:] == 'a':
521 elif n1[20:] == 'a':
519 # This extra 'a' is added by working copy manifest to mark
522 # This extra 'a' is added by working copy manifest to mark
520 # the file as locally added. We should forget it instead of
523 # the file as locally added. We should forget it instead of
521 # deleting it.
524 # deleting it.
522 actions[f] = ('f', None, "remote deleted")
525 actions[f] = ('f', None, "remote deleted")
523 else:
526 else:
524 actions[f] = ('r', None, "other deleted")
527 actions[f] = ('r', None, "other deleted")
525 elif n2: # file exists only on remote side
528 elif n2: # file exists only on remote side
526 if f in copied:
529 if f in copied:
527 pass # we'll deal with it on m1 side
530 pass # we'll deal with it on m1 side
528 elif f in movewithdir:
531 elif f in movewithdir:
529 f2 = movewithdir[f]
532 f2 = movewithdir[f]
530 if f2 in m1:
533 if f2 in m1:
531 actions[f2] = ('m', (f2, f, None, False, pa.node()),
534 actions[f2] = ('m', (f2, f, None, False, pa.node()),
532 "local directory rename, both created")
535 "local directory rename, both created")
533 else:
536 else:
534 actions[f2] = ('dg', (f, fl2),
537 actions[f2] = ('dg', (f, fl2),
535 "local directory rename - get from " + f)
538 "local directory rename - get from " + f)
536 elif f in copy:
539 elif f in copy:
537 f2 = copy[f]
540 f2 = copy[f]
538 if f2 in m2:
541 if f2 in m2:
539 actions[f] = ('m', (f2, f, f2, False, pa.node()),
542 actions[f] = ('m', (f2, f, f2, False, pa.node()),
540 "remote copied from " + f2)
543 "remote copied from " + f2)
541 else:
544 else:
542 actions[f] = ('m', (f2, f, f2, True, pa.node()),
545 actions[f] = ('m', (f2, f, f2, True, pa.node()),
543 "remote moved from " + f2)
546 "remote moved from " + f2)
544 elif f not in ma:
547 elif f not in ma:
545 # local unknown, remote created: the logic is described by the
548 # local unknown, remote created: the logic is described by the
546 # following table:
549 # following table:
547 #
550 #
548 # force branchmerge different | action
551 # force branchmerge different | action
549 # n * * | create
552 # n * * | create
550 # y n * | create
553 # y n * | create
551 # y y n | create
554 # y y n | create
552 # y y y | merge
555 # y y y | merge
553 #
556 #
554 # Checking whether the files are different is expensive, so we
557 # Checking whether the files are different is expensive, so we
555 # don't do that when we can avoid it.
558 # don't do that when we can avoid it.
556 if not force:
559 if not force:
557 actions[f] = ('c', (fl2,), "remote created")
560 actions[f] = ('c', (fl2,), "remote created")
558 elif not branchmerge:
561 elif not branchmerge:
559 actions[f] = ('c', (fl2,), "remote created")
562 actions[f] = ('c', (fl2,), "remote created")
560 else:
563 else:
561 actions[f] = ('cm', (fl2, pa.node()),
564 actions[f] = ('cm', (fl2, pa.node()),
562 "remote created, get or merge")
565 "remote created, get or merge")
563 elif n2 != ma[f]:
566 elif n2 != ma[f]:
564 if acceptremote:
567 if acceptremote:
565 actions[f] = ('c', (fl2,), "remote recreating")
568 actions[f] = ('c', (fl2,), "remote recreating")
566 else:
569 else:
567 actions[f] = ('dc', (fl2,), "prompt deleted/changed")
570 actions[f] = ('dc', (fl2,), "prompt deleted/changed")
568
571
569 return actions, diverge, renamedelete
572 return actions, diverge, renamedelete
570
573
571 def _resolvetrivial(repo, wctx, mctx, ancestor, actions):
574 def _resolvetrivial(repo, wctx, mctx, ancestor, actions):
572 """Resolves false conflicts where the nodeid changed but the content
575 """Resolves false conflicts where the nodeid changed but the content
573 remained the same."""
576 remained the same."""
574
577
575 for f, (m, args, msg) in actions.items():
578 for f, (m, args, msg) in actions.items():
576 if m == 'cd' and f in ancestor and not wctx[f].cmp(ancestor[f]):
579 if m == 'cd' and f in ancestor and not wctx[f].cmp(ancestor[f]):
577 # local did change but ended up with same content
580 # local did change but ended up with same content
578 actions[f] = 'r', None, "prompt same"
581 actions[f] = 'r', None, "prompt same"
579 elif m == 'dc' and f in ancestor and not mctx[f].cmp(ancestor[f]):
582 elif m == 'dc' and f in ancestor and not mctx[f].cmp(ancestor[f]):
580 # remote did change but ended up with same content
583 # remote did change but ended up with same content
581 del actions[f] # don't get = keep local deleted
584 del actions[f] # don't get = keep local deleted
582
585
583 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force, partial,
586 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force, partial,
584 acceptremote, followcopies):
587 acceptremote, followcopies):
585 "Calculate the actions needed to merge mctx into wctx using ancestors"
588 "Calculate the actions needed to merge mctx into wctx using ancestors"
586
589
587 if len(ancestors) == 1: # default
590 if len(ancestors) == 1: # default
588 actions, diverge, renamedelete = manifestmerge(
591 actions, diverge, renamedelete = manifestmerge(
589 repo, wctx, mctx, ancestors[0], branchmerge, force, partial,
592 repo, wctx, mctx, ancestors[0], branchmerge, force, partial,
590 acceptremote, followcopies)
593 acceptremote, followcopies)
591 _checkunknownfiles(repo, wctx, mctx, force, actions)
594 _checkunknownfiles(repo, wctx, mctx, force, actions)
592
595
593 else: # only when merge.preferancestor=* - the default
596 else: # only when merge.preferancestor=* - the default
594 repo.ui.note(
597 repo.ui.note(
595 _("note: merging %s and %s using bids from ancestors %s\n") %
598 _("note: merging %s and %s using bids from ancestors %s\n") %
596 (wctx, mctx, _(' and ').join(str(anc) for anc in ancestors)))
599 (wctx, mctx, _(' and ').join(str(anc) for anc in ancestors)))
597
600
598 # Call for bids
601 # Call for bids
599 fbids = {} # mapping filename to bids (action method to list af actions)
602 fbids = {} # mapping filename to bids (action method to list af actions)
600 diverge, renamedelete = None, None
603 diverge, renamedelete = None, None
601 for ancestor in ancestors:
604 for ancestor in ancestors:
602 repo.ui.note(_('\ncalculating bids for ancestor %s\n') % ancestor)
605 repo.ui.note(_('\ncalculating bids for ancestor %s\n') % ancestor)
603 actions, diverge1, renamedelete1 = manifestmerge(
606 actions, diverge1, renamedelete1 = manifestmerge(
604 repo, wctx, mctx, ancestor, branchmerge, force, partial,
607 repo, wctx, mctx, ancestor, branchmerge, force, partial,
605 acceptremote, followcopies)
608 acceptremote, followcopies)
606 _checkunknownfiles(repo, wctx, mctx, force, actions)
609 _checkunknownfiles(repo, wctx, mctx, force, actions)
607
610
608 # Track the shortest set of warning on the theory that bid
611 # Track the shortest set of warning on the theory that bid
609 # merge will correctly incorporate more information
612 # merge will correctly incorporate more information
610 if diverge is None or len(diverge1) < len(diverge):
613 if diverge is None or len(diverge1) < len(diverge):
611 diverge = diverge1
614 diverge = diverge1
612 if renamedelete is None or len(renamedelete) < len(renamedelete1):
615 if renamedelete is None or len(renamedelete) < len(renamedelete1):
613 renamedelete = renamedelete1
616 renamedelete = renamedelete1
614
617
615 for f, a in sorted(actions.iteritems()):
618 for f, a in sorted(actions.iteritems()):
616 m, args, msg = a
619 m, args, msg = a
617 repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m))
620 repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m))
618 if f in fbids:
621 if f in fbids:
619 d = fbids[f]
622 d = fbids[f]
620 if m in d:
623 if m in d:
621 d[m].append(a)
624 d[m].append(a)
622 else:
625 else:
623 d[m] = [a]
626 d[m] = [a]
624 else:
627 else:
625 fbids[f] = {m: [a]}
628 fbids[f] = {m: [a]}
626
629
627 # Pick the best bid for each file
630 # Pick the best bid for each file
628 repo.ui.note(_('\nauction for merging merge bids\n'))
631 repo.ui.note(_('\nauction for merging merge bids\n'))
629 actions = {}
632 actions = {}
630 for f, bids in sorted(fbids.items()):
633 for f, bids in sorted(fbids.items()):
631 # bids is a mapping from action method to list af actions
634 # bids is a mapping from action method to list af actions
632 # Consensus?
635 # Consensus?
633 if len(bids) == 1: # all bids are the same kind of method
636 if len(bids) == 1: # all bids are the same kind of method
634 m, l = bids.items()[0]
637 m, l = bids.items()[0]
635 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
638 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
636 repo.ui.note(" %s: consensus for %s\n" % (f, m))
639 repo.ui.note(" %s: consensus for %s\n" % (f, m))
637 actions[f] = l[0]
640 actions[f] = l[0]
638 continue
641 continue
639 # If keep is an option, just do it.
642 # If keep is an option, just do it.
640 if 'k' in bids:
643 if 'k' in bids:
641 repo.ui.note(" %s: picking 'keep' action\n" % f)
644 repo.ui.note(" %s: picking 'keep' action\n" % f)
642 actions[f] = bids['k'][0]
645 actions[f] = bids['k'][0]
643 continue
646 continue
644 # If there are gets and they all agree [how could they not?], do it.
647 # If there are gets and they all agree [how could they not?], do it.
645 if 'g' in bids:
648 if 'g' in bids:
646 ga0 = bids['g'][0]
649 ga0 = bids['g'][0]
647 if all(a == ga0 for a in bids['g'][1:]):
650 if all(a == ga0 for a in bids['g'][1:]):
648 repo.ui.note(" %s: picking 'get' action\n" % f)
651 repo.ui.note(" %s: picking 'get' action\n" % f)
649 actions[f] = ga0
652 actions[f] = ga0
650 continue
653 continue
651 # TODO: Consider other simple actions such as mode changes
654 # TODO: Consider other simple actions such as mode changes
652 # Handle inefficient democrazy.
655 # Handle inefficient democrazy.
653 repo.ui.note(_(' %s: multiple bids for merge action:\n') % f)
656 repo.ui.note(_(' %s: multiple bids for merge action:\n') % f)
654 for m, l in sorted(bids.items()):
657 for m, l in sorted(bids.items()):
655 for _f, args, msg in l:
658 for _f, args, msg in l:
656 repo.ui.note(' %s -> %s\n' % (msg, m))
659 repo.ui.note(' %s -> %s\n' % (msg, m))
657 # Pick random action. TODO: Instead, prompt user when resolving
660 # Pick random action. TODO: Instead, prompt user when resolving
658 m, l = bids.items()[0]
661 m, l = bids.items()[0]
659 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
662 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
660 (f, m))
663 (f, m))
661 actions[f] = l[0]
664 actions[f] = l[0]
662 continue
665 continue
663 repo.ui.note(_('end of auction\n\n'))
666 repo.ui.note(_('end of auction\n\n'))
664
667
665 _resolvetrivial(repo, wctx, mctx, ancestors[0], actions)
668 _resolvetrivial(repo, wctx, mctx, ancestors[0], actions)
666
669
667 if wctx.rev() is None:
670 if wctx.rev() is None:
668 fractions = _forgetremoved(wctx, mctx, branchmerge)
671 fractions = _forgetremoved(wctx, mctx, branchmerge)
669 actions.update(fractions)
672 actions.update(fractions)
670
673
671 return actions, diverge, renamedelete
674 return actions, diverge, renamedelete
672
675
673 def batchremove(repo, actions):
676 def batchremove(repo, actions):
674 """apply removes to the working directory
677 """apply removes to the working directory
675
678
676 yields tuples for progress updates
679 yields tuples for progress updates
677 """
680 """
678 verbose = repo.ui.verbose
681 verbose = repo.ui.verbose
679 unlink = util.unlinkpath
682 unlink = util.unlinkpath
680 wjoin = repo.wjoin
683 wjoin = repo.wjoin
681 audit = repo.wvfs.audit
684 audit = repo.wvfs.audit
682 i = 0
685 i = 0
683 for f, args, msg in actions:
686 for f, args, msg in actions:
684 repo.ui.debug(" %s: %s -> r\n" % (f, msg))
687 repo.ui.debug(" %s: %s -> r\n" % (f, msg))
685 if verbose:
688 if verbose:
686 repo.ui.note(_("removing %s\n") % f)
689 repo.ui.note(_("removing %s\n") % f)
687 audit(f)
690 audit(f)
688 try:
691 try:
689 unlink(wjoin(f), ignoremissing=True)
692 unlink(wjoin(f), ignoremissing=True)
690 except OSError as inst:
693 except OSError as inst:
691 repo.ui.warn(_("update failed to remove %s: %s!\n") %
694 repo.ui.warn(_("update failed to remove %s: %s!\n") %
692 (f, inst.strerror))
695 (f, inst.strerror))
693 if i == 100:
696 if i == 100:
694 yield i, f
697 yield i, f
695 i = 0
698 i = 0
696 i += 1
699 i += 1
697 if i > 0:
700 if i > 0:
698 yield i, f
701 yield i, f
699
702
700 def batchget(repo, mctx, actions):
703 def batchget(repo, mctx, actions):
701 """apply gets to the working directory
704 """apply gets to the working directory
702
705
703 mctx is the context to get from
706 mctx is the context to get from
704
707
705 yields tuples for progress updates
708 yields tuples for progress updates
706 """
709 """
707 verbose = repo.ui.verbose
710 verbose = repo.ui.verbose
708 fctx = mctx.filectx
711 fctx = mctx.filectx
709 wwrite = repo.wwrite
712 wwrite = repo.wwrite
710 i = 0
713 i = 0
711 for f, args, msg in actions:
714 for f, args, msg in actions:
712 repo.ui.debug(" %s: %s -> g\n" % (f, msg))
715 repo.ui.debug(" %s: %s -> g\n" % (f, msg))
713 if verbose:
716 if verbose:
714 repo.ui.note(_("getting %s\n") % f)
717 repo.ui.note(_("getting %s\n") % f)
715 wwrite(f, fctx(f).data(), args[0])
718 wwrite(f, fctx(f).data(), args[0])
716 if i == 100:
719 if i == 100:
717 yield i, f
720 yield i, f
718 i = 0
721 i = 0
719 i += 1
722 i += 1
720 if i > 0:
723 if i > 0:
721 yield i, f
724 yield i, f
722
725
723 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None):
726 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None):
724 """apply the merge action list to the working directory
727 """apply the merge action list to the working directory
725
728
726 wctx is the working copy context
729 wctx is the working copy context
727 mctx is the context to be merged into the working copy
730 mctx is the context to be merged into the working copy
728
731
729 Return a tuple of counts (updated, merged, removed, unresolved) that
732 Return a tuple of counts (updated, merged, removed, unresolved) that
730 describes how many files were affected by the update.
733 describes how many files were affected by the update.
731 """
734 """
732
735
733 updated, merged, removed, unresolved = 0, 0, 0, 0
736 updated, merged, removed, unresolved = 0, 0, 0, 0
734 ms = mergestate(repo)
737 ms = mergestate(repo)
735 ms.reset(wctx.p1().node(), mctx.node())
738 ms.reset(wctx.p1().node(), mctx.node())
736 moves = []
739 moves = []
737 for m, l in actions.items():
740 for m, l in actions.items():
738 l.sort()
741 l.sort()
739
742
740 # prescan for merges
743 # prescan for merges
741 for f, args, msg in actions['m']:
744 for f, args, msg in actions['m']:
742 f1, f2, fa, move, anc = args
745 f1, f2, fa, move, anc = args
743 if f == '.hgsubstate': # merged internally
746 if f == '.hgsubstate': # merged internally
744 continue
747 continue
745 repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f))
748 repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f))
746 fcl = wctx[f1]
749 fcl = wctx[f1]
747 fco = mctx[f2]
750 fco = mctx[f2]
748 actx = repo[anc]
751 actx = repo[anc]
749 if fa in actx:
752 if fa in actx:
750 fca = actx[fa]
753 fca = actx[fa]
751 else:
754 else:
752 fca = repo.filectx(f1, fileid=nullrev)
755 fca = repo.filectx(f1, fileid=nullrev)
753 ms.add(fcl, fco, fca, f)
756 ms.add(fcl, fco, fca, f)
754 if f1 != f and move:
757 if f1 != f and move:
755 moves.append(f1)
758 moves.append(f1)
756
759
757 audit = repo.wvfs.audit
760 audit = repo.wvfs.audit
758 _updating = _('updating')
761 _updating = _('updating')
759 _files = _('files')
762 _files = _('files')
760 progress = repo.ui.progress
763 progress = repo.ui.progress
761
764
762 # remove renamed files after safely stored
765 # remove renamed files after safely stored
763 for f in moves:
766 for f in moves:
764 if os.path.lexists(repo.wjoin(f)):
767 if os.path.lexists(repo.wjoin(f)):
765 repo.ui.debug("removing %s\n" % f)
768 repo.ui.debug("removing %s\n" % f)
766 audit(f)
769 audit(f)
767 util.unlinkpath(repo.wjoin(f))
770 util.unlinkpath(repo.wjoin(f))
768
771
769 numupdates = sum(len(l) for m, l in actions.items() if m != 'k')
772 numupdates = sum(len(l) for m, l in actions.items() if m != 'k')
770
773
771 if [a for a in actions['r'] if a[0] == '.hgsubstate']:
774 if [a for a in actions['r'] if a[0] == '.hgsubstate']:
772 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
775 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
773
776
774 # remove in parallel (must come first)
777 # remove in parallel (must come first)
775 z = 0
778 z = 0
776 prog = worker.worker(repo.ui, 0.001, batchremove, (repo,), actions['r'])
779 prog = worker.worker(repo.ui, 0.001, batchremove, (repo,), actions['r'])
777 for i, item in prog:
780 for i, item in prog:
778 z += i
781 z += i
779 progress(_updating, z, item=item, total=numupdates, unit=_files)
782 progress(_updating, z, item=item, total=numupdates, unit=_files)
780 removed = len(actions['r'])
783 removed = len(actions['r'])
781
784
782 # get in parallel
785 # get in parallel
783 prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx), actions['g'])
786 prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx), actions['g'])
784 for i, item in prog:
787 for i, item in prog:
785 z += i
788 z += i
786 progress(_updating, z, item=item, total=numupdates, unit=_files)
789 progress(_updating, z, item=item, total=numupdates, unit=_files)
787 updated = len(actions['g'])
790 updated = len(actions['g'])
788
791
789 if [a for a in actions['g'] if a[0] == '.hgsubstate']:
792 if [a for a in actions['g'] if a[0] == '.hgsubstate']:
790 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
793 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
791
794
792 # forget (manifest only, just log it) (must come first)
795 # forget (manifest only, just log it) (must come first)
793 for f, args, msg in actions['f']:
796 for f, args, msg in actions['f']:
794 repo.ui.debug(" %s: %s -> f\n" % (f, msg))
797 repo.ui.debug(" %s: %s -> f\n" % (f, msg))
795 z += 1
798 z += 1
796 progress(_updating, z, item=f, total=numupdates, unit=_files)
799 progress(_updating, z, item=f, total=numupdates, unit=_files)
797
800
798 # re-add (manifest only, just log it)
801 # re-add (manifest only, just log it)
799 for f, args, msg in actions['a']:
802 for f, args, msg in actions['a']:
800 repo.ui.debug(" %s: %s -> a\n" % (f, msg))
803 repo.ui.debug(" %s: %s -> a\n" % (f, msg))
801 z += 1
804 z += 1
802 progress(_updating, z, item=f, total=numupdates, unit=_files)
805 progress(_updating, z, item=f, total=numupdates, unit=_files)
803
806
804 # keep (noop, just log it)
807 # keep (noop, just log it)
805 for f, args, msg in actions['k']:
808 for f, args, msg in actions['k']:
806 repo.ui.debug(" %s: %s -> k\n" % (f, msg))
809 repo.ui.debug(" %s: %s -> k\n" % (f, msg))
807 # no progress
810 # no progress
808
811
809 # directory rename, move local
812 # directory rename, move local
810 for f, args, msg in actions['dm']:
813 for f, args, msg in actions['dm']:
811 repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
814 repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
812 z += 1
815 z += 1
813 progress(_updating, z, item=f, total=numupdates, unit=_files)
816 progress(_updating, z, item=f, total=numupdates, unit=_files)
814 f0, flags = args
817 f0, flags = args
815 repo.ui.note(_("moving %s to %s\n") % (f0, f))
818 repo.ui.note(_("moving %s to %s\n") % (f0, f))
816 audit(f)
819 audit(f)
817 repo.wwrite(f, wctx.filectx(f0).data(), flags)
820 repo.wwrite(f, wctx.filectx(f0).data(), flags)
818 util.unlinkpath(repo.wjoin(f0))
821 util.unlinkpath(repo.wjoin(f0))
819 updated += 1
822 updated += 1
820
823
821 # local directory rename, get
824 # local directory rename, get
822 for f, args, msg in actions['dg']:
825 for f, args, msg in actions['dg']:
823 repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
826 repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
824 z += 1
827 z += 1
825 progress(_updating, z, item=f, total=numupdates, unit=_files)
828 progress(_updating, z, item=f, total=numupdates, unit=_files)
826 f0, flags = args
829 f0, flags = args
827 repo.ui.note(_("getting %s to %s\n") % (f0, f))
830 repo.ui.note(_("getting %s to %s\n") % (f0, f))
828 repo.wwrite(f, mctx.filectx(f0).data(), flags)
831 repo.wwrite(f, mctx.filectx(f0).data(), flags)
829 updated += 1
832 updated += 1
830
833
831 # exec
834 # exec
832 for f, args, msg in actions['e']:
835 for f, args, msg in actions['e']:
833 repo.ui.debug(" %s: %s -> e\n" % (f, msg))
836 repo.ui.debug(" %s: %s -> e\n" % (f, msg))
834 z += 1
837 z += 1
835 progress(_updating, z, item=f, total=numupdates, unit=_files)
838 progress(_updating, z, item=f, total=numupdates, unit=_files)
836 flags, = args
839 flags, = args
837 audit(f)
840 audit(f)
838 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
841 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
839 updated += 1
842 updated += 1
840
843
841 # merge
844 # merge
842 for f, args, msg in actions['m']:
845 for f, args, msg in actions['m']:
843 repo.ui.debug(" %s: %s -> m\n" % (f, msg))
846 repo.ui.debug(" %s: %s -> m\n" % (f, msg))
844 z += 1
847 z += 1
845 progress(_updating, z, item=f, total=numupdates, unit=_files)
848 progress(_updating, z, item=f, total=numupdates, unit=_files)
846 if f == '.hgsubstate': # subrepo states need updating
849 if f == '.hgsubstate': # subrepo states need updating
847 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
850 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
848 overwrite)
851 overwrite)
849 continue
852 continue
850 audit(f)
853 audit(f)
851 r = ms.resolve(f, wctx, labels=labels)
854 r = ms.resolve(f, wctx, labels=labels)
852 if r is not None and r > 0:
855 if r is not None and r > 0:
853 unresolved += 1
856 unresolved += 1
854 else:
857 else:
855 if r is None:
858 if r is None:
856 updated += 1
859 updated += 1
857 else:
860 else:
858 merged += 1
861 merged += 1
859
862
860 ms.commit()
863 ms.commit()
861 progress(_updating, None, total=numupdates, unit=_files)
864 progress(_updating, None, total=numupdates, unit=_files)
862
865
863 return updated, merged, removed, unresolved
866 return updated, merged, removed, unresolved
864
867
865 def recordupdates(repo, actions, branchmerge):
868 def recordupdates(repo, actions, branchmerge):
866 "record merge actions to the dirstate"
869 "record merge actions to the dirstate"
867 # remove (must come first)
870 # remove (must come first)
868 for f, args, msg in actions['r']:
871 for f, args, msg in actions['r']:
869 if branchmerge:
872 if branchmerge:
870 repo.dirstate.remove(f)
873 repo.dirstate.remove(f)
871 else:
874 else:
872 repo.dirstate.drop(f)
875 repo.dirstate.drop(f)
873
876
874 # forget (must come first)
877 # forget (must come first)
875 for f, args, msg in actions['f']:
878 for f, args, msg in actions['f']:
876 repo.dirstate.drop(f)
879 repo.dirstate.drop(f)
877
880
878 # re-add
881 # re-add
879 for f, args, msg in actions['a']:
882 for f, args, msg in actions['a']:
880 if not branchmerge:
883 if not branchmerge:
881 repo.dirstate.add(f)
884 repo.dirstate.add(f)
882
885
883 # exec change
886 # exec change
884 for f, args, msg in actions['e']:
887 for f, args, msg in actions['e']:
885 repo.dirstate.normallookup(f)
888 repo.dirstate.normallookup(f)
886
889
887 # keep
890 # keep
888 for f, args, msg in actions['k']:
891 for f, args, msg in actions['k']:
889 pass
892 pass
890
893
891 # get
894 # get
892 for f, args, msg in actions['g']:
895 for f, args, msg in actions['g']:
893 if branchmerge:
896 if branchmerge:
894 repo.dirstate.otherparent(f)
897 repo.dirstate.otherparent(f)
895 else:
898 else:
896 repo.dirstate.normal(f)
899 repo.dirstate.normal(f)
897
900
898 # merge
901 # merge
899 for f, args, msg in actions['m']:
902 for f, args, msg in actions['m']:
900 f1, f2, fa, move, anc = args
903 f1, f2, fa, move, anc = args
901 if branchmerge:
904 if branchmerge:
902 # We've done a branch merge, mark this file as merged
905 # We've done a branch merge, mark this file as merged
903 # so that we properly record the merger later
906 # so that we properly record the merger later
904 repo.dirstate.merge(f)
907 repo.dirstate.merge(f)
905 if f1 != f2: # copy/rename
908 if f1 != f2: # copy/rename
906 if move:
909 if move:
907 repo.dirstate.remove(f1)
910 repo.dirstate.remove(f1)
908 if f1 != f:
911 if f1 != f:
909 repo.dirstate.copy(f1, f)
912 repo.dirstate.copy(f1, f)
910 else:
913 else:
911 repo.dirstate.copy(f2, f)
914 repo.dirstate.copy(f2, f)
912 else:
915 else:
913 # We've update-merged a locally modified file, so
916 # We've update-merged a locally modified file, so
914 # we set the dirstate to emulate a normal checkout
917 # we set the dirstate to emulate a normal checkout
915 # of that file some time in the past. Thus our
918 # of that file some time in the past. Thus our
916 # merge will appear as a normal local file
919 # merge will appear as a normal local file
917 # modification.
920 # modification.
918 if f2 == f: # file not locally copied/moved
921 if f2 == f: # file not locally copied/moved
919 repo.dirstate.normallookup(f)
922 repo.dirstate.normallookup(f)
920 if move:
923 if move:
921 repo.dirstate.drop(f1)
924 repo.dirstate.drop(f1)
922
925
923 # directory rename, move local
926 # directory rename, move local
924 for f, args, msg in actions['dm']:
927 for f, args, msg in actions['dm']:
925 f0, flag = args
928 f0, flag = args
926 if branchmerge:
929 if branchmerge:
927 repo.dirstate.add(f)
930 repo.dirstate.add(f)
928 repo.dirstate.remove(f0)
931 repo.dirstate.remove(f0)
929 repo.dirstate.copy(f0, f)
932 repo.dirstate.copy(f0, f)
930 else:
933 else:
931 repo.dirstate.normal(f)
934 repo.dirstate.normal(f)
932 repo.dirstate.drop(f0)
935 repo.dirstate.drop(f0)
933
936
934 # directory rename, get
937 # directory rename, get
935 for f, args, msg in actions['dg']:
938 for f, args, msg in actions['dg']:
936 f0, flag = args
939 f0, flag = args
937 if branchmerge:
940 if branchmerge:
938 repo.dirstate.add(f)
941 repo.dirstate.add(f)
939 repo.dirstate.copy(f0, f)
942 repo.dirstate.copy(f0, f)
940 else:
943 else:
941 repo.dirstate.normal(f)
944 repo.dirstate.normal(f)
942
945
943 def update(repo, node, branchmerge, force, partial, ancestor=None,
946 def update(repo, node, branchmerge, force, partial, ancestor=None,
944 mergeancestor=False, labels=None):
947 mergeancestor=False, labels=None):
945 """
948 """
946 Perform a merge between the working directory and the given node
949 Perform a merge between the working directory and the given node
947
950
948 node = the node to update to, or None if unspecified
951 node = the node to update to, or None if unspecified
949 branchmerge = whether to merge between branches
952 branchmerge = whether to merge between branches
950 force = whether to force branch merging or file overwriting
953 force = whether to force branch merging or file overwriting
951 partial = a function to filter file lists (dirstate not updated)
954 partial = a function to filter file lists (dirstate not updated)
952 mergeancestor = whether it is merging with an ancestor. If true,
955 mergeancestor = whether it is merging with an ancestor. If true,
953 we should accept the incoming changes for any prompts that occur.
956 we should accept the incoming changes for any prompts that occur.
954 If false, merging with an ancestor (fast-forward) is only allowed
957 If false, merging with an ancestor (fast-forward) is only allowed
955 between different named branches. This flag is used by rebase extension
958 between different named branches. This flag is used by rebase extension
956 as a temporary fix and should be avoided in general.
959 as a temporary fix and should be avoided in general.
957
960
958 The table below shows all the behaviors of the update command
961 The table below shows all the behaviors of the update command
959 given the -c and -C or no options, whether the working directory
962 given the -c and -C or no options, whether the working directory
960 is dirty, whether a revision is specified, and the relationship of
963 is dirty, whether a revision is specified, and the relationship of
961 the parent rev to the target rev (linear, on the same named
964 the parent rev to the target rev (linear, on the same named
962 branch, or on another named branch).
965 branch, or on another named branch).
963
966
964 This logic is tested by test-update-branches.t.
967 This logic is tested by test-update-branches.t.
965
968
966 -c -C dirty rev | linear same cross
969 -c -C dirty rev | linear same cross
967 n n n n | ok (1) x
970 n n n n | ok (1) x
968 n n n y | ok ok ok
971 n n n y | ok ok ok
969 n n y n | merge (2) (2)
972 n n y n | merge (2) (2)
970 n n y y | merge (3) (3)
973 n n y y | merge (3) (3)
971 n y * * | --- discard ---
974 n y * * | --- discard ---
972 y n y * | --- (4) ---
975 y n y * | --- (4) ---
973 y n n * | --- ok ---
976 y n n * | --- ok ---
974 y y * * | --- (5) ---
977 y y * * | --- (5) ---
975
978
976 x = can't happen
979 x = can't happen
977 * = don't-care
980 * = don't-care
978 1 = abort: not a linear update (merge or update --check to force update)
981 1 = abort: not a linear update (merge or update --check to force update)
979 2 = abort: uncommitted changes (commit and merge, or update --clean to
982 2 = abort: uncommitted changes (commit and merge, or update --clean to
980 discard changes)
983 discard changes)
981 3 = abort: uncommitted changes (commit or update --clean to discard changes)
984 3 = abort: uncommitted changes (commit or update --clean to discard changes)
982 4 = abort: uncommitted changes (checked in commands.py)
985 4 = abort: uncommitted changes (checked in commands.py)
983 5 = incompatible options (checked in commands.py)
986 5 = incompatible options (checked in commands.py)
984
987
985 Return the same tuple as applyupdates().
988 Return the same tuple as applyupdates().
986 """
989 """
987
990
988 onode = node
991 onode = node
989 wlock = repo.wlock()
992 wlock = repo.wlock()
990 try:
993 try:
991 wc = repo[None]
994 wc = repo[None]
992 pl = wc.parents()
995 pl = wc.parents()
993 p1 = pl[0]
996 p1 = pl[0]
994 pas = [None]
997 pas = [None]
995 if ancestor is not None:
998 if ancestor is not None:
996 pas = [repo[ancestor]]
999 pas = [repo[ancestor]]
997
1000
998 if node is None:
1001 if node is None:
999 node = repo[destutil.destupdate(repo)].node()
1002 node = repo[destutil.destupdate(repo)].node()
1000
1003
1001 overwrite = force and not branchmerge
1004 overwrite = force and not branchmerge
1002
1005
1003 p2 = repo[node]
1006 p2 = repo[node]
1004 if pas[0] is None:
1007 if pas[0] is None:
1005 if repo.ui.configlist('merge', 'preferancestor', ['*']) == ['*']:
1008 if repo.ui.configlist('merge', 'preferancestor', ['*']) == ['*']:
1006 cahs = repo.changelog.commonancestorsheads(p1.node(), p2.node())
1009 cahs = repo.changelog.commonancestorsheads(p1.node(), p2.node())
1007 pas = [repo[anc] for anc in (sorted(cahs) or [nullid])]
1010 pas = [repo[anc] for anc in (sorted(cahs) or [nullid])]
1008 else:
1011 else:
1009 pas = [p1.ancestor(p2, warn=branchmerge)]
1012 pas = [p1.ancestor(p2, warn=branchmerge)]
1010
1013
1011 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
1014 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
1012
1015
1013 ### check phase
1016 ### check phase
1014 if not overwrite and len(pl) > 1:
1017 if not overwrite and len(pl) > 1:
1015 raise error.Abort(_("outstanding uncommitted merge"))
1018 raise error.Abort(_("outstanding uncommitted merge"))
1016 if branchmerge:
1019 if branchmerge:
1017 if pas == [p2]:
1020 if pas == [p2]:
1018 raise error.Abort(_("merging with a working directory ancestor"
1021 raise error.Abort(_("merging with a working directory ancestor"
1019 " has no effect"))
1022 " has no effect"))
1020 elif pas == [p1]:
1023 elif pas == [p1]:
1021 if not mergeancestor and p1.branch() == p2.branch():
1024 if not mergeancestor and p1.branch() == p2.branch():
1022 raise error.Abort(_("nothing to merge"),
1025 raise error.Abort(_("nothing to merge"),
1023 hint=_("use 'hg update' "
1026 hint=_("use 'hg update' "
1024 "or check 'hg heads'"))
1027 "or check 'hg heads'"))
1025 if not force and (wc.files() or wc.deleted()):
1028 if not force and (wc.files() or wc.deleted()):
1026 raise error.Abort(_("uncommitted changes"),
1029 raise error.Abort(_("uncommitted changes"),
1027 hint=_("use 'hg status' to list changes"))
1030 hint=_("use 'hg status' to list changes"))
1028 for s in sorted(wc.substate):
1031 for s in sorted(wc.substate):
1029 wc.sub(s).bailifchanged()
1032 wc.sub(s).bailifchanged()
1030
1033
1031 elif not overwrite:
1034 elif not overwrite:
1032 if p1 == p2: # no-op update
1035 if p1 == p2: # no-op update
1033 # call the hooks and exit early
1036 # call the hooks and exit early
1034 repo.hook('preupdate', throw=True, parent1=xp2, parent2='')
1037 repo.hook('preupdate', throw=True, parent1=xp2, parent2='')
1035 repo.hook('update', parent1=xp2, parent2='', error=0)
1038 repo.hook('update', parent1=xp2, parent2='', error=0)
1036 return 0, 0, 0, 0
1039 return 0, 0, 0, 0
1037
1040
1038 if pas not in ([p1], [p2]): # nonlinear
1041 if pas not in ([p1], [p2]): # nonlinear
1039 dirty = wc.dirty(missing=True)
1042 dirty = wc.dirty(missing=True)
1040 if dirty or onode is None:
1043 if dirty or onode is None:
1041 # Branching is a bit strange to ensure we do the minimal
1044 # Branching is a bit strange to ensure we do the minimal
1042 # amount of call to obsolete.background.
1045 # amount of call to obsolete.background.
1043 foreground = obsolete.foreground(repo, [p1.node()])
1046 foreground = obsolete.foreground(repo, [p1.node()])
1044 # note: the <node> variable contains a random identifier
1047 # note: the <node> variable contains a random identifier
1045 if repo[node].node() in foreground:
1048 if repo[node].node() in foreground:
1046 pas = [p1] # allow updating to successors
1049 pas = [p1] # allow updating to successors
1047 elif dirty:
1050 elif dirty:
1048 msg = _("uncommitted changes")
1051 msg = _("uncommitted changes")
1049 if onode is None:
1052 if onode is None:
1050 hint = _("commit and merge, or update --clean to"
1053 hint = _("commit and merge, or update --clean to"
1051 " discard changes")
1054 " discard changes")
1052 else:
1055 else:
1053 hint = _("commit or update --clean to discard"
1056 hint = _("commit or update --clean to discard"
1054 " changes")
1057 " changes")
1055 raise error.Abort(msg, hint=hint)
1058 raise error.Abort(msg, hint=hint)
1056 else: # node is none
1059 else: # node is none
1057 msg = _("not a linear update")
1060 msg = _("not a linear update")
1058 hint = _("merge or update --check to force update")
1061 hint = _("merge or update --check to force update")
1059 raise error.Abort(msg, hint=hint)
1062 raise error.Abort(msg, hint=hint)
1060 else:
1063 else:
1061 # Allow jumping branches if clean and specific rev given
1064 # Allow jumping branches if clean and specific rev given
1062 pas = [p1]
1065 pas = [p1]
1063
1066
1064 # deprecated config: merge.followcopies
1067 # deprecated config: merge.followcopies
1065 followcopies = False
1068 followcopies = False
1066 if overwrite:
1069 if overwrite:
1067 pas = [wc]
1070 pas = [wc]
1068 elif pas == [p2]: # backwards
1071 elif pas == [p2]: # backwards
1069 pas = [wc.p1()]
1072 pas = [wc.p1()]
1070 elif not branchmerge and not wc.dirty(missing=True):
1073 elif not branchmerge and not wc.dirty(missing=True):
1071 pass
1074 pass
1072 elif pas[0] and repo.ui.configbool('merge', 'followcopies', True):
1075 elif pas[0] and repo.ui.configbool('merge', 'followcopies', True):
1073 followcopies = True
1076 followcopies = True
1074
1077
1075 ### calculate phase
1078 ### calculate phase
1076 actionbyfile, diverge, renamedelete = calculateupdates(
1079 actionbyfile, diverge, renamedelete = calculateupdates(
1077 repo, wc, p2, pas, branchmerge, force, partial, mergeancestor,
1080 repo, wc, p2, pas, branchmerge, force, partial, mergeancestor,
1078 followcopies)
1081 followcopies)
1079 # Convert to dictionary-of-lists format
1082 # Convert to dictionary-of-lists format
1080 actions = dict((m, []) for m in 'a f g cd dc r dm dg m e k'.split())
1083 actions = dict((m, []) for m in 'a f g cd dc r dm dg m e k'.split())
1081 for f, (m, args, msg) in actionbyfile.iteritems():
1084 for f, (m, args, msg) in actionbyfile.iteritems():
1082 if m not in actions:
1085 if m not in actions:
1083 actions[m] = []
1086 actions[m] = []
1084 actions[m].append((f, args, msg))
1087 actions[m].append((f, args, msg))
1085
1088
1086 if not util.checkcase(repo.path):
1089 if not util.checkcase(repo.path):
1087 # check collision between files only in p2 for clean update
1090 # check collision between files only in p2 for clean update
1088 if (not branchmerge and
1091 if (not branchmerge and
1089 (force or not wc.dirty(missing=True, branch=False))):
1092 (force or not wc.dirty(missing=True, branch=False))):
1090 _checkcollision(repo, p2.manifest(), None)
1093 _checkcollision(repo, p2.manifest(), None)
1091 else:
1094 else:
1092 _checkcollision(repo, wc.manifest(), actions)
1095 _checkcollision(repo, wc.manifest(), actions)
1093
1096
1094 # Prompt and create actions. TODO: Move this towards resolve phase.
1097 # Prompt and create actions. TODO: Move this towards resolve phase.
1095 for f, args, msg in sorted(actions['cd']):
1098 for f, args, msg in sorted(actions['cd']):
1096 if repo.ui.promptchoice(
1099 if repo.ui.promptchoice(
1097 _("local changed %s which remote deleted\n"
1100 _("local changed %s which remote deleted\n"
1098 "use (c)hanged version or (d)elete?"
1101 "use (c)hanged version or (d)elete?"
1099 "$$ &Changed $$ &Delete") % f, 0):
1102 "$$ &Changed $$ &Delete") % f, 0):
1100 actions['r'].append((f, None, "prompt delete"))
1103 actions['r'].append((f, None, "prompt delete"))
1101 else:
1104 else:
1102 actions['a'].append((f, None, "prompt keep"))
1105 actions['a'].append((f, None, "prompt keep"))
1103 del actions['cd'][:]
1106 del actions['cd'][:]
1104
1107
1105 for f, args, msg in sorted(actions['dc']):
1108 for f, args, msg in sorted(actions['dc']):
1106 flags, = args
1109 flags, = args
1107 if repo.ui.promptchoice(
1110 if repo.ui.promptchoice(
1108 _("remote changed %s which local deleted\n"
1111 _("remote changed %s which local deleted\n"
1109 "use (c)hanged version or leave (d)eleted?"
1112 "use (c)hanged version or leave (d)eleted?"
1110 "$$ &Changed $$ &Deleted") % f, 0) == 0:
1113 "$$ &Changed $$ &Deleted") % f, 0) == 0:
1111 actions['g'].append((f, (flags,), "prompt recreating"))
1114 actions['g'].append((f, (flags,), "prompt recreating"))
1112 del actions['dc'][:]
1115 del actions['dc'][:]
1113
1116
1114 ### apply phase
1117 ### apply phase
1115 if not branchmerge: # just jump to the new rev
1118 if not branchmerge: # just jump to the new rev
1116 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
1119 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
1117 if not partial:
1120 if not partial:
1118 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
1121 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
1119 # note that we're in the middle of an update
1122 # note that we're in the middle of an update
1120 repo.vfs.write('updatestate', p2.hex())
1123 repo.vfs.write('updatestate', p2.hex())
1121
1124
1122 stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels)
1125 stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels)
1123
1126
1124 # divergent renames
1127 # divergent renames
1125 for f, fl in sorted(diverge.iteritems()):
1128 for f, fl in sorted(diverge.iteritems()):
1126 repo.ui.warn(_("note: possible conflict - %s was renamed "
1129 repo.ui.warn(_("note: possible conflict - %s was renamed "
1127 "multiple times to:\n") % f)
1130 "multiple times to:\n") % f)
1128 for nf in fl:
1131 for nf in fl:
1129 repo.ui.warn(" %s\n" % nf)
1132 repo.ui.warn(" %s\n" % nf)
1130
1133
1131 # rename and delete
1134 # rename and delete
1132 for f, fl in sorted(renamedelete.iteritems()):
1135 for f, fl in sorted(renamedelete.iteritems()):
1133 repo.ui.warn(_("note: possible conflict - %s was deleted "
1136 repo.ui.warn(_("note: possible conflict - %s was deleted "
1134 "and renamed to:\n") % f)
1137 "and renamed to:\n") % f)
1135 for nf in fl:
1138 for nf in fl:
1136 repo.ui.warn(" %s\n" % nf)
1139 repo.ui.warn(" %s\n" % nf)
1137
1140
1138 if not partial:
1141 if not partial:
1139 repo.dirstate.beginparentchange()
1142 repo.dirstate.beginparentchange()
1140 repo.setparents(fp1, fp2)
1143 repo.setparents(fp1, fp2)
1141 recordupdates(repo, actions, branchmerge)
1144 recordupdates(repo, actions, branchmerge)
1142 # update completed, clear state
1145 # update completed, clear state
1143 util.unlink(repo.join('updatestate'))
1146 util.unlink(repo.join('updatestate'))
1144
1147
1145 if not branchmerge:
1148 if not branchmerge:
1146 repo.dirstate.setbranch(p2.branch())
1149 repo.dirstate.setbranch(p2.branch())
1147 repo.dirstate.endparentchange()
1150 repo.dirstate.endparentchange()
1148 finally:
1151 finally:
1149 wlock.release()
1152 wlock.release()
1150
1153
1151 if not partial:
1154 if not partial:
1152 def updatehook(parent1=xp1, parent2=xp2, error=stats[3]):
1155 def updatehook(parent1=xp1, parent2=xp2, error=stats[3]):
1153 repo.hook('update', parent1=parent1, parent2=parent2, error=error)
1156 repo.hook('update', parent1=parent1, parent2=parent2, error=error)
1154 repo._afterlock(updatehook)
1157 repo._afterlock(updatehook)
1155 return stats
1158 return stats
1156
1159
1157 def graft(repo, ctx, pctx, labels):
1160 def graft(repo, ctx, pctx, labels):
1158 """Do a graft-like merge.
1161 """Do a graft-like merge.
1159
1162
1160 This is a merge where the merge ancestor is chosen such that one
1163 This is a merge where the merge ancestor is chosen such that one
1161 or more changesets are grafted onto the current changeset. In
1164 or more changesets are grafted onto the current changeset. In
1162 addition to the merge, this fixes up the dirstate to include only
1165 addition to the merge, this fixes up the dirstate to include only
1163 a single parent and tries to duplicate any renames/copies
1166 a single parent and tries to duplicate any renames/copies
1164 appropriately.
1167 appropriately.
1165
1168
1166 ctx - changeset to rebase
1169 ctx - changeset to rebase
1167 pctx - merge base, usually ctx.p1()
1170 pctx - merge base, usually ctx.p1()
1168 labels - merge labels eg ['local', 'graft']
1171 labels - merge labels eg ['local', 'graft']
1169
1172
1170 """
1173 """
1171 # If we're grafting a descendant onto an ancestor, be sure to pass
1174 # If we're grafting a descendant onto an ancestor, be sure to pass
1172 # mergeancestor=True to update. This does two things: 1) allows the merge if
1175 # mergeancestor=True to update. This does two things: 1) allows the merge if
1173 # the destination is the same as the parent of the ctx (so we can use graft
1176 # the destination is the same as the parent of the ctx (so we can use graft
1174 # to copy commits), and 2) informs update that the incoming changes are
1177 # to copy commits), and 2) informs update that the incoming changes are
1175 # newer than the destination so it doesn't prompt about "remote changed foo
1178 # newer than the destination so it doesn't prompt about "remote changed foo
1176 # which local deleted".
1179 # which local deleted".
1177 mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node())
1180 mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node())
1178
1181
1179 stats = update(repo, ctx.node(), True, True, False, pctx.node(),
1182 stats = update(repo, ctx.node(), True, True, False, pctx.node(),
1180 mergeancestor=mergeancestor, labels=labels)
1183 mergeancestor=mergeancestor, labels=labels)
1181
1184
1182 # drop the second merge parent
1185 # drop the second merge parent
1183 repo.dirstate.beginparentchange()
1186 repo.dirstate.beginparentchange()
1184 repo.setparents(repo['.'].node(), nullid)
1187 repo.setparents(repo['.'].node(), nullid)
1185 repo.dirstate.write()
1188 repo.dirstate.write()
1186 # fix up dirstate for copies and renames
1189 # fix up dirstate for copies and renames
1187 copies.duplicatecopies(repo, ctx.rev(), pctx.rev())
1190 copies.duplicatecopies(repo, ctx.rev(), pctx.rev())
1188 repo.dirstate.endparentchange()
1191 repo.dirstate.endparentchange()
1189 return stats
1192 return stats
@@ -1,819 +1,821 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 skipping ancestor revision 2:5c095ad7e90f
65 skipping ancestor revision 2:5c095ad7e90f
66 skipping ancestor revision 1:5d205f8b35b6
66 skipping ancestor revision 1:5d205f8b35b6
67 [255]
67 [255]
68
68
69 Can't graft with dirty wd:
69 Can't graft with dirty wd:
70
70
71 $ hg up -q 0
71 $ hg up -q 0
72 $ echo foo > a
72 $ echo foo > a
73 $ hg graft 1
73 $ hg graft 1
74 abort: uncommitted changes
74 abort: uncommitted changes
75 [255]
75 [255]
76 $ hg revert a
76 $ hg revert a
77
77
78 Graft a rename:
78 Graft a rename:
79 (this also tests that editor is invoked if '--edit' is specified)
79 (this also tests that editor is invoked if '--edit' is specified)
80
80
81 $ hg status --rev "2^1" --rev 2
81 $ hg status --rev "2^1" --rev 2
82 A b
82 A b
83 R a
83 R a
84 $ HGEDITOR=cat hg graft 2 -u foo --edit
84 $ HGEDITOR=cat hg graft 2 -u foo --edit
85 grafting 2:5c095ad7e90f "2"
85 grafting 2:5c095ad7e90f "2"
86 merging a and b to b
86 merging a and b to b
87 2
87 2
88
88
89
89
90 HG: Enter commit message. Lines beginning with 'HG:' are removed.
90 HG: Enter commit message. Lines beginning with 'HG:' are removed.
91 HG: Leave message empty to abort commit.
91 HG: Leave message empty to abort commit.
92 HG: --
92 HG: --
93 HG: user: foo
93 HG: user: foo
94 HG: branch 'default'
94 HG: branch 'default'
95 HG: added b
95 HG: added b
96 HG: removed a
96 HG: removed a
97 $ hg export tip --git
97 $ hg export tip --git
98 # HG changeset patch
98 # HG changeset patch
99 # User foo
99 # User foo
100 # Date 0 0
100 # Date 0 0
101 # Thu Jan 01 00:00:00 1970 +0000
101 # Thu Jan 01 00:00:00 1970 +0000
102 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
102 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
103 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
103 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
104 2
104 2
105
105
106 diff --git a/a b/b
106 diff --git a/a b/b
107 rename from a
107 rename from a
108 rename to b
108 rename to b
109
109
110 Look for extra:source
110 Look for extra:source
111
111
112 $ hg log --debug -r tip
112 $ hg log --debug -r tip
113 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
113 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
114 tag: tip
114 tag: tip
115 phase: draft
115 phase: draft
116 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
116 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
117 parent: -1:0000000000000000000000000000000000000000
117 parent: -1:0000000000000000000000000000000000000000
118 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
118 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
119 user: foo
119 user: foo
120 date: Thu Jan 01 00:00:00 1970 +0000
120 date: Thu Jan 01 00:00:00 1970 +0000
121 files+: b
121 files+: b
122 files-: a
122 files-: a
123 extra: branch=default
123 extra: branch=default
124 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
124 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
125 description:
125 description:
126 2
126 2
127
127
128
128
129
129
130 Graft out of order, skipping a merge and a duplicate
130 Graft out of order, skipping a merge and a duplicate
131 (this also tests that editor is not invoked if '--edit' is not specified)
131 (this also tests that editor is not invoked if '--edit' is not specified)
132
132
133 $ hg graft 1 5 4 3 'merge()' 2 -n
133 $ hg graft 1 5 4 3 'merge()' 2 -n
134 skipping ungraftable merge revision 6
134 skipping ungraftable merge revision 6
135 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
135 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
136 grafting 1:5d205f8b35b6 "1"
136 grafting 1:5d205f8b35b6 "1"
137 grafting 5:97f8bfe72746 "5"
137 grafting 5:97f8bfe72746 "5"
138 grafting 4:9c233e8e184d "4"
138 grafting 4:9c233e8e184d "4"
139 grafting 3:4c60f11aa304 "3"
139 grafting 3:4c60f11aa304 "3"
140
140
141 $ HGEDITOR=cat hg graft 1 5 4 3 'merge()' 2 --debug
141 $ HGEDITOR=cat hg graft 1 5 4 3 'merge()' 2 --debug
142 skipping ungraftable merge revision 6
142 skipping ungraftable merge revision 6
143 scanning for duplicate grafts
143 scanning for duplicate grafts
144 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
144 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
145 grafting 1:5d205f8b35b6 "1"
145 grafting 1:5d205f8b35b6 "1"
146 searching for copies back to rev 1
146 searching for copies back to rev 1
147 unmatched files in local:
147 unmatched files in local:
148 b
148 b
149 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
149 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
150 src: 'a' -> dst: 'b' *
150 src: 'a' -> dst: 'b' *
151 checking for directory renames
151 checking for directory renames
152 resolving manifests
152 resolving manifests
153 branchmerge: True, force: True, partial: False
153 branchmerge: True, force: True, partial: False
154 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
154 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
155 preserving b for resolve of b
155 preserving b for resolve of b
156 b: local copied/moved from a -> m
156 b: local copied/moved from a -> m
157 picked tool ':merge' for b (binary False symlink False)
157 picked tool ':merge' for b (binary False symlink False)
158 merging b and a to b
158 merging b and a to b
159 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
159 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
160 premerge successful
160 premerge successful
161 committing files:
161 committing files:
162 b
162 b
163 committing manifest
163 committing manifest
164 committing changelog
164 committing changelog
165 grafting 5:97f8bfe72746 "5"
165 grafting 5:97f8bfe72746 "5"
166 searching for copies back to rev 1
166 searching for copies back to rev 1
167 resolving manifests
167 resolving manifests
168 branchmerge: True, force: True, partial: False
168 branchmerge: True, force: True, partial: False
169 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
169 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
170 e: remote is newer -> g
170 e: remote is newer -> g
171 getting e
171 getting e
172 b: remote unchanged -> k
172 b: remote unchanged -> k
173 committing files:
173 committing files:
174 e
174 e
175 committing manifest
175 committing manifest
176 committing changelog
176 committing changelog
177 grafting 4:9c233e8e184d "4"
177 grafting 4:9c233e8e184d "4"
178 searching for copies back to rev 1
178 searching for copies back to rev 1
179 resolving manifests
179 resolving manifests
180 branchmerge: True, force: True, partial: False
180 branchmerge: True, force: True, partial: False
181 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
181 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
182 preserving e for resolve of e
182 preserving e for resolve of e
183 d: remote is newer -> g
183 d: remote is newer -> g
184 getting d
184 getting d
185 b: remote unchanged -> k
185 b: remote unchanged -> k
186 e: versions differ -> m
186 e: versions differ -> m
187 picked tool ':merge' for e (binary False symlink False)
187 picked tool ':merge' for e (binary False symlink False)
188 merging e
188 merging e
189 my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
189 my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
190 picked tool ':merge' for e (binary False symlink False)
191 my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
190 warning: conflicts during merge.
192 warning: conflicts during merge.
191 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
193 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
192 abort: unresolved conflicts, can't continue
194 abort: unresolved conflicts, can't continue
193 (use hg resolve and hg graft --continue)
195 (use hg resolve and hg graft --continue)
194 [255]
196 [255]
195
197
196 Commit while interrupted should fail:
198 Commit while interrupted should fail:
197
199
198 $ hg ci -m 'commit interrupted graft'
200 $ hg ci -m 'commit interrupted graft'
199 abort: graft in progress
201 abort: graft in progress
200 (use 'hg graft --continue' or 'hg update' to abort)
202 (use 'hg graft --continue' or 'hg update' to abort)
201 [255]
203 [255]
202
204
203 Abort the graft and try committing:
205 Abort the graft and try committing:
204
206
205 $ hg up -C .
207 $ hg up -C .
206 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
208 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
207 $ echo c >> e
209 $ echo c >> e
208 $ hg ci -mtest
210 $ hg ci -mtest
209
211
210 $ hg strip . --config extensions.strip=
212 $ hg strip . --config extensions.strip=
211 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
213 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
214 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
213
215
214 Graft again:
216 Graft again:
215
217
216 $ hg graft 1 5 4 3 'merge()' 2
218 $ hg graft 1 5 4 3 'merge()' 2
217 skipping ungraftable merge revision 6
219 skipping ungraftable merge revision 6
218 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
220 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
219 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
221 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
220 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
222 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
221 grafting 4:9c233e8e184d "4"
223 grafting 4:9c233e8e184d "4"
222 merging e
224 merging e
223 warning: conflicts during merge.
225 warning: conflicts during merge.
224 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
226 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
225 abort: unresolved conflicts, can't continue
227 abort: unresolved conflicts, can't continue
226 (use hg resolve and hg graft --continue)
228 (use hg resolve and hg graft --continue)
227 [255]
229 [255]
228
230
229 Continue without resolve should fail:
231 Continue without resolve should fail:
230
232
231 $ hg graft -c
233 $ hg graft -c
232 grafting 4:9c233e8e184d "4"
234 grafting 4:9c233e8e184d "4"
233 abort: unresolved merge conflicts (see "hg help resolve")
235 abort: unresolved merge conflicts (see "hg help resolve")
234 [255]
236 [255]
235
237
236 Fix up:
238 Fix up:
237
239
238 $ echo b > e
240 $ echo b > e
239 $ hg resolve -m e
241 $ hg resolve -m e
240 (no more unresolved files)
242 (no more unresolved files)
241
243
242 Continue with a revision should fail:
244 Continue with a revision should fail:
243
245
244 $ hg graft -c 6
246 $ hg graft -c 6
245 abort: can't specify --continue and revisions
247 abort: can't specify --continue and revisions
246 [255]
248 [255]
247
249
248 $ hg graft -c -r 6
250 $ hg graft -c -r 6
249 abort: can't specify --continue and revisions
251 abort: can't specify --continue and revisions
250 [255]
252 [255]
251
253
252 Continue for real, clobber usernames
254 Continue for real, clobber usernames
253
255
254 $ hg graft -c -U
256 $ hg graft -c -U
255 grafting 4:9c233e8e184d "4"
257 grafting 4:9c233e8e184d "4"
256 grafting 3:4c60f11aa304 "3"
258 grafting 3:4c60f11aa304 "3"
257
259
258 Compare with original:
260 Compare with original:
259
261
260 $ hg diff -r 6
262 $ hg diff -r 6
261 $ hg status --rev 0:. -C
263 $ hg status --rev 0:. -C
262 M d
264 M d
263 M e
265 M e
264 A b
266 A b
265 a
267 a
266 A c
268 A c
267 a
269 a
268 R a
270 R a
269
271
270 View graph:
272 View graph:
271
273
272 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
274 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
273 @ test@11.draft: 3
275 @ test@11.draft: 3
274 |
276 |
275 o test@10.draft: 4
277 o test@10.draft: 4
276 |
278 |
277 o test@9.draft: 5
279 o test@9.draft: 5
278 |
280 |
279 o bar@8.draft: 1
281 o bar@8.draft: 1
280 |
282 |
281 o foo@7.draft: 2
283 o foo@7.draft: 2
282 |
284 |
283 | o test@6.secret: 6
285 | o test@6.secret: 6
284 | |\
286 | |\
285 | | o test@5.draft: 5
287 | | o test@5.draft: 5
286 | | |
288 | | |
287 | o | test@4.draft: 4
289 | o | test@4.draft: 4
288 | |/
290 | |/
289 | o baz@3.public: 3
291 | o baz@3.public: 3
290 | |
292 | |
291 | o test@2.public: 2
293 | o test@2.public: 2
292 | |
294 | |
293 | o bar@1.public: 1
295 | o bar@1.public: 1
294 |/
296 |/
295 o test@0.public: 0
297 o test@0.public: 0
296
298
297 Graft again onto another branch should preserve the original source
299 Graft again onto another branch should preserve the original source
298 $ hg up -q 0
300 $ hg up -q 0
299 $ echo 'g'>g
301 $ echo 'g'>g
300 $ hg add g
302 $ hg add g
301 $ hg ci -m 7
303 $ hg ci -m 7
302 created new head
304 created new head
303 $ hg graft 7
305 $ hg graft 7
304 grafting 7:ef0ef43d49e7 "2"
306 grafting 7:ef0ef43d49e7 "2"
305
307
306 $ hg log -r 7 --template '{rev}:{node}\n'
308 $ hg log -r 7 --template '{rev}:{node}\n'
307 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
309 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
308 $ hg log -r 2 --template '{rev}:{node}\n'
310 $ hg log -r 2 --template '{rev}:{node}\n'
309 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
311 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
310
312
311 $ hg log --debug -r tip
313 $ hg log --debug -r tip
312 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
314 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
313 tag: tip
315 tag: tip
314 phase: draft
316 phase: draft
315 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
317 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
316 parent: -1:0000000000000000000000000000000000000000
318 parent: -1:0000000000000000000000000000000000000000
317 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
319 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
318 user: foo
320 user: foo
319 date: Thu Jan 01 00:00:00 1970 +0000
321 date: Thu Jan 01 00:00:00 1970 +0000
320 files+: b
322 files+: b
321 files-: a
323 files-: a
322 extra: branch=default
324 extra: branch=default
323 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
325 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
324 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
326 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
325 description:
327 description:
326 2
328 2
327
329
328
330
329 Disallow grafting an already grafted cset onto its original branch
331 Disallow grafting an already grafted cset onto its original branch
330 $ hg up -q 6
332 $ hg up -q 6
331 $ hg graft 7
333 $ hg graft 7
332 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
334 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
333 [255]
335 [255]
334
336
335 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13
337 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13
336 --- */hg-5c095ad7e90f.patch * +0000 (glob)
338 --- */hg-5c095ad7e90f.patch * +0000 (glob)
337 +++ */hg-7a4785234d87.patch * +0000 (glob)
339 +++ */hg-7a4785234d87.patch * +0000 (glob)
338 @@ -1,18 +1,18 @@
340 @@ -1,18 +1,18 @@
339 # HG changeset patch
341 # HG changeset patch
340 -# User test
342 -# User test
341 +# User foo
343 +# User foo
342 # Date 0 0
344 # Date 0 0
343 # Thu Jan 01 00:00:00 1970 +0000
345 # Thu Jan 01 00:00:00 1970 +0000
344 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
346 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
345 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
347 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
346 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
348 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
347 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
349 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
348 2
350 2
349
351
350 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
352 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
351 +diff -r b592ea63bb0c -r 7a4785234d87 a
353 +diff -r b592ea63bb0c -r 7a4785234d87 a
352 --- a/a Thu Jan 01 00:00:00 1970 +0000
354 --- a/a Thu Jan 01 00:00:00 1970 +0000
353 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
355 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
354 @@ -1,1 +0,0 @@
356 @@ -1,1 +0,0 @@
355 --b
357 --b
356 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
358 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
357 +-a
359 +-a
358 +diff -r b592ea63bb0c -r 7a4785234d87 b
360 +diff -r b592ea63bb0c -r 7a4785234d87 b
359 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
361 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
360 +++ b/b Thu Jan 01 00:00:00 1970 +0000
362 +++ b/b Thu Jan 01 00:00:00 1970 +0000
361 @@ -0,0 +1,1 @@
363 @@ -0,0 +1,1 @@
362 -+b
364 -+b
363 ++a
365 ++a
364 [1]
366 [1]
365
367
366 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
368 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
367 --- */hg-5c095ad7e90f.patch * +0000 (glob)
369 --- */hg-5c095ad7e90f.patch * +0000 (glob)
368 +++ */hg-7a4785234d87.patch * +0000 (glob)
370 +++ */hg-7a4785234d87.patch * +0000 (glob)
369 @@ -1,8 +1,8 @@
371 @@ -1,8 +1,8 @@
370 # HG changeset patch
372 # HG changeset patch
371 -# User test
373 -# User test
372 +# User foo
374 +# User foo
373 # Date 0 0
375 # Date 0 0
374 # Thu Jan 01 00:00:00 1970 +0000
376 # Thu Jan 01 00:00:00 1970 +0000
375 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
377 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
376 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
378 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
377 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
379 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
378 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
380 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
379 2
381 2
380
382
381 [1]
383 [1]
382
384
383 Disallow grafting already grafted csets with the same origin onto each other
385 Disallow grafting already grafted csets with the same origin onto each other
384 $ hg up -q 13
386 $ hg up -q 13
385 $ hg graft 2
387 $ hg graft 2
386 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
388 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
387 [255]
389 [255]
388 $ hg graft 7
390 $ hg graft 7
389 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
391 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
390 [255]
392 [255]
391
393
392 $ hg up -q 7
394 $ hg up -q 7
393 $ hg graft 2
395 $ hg graft 2
394 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
396 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
395 [255]
397 [255]
396 $ hg graft tip
398 $ hg graft tip
397 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
399 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
398 [255]
400 [255]
399
401
400 Graft with --log
402 Graft with --log
401
403
402 $ hg up -Cq 1
404 $ hg up -Cq 1
403 $ hg graft 3 --log -u foo
405 $ hg graft 3 --log -u foo
404 grafting 3:4c60f11aa304 "3"
406 grafting 3:4c60f11aa304 "3"
405 warning: can't find ancestor for 'c' copied from 'b'!
407 warning: can't find ancestor for 'c' copied from 'b'!
406 $ hg log --template '{rev} {parents} {desc}\n' -r tip
408 $ hg log --template '{rev} {parents} {desc}\n' -r tip
407 14 1:5d205f8b35b6 3
409 14 1:5d205f8b35b6 3
408 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
410 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
409
411
410 Resolve conflicted graft
412 Resolve conflicted graft
411 $ hg up -q 0
413 $ hg up -q 0
412 $ echo b > a
414 $ echo b > a
413 $ hg ci -m 8
415 $ hg ci -m 8
414 created new head
416 created new head
415 $ echo c > a
417 $ echo c > a
416 $ hg ci -m 9
418 $ hg ci -m 9
417 $ hg graft 1 --tool internal:fail
419 $ hg graft 1 --tool internal:fail
418 grafting 1:5d205f8b35b6 "1"
420 grafting 1:5d205f8b35b6 "1"
419 abort: unresolved conflicts, can't continue
421 abort: unresolved conflicts, can't continue
420 (use hg resolve and hg graft --continue)
422 (use hg resolve and hg graft --continue)
421 [255]
423 [255]
422 $ hg resolve --all
424 $ hg resolve --all
423 merging a
425 merging a
424 warning: conflicts during merge.
426 warning: conflicts during merge.
425 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
427 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
426 [1]
428 [1]
427 $ cat a
429 $ cat a
428 <<<<<<< local: aaa4406d4f0a - test: 9
430 <<<<<<< local: aaa4406d4f0a - test: 9
429 c
431 c
430 =======
432 =======
431 b
433 b
432 >>>>>>> other: 5d205f8b35b6 - bar: 1
434 >>>>>>> other: 5d205f8b35b6 - bar: 1
433 $ echo b > a
435 $ echo b > a
434 $ hg resolve -m a
436 $ hg resolve -m a
435 (no more unresolved files)
437 (no more unresolved files)
436 $ hg graft -c
438 $ hg graft -c
437 grafting 1:5d205f8b35b6 "1"
439 grafting 1:5d205f8b35b6 "1"
438 $ hg export tip --git
440 $ hg export tip --git
439 # HG changeset patch
441 # HG changeset patch
440 # User bar
442 # User bar
441 # Date 0 0
443 # Date 0 0
442 # Thu Jan 01 00:00:00 1970 +0000
444 # Thu Jan 01 00:00:00 1970 +0000
443 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
445 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
444 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
446 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
445 1
447 1
446
448
447 diff --git a/a b/a
449 diff --git a/a b/a
448 --- a/a
450 --- a/a
449 +++ b/a
451 +++ b/a
450 @@ -1,1 +1,1 @@
452 @@ -1,1 +1,1 @@
451 -c
453 -c
452 +b
454 +b
453
455
454 Resolve conflicted graft with rename
456 Resolve conflicted graft with rename
455 $ echo c > a
457 $ echo c > a
456 $ hg ci -m 10
458 $ hg ci -m 10
457 $ hg graft 2 --tool internal:fail
459 $ hg graft 2 --tool internal:fail
458 grafting 2:5c095ad7e90f "2"
460 grafting 2:5c095ad7e90f "2"
459 abort: unresolved conflicts, can't continue
461 abort: unresolved conflicts, can't continue
460 (use hg resolve and hg graft --continue)
462 (use hg resolve and hg graft --continue)
461 [255]
463 [255]
462 $ hg resolve --all
464 $ hg resolve --all
463 merging a and b to b
465 merging a and b to b
464 (no more unresolved files)
466 (no more unresolved files)
465 $ hg graft -c
467 $ hg graft -c
466 grafting 2:5c095ad7e90f "2"
468 grafting 2:5c095ad7e90f "2"
467 $ hg export tip --git
469 $ hg export tip --git
468 # HG changeset patch
470 # HG changeset patch
469 # User test
471 # User test
470 # Date 0 0
472 # Date 0 0
471 # Thu Jan 01 00:00:00 1970 +0000
473 # Thu Jan 01 00:00:00 1970 +0000
472 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
474 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
473 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
475 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
474 2
476 2
475
477
476 diff --git a/a b/b
478 diff --git a/a b/b
477 rename from a
479 rename from a
478 rename to b
480 rename to b
479
481
480 Test simple origin(), with and without args
482 Test simple origin(), with and without args
481 $ hg log -r 'origin()'
483 $ hg log -r 'origin()'
482 changeset: 1:5d205f8b35b6
484 changeset: 1:5d205f8b35b6
483 user: bar
485 user: bar
484 date: Thu Jan 01 00:00:00 1970 +0000
486 date: Thu Jan 01 00:00:00 1970 +0000
485 summary: 1
487 summary: 1
486
488
487 changeset: 2:5c095ad7e90f
489 changeset: 2:5c095ad7e90f
488 user: test
490 user: test
489 date: Thu Jan 01 00:00:00 1970 +0000
491 date: Thu Jan 01 00:00:00 1970 +0000
490 summary: 2
492 summary: 2
491
493
492 changeset: 3:4c60f11aa304
494 changeset: 3:4c60f11aa304
493 user: baz
495 user: baz
494 date: Thu Jan 01 00:00:00 1970 +0000
496 date: Thu Jan 01 00:00:00 1970 +0000
495 summary: 3
497 summary: 3
496
498
497 changeset: 4:9c233e8e184d
499 changeset: 4:9c233e8e184d
498 user: test
500 user: test
499 date: Thu Jan 01 00:00:00 1970 +0000
501 date: Thu Jan 01 00:00:00 1970 +0000
500 summary: 4
502 summary: 4
501
503
502 changeset: 5:97f8bfe72746
504 changeset: 5:97f8bfe72746
503 branch: stable
505 branch: stable
504 parent: 3:4c60f11aa304
506 parent: 3:4c60f11aa304
505 user: test
507 user: test
506 date: Thu Jan 01 00:00:00 1970 +0000
508 date: Thu Jan 01 00:00:00 1970 +0000
507 summary: 5
509 summary: 5
508
510
509 $ hg log -r 'origin(7)'
511 $ hg log -r 'origin(7)'
510 changeset: 2:5c095ad7e90f
512 changeset: 2:5c095ad7e90f
511 user: test
513 user: test
512 date: Thu Jan 01 00:00:00 1970 +0000
514 date: Thu Jan 01 00:00:00 1970 +0000
513 summary: 2
515 summary: 2
514
516
515 Now transplant a graft to test following through copies
517 Now transplant a graft to test following through copies
516 $ hg up -q 0
518 $ hg up -q 0
517 $ hg branch -q dev
519 $ hg branch -q dev
518 $ hg ci -qm "dev branch"
520 $ hg ci -qm "dev branch"
519 $ hg --config extensions.transplant= transplant -q 7
521 $ hg --config extensions.transplant= transplant -q 7
520 $ hg log -r 'origin(.)'
522 $ hg log -r 'origin(.)'
521 changeset: 2:5c095ad7e90f
523 changeset: 2:5c095ad7e90f
522 user: test
524 user: test
523 date: Thu Jan 01 00:00:00 1970 +0000
525 date: Thu Jan 01 00:00:00 1970 +0000
524 summary: 2
526 summary: 2
525
527
526 Test that the graft and transplant markers in extra are converted, allowing
528 Test that the graft and transplant markers in extra are converted, allowing
527 origin() to still work. Note that these recheck the immediately preceeding two
529 origin() to still work. Note that these recheck the immediately preceeding two
528 tests.
530 tests.
529 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
531 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
530
532
531 The graft case
533 The graft case
532 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
534 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
533 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
535 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
534 branch=default
536 branch=default
535 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
537 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
536 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
538 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
537 $ hg -R ../converted log -r 'origin(7)'
539 $ hg -R ../converted log -r 'origin(7)'
538 changeset: 2:e0213322b2c1
540 changeset: 2:e0213322b2c1
539 user: test
541 user: test
540 date: Thu Jan 01 00:00:00 1970 +0000
542 date: Thu Jan 01 00:00:00 1970 +0000
541 summary: 2
543 summary: 2
542
544
543 Test that template correctly expands more than one 'extra' (issue4362), and that
545 Test that template correctly expands more than one 'extra' (issue4362), and that
544 'intermediate-source' is converted.
546 'intermediate-source' is converted.
545 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
547 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
546 Extra: branch=default
548 Extra: branch=default
547 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
549 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
548 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
550 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
549 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
551 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
550
552
551 The transplant case
553 The transplant case
552 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
554 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
553 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
555 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
554 branch=dev
556 branch=dev
555 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
557 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
556 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac (esc)
558 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac (esc)
557 `h\x9b (esc)
559 `h\x9b (esc)
558 $ hg -R ../converted log -r 'origin(tip)'
560 $ hg -R ../converted log -r 'origin(tip)'
559 changeset: 2:e0213322b2c1
561 changeset: 2:e0213322b2c1
560 user: test
562 user: test
561 date: Thu Jan 01 00:00:00 1970 +0000
563 date: Thu Jan 01 00:00:00 1970 +0000
562 summary: 2
564 summary: 2
563
565
564
566
565 Test simple destination
567 Test simple destination
566 $ hg log -r 'destination()'
568 $ hg log -r 'destination()'
567 changeset: 7:ef0ef43d49e7
569 changeset: 7:ef0ef43d49e7
568 parent: 0:68795b066622
570 parent: 0:68795b066622
569 user: foo
571 user: foo
570 date: Thu Jan 01 00:00:00 1970 +0000
572 date: Thu Jan 01 00:00:00 1970 +0000
571 summary: 2
573 summary: 2
572
574
573 changeset: 8:6b9e5368ca4e
575 changeset: 8:6b9e5368ca4e
574 user: bar
576 user: bar
575 date: Thu Jan 01 00:00:00 1970 +0000
577 date: Thu Jan 01 00:00:00 1970 +0000
576 summary: 1
578 summary: 1
577
579
578 changeset: 9:1905859650ec
580 changeset: 9:1905859650ec
579 user: test
581 user: test
580 date: Thu Jan 01 00:00:00 1970 +0000
582 date: Thu Jan 01 00:00:00 1970 +0000
581 summary: 5
583 summary: 5
582
584
583 changeset: 10:52dc0b4c6907
585 changeset: 10:52dc0b4c6907
584 user: test
586 user: test
585 date: Thu Jan 01 00:00:00 1970 +0000
587 date: Thu Jan 01 00:00:00 1970 +0000
586 summary: 4
588 summary: 4
587
589
588 changeset: 11:882b35362a6b
590 changeset: 11:882b35362a6b
589 user: test
591 user: test
590 date: Thu Jan 01 00:00:00 1970 +0000
592 date: Thu Jan 01 00:00:00 1970 +0000
591 summary: 3
593 summary: 3
592
594
593 changeset: 13:7a4785234d87
595 changeset: 13:7a4785234d87
594 user: foo
596 user: foo
595 date: Thu Jan 01 00:00:00 1970 +0000
597 date: Thu Jan 01 00:00:00 1970 +0000
596 summary: 2
598 summary: 2
597
599
598 changeset: 14:f64defefacee
600 changeset: 14:f64defefacee
599 parent: 1:5d205f8b35b6
601 parent: 1:5d205f8b35b6
600 user: foo
602 user: foo
601 date: Thu Jan 01 00:00:00 1970 +0000
603 date: Thu Jan 01 00:00:00 1970 +0000
602 summary: 3
604 summary: 3
603
605
604 changeset: 17:f67661df0c48
606 changeset: 17:f67661df0c48
605 user: bar
607 user: bar
606 date: Thu Jan 01 00:00:00 1970 +0000
608 date: Thu Jan 01 00:00:00 1970 +0000
607 summary: 1
609 summary: 1
608
610
609 changeset: 19:9627f653b421
611 changeset: 19:9627f653b421
610 user: test
612 user: test
611 date: Thu Jan 01 00:00:00 1970 +0000
613 date: Thu Jan 01 00:00:00 1970 +0000
612 summary: 2
614 summary: 2
613
615
614 changeset: 21:7e61b508e709
616 changeset: 21:7e61b508e709
615 branch: dev
617 branch: dev
616 tag: tip
618 tag: tip
617 user: foo
619 user: foo
618 date: Thu Jan 01 00:00:00 1970 +0000
620 date: Thu Jan 01 00:00:00 1970 +0000
619 summary: 2
621 summary: 2
620
622
621 $ hg log -r 'destination(2)'
623 $ hg log -r 'destination(2)'
622 changeset: 7:ef0ef43d49e7
624 changeset: 7:ef0ef43d49e7
623 parent: 0:68795b066622
625 parent: 0:68795b066622
624 user: foo
626 user: foo
625 date: Thu Jan 01 00:00:00 1970 +0000
627 date: Thu Jan 01 00:00:00 1970 +0000
626 summary: 2
628 summary: 2
627
629
628 changeset: 13:7a4785234d87
630 changeset: 13:7a4785234d87
629 user: foo
631 user: foo
630 date: Thu Jan 01 00:00:00 1970 +0000
632 date: Thu Jan 01 00:00:00 1970 +0000
631 summary: 2
633 summary: 2
632
634
633 changeset: 19:9627f653b421
635 changeset: 19:9627f653b421
634 user: test
636 user: test
635 date: Thu Jan 01 00:00:00 1970 +0000
637 date: Thu Jan 01 00:00:00 1970 +0000
636 summary: 2
638 summary: 2
637
639
638 changeset: 21:7e61b508e709
640 changeset: 21:7e61b508e709
639 branch: dev
641 branch: dev
640 tag: tip
642 tag: tip
641 user: foo
643 user: foo
642 date: Thu Jan 01 00:00:00 1970 +0000
644 date: Thu Jan 01 00:00:00 1970 +0000
643 summary: 2
645 summary: 2
644
646
645 Transplants of grafts can find a destination...
647 Transplants of grafts can find a destination...
646 $ hg log -r 'destination(7)'
648 $ hg log -r 'destination(7)'
647 changeset: 21:7e61b508e709
649 changeset: 21:7e61b508e709
648 branch: dev
650 branch: dev
649 tag: tip
651 tag: tip
650 user: foo
652 user: foo
651 date: Thu Jan 01 00:00:00 1970 +0000
653 date: Thu Jan 01 00:00:00 1970 +0000
652 summary: 2
654 summary: 2
653
655
654 ... grafts of grafts unfortunately can't
656 ... grafts of grafts unfortunately can't
655 $ hg graft -q 13
657 $ hg graft -q 13
656 warning: can't find ancestor for 'b' copied from 'a'!
658 warning: can't find ancestor for 'b' copied from 'a'!
657 $ hg log -r 'destination(13)'
659 $ hg log -r 'destination(13)'
658 All copies of a cset
660 All copies of a cset
659 $ hg log -r 'origin(13) or destination(origin(13))'
661 $ hg log -r 'origin(13) or destination(origin(13))'
660 changeset: 2:5c095ad7e90f
662 changeset: 2:5c095ad7e90f
661 user: test
663 user: test
662 date: Thu Jan 01 00:00:00 1970 +0000
664 date: Thu Jan 01 00:00:00 1970 +0000
663 summary: 2
665 summary: 2
664
666
665 changeset: 7:ef0ef43d49e7
667 changeset: 7:ef0ef43d49e7
666 parent: 0:68795b066622
668 parent: 0:68795b066622
667 user: foo
669 user: foo
668 date: Thu Jan 01 00:00:00 1970 +0000
670 date: Thu Jan 01 00:00:00 1970 +0000
669 summary: 2
671 summary: 2
670
672
671 changeset: 13:7a4785234d87
673 changeset: 13:7a4785234d87
672 user: foo
674 user: foo
673 date: Thu Jan 01 00:00:00 1970 +0000
675 date: Thu Jan 01 00:00:00 1970 +0000
674 summary: 2
676 summary: 2
675
677
676 changeset: 19:9627f653b421
678 changeset: 19:9627f653b421
677 user: test
679 user: test
678 date: Thu Jan 01 00:00:00 1970 +0000
680 date: Thu Jan 01 00:00:00 1970 +0000
679 summary: 2
681 summary: 2
680
682
681 changeset: 21:7e61b508e709
683 changeset: 21:7e61b508e709
682 branch: dev
684 branch: dev
683 user: foo
685 user: foo
684 date: Thu Jan 01 00:00:00 1970 +0000
686 date: Thu Jan 01 00:00:00 1970 +0000
685 summary: 2
687 summary: 2
686
688
687 changeset: 22:d1cb6591fa4b
689 changeset: 22:d1cb6591fa4b
688 branch: dev
690 branch: dev
689 tag: tip
691 tag: tip
690 user: foo
692 user: foo
691 date: Thu Jan 01 00:00:00 1970 +0000
693 date: Thu Jan 01 00:00:00 1970 +0000
692 summary: 2
694 summary: 2
693
695
694
696
695 graft works on complex revset
697 graft works on complex revset
696
698
697 $ hg graft 'origin(13) or destination(origin(13))'
699 $ hg graft 'origin(13) or destination(origin(13))'
698 skipping ancestor revision 21:7e61b508e709
700 skipping ancestor revision 21:7e61b508e709
699 skipping ancestor revision 22:d1cb6591fa4b
701 skipping ancestor revision 22:d1cb6591fa4b
700 skipping revision 2:5c095ad7e90f (already grafted to 22:d1cb6591fa4b)
702 skipping revision 2:5c095ad7e90f (already grafted to 22:d1cb6591fa4b)
701 grafting 7:ef0ef43d49e7 "2"
703 grafting 7:ef0ef43d49e7 "2"
702 warning: can't find ancestor for 'b' copied from 'a'!
704 warning: can't find ancestor for 'b' copied from 'a'!
703 grafting 13:7a4785234d87 "2"
705 grafting 13:7a4785234d87 "2"
704 warning: can't find ancestor for 'b' copied from 'a'!
706 warning: can't find ancestor for 'b' copied from 'a'!
705 grafting 19:9627f653b421 "2"
707 grafting 19:9627f653b421 "2"
706 merging b
708 merging b
707 warning: can't find ancestor for 'b' copied from 'a'!
709 warning: can't find ancestor for 'b' copied from 'a'!
708
710
709 graft with --force (still doesn't graft merges)
711 graft with --force (still doesn't graft merges)
710
712
711 $ hg graft 19 0 6
713 $ hg graft 19 0 6
712 skipping ungraftable merge revision 6
714 skipping ungraftable merge revision 6
713 skipping ancestor revision 0:68795b066622
715 skipping ancestor revision 0:68795b066622
714 skipping already grafted revision 19:9627f653b421 (22:d1cb6591fa4b also has origin 2:5c095ad7e90f)
716 skipping already grafted revision 19:9627f653b421 (22:d1cb6591fa4b also has origin 2:5c095ad7e90f)
715 [255]
717 [255]
716 $ hg graft 19 0 6 --force
718 $ hg graft 19 0 6 --force
717 skipping ungraftable merge revision 6
719 skipping ungraftable merge revision 6
718 grafting 19:9627f653b421 "2"
720 grafting 19:9627f653b421 "2"
719 merging b
721 merging b
720 warning: can't find ancestor for 'b' copied from 'a'!
722 warning: can't find ancestor for 'b' copied from 'a'!
721 grafting 0:68795b066622 "0"
723 grafting 0:68795b066622 "0"
722
724
723 graft --force after backout
725 graft --force after backout
724
726
725 $ echo abc > a
727 $ echo abc > a
726 $ hg ci -m 28
728 $ hg ci -m 28
727 $ hg backout 28
729 $ hg backout 28
728 reverting a
730 reverting a
729 changeset 29:53177ba928f6 backs out changeset 28:50a516bb8b57
731 changeset 29:53177ba928f6 backs out changeset 28:50a516bb8b57
730 $ hg graft 28
732 $ hg graft 28
731 skipping ancestor revision 28:50a516bb8b57
733 skipping ancestor revision 28:50a516bb8b57
732 [255]
734 [255]
733 $ hg graft 28 --force
735 $ hg graft 28 --force
734 grafting 28:50a516bb8b57 "28"
736 grafting 28:50a516bb8b57 "28"
735 merging a
737 merging a
736 $ cat a
738 $ cat a
737 abc
739 abc
738
740
739 graft --continue after --force
741 graft --continue after --force
740
742
741 $ echo def > a
743 $ echo def > a
742 $ hg ci -m 31
744 $ hg ci -m 31
743 $ hg graft 28 --force --tool internal:fail
745 $ hg graft 28 --force --tool internal:fail
744 grafting 28:50a516bb8b57 "28"
746 grafting 28:50a516bb8b57 "28"
745 abort: unresolved conflicts, can't continue
747 abort: unresolved conflicts, can't continue
746 (use hg resolve and hg graft --continue)
748 (use hg resolve and hg graft --continue)
747 [255]
749 [255]
748 $ hg resolve --all
750 $ hg resolve --all
749 merging a
751 merging a
750 warning: conflicts during merge.
752 warning: conflicts during merge.
751 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
753 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
752 [1]
754 [1]
753 $ echo abc > a
755 $ echo abc > a
754 $ hg resolve -m a
756 $ hg resolve -m a
755 (no more unresolved files)
757 (no more unresolved files)
756 $ hg graft -c
758 $ hg graft -c
757 grafting 28:50a516bb8b57 "28"
759 grafting 28:50a516bb8b57 "28"
758 $ cat a
760 $ cat a
759 abc
761 abc
760
762
761 Continue testing same origin policy, using revision numbers from test above
763 Continue testing same origin policy, using revision numbers from test above
762 but do some destructive editing of the repo:
764 but do some destructive editing of the repo:
763
765
764 $ hg up -qC 7
766 $ hg up -qC 7
765 $ hg tag -l -r 13 tmp
767 $ hg tag -l -r 13 tmp
766 $ hg --config extensions.strip= strip 2
768 $ hg --config extensions.strip= strip 2
767 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg (glob)
769 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg (glob)
768 $ hg graft tmp
770 $ hg graft tmp
769 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
771 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
770 [255]
772 [255]
771
773
772 Empty graft
774 Empty graft
773
775
774 $ hg up -qr 26
776 $ hg up -qr 26
775 $ hg tag -f something
777 $ hg tag -f something
776 $ hg graft -qr 27
778 $ hg graft -qr 27
777 $ hg graft -f 27
779 $ hg graft -f 27
778 grafting 27:ed6c7e54e319 "28"
780 grafting 27:ed6c7e54e319 "28"
779 note: graft of 27:ed6c7e54e319 created no changes to commit
781 note: graft of 27:ed6c7e54e319 created no changes to commit
780
782
781 $ cd ..
783 $ cd ..
782
784
783 Graft to duplicate a commit
785 Graft to duplicate a commit
784
786
785 $ hg init graftsibling
787 $ hg init graftsibling
786 $ cd graftsibling
788 $ cd graftsibling
787 $ touch a
789 $ touch a
788 $ hg commit -qAm a
790 $ hg commit -qAm a
789 $ touch b
791 $ touch b
790 $ hg commit -qAm b
792 $ hg commit -qAm b
791 $ hg log -G -T '{rev}\n'
793 $ hg log -G -T '{rev}\n'
792 @ 1
794 @ 1
793 |
795 |
794 o 0
796 o 0
795
797
796 $ hg up -q 0
798 $ hg up -q 0
797 $ hg graft -r 1
799 $ hg graft -r 1
798 grafting 1:0e067c57feba "b" (tip)
800 grafting 1:0e067c57feba "b" (tip)
799 $ hg log -G -T '{rev}\n'
801 $ hg log -G -T '{rev}\n'
800 @ 2
802 @ 2
801 |
803 |
802 | o 1
804 | o 1
803 |/
805 |/
804 o 0
806 o 0
805
807
806 Graft to duplicate a commit twice
808 Graft to duplicate a commit twice
807
809
808 $ hg up -q 0
810 $ hg up -q 0
809 $ hg graft -r 2
811 $ hg graft -r 2
810 grafting 2:044ec77f6389 "b" (tip)
812 grafting 2:044ec77f6389 "b" (tip)
811 $ hg log -G -T '{rev}\n'
813 $ hg log -G -T '{rev}\n'
812 @ 3
814 @ 3
813 |
815 |
814 | o 2
816 | o 2
815 |/
817 |/
816 | o 1
818 | o 1
817 |/
819 |/
818 o 0
820 o 0
819
821
@@ -1,349 +1,351 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
85 f2: versions differ -> m
86 picked tool ':dump' for f2 (binary False symlink False)
86 picked tool ':dump' for f2 (binary False symlink 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@40494bf2444c
89 picked tool ':dump' for f2 (binary False symlink False)
90 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@40494bf2444c
89 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
91 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
90 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
92 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
91 [1]
93 [1]
92
94
93 $ head *
95 $ head *
94 ==> f1 <==
96 ==> f1 <==
95 5 second change
97 5 second change
96
98
97 ==> f2 <==
99 ==> f2 <==
98 6 second change
100 6 second change
99
101
100 ==> f2.base <==
102 ==> f2.base <==
101 0 base
103 0 base
102
104
103 ==> f2.local <==
105 ==> f2.local <==
104 6 second change
106 6 second change
105
107
106 ==> f2.orig <==
108 ==> f2.orig <==
107 6 second change
109 6 second change
108
110
109 ==> f2.other <==
111 ==> f2.other <==
110 2 first change
112 2 first change
111
113
112 $ hg up -qC .
114 $ hg up -qC .
113 $ hg merge -v --tool internal:dump 5 --config merge.preferancestor="null 40663881 3b08d"
115 $ hg merge -v --tool internal:dump 5 --config merge.preferancestor="null 40663881 3b08d"
114 note: using 40663881a6dd as ancestor of 3b08d01b0ab5 and adfe50279922
116 note: using 40663881a6dd as ancestor of 3b08d01b0ab5 and adfe50279922
115 alternatively, use --config merge.preferancestor=0f6b37dbe527
117 alternatively, use --config merge.preferancestor=0f6b37dbe527
116 resolving manifests
118 resolving manifests
117 merging f1
119 merging f1
118 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
120 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
119 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
121 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
120 [1]
122 [1]
121
123
122 Redo merge with merge.preferancestor="*" to enable bid merge
124 Redo merge with merge.preferancestor="*" to enable bid merge
123
125
124 $ rm f*
126 $ rm f*
125 $ hg up -qC .
127 $ hg up -qC .
126 $ hg merge -v --debug --tool internal:dump 5 --config merge.preferancestor="*"
128 $ hg merge -v --debug --tool internal:dump 5 --config merge.preferancestor="*"
127 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
129 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
128
130
129 calculating bids for ancestor 0f6b37dbe527
131 calculating bids for ancestor 0f6b37dbe527
130 searching for copies back to rev 3
132 searching for copies back to rev 3
131 resolving manifests
133 resolving manifests
132 branchmerge: True, force: False, partial: False
134 branchmerge: True, force: False, partial: False
133 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
135 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
134 f1: remote is newer -> g
136 f1: remote is newer -> g
135 f2: versions differ -> m
137 f2: versions differ -> m
136
138
137 calculating bids for ancestor 40663881a6dd
139 calculating bids for ancestor 40663881a6dd
138 searching for copies back to rev 3
140 searching for copies back to rev 3
139 resolving manifests
141 resolving manifests
140 branchmerge: True, force: False, partial: False
142 branchmerge: True, force: False, partial: False
141 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
143 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
142 f1: versions differ -> m
144 f1: versions differ -> m
143 f2: remote unchanged -> k
145 f2: remote unchanged -> k
144
146
145 auction for merging merge bids
147 auction for merging merge bids
146 f1: picking 'get' action
148 f1: picking 'get' action
147 f2: picking 'keep' action
149 f2: picking 'keep' action
148 end of auction
150 end of auction
149
151
150 f1: remote is newer -> g
152 f1: remote is newer -> g
151 getting f1
153 getting f1
152 f2: remote unchanged -> k
154 f2: remote unchanged -> k
153 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
155 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
154 (branch merge, don't forget to commit)
156 (branch merge, don't forget to commit)
155
157
156 $ head *
158 $ head *
157 ==> f1 <==
159 ==> f1 <==
158 5 second change
160 5 second change
159
161
160 ==> f2 <==
162 ==> f2 <==
161 6 second change
163 6 second change
162
164
163
165
164 The other way around:
166 The other way around:
165
167
166 $ hg up -C -r5
168 $ hg up -C -r5
167 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
169 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
168 $ hg merge -v --debug --config merge.preferancestor="*"
170 $ hg merge -v --debug --config merge.preferancestor="*"
169 note: merging adfe50279922+ and 3b08d01b0ab5 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
171 note: merging adfe50279922+ and 3b08d01b0ab5 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
170
172
171 calculating bids for ancestor 0f6b37dbe527
173 calculating bids for ancestor 0f6b37dbe527
172 searching for copies back to rev 3
174 searching for copies back to rev 3
173 resolving manifests
175 resolving manifests
174 branchmerge: True, force: False, partial: False
176 branchmerge: True, force: False, partial: False
175 ancestor: 0f6b37dbe527, local: adfe50279922+, remote: 3b08d01b0ab5
177 ancestor: 0f6b37dbe527, local: adfe50279922+, remote: 3b08d01b0ab5
176 f1: remote unchanged -> k
178 f1: remote unchanged -> k
177 f2: versions differ -> m
179 f2: versions differ -> m
178
180
179 calculating bids for ancestor 40663881a6dd
181 calculating bids for ancestor 40663881a6dd
180 searching for copies back to rev 3
182 searching for copies back to rev 3
181 resolving manifests
183 resolving manifests
182 branchmerge: True, force: False, partial: False
184 branchmerge: True, force: False, partial: False
183 ancestor: 40663881a6dd, local: adfe50279922+, remote: 3b08d01b0ab5
185 ancestor: 40663881a6dd, local: adfe50279922+, remote: 3b08d01b0ab5
184 f1: versions differ -> m
186 f1: versions differ -> m
185 f2: remote is newer -> g
187 f2: remote is newer -> g
186
188
187 auction for merging merge bids
189 auction for merging merge bids
188 f1: picking 'keep' action
190 f1: picking 'keep' action
189 f2: picking 'get' action
191 f2: picking 'get' action
190 end of auction
192 end of auction
191
193
192 f2: remote is newer -> g
194 f2: remote is newer -> g
193 getting f2
195 getting f2
194 f1: remote unchanged -> k
196 f1: remote unchanged -> k
195 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
197 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 (branch merge, don't forget to commit)
198 (branch merge, don't forget to commit)
197
199
198 $ head *
200 $ head *
199 ==> f1 <==
201 ==> f1 <==
200 5 second change
202 5 second change
201
203
202 ==> f2 <==
204 ==> f2 <==
203 6 second change
205 6 second change
204
206
205 Verify how the output looks and and how verbose it is:
207 Verify how the output looks and and how verbose it is:
206
208
207 $ hg up -qC
209 $ hg up -qC
208 $ hg merge
210 $ hg merge
209 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
211 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 (branch merge, don't forget to commit)
212 (branch merge, don't forget to commit)
211
213
212 $ hg up -qC
214 $ hg up -qC
213 $ hg merge -v
215 $ hg merge -v
214 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
216 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
215
217
216 calculating bids for ancestor 0f6b37dbe527
218 calculating bids for ancestor 0f6b37dbe527
217 resolving manifests
219 resolving manifests
218
220
219 calculating bids for ancestor 40663881a6dd
221 calculating bids for ancestor 40663881a6dd
220 resolving manifests
222 resolving manifests
221
223
222 auction for merging merge bids
224 auction for merging merge bids
223 f1: picking 'get' action
225 f1: picking 'get' action
224 f2: picking 'keep' action
226 f2: picking 'keep' action
225 end of auction
227 end of auction
226
228
227 getting f1
229 getting f1
228 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
230 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
229 (branch merge, don't forget to commit)
231 (branch merge, don't forget to commit)
230
232
231 $ hg up -qC
233 $ hg up -qC
232 $ hg merge -v --debug --config merge.preferancestor="*"
234 $ hg merge -v --debug --config merge.preferancestor="*"
233 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
235 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
234
236
235 calculating bids for ancestor 0f6b37dbe527
237 calculating bids for ancestor 0f6b37dbe527
236 searching for copies back to rev 3
238 searching for copies back to rev 3
237 resolving manifests
239 resolving manifests
238 branchmerge: True, force: False, partial: False
240 branchmerge: True, force: False, partial: False
239 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
241 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
240 f1: remote is newer -> g
242 f1: remote is newer -> g
241 f2: versions differ -> m
243 f2: versions differ -> m
242
244
243 calculating bids for ancestor 40663881a6dd
245 calculating bids for ancestor 40663881a6dd
244 searching for copies back to rev 3
246 searching for copies back to rev 3
245 resolving manifests
247 resolving manifests
246 branchmerge: True, force: False, partial: False
248 branchmerge: True, force: False, partial: False
247 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
249 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
248 f1: versions differ -> m
250 f1: versions differ -> m
249 f2: remote unchanged -> k
251 f2: remote unchanged -> k
250
252
251 auction for merging merge bids
253 auction for merging merge bids
252 f1: picking 'get' action
254 f1: picking 'get' action
253 f2: picking 'keep' action
255 f2: picking 'keep' action
254 end of auction
256 end of auction
255
257
256 f1: remote is newer -> g
258 f1: remote is newer -> g
257 getting f1
259 getting f1
258 f2: remote unchanged -> k
260 f2: remote unchanged -> k
259 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
261 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
260 (branch merge, don't forget to commit)
262 (branch merge, don't forget to commit)
261
263
262 $ cd ..
264 $ cd ..
263
265
264 http://stackoverflow.com/questions/9350005/how-do-i-specify-a-merge-base-to-use-in-a-hg-merge/9430810
266 http://stackoverflow.com/questions/9350005/how-do-i-specify-a-merge-base-to-use-in-a-hg-merge/9430810
265
267
266 $ hg init ancestor-merging
268 $ hg init ancestor-merging
267 $ cd ancestor-merging
269 $ cd ancestor-merging
268 $ echo a > x
270 $ echo a > x
269 $ hg commit -A -m a x
271 $ hg commit -A -m a x
270 $ hg update -q 0
272 $ hg update -q 0
271 $ echo b >> x
273 $ echo b >> x
272 $ hg commit -m b
274 $ hg commit -m b
273 $ hg update -q 0
275 $ hg update -q 0
274 $ echo c >> x
276 $ echo c >> x
275 $ hg commit -qm c
277 $ hg commit -qm c
276 $ hg update -q 1
278 $ hg update -q 1
277 $ hg merge -q --tool internal:local 2
279 $ hg merge -q --tool internal:local 2
278 $ echo c >> x
280 $ echo c >> x
279 $ hg commit -m bc
281 $ hg commit -m bc
280 $ hg update -q 2
282 $ hg update -q 2
281 $ hg merge -q --tool internal:local 1
283 $ hg merge -q --tool internal:local 1
282 $ echo b >> x
284 $ echo b >> x
283 $ hg commit -qm cb
285 $ hg commit -qm cb
284
286
285 $ hg merge --config merge.preferancestor='!'
287 $ hg merge --config merge.preferancestor='!'
286 note: using 70008a2163f6 as ancestor of 0d355fdef312 and 4b8b546a3eef
288 note: using 70008a2163f6 as ancestor of 0d355fdef312 and 4b8b546a3eef
287 alternatively, use --config merge.preferancestor=b211bbc6eb3c
289 alternatively, use --config merge.preferancestor=b211bbc6eb3c
288 merging x
290 merging x
289 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
291 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
290 (branch merge, don't forget to commit)
292 (branch merge, don't forget to commit)
291 $ cat x
293 $ cat x
292 a
294 a
293 c
295 c
294 b
296 b
295 c
297 c
296
298
297 $ hg up -qC .
299 $ hg up -qC .
298
300
299 $ hg merge --config merge.preferancestor=b211bbc6eb3c
301 $ hg merge --config merge.preferancestor=b211bbc6eb3c
300 note: using b211bbc6eb3c as ancestor of 0d355fdef312 and 4b8b546a3eef
302 note: using b211bbc6eb3c as ancestor of 0d355fdef312 and 4b8b546a3eef
301 alternatively, use --config merge.preferancestor=70008a2163f6
303 alternatively, use --config merge.preferancestor=70008a2163f6
302 merging x
304 merging x
303 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
305 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
304 (branch merge, don't forget to commit)
306 (branch merge, don't forget to commit)
305 $ cat x
307 $ cat x
306 a
308 a
307 b
309 b
308 c
310 c
309 b
311 b
310
312
311 $ hg up -qC .
313 $ hg up -qC .
312
314
313 $ hg merge -v --config merge.preferancestor="*"
315 $ hg merge -v --config merge.preferancestor="*"
314 note: merging 0d355fdef312+ and 4b8b546a3eef using bids from ancestors 70008a2163f6 and b211bbc6eb3c
316 note: merging 0d355fdef312+ and 4b8b546a3eef using bids from ancestors 70008a2163f6 and b211bbc6eb3c
315
317
316 calculating bids for ancestor 70008a2163f6
318 calculating bids for ancestor 70008a2163f6
317 resolving manifests
319 resolving manifests
318
320
319 calculating bids for ancestor b211bbc6eb3c
321 calculating bids for ancestor b211bbc6eb3c
320 resolving manifests
322 resolving manifests
321
323
322 auction for merging merge bids
324 auction for merging merge bids
323 x: multiple bids for merge action:
325 x: multiple bids for merge action:
324 versions differ -> m
326 versions differ -> m
325 versions differ -> m
327 versions differ -> m
326 x: ambiguous merge - picked m action
328 x: ambiguous merge - picked m action
327 end of auction
329 end of auction
328
330
329 merging x
331 merging x
330 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
332 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
331 (branch merge, don't forget to commit)
333 (branch merge, don't forget to commit)
332 $ cat x
334 $ cat x
333 a
335 a
334 c
336 c
335 b
337 b
336 c
338 c
337
339
338 Verify that the old context ancestor works with / despite preferancestor:
340 Verify that the old context ancestor works with / despite preferancestor:
339
341
340 $ hg log -r 'ancestor(head())' --config merge.preferancestor=1 -T '{rev}\n'
342 $ hg log -r 'ancestor(head())' --config merge.preferancestor=1 -T '{rev}\n'
341 1
343 1
342 $ hg log -r 'ancestor(head())' --config merge.preferancestor=2 -T '{rev}\n'
344 $ hg log -r 'ancestor(head())' --config merge.preferancestor=2 -T '{rev}\n'
343 2
345 2
344 $ hg log -r 'ancestor(head())' --config merge.preferancestor=3 -T '{rev}\n'
346 $ hg log -r 'ancestor(head())' --config merge.preferancestor=3 -T '{rev}\n'
345 1
347 1
346 $ hg log -r 'ancestor(head())' --config merge.preferancestor='1337 * - 2' -T '{rev}\n'
348 $ hg log -r 'ancestor(head())' --config merge.preferancestor='1337 * - 2' -T '{rev}\n'
347 2
349 2
348
350
349 $ cd ..
351 $ cd ..
@@ -1,1030 +1,1032 b''
1 test merge-tools configuration - mostly exercising filemerge.py
1 test merge-tools configuration - mostly exercising filemerge.py
2
2
3 $ unset HGMERGE # make sure HGMERGE doesn't interfere with the test
3 $ unset HGMERGE # make sure HGMERGE doesn't interfere with the test
4 $ hg init
4 $ hg init
5
5
6 revision 0
6 revision 0
7
7
8 $ echo "revision 0" > f
8 $ echo "revision 0" > f
9 $ echo "space" >> f
9 $ echo "space" >> f
10 $ hg commit -Am "revision 0"
10 $ hg commit -Am "revision 0"
11 adding f
11 adding f
12
12
13 revision 1
13 revision 1
14
14
15 $ echo "revision 1" > f
15 $ echo "revision 1" > f
16 $ echo "space" >> f
16 $ echo "space" >> f
17 $ hg commit -Am "revision 1"
17 $ hg commit -Am "revision 1"
18 $ hg update 0 > /dev/null
18 $ hg update 0 > /dev/null
19
19
20 revision 2
20 revision 2
21
21
22 $ echo "revision 2" > f
22 $ echo "revision 2" > f
23 $ echo "space" >> f
23 $ echo "space" >> f
24 $ hg commit -Am "revision 2"
24 $ hg commit -Am "revision 2"
25 created new head
25 created new head
26 $ hg update 0 > /dev/null
26 $ hg update 0 > /dev/null
27
27
28 revision 3 - simple to merge
28 revision 3 - simple to merge
29
29
30 $ echo "revision 3" >> f
30 $ echo "revision 3" >> f
31 $ hg commit -Am "revision 3"
31 $ hg commit -Am "revision 3"
32 created new head
32 created new head
33
33
34 revision 4 - hard to merge
34 revision 4 - hard to merge
35
35
36 $ hg update 0 > /dev/null
36 $ hg update 0 > /dev/null
37 $ echo "revision 4" > f
37 $ echo "revision 4" > f
38 $ hg commit -Am "revision 4"
38 $ hg commit -Am "revision 4"
39 created new head
39 created new head
40
40
41 $ echo "[merge-tools]" > .hg/hgrc
41 $ echo "[merge-tools]" > .hg/hgrc
42
42
43 $ beforemerge() {
43 $ beforemerge() {
44 > cat .hg/hgrc
44 > cat .hg/hgrc
45 > echo "# hg update -C 1"
45 > echo "# hg update -C 1"
46 > hg update -C 1 > /dev/null
46 > hg update -C 1 > /dev/null
47 > }
47 > }
48 $ aftermerge() {
48 $ aftermerge() {
49 > echo "# cat f"
49 > echo "# cat f"
50 > cat f
50 > cat f
51 > echo "# hg stat"
51 > echo "# hg stat"
52 > hg stat
52 > hg stat
53 > rm -f f.orig
53 > rm -f f.orig
54 > }
54 > }
55
55
56 Tool selection
56 Tool selection
57
57
58 default is internal merge:
58 default is internal merge:
59
59
60 $ beforemerge
60 $ beforemerge
61 [merge-tools]
61 [merge-tools]
62 # hg update -C 1
62 # hg update -C 1
63
63
64 hg merge -r 2
64 hg merge -r 2
65 override $PATH to ensure hgmerge not visible; use $PYTHON in case we're
65 override $PATH to ensure hgmerge not visible; use $PYTHON in case we're
66 running from a devel copy, not a temp installation
66 running from a devel copy, not a temp installation
67
67
68 $ PATH="$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
68 $ PATH="$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
69 merging f
69 merging f
70 warning: conflicts during merge.
70 warning: conflicts during merge.
71 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
71 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
72 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
72 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
73 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
73 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
74 [1]
74 [1]
75 $ aftermerge
75 $ aftermerge
76 # cat f
76 # cat f
77 <<<<<<< local: ef83787e2614 - test: revision 1
77 <<<<<<< local: ef83787e2614 - test: revision 1
78 revision 1
78 revision 1
79 =======
79 =======
80 revision 2
80 revision 2
81 >>>>>>> other: 0185f4e0cf02 - test: revision 2
81 >>>>>>> other: 0185f4e0cf02 - test: revision 2
82 space
82 space
83 # hg stat
83 # hg stat
84 M f
84 M f
85 ? f.orig
85 ? f.orig
86
86
87 simplest hgrc using false for merge:
87 simplest hgrc using false for merge:
88
88
89 $ echo "false.whatever=" >> .hg/hgrc
89 $ echo "false.whatever=" >> .hg/hgrc
90 $ beforemerge
90 $ beforemerge
91 [merge-tools]
91 [merge-tools]
92 false.whatever=
92 false.whatever=
93 # hg update -C 1
93 # hg update -C 1
94 $ hg merge -r 2
94 $ hg merge -r 2
95 merging f
95 merging f
96 merging f failed!
96 merging f failed!
97 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
97 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
98 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
98 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
99 [1]
99 [1]
100 $ aftermerge
100 $ aftermerge
101 # cat f
101 # cat f
102 revision 1
102 revision 1
103 space
103 space
104 # hg stat
104 # hg stat
105 M f
105 M f
106 ? f.orig
106 ? f.orig
107
107
108 #if unix-permissions
108 #if unix-permissions
109
109
110 unexecutable file in $PATH shouldn't be found:
110 unexecutable file in $PATH shouldn't be found:
111
111
112 $ echo "echo fail" > false
112 $ echo "echo fail" > false
113 $ hg up -qC 1
113 $ hg up -qC 1
114 $ PATH="`pwd`:$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
114 $ PATH="`pwd`:$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
115 merging f
115 merging f
116 warning: conflicts during merge.
116 warning: conflicts during merge.
117 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
117 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
118 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
118 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
119 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
119 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
120 [1]
120 [1]
121 $ rm false
121 $ rm false
122
122
123 #endif
123 #endif
124
124
125 executable directory in $PATH shouldn't be found:
125 executable directory in $PATH shouldn't be found:
126
126
127 $ mkdir false
127 $ mkdir false
128 $ hg up -qC 1
128 $ hg up -qC 1
129 $ PATH="`pwd`:$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
129 $ PATH="`pwd`:$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
130 merging f
130 merging f
131 warning: conflicts during merge.
131 warning: conflicts during merge.
132 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
132 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
133 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
133 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
134 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
134 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
135 [1]
135 [1]
136 $ rmdir false
136 $ rmdir false
137
137
138 true with higher .priority gets precedence:
138 true with higher .priority gets precedence:
139
139
140 $ echo "true.priority=1" >> .hg/hgrc
140 $ echo "true.priority=1" >> .hg/hgrc
141 $ beforemerge
141 $ beforemerge
142 [merge-tools]
142 [merge-tools]
143 false.whatever=
143 false.whatever=
144 true.priority=1
144 true.priority=1
145 # hg update -C 1
145 # hg update -C 1
146 $ hg merge -r 2
146 $ hg merge -r 2
147 merging f
147 merging f
148 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
148 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
149 (branch merge, don't forget to commit)
149 (branch merge, don't forget to commit)
150 $ aftermerge
150 $ aftermerge
151 # cat f
151 # cat f
152 revision 1
152 revision 1
153 space
153 space
154 # hg stat
154 # hg stat
155 M f
155 M f
156
156
157 unless lowered on command line:
157 unless lowered on command line:
158
158
159 $ beforemerge
159 $ beforemerge
160 [merge-tools]
160 [merge-tools]
161 false.whatever=
161 false.whatever=
162 true.priority=1
162 true.priority=1
163 # hg update -C 1
163 # hg update -C 1
164 $ hg merge -r 2 --config merge-tools.true.priority=-7
164 $ hg merge -r 2 --config merge-tools.true.priority=-7
165 merging f
165 merging f
166 merging f failed!
166 merging f failed!
167 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
167 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
168 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
168 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
169 [1]
169 [1]
170 $ aftermerge
170 $ aftermerge
171 # cat f
171 # cat f
172 revision 1
172 revision 1
173 space
173 space
174 # hg stat
174 # hg stat
175 M f
175 M f
176 ? f.orig
176 ? f.orig
177
177
178 or false set higher on command line:
178 or false set higher on command line:
179
179
180 $ beforemerge
180 $ beforemerge
181 [merge-tools]
181 [merge-tools]
182 false.whatever=
182 false.whatever=
183 true.priority=1
183 true.priority=1
184 # hg update -C 1
184 # hg update -C 1
185 $ hg merge -r 2 --config merge-tools.false.priority=117
185 $ hg merge -r 2 --config merge-tools.false.priority=117
186 merging f
186 merging f
187 merging f failed!
187 merging f failed!
188 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
188 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
189 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
189 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
190 [1]
190 [1]
191 $ aftermerge
191 $ aftermerge
192 # cat f
192 # cat f
193 revision 1
193 revision 1
194 space
194 space
195 # hg stat
195 # hg stat
196 M f
196 M f
197 ? f.orig
197 ? f.orig
198
198
199 or true.executable not found in PATH:
199 or true.executable not found in PATH:
200
200
201 $ beforemerge
201 $ beforemerge
202 [merge-tools]
202 [merge-tools]
203 false.whatever=
203 false.whatever=
204 true.priority=1
204 true.priority=1
205 # hg update -C 1
205 # hg update -C 1
206 $ hg merge -r 2 --config merge-tools.true.executable=nonexistentmergetool
206 $ hg merge -r 2 --config merge-tools.true.executable=nonexistentmergetool
207 merging f
207 merging f
208 merging f failed!
208 merging f failed!
209 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
209 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
210 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
210 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
211 [1]
211 [1]
212 $ aftermerge
212 $ aftermerge
213 # cat f
213 # cat f
214 revision 1
214 revision 1
215 space
215 space
216 # hg stat
216 # hg stat
217 M f
217 M f
218 ? f.orig
218 ? f.orig
219
219
220 or true.executable with bogus path:
220 or true.executable with bogus path:
221
221
222 $ beforemerge
222 $ beforemerge
223 [merge-tools]
223 [merge-tools]
224 false.whatever=
224 false.whatever=
225 true.priority=1
225 true.priority=1
226 # hg update -C 1
226 # hg update -C 1
227 $ hg merge -r 2 --config merge-tools.true.executable=/nonexistent/mergetool
227 $ hg merge -r 2 --config merge-tools.true.executable=/nonexistent/mergetool
228 merging f
228 merging f
229 merging f failed!
229 merging f failed!
230 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
230 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
231 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
231 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
232 [1]
232 [1]
233 $ aftermerge
233 $ aftermerge
234 # cat f
234 # cat f
235 revision 1
235 revision 1
236 space
236 space
237 # hg stat
237 # hg stat
238 M f
238 M f
239 ? f.orig
239 ? f.orig
240
240
241 but true.executable set to cat found in PATH works:
241 but true.executable set to cat found in PATH works:
242
242
243 $ echo "true.executable=cat" >> .hg/hgrc
243 $ echo "true.executable=cat" >> .hg/hgrc
244 $ beforemerge
244 $ beforemerge
245 [merge-tools]
245 [merge-tools]
246 false.whatever=
246 false.whatever=
247 true.priority=1
247 true.priority=1
248 true.executable=cat
248 true.executable=cat
249 # hg update -C 1
249 # hg update -C 1
250 $ hg merge -r 2
250 $ hg merge -r 2
251 merging f
251 merging f
252 revision 1
252 revision 1
253 space
253 space
254 revision 0
254 revision 0
255 space
255 space
256 revision 2
256 revision 2
257 space
257 space
258 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
258 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
259 (branch merge, don't forget to commit)
259 (branch merge, don't forget to commit)
260 $ aftermerge
260 $ aftermerge
261 # cat f
261 # cat f
262 revision 1
262 revision 1
263 space
263 space
264 # hg stat
264 # hg stat
265 M f
265 M f
266
266
267 and true.executable set to cat with path works:
267 and true.executable set to cat with path works:
268
268
269 $ beforemerge
269 $ beforemerge
270 [merge-tools]
270 [merge-tools]
271 false.whatever=
271 false.whatever=
272 true.priority=1
272 true.priority=1
273 true.executable=cat
273 true.executable=cat
274 # hg update -C 1
274 # hg update -C 1
275 $ hg merge -r 2 --config merge-tools.true.executable=cat
275 $ hg merge -r 2 --config merge-tools.true.executable=cat
276 merging f
276 merging f
277 revision 1
277 revision 1
278 space
278 space
279 revision 0
279 revision 0
280 space
280 space
281 revision 2
281 revision 2
282 space
282 space
283 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
283 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
284 (branch merge, don't forget to commit)
284 (branch merge, don't forget to commit)
285 $ aftermerge
285 $ aftermerge
286 # cat f
286 # cat f
287 revision 1
287 revision 1
288 space
288 space
289 # hg stat
289 # hg stat
290 M f
290 M f
291
291
292 #if unix-permissions
292 #if unix-permissions
293
293
294 environment variables in true.executable are handled:
294 environment variables in true.executable are handled:
295
295
296 $ echo 'echo "custom merge tool"' > .hg/merge.sh
296 $ echo 'echo "custom merge tool"' > .hg/merge.sh
297 $ beforemerge
297 $ beforemerge
298 [merge-tools]
298 [merge-tools]
299 false.whatever=
299 false.whatever=
300 true.priority=1
300 true.priority=1
301 true.executable=cat
301 true.executable=cat
302 # hg update -C 1
302 # hg update -C 1
303 $ hg --config merge-tools.true.executable='sh' \
303 $ hg --config merge-tools.true.executable='sh' \
304 > --config merge-tools.true.args=.hg/merge.sh \
304 > --config merge-tools.true.args=.hg/merge.sh \
305 > merge -r 2
305 > merge -r 2
306 merging f
306 merging f
307 custom merge tool
307 custom merge tool
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 $ aftermerge
310 $ aftermerge
311 # cat f
311 # cat f
312 revision 1
312 revision 1
313 space
313 space
314 # hg stat
314 # hg stat
315 M f
315 M f
316
316
317 #endif
317 #endif
318
318
319 Tool selection and merge-patterns
319 Tool selection and merge-patterns
320
320
321 merge-patterns specifies new tool false:
321 merge-patterns specifies new tool false:
322
322
323 $ beforemerge
323 $ beforemerge
324 [merge-tools]
324 [merge-tools]
325 false.whatever=
325 false.whatever=
326 true.priority=1
326 true.priority=1
327 true.executable=cat
327 true.executable=cat
328 # hg update -C 1
328 # hg update -C 1
329 $ hg merge -r 2 --config merge-patterns.f=false
329 $ hg merge -r 2 --config merge-patterns.f=false
330 merging f
330 merging f
331 merging f failed!
331 merging f failed!
332 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
332 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
333 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
333 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
334 [1]
334 [1]
335 $ aftermerge
335 $ aftermerge
336 # cat f
336 # cat f
337 revision 1
337 revision 1
338 space
338 space
339 # hg stat
339 # hg stat
340 M f
340 M f
341 ? f.orig
341 ? f.orig
342
342
343 merge-patterns specifies executable not found in PATH and gets warning:
343 merge-patterns specifies executable not found in PATH and gets warning:
344
344
345 $ beforemerge
345 $ beforemerge
346 [merge-tools]
346 [merge-tools]
347 false.whatever=
347 false.whatever=
348 true.priority=1
348 true.priority=1
349 true.executable=cat
349 true.executable=cat
350 # hg update -C 1
350 # hg update -C 1
351 $ hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=nonexistentmergetool
351 $ hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=nonexistentmergetool
352 couldn't find merge tool true specified for f
352 couldn't find merge tool true specified for f
353 merging f
353 merging f
354 couldn't find merge tool true specified for f
354 merging f failed!
355 merging f failed!
355 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
356 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
356 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
357 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
357 [1]
358 [1]
358 $ aftermerge
359 $ aftermerge
359 # cat f
360 # cat f
360 revision 1
361 revision 1
361 space
362 space
362 # hg stat
363 # hg stat
363 M f
364 M f
364 ? f.orig
365 ? f.orig
365
366
366 merge-patterns specifies executable with bogus path and gets warning:
367 merge-patterns specifies executable with bogus path and gets warning:
367
368
368 $ beforemerge
369 $ beforemerge
369 [merge-tools]
370 [merge-tools]
370 false.whatever=
371 false.whatever=
371 true.priority=1
372 true.priority=1
372 true.executable=cat
373 true.executable=cat
373 # hg update -C 1
374 # hg update -C 1
374 $ hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=/nonexistent/mergetool
375 $ hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=/nonexistent/mergetool
375 couldn't find merge tool true specified for f
376 couldn't find merge tool true specified for f
376 merging f
377 merging f
378 couldn't find merge tool true specified for f
377 merging f failed!
379 merging f failed!
378 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
380 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
379 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
381 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
380 [1]
382 [1]
381 $ aftermerge
383 $ aftermerge
382 # cat f
384 # cat f
383 revision 1
385 revision 1
384 space
386 space
385 # hg stat
387 # hg stat
386 M f
388 M f
387 ? f.orig
389 ? f.orig
388
390
389 ui.merge overrules priority
391 ui.merge overrules priority
390
392
391 ui.merge specifies false:
393 ui.merge specifies false:
392
394
393 $ beforemerge
395 $ beforemerge
394 [merge-tools]
396 [merge-tools]
395 false.whatever=
397 false.whatever=
396 true.priority=1
398 true.priority=1
397 true.executable=cat
399 true.executable=cat
398 # hg update -C 1
400 # hg update -C 1
399 $ hg merge -r 2 --config ui.merge=false
401 $ hg merge -r 2 --config ui.merge=false
400 merging f
402 merging f
401 merging f failed!
403 merging f failed!
402 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
404 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
403 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
405 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
404 [1]
406 [1]
405 $ aftermerge
407 $ aftermerge
406 # cat f
408 # cat f
407 revision 1
409 revision 1
408 space
410 space
409 # hg stat
411 # hg stat
410 M f
412 M f
411 ? f.orig
413 ? f.orig
412
414
413 ui.merge specifies internal:fail:
415 ui.merge specifies internal:fail:
414
416
415 $ beforemerge
417 $ beforemerge
416 [merge-tools]
418 [merge-tools]
417 false.whatever=
419 false.whatever=
418 true.priority=1
420 true.priority=1
419 true.executable=cat
421 true.executable=cat
420 # hg update -C 1
422 # hg update -C 1
421 $ hg merge -r 2 --config ui.merge=internal:fail
423 $ hg merge -r 2 --config ui.merge=internal:fail
422 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
424 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
423 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
425 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
424 [1]
426 [1]
425 $ aftermerge
427 $ aftermerge
426 # cat f
428 # cat f
427 revision 1
429 revision 1
428 space
430 space
429 # hg stat
431 # hg stat
430 M f
432 M f
431
433
432 ui.merge specifies :local (without internal prefix):
434 ui.merge specifies :local (without internal prefix):
433
435
434 $ beforemerge
436 $ beforemerge
435 [merge-tools]
437 [merge-tools]
436 false.whatever=
438 false.whatever=
437 true.priority=1
439 true.priority=1
438 true.executable=cat
440 true.executable=cat
439 # hg update -C 1
441 # hg update -C 1
440 $ hg merge -r 2 --config ui.merge=:local
442 $ hg merge -r 2 --config ui.merge=:local
441 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
443 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
442 (branch merge, don't forget to commit)
444 (branch merge, don't forget to commit)
443 $ aftermerge
445 $ aftermerge
444 # cat f
446 # cat f
445 revision 1
447 revision 1
446 space
448 space
447 # hg stat
449 # hg stat
448 M f
450 M f
449
451
450 ui.merge specifies internal:other:
452 ui.merge specifies internal:other:
451
453
452 $ beforemerge
454 $ beforemerge
453 [merge-tools]
455 [merge-tools]
454 false.whatever=
456 false.whatever=
455 true.priority=1
457 true.priority=1
456 true.executable=cat
458 true.executable=cat
457 # hg update -C 1
459 # hg update -C 1
458 $ hg merge -r 2 --config ui.merge=internal:other
460 $ hg merge -r 2 --config ui.merge=internal:other
459 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
461 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
460 (branch merge, don't forget to commit)
462 (branch merge, don't forget to commit)
461 $ aftermerge
463 $ aftermerge
462 # cat f
464 # cat f
463 revision 2
465 revision 2
464 space
466 space
465 # hg stat
467 # hg stat
466 M f
468 M f
467
469
468 ui.merge specifies internal:prompt:
470 ui.merge specifies internal:prompt:
469
471
470 $ beforemerge
472 $ beforemerge
471 [merge-tools]
473 [merge-tools]
472 false.whatever=
474 false.whatever=
473 true.priority=1
475 true.priority=1
474 true.executable=cat
476 true.executable=cat
475 # hg update -C 1
477 # hg update -C 1
476 $ hg merge -r 2 --config ui.merge=internal:prompt
478 $ hg merge -r 2 --config ui.merge=internal:prompt
477 no tool found to merge f
479 no tool found to merge f
478 keep (l)ocal or take (o)ther? l
480 keep (l)ocal or take (o)ther? l
479 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
481 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
480 (branch merge, don't forget to commit)
482 (branch merge, don't forget to commit)
481 $ aftermerge
483 $ aftermerge
482 # cat f
484 # cat f
483 revision 1
485 revision 1
484 space
486 space
485 # hg stat
487 # hg stat
486 M f
488 M f
487
489
488 ui.merge specifies internal:dump:
490 ui.merge specifies internal:dump:
489
491
490 $ beforemerge
492 $ beforemerge
491 [merge-tools]
493 [merge-tools]
492 false.whatever=
494 false.whatever=
493 true.priority=1
495 true.priority=1
494 true.executable=cat
496 true.executable=cat
495 # hg update -C 1
497 # hg update -C 1
496 $ hg merge -r 2 --config ui.merge=internal:dump
498 $ hg merge -r 2 --config ui.merge=internal:dump
497 merging f
499 merging f
498 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
500 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
499 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
501 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
500 [1]
502 [1]
501 $ aftermerge
503 $ aftermerge
502 # cat f
504 # cat f
503 revision 1
505 revision 1
504 space
506 space
505 # hg stat
507 # hg stat
506 M f
508 M f
507 ? f.base
509 ? f.base
508 ? f.local
510 ? f.local
509 ? f.orig
511 ? f.orig
510 ? f.other
512 ? f.other
511
513
512 f.base:
514 f.base:
513
515
514 $ cat f.base
516 $ cat f.base
515 revision 0
517 revision 0
516 space
518 space
517
519
518 f.local:
520 f.local:
519
521
520 $ cat f.local
522 $ cat f.local
521 revision 1
523 revision 1
522 space
524 space
523
525
524 f.other:
526 f.other:
525
527
526 $ cat f.other
528 $ cat f.other
527 revision 2
529 revision 2
528 space
530 space
529 $ rm f.base f.local f.other
531 $ rm f.base f.local f.other
530
532
531 ui.merge specifies internal:other but is overruled by pattern for false:
533 ui.merge specifies internal:other but is overruled by pattern for false:
532
534
533 $ beforemerge
535 $ beforemerge
534 [merge-tools]
536 [merge-tools]
535 false.whatever=
537 false.whatever=
536 true.priority=1
538 true.priority=1
537 true.executable=cat
539 true.executable=cat
538 # hg update -C 1
540 # hg update -C 1
539 $ hg merge -r 2 --config ui.merge=internal:other --config merge-patterns.f=false
541 $ hg merge -r 2 --config ui.merge=internal:other --config merge-patterns.f=false
540 merging f
542 merging f
541 merging f failed!
543 merging f failed!
542 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
544 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
543 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
545 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
544 [1]
546 [1]
545 $ aftermerge
547 $ aftermerge
546 # cat f
548 # cat f
547 revision 1
549 revision 1
548 space
550 space
549 # hg stat
551 # hg stat
550 M f
552 M f
551 ? f.orig
553 ? f.orig
552
554
553 Premerge
555 Premerge
554
556
555 ui.merge specifies internal:other but is overruled by --tool=false
557 ui.merge specifies internal:other but is overruled by --tool=false
556
558
557 $ beforemerge
559 $ beforemerge
558 [merge-tools]
560 [merge-tools]
559 false.whatever=
561 false.whatever=
560 true.priority=1
562 true.priority=1
561 true.executable=cat
563 true.executable=cat
562 # hg update -C 1
564 # hg update -C 1
563 $ hg merge -r 2 --config ui.merge=internal:other --tool=false
565 $ hg merge -r 2 --config ui.merge=internal:other --tool=false
564 merging f
566 merging f
565 merging f failed!
567 merging f failed!
566 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
568 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
567 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
569 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
568 [1]
570 [1]
569 $ aftermerge
571 $ aftermerge
570 # cat f
572 # cat f
571 revision 1
573 revision 1
572 space
574 space
573 # hg stat
575 # hg stat
574 M f
576 M f
575 ? f.orig
577 ? f.orig
576
578
577 HGMERGE specifies internal:other but is overruled by --tool=false
579 HGMERGE specifies internal:other but is overruled by --tool=false
578
580
579 $ HGMERGE=internal:other ; export HGMERGE
581 $ HGMERGE=internal:other ; export HGMERGE
580 $ beforemerge
582 $ beforemerge
581 [merge-tools]
583 [merge-tools]
582 false.whatever=
584 false.whatever=
583 true.priority=1
585 true.priority=1
584 true.executable=cat
586 true.executable=cat
585 # hg update -C 1
587 # hg update -C 1
586 $ hg merge -r 2 --tool=false
588 $ hg merge -r 2 --tool=false
587 merging f
589 merging f
588 merging f failed!
590 merging f failed!
589 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
591 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
590 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
592 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
591 [1]
593 [1]
592 $ aftermerge
594 $ aftermerge
593 # cat f
595 # cat f
594 revision 1
596 revision 1
595 space
597 space
596 # hg stat
598 # hg stat
597 M f
599 M f
598 ? f.orig
600 ? f.orig
599
601
600 $ unset HGMERGE # make sure HGMERGE doesn't interfere with remaining tests
602 $ unset HGMERGE # make sure HGMERGE doesn't interfere with remaining tests
601
603
602 update is a merge ...
604 update is a merge ...
603
605
604 (this also tests that files reverted with '--rev REV' are treated as
606 (this also tests that files reverted with '--rev REV' are treated as
605 "modified", even if none of mode, size and timestamp of them isn't
607 "modified", even if none of mode, size and timestamp of them isn't
606 changed on the filesystem (see also issue4583))
608 changed on the filesystem (see also issue4583))
607
609
608 $ cat >> $HGRCPATH <<EOF
610 $ cat >> $HGRCPATH <<EOF
609 > [fakedirstatewritetime]
611 > [fakedirstatewritetime]
610 > # emulate invoking dirstate.write() via repo.status()
612 > # emulate invoking dirstate.write() via repo.status()
611 > # at 2000-01-01 00:00
613 > # at 2000-01-01 00:00
612 > fakenow = 200001010000
614 > fakenow = 200001010000
613 > EOF
615 > EOF
614
616
615 $ beforemerge
617 $ beforemerge
616 [merge-tools]
618 [merge-tools]
617 false.whatever=
619 false.whatever=
618 true.priority=1
620 true.priority=1
619 true.executable=cat
621 true.executable=cat
620 # hg update -C 1
622 # hg update -C 1
621 $ hg update -q 0
623 $ hg update -q 0
622 $ f -s f
624 $ f -s f
623 f: size=17
625 f: size=17
624 $ touch -t 200001010000 f
626 $ touch -t 200001010000 f
625 $ hg debugrebuildstate
627 $ hg debugrebuildstate
626 $ cat >> $HGRCPATH <<EOF
628 $ cat >> $HGRCPATH <<EOF
627 > [extensions]
629 > [extensions]
628 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
630 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
629 > EOF
631 > EOF
630 $ hg revert -q -r 1 .
632 $ hg revert -q -r 1 .
631 $ cat >> $HGRCPATH <<EOF
633 $ cat >> $HGRCPATH <<EOF
632 > [extensions]
634 > [extensions]
633 > fakedirstatewritetime = !
635 > fakedirstatewritetime = !
634 > EOF
636 > EOF
635 $ f -s f
637 $ f -s f
636 f: size=17
638 f: size=17
637 $ touch -t 200001010000 f
639 $ touch -t 200001010000 f
638 $ hg status f
640 $ hg status f
639 M f
641 M f
640 $ hg update -r 2
642 $ hg update -r 2
641 merging f
643 merging f
642 revision 1
644 revision 1
643 space
645 space
644 revision 0
646 revision 0
645 space
647 space
646 revision 2
648 revision 2
647 space
649 space
648 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
650 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
649 $ aftermerge
651 $ aftermerge
650 # cat f
652 # cat f
651 revision 1
653 revision 1
652 space
654 space
653 # hg stat
655 # hg stat
654 M f
656 M f
655
657
656 update should also have --tool
658 update should also have --tool
657
659
658 $ beforemerge
660 $ beforemerge
659 [merge-tools]
661 [merge-tools]
660 false.whatever=
662 false.whatever=
661 true.priority=1
663 true.priority=1
662 true.executable=cat
664 true.executable=cat
663 # hg update -C 1
665 # hg update -C 1
664 $ hg update -q 0
666 $ hg update -q 0
665 $ f -s f
667 $ f -s f
666 f: size=17
668 f: size=17
667 $ touch -t 200001010000 f
669 $ touch -t 200001010000 f
668 $ hg debugrebuildstate
670 $ hg debugrebuildstate
669 $ cat >> $HGRCPATH <<EOF
671 $ cat >> $HGRCPATH <<EOF
670 > [extensions]
672 > [extensions]
671 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
673 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
672 > EOF
674 > EOF
673 $ hg revert -q -r 1 .
675 $ hg revert -q -r 1 .
674 $ cat >> $HGRCPATH <<EOF
676 $ cat >> $HGRCPATH <<EOF
675 > [extensions]
677 > [extensions]
676 > fakedirstatewritetime = !
678 > fakedirstatewritetime = !
677 > EOF
679 > EOF
678 $ f -s f
680 $ f -s f
679 f: size=17
681 f: size=17
680 $ touch -t 200001010000 f
682 $ touch -t 200001010000 f
681 $ hg status f
683 $ hg status f
682 M f
684 M f
683 $ hg update -r 2 --tool false
685 $ hg update -r 2 --tool false
684 merging f
686 merging f
685 merging f failed!
687 merging f failed!
686 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
688 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
687 use 'hg resolve' to retry unresolved file merges
689 use 'hg resolve' to retry unresolved file merges
688 [1]
690 [1]
689 $ aftermerge
691 $ aftermerge
690 # cat f
692 # cat f
691 revision 1
693 revision 1
692 space
694 space
693 # hg stat
695 # hg stat
694 M f
696 M f
695 ? f.orig
697 ? f.orig
696
698
697 Default is silent simplemerge:
699 Default is silent simplemerge:
698
700
699 $ beforemerge
701 $ beforemerge
700 [merge-tools]
702 [merge-tools]
701 false.whatever=
703 false.whatever=
702 true.priority=1
704 true.priority=1
703 true.executable=cat
705 true.executable=cat
704 # hg update -C 1
706 # hg update -C 1
705 $ hg merge -r 3
707 $ hg merge -r 3
706 merging f
708 merging f
707 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
709 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
708 (branch merge, don't forget to commit)
710 (branch merge, don't forget to commit)
709 $ aftermerge
711 $ aftermerge
710 # cat f
712 # cat f
711 revision 1
713 revision 1
712 space
714 space
713 revision 3
715 revision 3
714 # hg stat
716 # hg stat
715 M f
717 M f
716
718
717 .premerge=True is same:
719 .premerge=True is same:
718
720
719 $ beforemerge
721 $ beforemerge
720 [merge-tools]
722 [merge-tools]
721 false.whatever=
723 false.whatever=
722 true.priority=1
724 true.priority=1
723 true.executable=cat
725 true.executable=cat
724 # hg update -C 1
726 # hg update -C 1
725 $ hg merge -r 3 --config merge-tools.true.premerge=True
727 $ hg merge -r 3 --config merge-tools.true.premerge=True
726 merging f
728 merging f
727 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
729 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
728 (branch merge, don't forget to commit)
730 (branch merge, don't forget to commit)
729 $ aftermerge
731 $ aftermerge
730 # cat f
732 # cat f
731 revision 1
733 revision 1
732 space
734 space
733 revision 3
735 revision 3
734 # hg stat
736 # hg stat
735 M f
737 M f
736
738
737 .premerge=False executes merge-tool:
739 .premerge=False executes merge-tool:
738
740
739 $ beforemerge
741 $ beforemerge
740 [merge-tools]
742 [merge-tools]
741 false.whatever=
743 false.whatever=
742 true.priority=1
744 true.priority=1
743 true.executable=cat
745 true.executable=cat
744 # hg update -C 1
746 # hg update -C 1
745 $ hg merge -r 3 --config merge-tools.true.premerge=False
747 $ hg merge -r 3 --config merge-tools.true.premerge=False
746 merging f
748 merging f
747 revision 1
749 revision 1
748 space
750 space
749 revision 0
751 revision 0
750 space
752 space
751 revision 0
753 revision 0
752 space
754 space
753 revision 3
755 revision 3
754 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
756 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
755 (branch merge, don't forget to commit)
757 (branch merge, don't forget to commit)
756 $ aftermerge
758 $ aftermerge
757 # cat f
759 # cat f
758 revision 1
760 revision 1
759 space
761 space
760 # hg stat
762 # hg stat
761 M f
763 M f
762
764
763 premerge=keep keeps conflict markers in:
765 premerge=keep keeps conflict markers in:
764
766
765 $ beforemerge
767 $ beforemerge
766 [merge-tools]
768 [merge-tools]
767 false.whatever=
769 false.whatever=
768 true.priority=1
770 true.priority=1
769 true.executable=cat
771 true.executable=cat
770 # hg update -C 1
772 # hg update -C 1
771 $ hg merge -r 4 --config merge-tools.true.premerge=keep
773 $ hg merge -r 4 --config merge-tools.true.premerge=keep
772 merging f
774 merging f
773 <<<<<<< local: ef83787e2614 - test: revision 1
775 <<<<<<< local: ef83787e2614 - test: revision 1
774 revision 1
776 revision 1
775 space
777 space
776 =======
778 =======
777 revision 4
779 revision 4
778 >>>>>>> other: 81448d39c9a0 - test: revision 4
780 >>>>>>> other: 81448d39c9a0 - test: revision 4
779 revision 0
781 revision 0
780 space
782 space
781 revision 4
783 revision 4
782 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
784 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
783 (branch merge, don't forget to commit)
785 (branch merge, don't forget to commit)
784 $ aftermerge
786 $ aftermerge
785 # cat f
787 # cat f
786 <<<<<<< local: ef83787e2614 - test: revision 1
788 <<<<<<< local: ef83787e2614 - test: revision 1
787 revision 1
789 revision 1
788 space
790 space
789 =======
791 =======
790 revision 4
792 revision 4
791 >>>>>>> other: 81448d39c9a0 - test: revision 4
793 >>>>>>> other: 81448d39c9a0 - test: revision 4
792 # hg stat
794 # hg stat
793 M f
795 M f
794
796
795 premerge=keep-merge3 keeps conflict markers with base content:
797 premerge=keep-merge3 keeps conflict markers with base content:
796
798
797 $ beforemerge
799 $ beforemerge
798 [merge-tools]
800 [merge-tools]
799 false.whatever=
801 false.whatever=
800 true.priority=1
802 true.priority=1
801 true.executable=cat
803 true.executable=cat
802 # hg update -C 1
804 # hg update -C 1
803 $ hg merge -r 4 --config merge-tools.true.premerge=keep-merge3
805 $ hg merge -r 4 --config merge-tools.true.premerge=keep-merge3
804 merging f
806 merging f
805 <<<<<<< local: ef83787e2614 - test: revision 1
807 <<<<<<< local: ef83787e2614 - test: revision 1
806 revision 1
808 revision 1
807 space
809 space
808 ||||||| base
810 ||||||| base
809 revision 0
811 revision 0
810 space
812 space
811 =======
813 =======
812 revision 4
814 revision 4
813 >>>>>>> other: 81448d39c9a0 - test: revision 4
815 >>>>>>> other: 81448d39c9a0 - test: revision 4
814 revision 0
816 revision 0
815 space
817 space
816 revision 4
818 revision 4
817 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
819 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
818 (branch merge, don't forget to commit)
820 (branch merge, don't forget to commit)
819 $ aftermerge
821 $ aftermerge
820 # cat f
822 # cat f
821 <<<<<<< local: ef83787e2614 - test: revision 1
823 <<<<<<< local: ef83787e2614 - test: revision 1
822 revision 1
824 revision 1
823 space
825 space
824 ||||||| base
826 ||||||| base
825 revision 0
827 revision 0
826 space
828 space
827 =======
829 =======
828 revision 4
830 revision 4
829 >>>>>>> other: 81448d39c9a0 - test: revision 4
831 >>>>>>> other: 81448d39c9a0 - test: revision 4
830 # hg stat
832 # hg stat
831 M f
833 M f
832
834
833
835
834 Tool execution
836 Tool execution
835
837
836 set tools.args explicit to include $base $local $other $output:
838 set tools.args explicit to include $base $local $other $output:
837
839
838 $ beforemerge
840 $ beforemerge
839 [merge-tools]
841 [merge-tools]
840 false.whatever=
842 false.whatever=
841 true.priority=1
843 true.priority=1
842 true.executable=cat
844 true.executable=cat
843 # hg update -C 1
845 # hg update -C 1
844 $ hg merge -r 2 --config merge-tools.true.executable=head --config merge-tools.true.args='$base $local $other $output' \
846 $ hg merge -r 2 --config merge-tools.true.executable=head --config merge-tools.true.args='$base $local $other $output' \
845 > | sed 's,==> .* <==,==> ... <==,g'
847 > | sed 's,==> .* <==,==> ... <==,g'
846 merging f
848 merging f
847 ==> ... <==
849 ==> ... <==
848 revision 0
850 revision 0
849 space
851 space
850
852
851 ==> ... <==
853 ==> ... <==
852 revision 1
854 revision 1
853 space
855 space
854
856
855 ==> ... <==
857 ==> ... <==
856 revision 2
858 revision 2
857 space
859 space
858
860
859 ==> ... <==
861 ==> ... <==
860 revision 1
862 revision 1
861 space
863 space
862 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
864 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
863 (branch merge, don't forget to commit)
865 (branch merge, don't forget to commit)
864 $ aftermerge
866 $ aftermerge
865 # cat f
867 # cat f
866 revision 1
868 revision 1
867 space
869 space
868 # hg stat
870 # hg stat
869 M f
871 M f
870
872
871 Merge with "echo mergeresult > $local":
873 Merge with "echo mergeresult > $local":
872
874
873 $ beforemerge
875 $ beforemerge
874 [merge-tools]
876 [merge-tools]
875 false.whatever=
877 false.whatever=
876 true.priority=1
878 true.priority=1
877 true.executable=cat
879 true.executable=cat
878 # hg update -C 1
880 # hg update -C 1
879 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $local'
881 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $local'
880 merging f
882 merging f
881 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
883 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
882 (branch merge, don't forget to commit)
884 (branch merge, don't forget to commit)
883 $ aftermerge
885 $ aftermerge
884 # cat f
886 # cat f
885 mergeresult
887 mergeresult
886 # hg stat
888 # hg stat
887 M f
889 M f
888
890
889 - and $local is the file f:
891 - and $local is the file f:
890
892
891 $ beforemerge
893 $ beforemerge
892 [merge-tools]
894 [merge-tools]
893 false.whatever=
895 false.whatever=
894 true.priority=1
896 true.priority=1
895 true.executable=cat
897 true.executable=cat
896 # hg update -C 1
898 # hg update -C 1
897 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > f'
899 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > f'
898 merging f
900 merging f
899 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
901 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
900 (branch merge, don't forget to commit)
902 (branch merge, don't forget to commit)
901 $ aftermerge
903 $ aftermerge
902 # cat f
904 # cat f
903 mergeresult
905 mergeresult
904 # hg stat
906 # hg stat
905 M f
907 M f
906
908
907 Merge with "echo mergeresult > $output" - the variable is a bit magic:
909 Merge with "echo mergeresult > $output" - the variable is a bit magic:
908
910
909 $ beforemerge
911 $ beforemerge
910 [merge-tools]
912 [merge-tools]
911 false.whatever=
913 false.whatever=
912 true.priority=1
914 true.priority=1
913 true.executable=cat
915 true.executable=cat
914 # hg update -C 1
916 # hg update -C 1
915 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $output'
917 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $output'
916 merging f
918 merging f
917 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
919 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
918 (branch merge, don't forget to commit)
920 (branch merge, don't forget to commit)
919 $ aftermerge
921 $ aftermerge
920 # cat f
922 # cat f
921 mergeresult
923 mergeresult
922 # hg stat
924 # hg stat
923 M f
925 M f
924
926
925 Merge using tool with a path that must be quoted:
927 Merge using tool with a path that must be quoted:
926
928
927 $ beforemerge
929 $ beforemerge
928 [merge-tools]
930 [merge-tools]
929 false.whatever=
931 false.whatever=
930 true.priority=1
932 true.priority=1
931 true.executable=cat
933 true.executable=cat
932 # hg update -C 1
934 # hg update -C 1
933 $ cat <<EOF > 'my merge tool'
935 $ cat <<EOF > 'my merge tool'
934 > cat "\$1" "\$2" "\$3" > "\$4"
936 > cat "\$1" "\$2" "\$3" > "\$4"
935 > EOF
937 > EOF
936 $ hg --config merge-tools.true.executable='sh' \
938 $ hg --config merge-tools.true.executable='sh' \
937 > --config merge-tools.true.args='"./my merge tool" $base $local $other $output' \
939 > --config merge-tools.true.args='"./my merge tool" $base $local $other $output' \
938 > merge -r 2
940 > merge -r 2
939 merging f
941 merging f
940 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
942 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
941 (branch merge, don't forget to commit)
943 (branch merge, don't forget to commit)
942 $ rm -f 'my merge tool'
944 $ rm -f 'my merge tool'
943 $ aftermerge
945 $ aftermerge
944 # cat f
946 # cat f
945 revision 0
947 revision 0
946 space
948 space
947 revision 1
949 revision 1
948 space
950 space
949 revision 2
951 revision 2
950 space
952 space
951 # hg stat
953 # hg stat
952 M f
954 M f
953
955
954 Issue3581: Merging a filename that needs to be quoted
956 Issue3581: Merging a filename that needs to be quoted
955 (This test doesn't work on Windows filesystems even on Linux, so check
957 (This test doesn't work on Windows filesystems even on Linux, so check
956 for Unix-like permission)
958 for Unix-like permission)
957
959
958 #if unix-permissions
960 #if unix-permissions
959 $ beforemerge
961 $ beforemerge
960 [merge-tools]
962 [merge-tools]
961 false.whatever=
963 false.whatever=
962 true.priority=1
964 true.priority=1
963 true.executable=cat
965 true.executable=cat
964 # hg update -C 1
966 # hg update -C 1
965 $ echo "revision 5" > '"; exit 1; echo "'
967 $ echo "revision 5" > '"; exit 1; echo "'
966 $ hg commit -Am "revision 5"
968 $ hg commit -Am "revision 5"
967 adding "; exit 1; echo "
969 adding "; exit 1; echo "
968 warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "'
970 warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "'
969 $ hg update -C 1 > /dev/null
971 $ hg update -C 1 > /dev/null
970 $ echo "revision 6" > '"; exit 1; echo "'
972 $ echo "revision 6" > '"; exit 1; echo "'
971 $ hg commit -Am "revision 6"
973 $ hg commit -Am "revision 6"
972 adding "; exit 1; echo "
974 adding "; exit 1; echo "
973 warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "'
975 warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "'
974 created new head
976 created new head
975 $ hg merge --config merge-tools.true.executable="true" -r 5
977 $ hg merge --config merge-tools.true.executable="true" -r 5
976 merging "; exit 1; echo "
978 merging "; exit 1; echo "
977 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
979 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
978 (branch merge, don't forget to commit)
980 (branch merge, don't forget to commit)
979 $ hg update -C 1 > /dev/null
981 $ hg update -C 1 > /dev/null
980 #endif
982 #endif
981
983
982 Merge post-processing
984 Merge post-processing
983
985
984 cat is a bad merge-tool and doesn't change:
986 cat is a bad merge-tool and doesn't change:
985
987
986 $ beforemerge
988 $ beforemerge
987 [merge-tools]
989 [merge-tools]
988 false.whatever=
990 false.whatever=
989 true.priority=1
991 true.priority=1
990 true.executable=cat
992 true.executable=cat
991 # hg update -C 1
993 # hg update -C 1
992 $ hg merge -y -r 2 --config merge-tools.true.checkchanged=1
994 $ hg merge -y -r 2 --config merge-tools.true.checkchanged=1
993 merging f
995 merging f
994 revision 1
996 revision 1
995 space
997 space
996 revision 0
998 revision 0
997 space
999 space
998 revision 2
1000 revision 2
999 space
1001 space
1000 output file f appears unchanged
1002 output file f appears unchanged
1001 was merge successful (yn)? n
1003 was merge successful (yn)? n
1002 merging f failed!
1004 merging f failed!
1003 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1005 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1004 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1006 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1005 [1]
1007 [1]
1006 $ aftermerge
1008 $ aftermerge
1007 # cat f
1009 # cat f
1008 revision 1
1010 revision 1
1009 space
1011 space
1010 # hg stat
1012 # hg stat
1011 M f
1013 M f
1012 ? f.orig
1014 ? f.orig
1013
1015
1014 #if symlink
1016 #if symlink
1015
1017
1016 internal merge cannot handle symlinks and shouldn't try:
1018 internal merge cannot handle symlinks and shouldn't try:
1017
1019
1018 $ hg update -q -C 1
1020 $ hg update -q -C 1
1019 $ rm f
1021 $ rm f
1020 $ ln -s symlink f
1022 $ ln -s symlink f
1021 $ hg commit -qm 'f is symlink'
1023 $ hg commit -qm 'f is symlink'
1022 $ hg merge -r 2 --tool internal:merge
1024 $ hg merge -r 2 --tool internal:merge
1023 merging f
1025 merging f
1024 warning: internal :merge cannot merge symlinks for f
1026 warning: internal :merge cannot merge symlinks for f
1025 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
1027 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
1026 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1028 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1027 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1029 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1028 [1]
1030 [1]
1029
1031
1030 #endif
1032 #endif
@@ -1,147 +1,149 b''
1 initial
1 initial
2 $ hg init test-a
2 $ hg init test-a
3 $ cd test-a
3 $ cd test-a
4 $ cat >test.txt <<"EOF"
4 $ cat >test.txt <<"EOF"
5 > 1
5 > 1
6 > 2
6 > 2
7 > 3
7 > 3
8 > EOF
8 > EOF
9 $ hg add test.txt
9 $ hg add test.txt
10 $ hg commit -m "Initial"
10 $ hg commit -m "Initial"
11
11
12 clone
12 clone
13 $ cd ..
13 $ cd ..
14 $ hg clone test-a test-b
14 $ hg clone test-a test-b
15 updating to branch default
15 updating to branch default
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17
17
18 change test-a
18 change test-a
19 $ cd test-a
19 $ cd test-a
20 $ cat >test.txt <<"EOF"
20 $ cat >test.txt <<"EOF"
21 > one
21 > one
22 > two
22 > two
23 > three
23 > three
24 > EOF
24 > EOF
25 $ hg commit -m "Numbers as words"
25 $ hg commit -m "Numbers as words"
26
26
27 change test-b
27 change test-b
28 $ cd ../test-b
28 $ cd ../test-b
29 $ cat >test.txt <<"EOF"
29 $ cat >test.txt <<"EOF"
30 > 1
30 > 1
31 > 2.5
31 > 2.5
32 > 3
32 > 3
33 > EOF
33 > EOF
34 $ hg commit -m "2 -> 2.5"
34 $ hg commit -m "2 -> 2.5"
35
35
36 now pull and merge from test-a
36 now pull and merge from test-a
37 $ hg pull ../test-a
37 $ hg pull ../test-a
38 pulling from ../test-a
38 pulling from ../test-a
39 searching for changes
39 searching for changes
40 adding changesets
40 adding changesets
41 adding manifests
41 adding manifests
42 adding file changes
42 adding file changes
43 added 1 changesets with 1 changes to 1 files (+1 heads)
43 added 1 changesets with 1 changes to 1 files (+1 heads)
44 (run 'hg heads' to see heads, 'hg merge' to merge)
44 (run 'hg heads' to see heads, 'hg merge' to merge)
45 $ hg merge
45 $ hg merge
46 merging test.txt
46 merging test.txt
47 warning: conflicts during merge.
47 warning: conflicts during merge.
48 merging test.txt incomplete! (edit conflicts, then use 'hg resolve --mark')
48 merging test.txt incomplete! (edit conflicts, then use 'hg resolve --mark')
49 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
49 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
50 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
50 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
51 [1]
51 [1]
52 resolve conflict
52 resolve conflict
53 $ cat >test.txt <<"EOF"
53 $ cat >test.txt <<"EOF"
54 > one
54 > one
55 > two-point-five
55 > two-point-five
56 > three
56 > three
57 > EOF
57 > EOF
58 $ rm -f *.orig
58 $ rm -f *.orig
59 $ hg resolve -m test.txt
59 $ hg resolve -m test.txt
60 (no more unresolved files)
60 (no more unresolved files)
61 $ hg commit -m "Merge 1"
61 $ hg commit -m "Merge 1"
62
62
63 change test-a again
63 change test-a again
64 $ cd ../test-a
64 $ cd ../test-a
65 $ cat >test.txt <<"EOF"
65 $ cat >test.txt <<"EOF"
66 > one
66 > one
67 > two-point-one
67 > two-point-one
68 > three
68 > three
69 > EOF
69 > EOF
70 $ hg commit -m "two -> two-point-one"
70 $ hg commit -m "two -> two-point-one"
71
71
72 pull and merge from test-a again
72 pull and merge from test-a again
73 $ cd ../test-b
73 $ cd ../test-b
74 $ hg pull ../test-a
74 $ hg pull ../test-a
75 pulling from ../test-a
75 pulling from ../test-a
76 searching for changes
76 searching for changes
77 adding changesets
77 adding changesets
78 adding manifests
78 adding manifests
79 adding file changes
79 adding file changes
80 added 1 changesets with 1 changes to 1 files (+1 heads)
80 added 1 changesets with 1 changes to 1 files (+1 heads)
81 (run 'hg heads' to see heads, 'hg merge' to merge)
81 (run 'hg heads' to see heads, 'hg merge' to merge)
82 $ hg merge --debug
82 $ hg merge --debug
83 searching for copies back to rev 1
83 searching for copies back to rev 1
84 resolving manifests
84 resolving manifests
85 branchmerge: True, force: False, partial: False
85 branchmerge: True, force: False, partial: False
86 ancestor: 96b70246a118, local: 50c3a7e29886+, remote: 40d11a4173a8
86 ancestor: 96b70246a118, local: 50c3a7e29886+, remote: 40d11a4173a8
87 preserving test.txt for resolve of test.txt
87 preserving test.txt for resolve of test.txt
88 test.txt: versions differ -> m
88 test.txt: versions differ -> m
89 picked tool ':merge' for test.txt (binary False symlink False)
89 picked tool ':merge' for test.txt (binary False symlink False)
90 merging test.txt
90 merging test.txt
91 my test.txt@50c3a7e29886+ other test.txt@40d11a4173a8 ancestor test.txt@96b70246a118
91 my test.txt@50c3a7e29886+ other test.txt@40d11a4173a8 ancestor test.txt@96b70246a118
92 picked tool ':merge' for test.txt (binary False symlink False)
93 my test.txt@50c3a7e29886+ other test.txt@40d11a4173a8 ancestor test.txt@96b70246a118
92 warning: conflicts during merge.
94 warning: conflicts during merge.
93 merging test.txt incomplete! (edit conflicts, then use 'hg resolve --mark')
95 merging test.txt incomplete! (edit conflicts, then use 'hg resolve --mark')
94 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
96 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
95 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
97 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
96 [1]
98 [1]
97
99
98 $ cat test.txt
100 $ cat test.txt
99 one
101 one
100 <<<<<<< local: 50c3a7e29886 - test: Merge 1
102 <<<<<<< local: 50c3a7e29886 - test: Merge 1
101 two-point-five
103 two-point-five
102 =======
104 =======
103 two-point-one
105 two-point-one
104 >>>>>>> other: 40d11a4173a8 - test: two -> two-point-one
106 >>>>>>> other: 40d11a4173a8 - test: two -> two-point-one
105 three
107 three
106
108
107 $ hg debugindex test.txt
109 $ hg debugindex test.txt
108 rev offset length ..... linkrev nodeid p1 p2 (re)
110 rev offset length ..... linkrev nodeid p1 p2 (re)
109 0 0 7 ..... 0 01365c4cca56 000000000000 000000000000 (re)
111 0 0 7 ..... 0 01365c4cca56 000000000000 000000000000 (re)
110 1 7 9 ..... 1 7b013192566a 01365c4cca56 000000000000 (re)
112 1 7 9 ..... 1 7b013192566a 01365c4cca56 000000000000 (re)
111 2 16 15 ..... 2 8fe46a3eb557 01365c4cca56 000000000000 (re)
113 2 16 15 ..... 2 8fe46a3eb557 01365c4cca56 000000000000 (re)
112 3 31 2. ..... 3 fc3148072371 7b013192566a 8fe46a3eb557 (re)
114 3 31 2. ..... 3 fc3148072371 7b013192566a 8fe46a3eb557 (re)
113 4 5. 25 ..... 4 d40249267ae3 8fe46a3eb557 000000000000 (re)
115 4 5. 25 ..... 4 d40249267ae3 8fe46a3eb557 000000000000 (re)
114
116
115 $ hg log
117 $ hg log
116 changeset: 4:40d11a4173a8
118 changeset: 4:40d11a4173a8
117 tag: tip
119 tag: tip
118 parent: 2:96b70246a118
120 parent: 2:96b70246a118
119 user: test
121 user: test
120 date: Thu Jan 01 00:00:00 1970 +0000
122 date: Thu Jan 01 00:00:00 1970 +0000
121 summary: two -> two-point-one
123 summary: two -> two-point-one
122
124
123 changeset: 3:50c3a7e29886
125 changeset: 3:50c3a7e29886
124 parent: 1:d1e159716d41
126 parent: 1:d1e159716d41
125 parent: 2:96b70246a118
127 parent: 2:96b70246a118
126 user: test
128 user: test
127 date: Thu Jan 01 00:00:00 1970 +0000
129 date: Thu Jan 01 00:00:00 1970 +0000
128 summary: Merge 1
130 summary: Merge 1
129
131
130 changeset: 2:96b70246a118
132 changeset: 2:96b70246a118
131 parent: 0:b1832b9d912a
133 parent: 0:b1832b9d912a
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: Numbers as words
136 summary: Numbers as words
135
137
136 changeset: 1:d1e159716d41
138 changeset: 1:d1e159716d41
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: 2 -> 2.5
141 summary: 2 -> 2.5
140
142
141 changeset: 0:b1832b9d912a
143 changeset: 0:b1832b9d912a
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: Initial
146 summary: Initial
145
147
146
148
147 $ cd ..
149 $ cd ..
@@ -1,975 +1,1039 b''
1
1
2 $ mkdir -p t
2 $ mkdir -p t
3 $ cd t
3 $ cd t
4 $ cat <<EOF > merge
4 $ cat <<EOF > merge
5 > import sys, os
5 > import sys, os
6 > f = open(sys.argv[1], "wb")
6 > f = open(sys.argv[1], "wb")
7 > f.write("merge %s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
7 > f.write("merge %s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
8 > f.close()
8 > f.close()
9 > EOF
9 > EOF
10
10
11 perform a test merge with possible renaming
11 perform a test merge with possible renaming
12 args:
12 args:
13 $1 = action in local branch
13 $1 = action in local branch
14 $2 = action in remote branch
14 $2 = action in remote branch
15 $3 = action in working dir
15 $3 = action in working dir
16 $4 = expected result
16 $4 = expected result
17
17
18 $ tm()
18 $ tm()
19 > {
19 > {
20 > hg init t
20 > hg init t
21 > cd t
21 > cd t
22 > echo "[merge]" >> .hg/hgrc
22 > echo "[merge]" >> .hg/hgrc
23 > echo "followcopies = 1" >> .hg/hgrc
23 > echo "followcopies = 1" >> .hg/hgrc
24 >
24 >
25 > # base
25 > # base
26 > echo base > a
26 > echo base > a
27 > echo base > rev # used to force commits
27 > echo base > rev # used to force commits
28 > hg add a rev
28 > hg add a rev
29 > hg ci -m "base"
29 > hg ci -m "base"
30 >
30 >
31 > # remote
31 > # remote
32 > echo remote > rev
32 > echo remote > rev
33 > if [ "$2" != "" ] ; then $2 ; fi
33 > if [ "$2" != "" ] ; then $2 ; fi
34 > hg ci -m "remote"
34 > hg ci -m "remote"
35 >
35 >
36 > # local
36 > # local
37 > hg co -q 0
37 > hg co -q 0
38 > echo local > rev
38 > echo local > rev
39 > if [ "$1" != "" ] ; then $1 ; fi
39 > if [ "$1" != "" ] ; then $1 ; fi
40 > hg ci -m "local"
40 > hg ci -m "local"
41 >
41 >
42 > # working dir
42 > # working dir
43 > echo local > rev
43 > echo local > rev
44 > if [ "$3" != "" ] ; then $3 ; fi
44 > if [ "$3" != "" ] ; then $3 ; fi
45 >
45 >
46 > # merge
46 > # merge
47 > echo "--------------"
47 > echo "--------------"
48 > echo "test L:$1 R:$2 W:$3 - $4"
48 > echo "test L:$1 R:$2 W:$3 - $4"
49 > echo "--------------"
49 > echo "--------------"
50 > hg merge -y --debug --traceback --tool="python ../merge"
50 > hg merge -y --debug --traceback --tool="python ../merge"
51 >
51 >
52 > echo "--------------"
52 > echo "--------------"
53 > hg status -camC -X rev
53 > hg status -camC -X rev
54 >
54 >
55 > hg ci -m "merge"
55 > hg ci -m "merge"
56 >
56 >
57 > echo "--------------"
57 > echo "--------------"
58 > echo
58 > echo
59 >
59 >
60 > cd ..
60 > cd ..
61 > rm -r t
61 > rm -r t
62 > }
62 > }
63 $ up() {
63 $ up() {
64 > cp rev $1
64 > cp rev $1
65 > hg add $1 2> /dev/null
65 > hg add $1 2> /dev/null
66 > if [ "$2" != "" ] ; then
66 > if [ "$2" != "" ] ; then
67 > cp rev $2
67 > cp rev $2
68 > hg add $2 2> /dev/null
68 > hg add $2 2> /dev/null
69 > fi
69 > fi
70 > }
70 > }
71 $ uc() { up $1; hg cp $1 $2; } # update + copy
71 $ uc() { up $1; hg cp $1 $2; } # update + copy
72 $ um() { up $1; hg mv $1 $2; }
72 $ um() { up $1; hg mv $1 $2; }
73 $ nc() { hg cp $1 $2; } # just copy
73 $ nc() { hg cp $1 $2; } # just copy
74 $ nm() { hg mv $1 $2; } # just move
74 $ nm() { hg mv $1 $2; } # just move
75 $ tm "up a " "nc a b" " " "1 get local a to b"
75 $ tm "up a " "nc a b" " " "1 get local a to b"
76 created new head
76 created new head
77 --------------
77 --------------
78 test L:up a R:nc a b W: - 1 get local a to b
78 test L:up a R:nc a b W: - 1 get local a to b
79 --------------
79 --------------
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 b
82 b
83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
84 src: 'a' -> dst: 'b' *
84 src: 'a' -> dst: 'b' *
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: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
88 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
89 preserving a for resolve of b
89 preserving a for resolve of b
90 preserving rev for resolve of rev
90 preserving rev for resolve of rev
91 a: remote unchanged -> k
91 a: remote unchanged -> k
92 b: remote copied from a -> m
92 b: remote copied from a -> m
93 picked tool 'python ../merge' for b (binary False symlink False)
93 picked tool 'python ../merge' for b (binary False symlink False)
94 merging a and b to b
94 merging a and b to b
95 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
95 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
96 premerge successful
96 premerge successful
97 rev: versions differ -> m
97 rev: versions differ -> m
98 picked tool 'python ../merge' for rev (binary False symlink False)
98 picked tool 'python ../merge' for rev (binary False symlink False)
99 merging rev
99 merging rev
100 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
100 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
101 picked tool 'python ../merge' for rev (binary False symlink False)
102 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
101 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
103 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
102 merge tool returned: 0
104 merge tool returned: 0
103 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
105 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
104 (branch merge, don't forget to commit)
106 (branch merge, don't forget to commit)
105 --------------
107 --------------
106 M b
108 M b
107 a
109 a
108 C a
110 C a
109 --------------
111 --------------
110
112
111 $ tm "nc a b" "up a " " " "2 get rem change to a and b"
113 $ tm "nc a b" "up a " " " "2 get rem change to a and b"
112 created new head
114 created new head
113 --------------
115 --------------
114 test L:nc a b R:up a W: - 2 get rem change to a and b
116 test L:nc a b R:up a W: - 2 get rem change to a and b
115 --------------
117 --------------
116 searching for copies back to rev 1
118 searching for copies back to rev 1
117 unmatched files in local:
119 unmatched files in local:
118 b
120 b
119 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
121 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
120 src: 'a' -> dst: 'b' *
122 src: 'a' -> dst: 'b' *
121 checking for directory renames
123 checking for directory renames
122 resolving manifests
124 resolving manifests
123 branchmerge: True, force: False, partial: False
125 branchmerge: True, force: False, partial: False
124 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
126 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
125 preserving b for resolve of b
127 preserving b for resolve of b
126 preserving rev for resolve of rev
128 preserving rev for resolve of rev
127 a: remote is newer -> g
129 a: remote is newer -> g
128 getting a
130 getting a
129 b: local copied/moved from a -> m
131 b: local copied/moved from a -> m
130 picked tool 'python ../merge' for b (binary False symlink False)
132 picked tool 'python ../merge' for b (binary False symlink False)
131 merging b and a to b
133 merging b and a to b
132 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
134 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
133 premerge successful
135 premerge successful
134 rev: versions differ -> m
136 rev: versions differ -> m
135 picked tool 'python ../merge' for rev (binary False symlink False)
137 picked tool 'python ../merge' for rev (binary False symlink False)
136 merging rev
138 merging rev
137 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
139 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
138 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * (glob)
140 picked tool 'python ../merge' for rev (binary False symlink False)
141 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
142 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
139 merge tool returned: 0
143 merge tool returned: 0
140 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
144 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
141 (branch merge, don't forget to commit)
145 (branch merge, don't forget to commit)
142 --------------
146 --------------
143 M a
147 M a
144 M b
148 M b
145 a
149 a
146 --------------
150 --------------
147
151
148 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
152 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
149 created new head
153 created new head
150 --------------
154 --------------
151 test L:up a R:nm a b W: - 3 get local a change to b, remove a
155 test L:up a R:nm a b W: - 3 get local a change to b, remove a
152 --------------
156 --------------
153 searching for copies back to rev 1
157 searching for copies back to rev 1
154 unmatched files in other:
158 unmatched files in other:
155 b
159 b
156 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
160 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
157 src: 'a' -> dst: 'b' *
161 src: 'a' -> dst: 'b' *
158 checking for directory renames
162 checking for directory renames
159 resolving manifests
163 resolving manifests
160 branchmerge: True, force: False, partial: False
164 branchmerge: True, force: False, partial: False
161 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
165 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
162 preserving a for resolve of b
166 preserving a for resolve of b
163 preserving rev for resolve of rev
167 preserving rev for resolve of rev
164 removing a
168 removing a
165 b: remote moved from a -> m
169 b: remote moved from a -> m
166 picked tool 'python ../merge' for b (binary False symlink False)
170 picked tool 'python ../merge' for b (binary False symlink False)
167 merging a and b to b
171 merging a and b to b
168 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
172 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
169 premerge successful
173 premerge successful
170 rev: versions differ -> m
174 rev: versions differ -> m
171 picked tool 'python ../merge' for rev (binary False symlink False)
175 picked tool 'python ../merge' for rev (binary False symlink False)
172 merging rev
176 merging rev
173 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
177 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
178 picked tool 'python ../merge' for rev (binary False symlink False)
179 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
174 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
180 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
175 merge tool returned: 0
181 merge tool returned: 0
176 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
182 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
177 (branch merge, don't forget to commit)
183 (branch merge, don't forget to commit)
178 --------------
184 --------------
179 M b
185 M b
180 a
186 a
181 --------------
187 --------------
182
188
183 $ tm "nm a b" "up a " " " "4 get remote change to b"
189 $ tm "nm a b" "up a " " " "4 get remote change to b"
184 created new head
190 created new head
185 --------------
191 --------------
186 test L:nm a b R:up a W: - 4 get remote change to b
192 test L:nm a b R:up a W: - 4 get remote change to b
187 --------------
193 --------------
188 searching for copies back to rev 1
194 searching for copies back to rev 1
189 unmatched files in local:
195 unmatched files in local:
190 b
196 b
191 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
197 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
192 src: 'a' -> dst: 'b' *
198 src: 'a' -> dst: 'b' *
193 checking for directory renames
199 checking for directory renames
194 resolving manifests
200 resolving manifests
195 branchmerge: True, force: False, partial: False
201 branchmerge: True, force: False, partial: False
196 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
202 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
197 preserving b for resolve of b
203 preserving b for resolve of b
198 preserving rev for resolve of rev
204 preserving rev for resolve of rev
199 b: local copied/moved from a -> m
205 b: local copied/moved from a -> m
200 picked tool 'python ../merge' for b (binary False symlink False)
206 picked tool 'python ../merge' for b (binary False symlink False)
201 merging b and a to b
207 merging b and a to b
202 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
208 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
203 premerge successful
209 premerge successful
204 rev: versions differ -> m
210 rev: versions differ -> m
205 picked tool 'python ../merge' for rev (binary False symlink False)
211 picked tool 'python ../merge' for rev (binary False symlink False)
206 merging rev
212 merging rev
207 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
213 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
214 picked tool 'python ../merge' for rev (binary False symlink False)
215 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
208 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
216 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
209 merge tool returned: 0
217 merge tool returned: 0
210 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
218 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
211 (branch merge, don't forget to commit)
219 (branch merge, don't forget to commit)
212 --------------
220 --------------
213 M b
221 M b
214 a
222 a
215 --------------
223 --------------
216
224
217 $ tm " " "nc a b" " " "5 get b"
225 $ tm " " "nc a b" " " "5 get b"
218 created new head
226 created new head
219 --------------
227 --------------
220 test L: R:nc a b W: - 5 get b
228 test L: R:nc a b W: - 5 get b
221 --------------
229 --------------
222 searching for copies back to rev 1
230 searching for copies back to rev 1
223 unmatched files in other:
231 unmatched files in other:
224 b
232 b
225 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
233 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
226 src: 'a' -> dst: 'b'
234 src: 'a' -> dst: 'b'
227 checking for directory renames
235 checking for directory renames
228 resolving manifests
236 resolving manifests
229 branchmerge: True, force: False, partial: False
237 branchmerge: True, force: False, partial: False
230 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
238 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
231 preserving rev for resolve of rev
239 preserving rev for resolve of rev
232 b: remote created -> g
240 b: remote created -> g
233 getting b
241 getting b
234 rev: versions differ -> m
242 rev: versions differ -> m
235 picked tool 'python ../merge' for rev (binary False symlink False)
243 picked tool 'python ../merge' for rev (binary False symlink False)
236 merging rev
244 merging rev
237 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
245 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
246 picked tool 'python ../merge' for rev (binary False symlink False)
247 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
238 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
248 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
239 merge tool returned: 0
249 merge tool returned: 0
240 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
250 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
241 (branch merge, don't forget to commit)
251 (branch merge, don't forget to commit)
242 --------------
252 --------------
243 M b
253 M b
244 C a
254 C a
245 --------------
255 --------------
246
256
247 $ tm "nc a b" " " " " "6 nothing"
257 $ tm "nc a b" " " " " "6 nothing"
248 created new head
258 created new head
249 --------------
259 --------------
250 test L:nc a b R: W: - 6 nothing
260 test L:nc a b R: W: - 6 nothing
251 --------------
261 --------------
252 searching for copies back to rev 1
262 searching for copies back to rev 1
253 unmatched files in local:
263 unmatched files in local:
254 b
264 b
255 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
265 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
256 src: 'a' -> dst: 'b'
266 src: 'a' -> dst: 'b'
257 checking for directory renames
267 checking for directory renames
258 resolving manifests
268 resolving manifests
259 branchmerge: True, force: False, partial: False
269 branchmerge: True, force: False, partial: False
260 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
270 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
261 preserving rev for resolve of rev
271 preserving rev for resolve of rev
262 rev: versions differ -> m
272 rev: versions differ -> m
263 picked tool 'python ../merge' for rev (binary False symlink False)
273 picked tool 'python ../merge' for rev (binary False symlink False)
264 merging rev
274 merging rev
265 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
275 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
276 picked tool 'python ../merge' for rev (binary False symlink False)
277 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
266 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
278 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
267 merge tool returned: 0
279 merge tool returned: 0
268 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
280 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
269 (branch merge, don't forget to commit)
281 (branch merge, don't forget to commit)
270 --------------
282 --------------
271 C a
283 C a
272 C b
284 C b
273 --------------
285 --------------
274
286
275 $ tm " " "nm a b" " " "7 get b"
287 $ tm " " "nm a b" " " "7 get b"
276 created new head
288 created new head
277 --------------
289 --------------
278 test L: R:nm a b W: - 7 get b
290 test L: R:nm a b W: - 7 get b
279 --------------
291 --------------
280 searching for copies back to rev 1
292 searching for copies back to rev 1
281 unmatched files in other:
293 unmatched files in other:
282 b
294 b
283 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
295 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
284 src: 'a' -> dst: 'b'
296 src: 'a' -> dst: 'b'
285 checking for directory renames
297 checking for directory renames
286 resolving manifests
298 resolving manifests
287 branchmerge: True, force: False, partial: False
299 branchmerge: True, force: False, partial: False
288 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
300 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
289 preserving rev for resolve of rev
301 preserving rev for resolve of rev
290 a: other deleted -> r
302 a: other deleted -> r
291 removing a
303 removing a
292 b: remote created -> g
304 b: remote created -> g
293 getting b
305 getting b
294 rev: versions differ -> m
306 rev: versions differ -> m
295 picked tool 'python ../merge' for rev (binary False symlink False)
307 picked tool 'python ../merge' for rev (binary False symlink False)
296 merging rev
308 merging rev
297 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
309 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
310 picked tool 'python ../merge' for rev (binary False symlink False)
311 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
298 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
312 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
299 merge tool returned: 0
313 merge tool returned: 0
300 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
314 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
301 (branch merge, don't forget to commit)
315 (branch merge, don't forget to commit)
302 --------------
316 --------------
303 M b
317 M b
304 --------------
318 --------------
305
319
306 $ tm "nm a b" " " " " "8 nothing"
320 $ tm "nm a b" " " " " "8 nothing"
307 created new head
321 created new head
308 --------------
322 --------------
309 test L:nm a b R: W: - 8 nothing
323 test L:nm a b R: W: - 8 nothing
310 --------------
324 --------------
311 searching for copies back to rev 1
325 searching for copies back to rev 1
312 unmatched files in local:
326 unmatched files in local:
313 b
327 b
314 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
328 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
315 src: 'a' -> dst: 'b'
329 src: 'a' -> dst: 'b'
316 checking for directory renames
330 checking for directory renames
317 resolving manifests
331 resolving manifests
318 branchmerge: True, force: False, partial: False
332 branchmerge: True, force: False, partial: False
319 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
333 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
320 preserving rev for resolve of rev
334 preserving rev for resolve of rev
321 rev: versions differ -> m
335 rev: versions differ -> m
322 picked tool 'python ../merge' for rev (binary False symlink False)
336 picked tool 'python ../merge' for rev (binary False symlink False)
323 merging rev
337 merging rev
324 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
338 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
339 picked tool 'python ../merge' for rev (binary False symlink False)
340 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
325 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
341 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
326 merge tool returned: 0
342 merge tool returned: 0
327 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
328 (branch merge, don't forget to commit)
344 (branch merge, don't forget to commit)
329 --------------
345 --------------
330 C b
346 C b
331 --------------
347 --------------
332
348
333 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
349 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
334 created new head
350 created new head
335 --------------
351 --------------
336 test L:um a b R:um a b W: - 9 do merge with ancestor in a
352 test L:um a b R:um a b W: - 9 do merge with ancestor in a
337 --------------
353 --------------
338 searching for copies back to rev 1
354 searching for copies back to rev 1
339 unmatched files new in both:
355 unmatched files new in both:
340 b
356 b
341 resolving manifests
357 resolving manifests
342 branchmerge: True, force: False, partial: False
358 branchmerge: True, force: False, partial: False
343 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
359 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
344 preserving b for resolve of b
360 preserving b for resolve of b
345 preserving rev for resolve of rev
361 preserving rev for resolve of rev
346 b: both renamed from a -> m
362 b: both renamed from a -> m
347 picked tool 'python ../merge' for b (binary False symlink False)
363 picked tool 'python ../merge' for b (binary False symlink False)
348 merging b
364 merging b
349 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
365 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
366 picked tool 'python ../merge' for b (binary False symlink False)
367 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
350 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
368 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
351 merge tool returned: 0
369 merge tool returned: 0
352 rev: versions differ -> m
370 rev: versions differ -> m
353 picked tool 'python ../merge' for rev (binary False symlink False)
371 picked tool 'python ../merge' for rev (binary False symlink False)
354 merging rev
372 merging rev
355 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
373 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
374 picked tool 'python ../merge' for rev (binary False symlink False)
375 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
356 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
376 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
357 merge tool returned: 0
377 merge tool returned: 0
358 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
378 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
359 (branch merge, don't forget to commit)
379 (branch merge, don't forget to commit)
360 --------------
380 --------------
361 M b
381 M b
362 --------------
382 --------------
363
383
364
384
365 m "um a c" "um x c" " " "10 do merge with no ancestor"
385 m "um a c" "um x c" " " "10 do merge with no ancestor"
366
386
367 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
387 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
368 created new head
388 created new head
369 --------------
389 --------------
370 test L:nm a b R:nm a c W: - 11 get c, keep b
390 test L:nm a b R:nm a c W: - 11 get c, keep b
371 --------------
391 --------------
372 searching for copies back to rev 1
392 searching for copies back to rev 1
373 unmatched files in local:
393 unmatched files in local:
374 b
394 b
375 unmatched files in other:
395 unmatched files in other:
376 c
396 c
377 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
397 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
378 src: 'a' -> dst: 'b' !
398 src: 'a' -> dst: 'b' !
379 src: 'a' -> dst: 'c' !
399 src: 'a' -> dst: 'c' !
380 checking for directory renames
400 checking for directory renames
381 resolving manifests
401 resolving manifests
382 branchmerge: True, force: False, partial: False
402 branchmerge: True, force: False, partial: False
383 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
403 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
384 preserving rev for resolve of rev
404 preserving rev for resolve of rev
385 c: remote created -> g
405 c: remote created -> g
386 getting c
406 getting c
387 rev: versions differ -> m
407 rev: versions differ -> m
388 picked tool 'python ../merge' for rev (binary False symlink False)
408 picked tool 'python ../merge' for rev (binary False symlink False)
389 merging rev
409 merging rev
390 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
410 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
411 picked tool 'python ../merge' for rev (binary False symlink False)
412 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
391 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
413 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
392 merge tool returned: 0
414 merge tool returned: 0
393 note: possible conflict - a was renamed multiple times to:
415 note: possible conflict - a was renamed multiple times to:
394 b
416 b
395 c
417 c
396 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
418 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
397 (branch merge, don't forget to commit)
419 (branch merge, don't forget to commit)
398 --------------
420 --------------
399 M c
421 M c
400 C b
422 C b
401 --------------
423 --------------
402
424
403 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
425 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
404 created new head
426 created new head
405 --------------
427 --------------
406 test L:nc a b R:up b W: - 12 merge b no ancestor
428 test L:nc a b R:up b W: - 12 merge b no ancestor
407 --------------
429 --------------
408 searching for copies back to rev 1
430 searching for copies back to rev 1
409 unmatched files new in both:
431 unmatched files new in both:
410 b
432 b
411 resolving manifests
433 resolving manifests
412 branchmerge: True, force: False, partial: False
434 branchmerge: True, force: False, partial: False
413 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
435 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
414 preserving b for resolve of b
436 preserving b for resolve of b
415 preserving rev for resolve of rev
437 preserving rev for resolve of rev
416 b: both created -> m
438 b: both created -> m
417 picked tool 'python ../merge' for b (binary False symlink False)
439 picked tool 'python ../merge' for b (binary False symlink False)
418 merging b
440 merging b
419 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
441 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
442 picked tool 'python ../merge' for b (binary False symlink False)
443 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
420 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
444 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
421 merge tool returned: 0
445 merge tool returned: 0
422 rev: versions differ -> m
446 rev: versions differ -> m
423 picked tool 'python ../merge' for rev (binary False symlink False)
447 picked tool 'python ../merge' for rev (binary False symlink False)
424 merging rev
448 merging rev
425 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
449 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
450 picked tool 'python ../merge' for rev (binary False symlink False)
451 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
426 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
452 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
427 merge tool returned: 0
453 merge tool returned: 0
428 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
454 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
429 (branch merge, don't forget to commit)
455 (branch merge, don't forget to commit)
430 --------------
456 --------------
431 M b
457 M b
432 C a
458 C a
433 --------------
459 --------------
434
460
435 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
461 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
436 created new head
462 created new head
437 --------------
463 --------------
438 test L:up b R:nm a b W: - 13 merge b no ancestor
464 test L:up b R:nm a b W: - 13 merge b no ancestor
439 --------------
465 --------------
440 searching for copies back to rev 1
466 searching for copies back to rev 1
441 unmatched files new in both:
467 unmatched files new in both:
442 b
468 b
443 resolving manifests
469 resolving manifests
444 branchmerge: True, force: False, partial: False
470 branchmerge: True, force: False, partial: False
445 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
471 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
446 preserving b for resolve of b
472 preserving b for resolve of b
447 preserving rev for resolve of rev
473 preserving rev for resolve of rev
448 a: other deleted -> r
474 a: other deleted -> r
449 removing a
475 removing a
450 b: both created -> m
476 b: both created -> m
451 picked tool 'python ../merge' for b (binary False symlink False)
477 picked tool 'python ../merge' for b (binary False symlink False)
452 merging b
478 merging b
453 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
479 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
480 picked tool 'python ../merge' for b (binary False symlink False)
481 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
454 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
482 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
455 merge tool returned: 0
483 merge tool returned: 0
456 rev: versions differ -> m
484 rev: versions differ -> m
457 picked tool 'python ../merge' for rev (binary False symlink False)
485 picked tool 'python ../merge' for rev (binary False symlink False)
458 merging rev
486 merging rev
459 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
487 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
488 picked tool 'python ../merge' for rev (binary False symlink False)
489 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
460 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
490 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
461 merge tool returned: 0
491 merge tool returned: 0
462 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
492 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
463 (branch merge, don't forget to commit)
493 (branch merge, don't forget to commit)
464 --------------
494 --------------
465 M b
495 M b
466 --------------
496 --------------
467
497
468 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
498 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
469 created new head
499 created new head
470 --------------
500 --------------
471 test L:nc a b R:up a b W: - 14 merge b no ancestor
501 test L:nc a b R:up a b W: - 14 merge b no ancestor
472 --------------
502 --------------
473 searching for copies back to rev 1
503 searching for copies back to rev 1
474 unmatched files new in both:
504 unmatched files new in both:
475 b
505 b
476 resolving manifests
506 resolving manifests
477 branchmerge: True, force: False, partial: False
507 branchmerge: True, force: False, partial: False
478 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
508 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
479 preserving b for resolve of b
509 preserving b for resolve of b
480 preserving rev for resolve of rev
510 preserving rev for resolve of rev
481 a: remote is newer -> g
511 a: remote is newer -> g
482 getting a
512 getting a
483 b: both created -> m
513 b: both created -> m
484 picked tool 'python ../merge' for b (binary False symlink False)
514 picked tool 'python ../merge' for b (binary False symlink False)
485 merging b
515 merging b
486 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
516 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
517 picked tool 'python ../merge' for b (binary False symlink False)
518 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
487 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
519 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
488 merge tool returned: 0
520 merge tool returned: 0
489 rev: versions differ -> m
521 rev: versions differ -> m
490 picked tool 'python ../merge' for rev (binary False symlink False)
522 picked tool 'python ../merge' for rev (binary False symlink False)
491 merging rev
523 merging rev
492 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
524 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
525 picked tool 'python ../merge' for rev (binary False symlink False)
526 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
493 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
527 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
494 merge tool returned: 0
528 merge tool returned: 0
495 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
529 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
496 (branch merge, don't forget to commit)
530 (branch merge, don't forget to commit)
497 --------------
531 --------------
498 M a
532 M a
499 M b
533 M b
500 --------------
534 --------------
501
535
502 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
536 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
503 created new head
537 created new head
504 --------------
538 --------------
505 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
539 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
506 --------------
540 --------------
507 searching for copies back to rev 1
541 searching for copies back to rev 1
508 unmatched files new in both:
542 unmatched files new in both:
509 b
543 b
510 resolving manifests
544 resolving manifests
511 branchmerge: True, force: False, partial: False
545 branchmerge: True, force: False, partial: False
512 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
546 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
513 preserving b for resolve of b
547 preserving b for resolve of b
514 preserving rev for resolve of rev
548 preserving rev for resolve of rev
515 a: other deleted -> r
549 a: other deleted -> r
516 removing a
550 removing a
517 b: both created -> m
551 b: both created -> m
518 picked tool 'python ../merge' for b (binary False symlink False)
552 picked tool 'python ../merge' for b (binary False symlink False)
519 merging b
553 merging b
520 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
554 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
555 picked tool 'python ../merge' for b (binary False symlink False)
556 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
521 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
557 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
522 merge tool returned: 0
558 merge tool returned: 0
523 rev: versions differ -> m
559 rev: versions differ -> m
524 picked tool 'python ../merge' for rev (binary False symlink False)
560 picked tool 'python ../merge' for rev (binary False symlink False)
525 merging rev
561 merging rev
526 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
562 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
563 picked tool 'python ../merge' for rev (binary False symlink False)
564 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
527 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
565 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
528 merge tool returned: 0
566 merge tool returned: 0
529 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
567 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
530 (branch merge, don't forget to commit)
568 (branch merge, don't forget to commit)
531 --------------
569 --------------
532 M b
570 M b
533 --------------
571 --------------
534
572
535 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
573 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
536 created new head
574 created new head
537 --------------
575 --------------
538 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
576 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
539 --------------
577 --------------
540 searching for copies back to rev 1
578 searching for copies back to rev 1
541 unmatched files new in both:
579 unmatched files new in both:
542 b
580 b
543 resolving manifests
581 resolving manifests
544 branchmerge: True, force: False, partial: False
582 branchmerge: True, force: False, partial: False
545 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
583 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
546 preserving b for resolve of b
584 preserving b for resolve of b
547 preserving rev for resolve of rev
585 preserving rev for resolve of rev
548 a: remote is newer -> g
586 a: remote is newer -> g
549 getting a
587 getting a
550 b: both created -> m
588 b: both created -> m
551 picked tool 'python ../merge' for b (binary False symlink False)
589 picked tool 'python ../merge' for b (binary False symlink False)
552 merging b
590 merging b
553 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
591 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
592 picked tool 'python ../merge' for b (binary False symlink False)
593 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
554 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
594 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
555 merge tool returned: 0
595 merge tool returned: 0
556 rev: versions differ -> m
596 rev: versions differ -> m
557 picked tool 'python ../merge' for rev (binary False symlink False)
597 picked tool 'python ../merge' for rev (binary False symlink False)
558 merging rev
598 merging rev
559 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
599 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
600 picked tool 'python ../merge' for rev (binary False symlink False)
601 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
560 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
602 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
561 merge tool returned: 0
603 merge tool returned: 0
562 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
604 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
563 (branch merge, don't forget to commit)
605 (branch merge, don't forget to commit)
564 --------------
606 --------------
565 M a
607 M a
566 M b
608 M b
567 --------------
609 --------------
568
610
569 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
611 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
570 created new head
612 created new head
571 --------------
613 --------------
572 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
614 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
573 --------------
615 --------------
574 searching for copies back to rev 1
616 searching for copies back to rev 1
575 unmatched files new in both:
617 unmatched files new in both:
576 b
618 b
577 resolving manifests
619 resolving manifests
578 branchmerge: True, force: False, partial: False
620 branchmerge: True, force: False, partial: False
579 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
621 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
580 preserving b for resolve of b
622 preserving b for resolve of b
581 preserving rev for resolve of rev
623 preserving rev for resolve of rev
582 a: remote unchanged -> k
624 a: remote unchanged -> k
583 b: both created -> m
625 b: both created -> m
584 picked tool 'python ../merge' for b (binary False symlink False)
626 picked tool 'python ../merge' for b (binary False symlink False)
585 merging b
627 merging b
586 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
628 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
629 picked tool 'python ../merge' for b (binary False symlink False)
630 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
587 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
631 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
588 merge tool returned: 0
632 merge tool returned: 0
589 rev: versions differ -> m
633 rev: versions differ -> m
590 picked tool 'python ../merge' for rev (binary False symlink False)
634 picked tool 'python ../merge' for rev (binary False symlink False)
591 merging rev
635 merging rev
592 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
636 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
637 picked tool 'python ../merge' for rev (binary False symlink False)
638 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
593 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
639 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
594 merge tool returned: 0
640 merge tool returned: 0
595 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
641 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
596 (branch merge, don't forget to commit)
642 (branch merge, don't forget to commit)
597 --------------
643 --------------
598 M b
644 M b
599 C a
645 C a
600 --------------
646 --------------
601
647
602 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
648 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
603 created new head
649 created new head
604 --------------
650 --------------
605 test L:nm a b R:up a b W: - 18 merge b no ancestor
651 test L:nm a b R:up a b W: - 18 merge b no ancestor
606 --------------
652 --------------
607 searching for copies back to rev 1
653 searching for copies back to rev 1
608 unmatched files new in both:
654 unmatched files new in both:
609 b
655 b
610 resolving manifests
656 resolving manifests
611 branchmerge: True, force: False, partial: False
657 branchmerge: True, force: False, partial: False
612 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
658 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
613 remote changed a which local deleted
659 remote changed a which local deleted
614 use (c)hanged version or leave (d)eleted? c
660 use (c)hanged version or leave (d)eleted? c
615 preserving b for resolve of b
661 preserving b for resolve of b
616 preserving rev for resolve of rev
662 preserving rev for resolve of rev
617 a: prompt recreating -> g
663 a: prompt recreating -> g
618 getting a
664 getting a
619 b: both created -> m
665 b: both created -> m
620 picked tool 'python ../merge' for b (binary False symlink False)
666 picked tool 'python ../merge' for b (binary False symlink False)
621 merging b
667 merging b
622 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
668 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
669 picked tool 'python ../merge' for b (binary False symlink False)
670 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
623 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
671 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
624 merge tool returned: 0
672 merge tool returned: 0
625 rev: versions differ -> m
673 rev: versions differ -> m
626 picked tool 'python ../merge' for rev (binary False symlink False)
674 picked tool 'python ../merge' for rev (binary False symlink False)
627 merging rev
675 merging rev
628 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
676 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
677 picked tool 'python ../merge' for rev (binary False symlink False)
678 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
629 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
679 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
630 merge tool returned: 0
680 merge tool returned: 0
631 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
681 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
632 (branch merge, don't forget to commit)
682 (branch merge, don't forget to commit)
633 --------------
683 --------------
634 M a
684 M a
635 M b
685 M b
636 --------------
686 --------------
637
687
638 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
688 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
639 created new head
689 created new head
640 --------------
690 --------------
641 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
691 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
642 --------------
692 --------------
643 searching for copies back to rev 1
693 searching for copies back to rev 1
644 unmatched files new in both:
694 unmatched files new in both:
645 b
695 b
646 resolving manifests
696 resolving manifests
647 branchmerge: True, force: False, partial: False
697 branchmerge: True, force: False, partial: False
648 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
698 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
649 local changed a which remote deleted
699 local changed a which remote deleted
650 use (c)hanged version or (d)elete? c
700 use (c)hanged version or (d)elete? c
651 preserving b for resolve of b
701 preserving b for resolve of b
652 preserving rev for resolve of rev
702 preserving rev for resolve of rev
653 a: prompt keep -> a
703 a: prompt keep -> a
654 b: both created -> m
704 b: both created -> m
655 picked tool 'python ../merge' for b (binary False symlink False)
705 picked tool 'python ../merge' for b (binary False symlink False)
656 merging b
706 merging b
657 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
707 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
708 picked tool 'python ../merge' for b (binary False symlink False)
709 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
658 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
710 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
659 merge tool returned: 0
711 merge tool returned: 0
660 rev: versions differ -> m
712 rev: versions differ -> m
661 picked tool 'python ../merge' for rev (binary False symlink False)
713 picked tool 'python ../merge' for rev (binary False symlink False)
662 merging rev
714 merging rev
663 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
715 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
716 picked tool 'python ../merge' for rev (binary False symlink False)
717 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
664 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
718 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
665 merge tool returned: 0
719 merge tool returned: 0
666 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
720 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
667 (branch merge, don't forget to commit)
721 (branch merge, don't forget to commit)
668 --------------
722 --------------
669 M b
723 M b
670 C a
724 C a
671 --------------
725 --------------
672
726
673 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
727 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
674 created new head
728 created new head
675 --------------
729 --------------
676 test L:up a R:um a b W: - 20 merge a and b to b, remove a
730 test L:up a R:um a b W: - 20 merge a and b to b, remove a
677 --------------
731 --------------
678 searching for copies back to rev 1
732 searching for copies back to rev 1
679 unmatched files in other:
733 unmatched files in other:
680 b
734 b
681 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
735 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
682 src: 'a' -> dst: 'b' *
736 src: 'a' -> dst: 'b' *
683 checking for directory renames
737 checking for directory renames
684 resolving manifests
738 resolving manifests
685 branchmerge: True, force: False, partial: False
739 branchmerge: True, force: False, partial: False
686 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
740 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
687 preserving a for resolve of b
741 preserving a for resolve of b
688 preserving rev for resolve of rev
742 preserving rev for resolve of rev
689 removing a
743 removing a
690 b: remote moved from a -> m
744 b: remote moved from a -> m
691 picked tool 'python ../merge' for b (binary False symlink False)
745 picked tool 'python ../merge' for b (binary False symlink False)
692 merging a and b to b
746 merging a and b to b
693 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
747 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
748 picked tool 'python ../merge' for b (binary False symlink False)
749 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
694 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
750 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
695 merge tool returned: 0
751 merge tool returned: 0
696 rev: versions differ -> m
752 rev: versions differ -> m
697 picked tool 'python ../merge' for rev (binary False symlink False)
753 picked tool 'python ../merge' for rev (binary False symlink False)
698 merging rev
754 merging rev
699 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
755 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
756 picked tool 'python ../merge' for rev (binary False symlink False)
757 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
700 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
758 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
701 merge tool returned: 0
759 merge tool returned: 0
702 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
760 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
703 (branch merge, don't forget to commit)
761 (branch merge, don't forget to commit)
704 --------------
762 --------------
705 M b
763 M b
706 a
764 a
707 --------------
765 --------------
708
766
709 $ tm "um a b" "up a " " " "21 merge a and b to b"
767 $ tm "um a b" "up a " " " "21 merge a and b to b"
710 created new head
768 created new head
711 --------------
769 --------------
712 test L:um a b R:up a W: - 21 merge a and b to b
770 test L:um a b R:up a W: - 21 merge a and b to b
713 --------------
771 --------------
714 searching for copies back to rev 1
772 searching for copies back to rev 1
715 unmatched files in local:
773 unmatched files in local:
716 b
774 b
717 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
775 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
718 src: 'a' -> dst: 'b' *
776 src: 'a' -> dst: 'b' *
719 checking for directory renames
777 checking for directory renames
720 resolving manifests
778 resolving manifests
721 branchmerge: True, force: False, partial: False
779 branchmerge: True, force: False, partial: False
722 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
780 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
723 preserving b for resolve of b
781 preserving b for resolve of b
724 preserving rev for resolve of rev
782 preserving rev for resolve of rev
725 b: local copied/moved from a -> m
783 b: local copied/moved from a -> m
726 picked tool 'python ../merge' for b (binary False symlink False)
784 picked tool 'python ../merge' for b (binary False symlink False)
727 merging b and a to b
785 merging b and a to b
728 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
786 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
787 picked tool 'python ../merge' for b (binary False symlink False)
788 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
729 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
789 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
730 merge tool returned: 0
790 merge tool returned: 0
731 rev: versions differ -> m
791 rev: versions differ -> m
732 picked tool 'python ../merge' for rev (binary False symlink False)
792 picked tool 'python ../merge' for rev (binary False symlink False)
733 merging rev
793 merging rev
734 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
794 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
795 picked tool 'python ../merge' for rev (binary False symlink False)
796 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
735 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
797 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
736 merge tool returned: 0
798 merge tool returned: 0
737 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
799 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
738 (branch merge, don't forget to commit)
800 (branch merge, don't forget to commit)
739 --------------
801 --------------
740 M b
802 M b
741 a
803 a
742 --------------
804 --------------
743
805
744
806
745 m "nm a b" "um x a" " " "22 get a, keep b"
807 m "nm a b" "um x a" " " "22 get a, keep b"
746
808
747 $ tm "nm a b" "up a c" " " "23 get c, keep b"
809 $ tm "nm a b" "up a c" " " "23 get c, keep b"
748 created new head
810 created new head
749 --------------
811 --------------
750 test L:nm a b R:up a c W: - 23 get c, keep b
812 test L:nm a b R:up a c W: - 23 get c, keep b
751 --------------
813 --------------
752 searching for copies back to rev 1
814 searching for copies back to rev 1
753 unmatched files in local:
815 unmatched files in local:
754 b
816 b
755 unmatched files in other:
817 unmatched files in other:
756 c
818 c
757 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
819 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
758 src: 'a' -> dst: 'b' *
820 src: 'a' -> dst: 'b' *
759 checking for directory renames
821 checking for directory renames
760 resolving manifests
822 resolving manifests
761 branchmerge: True, force: False, partial: False
823 branchmerge: True, force: False, partial: False
762 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
824 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
763 preserving b for resolve of b
825 preserving b for resolve of b
764 preserving rev for resolve of rev
826 preserving rev for resolve of rev
765 c: remote created -> g
827 c: remote created -> g
766 getting c
828 getting c
767 b: local copied/moved from a -> m
829 b: local copied/moved from a -> m
768 picked tool 'python ../merge' for b (binary False symlink False)
830 picked tool 'python ../merge' for b (binary False symlink False)
769 merging b and a to b
831 merging b and a to b
770 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
832 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
771 premerge successful
833 premerge successful
772 rev: versions differ -> m
834 rev: versions differ -> m
773 picked tool 'python ../merge' for rev (binary False symlink False)
835 picked tool 'python ../merge' for rev (binary False symlink False)
774 merging rev
836 merging rev
775 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
837 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
838 picked tool 'python ../merge' for rev (binary False symlink False)
839 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
776 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
840 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
777 merge tool returned: 0
841 merge tool returned: 0
778 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
842 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
779 (branch merge, don't forget to commit)
843 (branch merge, don't forget to commit)
780 --------------
844 --------------
781 M b
845 M b
782 a
846 a
783 M c
847 M c
784 --------------
848 --------------
785
849
786
850
787 $ cd ..
851 $ cd ..
788
852
789
853
790 Systematic and terse testing of merge merges and ancestor calculation:
854 Systematic and terse testing of merge merges and ancestor calculation:
791
855
792 Expected result:
856 Expected result:
793
857
794 \ a m1 m2 dst
858 \ a m1 m2 dst
795 0 - f f f "versions differ"
859 0 - f f f "versions differ"
796 1 f g g g "versions differ"
860 1 f g g g "versions differ"
797 2 f f f f "versions differ"
861 2 f f f f "versions differ"
798 3 f f g f+g "remote copied to " + f
862 3 f f g f+g "remote copied to " + f
799 4 f f g g "remote moved to " + f
863 4 f f g g "remote moved to " + f
800 5 f g f f+g "local copied to " + f2
864 5 f g f f+g "local copied to " + f2
801 6 f g f g "local moved to " + f2
865 6 f g f g "local moved to " + f2
802 7 - (f) f f "remote differs from untracked local"
866 7 - (f) f f "remote differs from untracked local"
803 8 f (f) f f "remote differs from untracked local"
867 8 f (f) f f "remote differs from untracked local"
804
868
805 $ hg init ancestortest
869 $ hg init ancestortest
806 $ cd ancestortest
870 $ cd ancestortest
807 $ for x in 1 2 3 4 5 6 8; do mkdir $x; echo a > $x/f; done
871 $ for x in 1 2 3 4 5 6 8; do mkdir $x; echo a > $x/f; done
808 $ hg ci -Aqm "a"
872 $ hg ci -Aqm "a"
809 $ mkdir 0
873 $ mkdir 0
810 $ touch 0/f
874 $ touch 0/f
811 $ hg mv 1/f 1/g
875 $ hg mv 1/f 1/g
812 $ hg cp 5/f 5/g
876 $ hg cp 5/f 5/g
813 $ hg mv 6/f 6/g
877 $ hg mv 6/f 6/g
814 $ hg rm 8/f
878 $ hg rm 8/f
815 $ for x in */*; do echo m1 > $x; done
879 $ for x in */*; do echo m1 > $x; done
816 $ hg ci -Aqm "m1"
880 $ hg ci -Aqm "m1"
817 $ hg up -qr0
881 $ hg up -qr0
818 $ mkdir 0 7
882 $ mkdir 0 7
819 $ touch 0/f 7/f
883 $ touch 0/f 7/f
820 $ hg mv 1/f 1/g
884 $ hg mv 1/f 1/g
821 $ hg cp 3/f 3/g
885 $ hg cp 3/f 3/g
822 $ hg mv 4/f 4/g
886 $ hg mv 4/f 4/g
823 $ for x in */*; do echo m2 > $x; done
887 $ for x in */*; do echo m2 > $x; done
824 $ hg ci -Aqm "m2"
888 $ hg ci -Aqm "m2"
825 $ hg up -qr1
889 $ hg up -qr1
826 $ mkdir 7 8
890 $ mkdir 7 8
827 $ echo m > 7/f
891 $ echo m > 7/f
828 $ echo m > 8/f
892 $ echo m > 8/f
829 $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^ 0\/f: both created -> m/,$d' 2> /dev/null
893 $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^ 0\/f: both created -> m/,$d' 2> /dev/null
830 searching for copies back to rev 1
894 searching for copies back to rev 1
831 unmatched files in local:
895 unmatched files in local:
832 5/g
896 5/g
833 6/g
897 6/g
834 unmatched files in other:
898 unmatched files in other:
835 3/g
899 3/g
836 4/g
900 4/g
837 7/f
901 7/f
838 unmatched files new in both:
902 unmatched files new in both:
839 0/f
903 0/f
840 1/g
904 1/g
841 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
905 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
842 src: '3/f' -> dst: '3/g' *
906 src: '3/f' -> dst: '3/g' *
843 src: '4/f' -> dst: '4/g' *
907 src: '4/f' -> dst: '4/g' *
844 src: '5/f' -> dst: '5/g' *
908 src: '5/f' -> dst: '5/g' *
845 src: '6/f' -> dst: '6/g' *
909 src: '6/f' -> dst: '6/g' *
846 checking for directory renames
910 checking for directory renames
847 resolving manifests
911 resolving manifests
848 branchmerge: True, force: True, partial: False
912 branchmerge: True, force: True, partial: False
849 ancestor: e6cb3cf11019, local: ec44bf929ab5+, remote: c62e34d0b898
913 ancestor: e6cb3cf11019, local: ec44bf929ab5+, remote: c62e34d0b898
850 remote changed 8/f which local deleted
914 remote changed 8/f which local deleted
851 use (c)hanged version or leave (d)eleted? c
915 use (c)hanged version or leave (d)eleted? c
852 preserving 0/f for resolve of 0/f
916 preserving 0/f for resolve of 0/f
853 preserving 1/g for resolve of 1/g
917 preserving 1/g for resolve of 1/g
854 preserving 2/f for resolve of 2/f
918 preserving 2/f for resolve of 2/f
855 preserving 3/f for resolve of 3/f
919 preserving 3/f for resolve of 3/f
856 preserving 3/f for resolve of 3/g
920 preserving 3/f for resolve of 3/g
857 preserving 4/f for resolve of 4/g
921 preserving 4/f for resolve of 4/g
858 preserving 5/f for resolve of 5/f
922 preserving 5/f for resolve of 5/f
859 preserving 5/g for resolve of 5/g
923 preserving 5/g for resolve of 5/g
860 preserving 6/g for resolve of 6/g
924 preserving 6/g for resolve of 6/g
861 preserving 7/f for resolve of 7/f
925 preserving 7/f for resolve of 7/f
862 removing 4/f
926 removing 4/f
863 8/f: prompt recreating -> g
927 8/f: prompt recreating -> g
864 getting 8/f
928 getting 8/f
865 $ hg mani
929 $ hg mani
866 0/f
930 0/f
867 1/g
931 1/g
868 2/f
932 2/f
869 3/f
933 3/f
870 4/f
934 4/f
871 5/f
935 5/f
872 5/g
936 5/g
873 6/g
937 6/g
874 $ for f in */*; do echo $f:; cat $f; done
938 $ for f in */*; do echo $f:; cat $f; done
875 0/f:
939 0/f:
876 m1
940 m1
877 0/f.base:
941 0/f.base:
878 0/f.local:
942 0/f.local:
879 m1
943 m1
880 0/f.orig:
944 0/f.orig:
881 m1
945 m1
882 0/f.other:
946 0/f.other:
883 m2
947 m2
884 1/g:
948 1/g:
885 m1
949 m1
886 1/g.base:
950 1/g.base:
887 a
951 a
888 1/g.local:
952 1/g.local:
889 m1
953 m1
890 1/g.orig:
954 1/g.orig:
891 m1
955 m1
892 1/g.other:
956 1/g.other:
893 m2
957 m2
894 2/f:
958 2/f:
895 m1
959 m1
896 2/f.base:
960 2/f.base:
897 a
961 a
898 2/f.local:
962 2/f.local:
899 m1
963 m1
900 2/f.orig:
964 2/f.orig:
901 m1
965 m1
902 2/f.other:
966 2/f.other:
903 m2
967 m2
904 3/f:
968 3/f:
905 m1
969 m1
906 3/f.base:
970 3/f.base:
907 a
971 a
908 3/f.local:
972 3/f.local:
909 m1
973 m1
910 3/f.orig:
974 3/f.orig:
911 m1
975 m1
912 3/f.other:
976 3/f.other:
913 m2
977 m2
914 3/g:
978 3/g:
915 m1
979 m1
916 3/g.base:
980 3/g.base:
917 a
981 a
918 3/g.local:
982 3/g.local:
919 m1
983 m1
920 3/g.orig:
984 3/g.orig:
921 m1
985 m1
922 3/g.other:
986 3/g.other:
923 m2
987 m2
924 4/g:
988 4/g:
925 m1
989 m1
926 4/g.base:
990 4/g.base:
927 a
991 a
928 4/g.local:
992 4/g.local:
929 m1
993 m1
930 4/g.orig:
994 4/g.orig:
931 m1
995 m1
932 4/g.other:
996 4/g.other:
933 m2
997 m2
934 5/f:
998 5/f:
935 m1
999 m1
936 5/f.base:
1000 5/f.base:
937 a
1001 a
938 5/f.local:
1002 5/f.local:
939 m1
1003 m1
940 5/f.orig:
1004 5/f.orig:
941 m1
1005 m1
942 5/f.other:
1006 5/f.other:
943 m2
1007 m2
944 5/g:
1008 5/g:
945 m1
1009 m1
946 5/g.base:
1010 5/g.base:
947 a
1011 a
948 5/g.local:
1012 5/g.local:
949 m1
1013 m1
950 5/g.orig:
1014 5/g.orig:
951 m1
1015 m1
952 5/g.other:
1016 5/g.other:
953 m2
1017 m2
954 6/g:
1018 6/g:
955 m1
1019 m1
956 6/g.base:
1020 6/g.base:
957 a
1021 a
958 6/g.local:
1022 6/g.local:
959 m1
1023 m1
960 6/g.orig:
1024 6/g.orig:
961 m1
1025 m1
962 6/g.other:
1026 6/g.other:
963 m2
1027 m2
964 7/f:
1028 7/f:
965 m
1029 m
966 7/f.base:
1030 7/f.base:
967 7/f.local:
1031 7/f.local:
968 m
1032 m
969 7/f.orig:
1033 7/f.orig:
970 m
1034 m
971 7/f.other:
1035 7/f.other:
972 m2
1036 m2
973 8/f:
1037 8/f:
974 m2
1038 m2
975 $ cd ..
1039 $ cd ..
@@ -1,1757 +1,1759 b''
1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
2
2
3 $ echo "[ui]" >> $HGRCPATH
3 $ echo "[ui]" >> $HGRCPATH
4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
5
5
6 $ hg init t
6 $ hg init t
7 $ cd t
7 $ cd t
8
8
9 first revision, no sub
9 first revision, no sub
10
10
11 $ echo a > a
11 $ echo a > a
12 $ hg ci -Am0
12 $ hg ci -Am0
13 adding a
13 adding a
14
14
15 add first sub
15 add first sub
16
16
17 $ echo s = s > .hgsub
17 $ echo s = s > .hgsub
18 $ hg add .hgsub
18 $ hg add .hgsub
19 $ hg init s
19 $ hg init s
20 $ echo a > s/a
20 $ echo a > s/a
21
21
22 Issue2232: committing a subrepo without .hgsub
22 Issue2232: committing a subrepo without .hgsub
23
23
24 $ hg ci -mbad s
24 $ hg ci -mbad s
25 abort: can't commit subrepos without .hgsub
25 abort: can't commit subrepos without .hgsub
26 [255]
26 [255]
27
27
28 $ hg -R s add s/a
28 $ hg -R s add s/a
29 $ hg files -S
29 $ hg files -S
30 .hgsub
30 .hgsub
31 a
31 a
32 s/a (glob)
32 s/a (glob)
33
33
34 $ hg -R s ci -Ams0
34 $ hg -R s ci -Ams0
35 $ hg sum
35 $ hg sum
36 parent: 0:f7b1eb17ad24 tip
36 parent: 0:f7b1eb17ad24 tip
37 0
37 0
38 branch: default
38 branch: default
39 commit: 1 added, 1 subrepos
39 commit: 1 added, 1 subrepos
40 update: (current)
40 update: (current)
41 phases: 1 draft
41 phases: 1 draft
42 $ hg ci -m1
42 $ hg ci -m1
43
43
44 test handling .hgsubstate "added" explicitly.
44 test handling .hgsubstate "added" explicitly.
45
45
46 $ hg parents --template '{node}\n{files}\n'
46 $ hg parents --template '{node}\n{files}\n'
47 7cf8cfea66e410e8e3336508dfeec07b3192de51
47 7cf8cfea66e410e8e3336508dfeec07b3192de51
48 .hgsub .hgsubstate
48 .hgsub .hgsubstate
49 $ hg rollback -q
49 $ hg rollback -q
50 $ hg add .hgsubstate
50 $ hg add .hgsubstate
51 $ hg ci -m1
51 $ hg ci -m1
52 $ hg parents --template '{node}\n{files}\n'
52 $ hg parents --template '{node}\n{files}\n'
53 7cf8cfea66e410e8e3336508dfeec07b3192de51
53 7cf8cfea66e410e8e3336508dfeec07b3192de51
54 .hgsub .hgsubstate
54 .hgsub .hgsubstate
55
55
56 Revert subrepo and test subrepo fileset keyword:
56 Revert subrepo and test subrepo fileset keyword:
57
57
58 $ echo b > s/a
58 $ echo b > s/a
59 $ hg revert --dry-run "set:subrepo('glob:s*')"
59 $ hg revert --dry-run "set:subrepo('glob:s*')"
60 reverting subrepo s
60 reverting subrepo s
61 reverting s/a (glob)
61 reverting s/a (glob)
62 $ cat s/a
62 $ cat s/a
63 b
63 b
64 $ hg revert "set:subrepo('glob:s*')"
64 $ hg revert "set:subrepo('glob:s*')"
65 reverting subrepo s
65 reverting subrepo s
66 reverting s/a (glob)
66 reverting s/a (glob)
67 $ cat s/a
67 $ cat s/a
68 a
68 a
69 $ rm s/a.orig
69 $ rm s/a.orig
70
70
71 Revert subrepo with no backup. The "reverting s/a" line is gone since
71 Revert subrepo with no backup. The "reverting s/a" line is gone since
72 we're really running 'hg update' in the subrepo:
72 we're really running 'hg update' in the subrepo:
73
73
74 $ echo b > s/a
74 $ echo b > s/a
75 $ hg revert --no-backup s
75 $ hg revert --no-backup s
76 reverting subrepo s
76 reverting subrepo s
77
77
78 Issue2022: update -C
78 Issue2022: update -C
79
79
80 $ echo b > s/a
80 $ echo b > s/a
81 $ hg sum
81 $ hg sum
82 parent: 1:7cf8cfea66e4 tip
82 parent: 1:7cf8cfea66e4 tip
83 1
83 1
84 branch: default
84 branch: default
85 commit: 1 subrepos
85 commit: 1 subrepos
86 update: (current)
86 update: (current)
87 phases: 2 draft
87 phases: 2 draft
88 $ hg co -C 1
88 $ hg co -C 1
89 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 $ hg sum
90 $ hg sum
91 parent: 1:7cf8cfea66e4 tip
91 parent: 1:7cf8cfea66e4 tip
92 1
92 1
93 branch: default
93 branch: default
94 commit: (clean)
94 commit: (clean)
95 update: (current)
95 update: (current)
96 phases: 2 draft
96 phases: 2 draft
97
97
98 commands that require a clean repo should respect subrepos
98 commands that require a clean repo should respect subrepos
99
99
100 $ echo b >> s/a
100 $ echo b >> s/a
101 $ hg backout tip
101 $ hg backout tip
102 abort: uncommitted changes in subrepository 's'
102 abort: uncommitted changes in subrepository 's'
103 [255]
103 [255]
104 $ hg revert -C -R s s/a
104 $ hg revert -C -R s s/a
105
105
106 add sub sub
106 add sub sub
107
107
108 $ echo ss = ss > s/.hgsub
108 $ echo ss = ss > s/.hgsub
109 $ hg init s/ss
109 $ hg init s/ss
110 $ echo a > s/ss/a
110 $ echo a > s/ss/a
111 $ hg -R s add s/.hgsub
111 $ hg -R s add s/.hgsub
112 $ hg -R s/ss add s/ss/a
112 $ hg -R s/ss add s/ss/a
113 $ hg sum
113 $ hg sum
114 parent: 1:7cf8cfea66e4 tip
114 parent: 1:7cf8cfea66e4 tip
115 1
115 1
116 branch: default
116 branch: default
117 commit: 1 subrepos
117 commit: 1 subrepos
118 update: (current)
118 update: (current)
119 phases: 2 draft
119 phases: 2 draft
120 $ hg ci -m2
120 $ hg ci -m2
121 committing subrepository s
121 committing subrepository s
122 committing subrepository s/ss (glob)
122 committing subrepository s/ss (glob)
123 $ hg sum
123 $ hg sum
124 parent: 2:df30734270ae tip
124 parent: 2:df30734270ae tip
125 2
125 2
126 branch: default
126 branch: default
127 commit: (clean)
127 commit: (clean)
128 update: (current)
128 update: (current)
129 phases: 3 draft
129 phases: 3 draft
130
130
131 test handling .hgsubstate "modified" explicitly.
131 test handling .hgsubstate "modified" explicitly.
132
132
133 $ hg parents --template '{node}\n{files}\n'
133 $ hg parents --template '{node}\n{files}\n'
134 df30734270ae757feb35e643b7018e818e78a9aa
134 df30734270ae757feb35e643b7018e818e78a9aa
135 .hgsubstate
135 .hgsubstate
136 $ hg rollback -q
136 $ hg rollback -q
137 $ hg status -A .hgsubstate
137 $ hg status -A .hgsubstate
138 M .hgsubstate
138 M .hgsubstate
139 $ hg ci -m2
139 $ hg ci -m2
140 $ hg parents --template '{node}\n{files}\n'
140 $ hg parents --template '{node}\n{files}\n'
141 df30734270ae757feb35e643b7018e818e78a9aa
141 df30734270ae757feb35e643b7018e818e78a9aa
142 .hgsubstate
142 .hgsubstate
143
143
144 bump sub rev (and check it is ignored by ui.commitsubrepos)
144 bump sub rev (and check it is ignored by ui.commitsubrepos)
145
145
146 $ echo b > s/a
146 $ echo b > s/a
147 $ hg -R s ci -ms1
147 $ hg -R s ci -ms1
148 $ hg --config ui.commitsubrepos=no ci -m3
148 $ hg --config ui.commitsubrepos=no ci -m3
149
149
150 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
150 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
151
151
152 $ echo c > s/a
152 $ echo c > s/a
153 $ hg --config ui.commitsubrepos=no ci -m4
153 $ hg --config ui.commitsubrepos=no ci -m4
154 abort: uncommitted changes in subrepository 's'
154 abort: uncommitted changes in subrepository 's'
155 (use --subrepos for recursive commit)
155 (use --subrepos for recursive commit)
156 [255]
156 [255]
157 $ hg id
157 $ hg id
158 f6affe3fbfaa+ tip
158 f6affe3fbfaa+ tip
159 $ hg -R s ci -mc
159 $ hg -R s ci -mc
160 $ hg id
160 $ hg id
161 f6affe3fbfaa+ tip
161 f6affe3fbfaa+ tip
162 $ echo d > s/a
162 $ echo d > s/a
163 $ hg ci -m4
163 $ hg ci -m4
164 committing subrepository s
164 committing subrepository s
165 $ hg tip -R s
165 $ hg tip -R s
166 changeset: 4:02dcf1d70411
166 changeset: 4:02dcf1d70411
167 tag: tip
167 tag: tip
168 user: test
168 user: test
169 date: Thu Jan 01 00:00:00 1970 +0000
169 date: Thu Jan 01 00:00:00 1970 +0000
170 summary: 4
170 summary: 4
171
171
172
172
173 check caching
173 check caching
174
174
175 $ hg co 0
175 $ hg co 0
176 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
176 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
177 $ hg debugsub
177 $ hg debugsub
178
178
179 restore
179 restore
180
180
181 $ hg co
181 $ hg co
182 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
182 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
183 $ hg debugsub
183 $ hg debugsub
184 path s
184 path s
185 source s
185 source s
186 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
186 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
187
187
188 new branch for merge tests
188 new branch for merge tests
189
189
190 $ hg co 1
190 $ hg co 1
191 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 $ echo t = t >> .hgsub
192 $ echo t = t >> .hgsub
193 $ hg init t
193 $ hg init t
194 $ echo t > t/t
194 $ echo t > t/t
195 $ hg -R t add t
195 $ hg -R t add t
196 adding t/t (glob)
196 adding t/t (glob)
197
197
198 5
198 5
199
199
200 $ hg ci -m5 # add sub
200 $ hg ci -m5 # add sub
201 committing subrepository t
201 committing subrepository t
202 created new head
202 created new head
203 $ echo t2 > t/t
203 $ echo t2 > t/t
204
204
205 6
205 6
206
206
207 $ hg st -R s
207 $ hg st -R s
208 $ hg ci -m6 # change sub
208 $ hg ci -m6 # change sub
209 committing subrepository t
209 committing subrepository t
210 $ hg debugsub
210 $ hg debugsub
211 path s
211 path s
212 source s
212 source s
213 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
213 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
214 path t
214 path t
215 source t
215 source t
216 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
216 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
217 $ echo t3 > t/t
217 $ echo t3 > t/t
218
218
219 7
219 7
220
220
221 $ hg ci -m7 # change sub again for conflict test
221 $ hg ci -m7 # change sub again for conflict test
222 committing subrepository t
222 committing subrepository t
223 $ hg rm .hgsub
223 $ hg rm .hgsub
224
224
225 8
225 8
226
226
227 $ hg ci -m8 # remove sub
227 $ hg ci -m8 # remove sub
228
228
229 test handling .hgsubstate "removed" explicitly.
229 test handling .hgsubstate "removed" explicitly.
230
230
231 $ hg parents --template '{node}\n{files}\n'
231 $ hg parents --template '{node}\n{files}\n'
232 96615c1dad2dc8e3796d7332c77ce69156f7b78e
232 96615c1dad2dc8e3796d7332c77ce69156f7b78e
233 .hgsub .hgsubstate
233 .hgsub .hgsubstate
234 $ hg rollback -q
234 $ hg rollback -q
235 $ hg remove .hgsubstate
235 $ hg remove .hgsubstate
236 $ hg ci -m8
236 $ hg ci -m8
237 $ hg parents --template '{node}\n{files}\n'
237 $ hg parents --template '{node}\n{files}\n'
238 96615c1dad2dc8e3796d7332c77ce69156f7b78e
238 96615c1dad2dc8e3796d7332c77ce69156f7b78e
239 .hgsub .hgsubstate
239 .hgsub .hgsubstate
240
240
241 merge tests
241 merge tests
242
242
243 $ hg co -C 3
243 $ hg co -C 3
244 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
244 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
245 $ hg merge 5 # test adding
245 $ hg merge 5 # test adding
246 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
246 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
247 (branch merge, don't forget to commit)
247 (branch merge, don't forget to commit)
248 $ hg debugsub
248 $ hg debugsub
249 path s
249 path s
250 source s
250 source s
251 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
251 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
252 path t
252 path t
253 source t
253 source t
254 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
254 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
255 $ hg ci -m9
255 $ hg ci -m9
256 created new head
256 created new head
257 $ hg merge 6 --debug # test change
257 $ hg merge 6 --debug # test change
258 searching for copies back to rev 2
258 searching for copies back to rev 2
259 resolving manifests
259 resolving manifests
260 branchmerge: True, force: False, partial: False
260 branchmerge: True, force: False, partial: False
261 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
261 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
262 .hgsubstate: versions differ -> m
262 .hgsubstate: versions differ -> m
263 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
263 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
264 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
264 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
265 getting subrepo t
265 getting subrepo t
266 resolving manifests
266 resolving manifests
267 branchmerge: False, force: False, partial: False
267 branchmerge: False, force: False, partial: False
268 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
268 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
269 t: remote is newer -> g
269 t: remote is newer -> g
270 getting t
270 getting t
271 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
271 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
272 (branch merge, don't forget to commit)
272 (branch merge, don't forget to commit)
273 $ hg debugsub
273 $ hg debugsub
274 path s
274 path s
275 source s
275 source s
276 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
276 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
277 path t
277 path t
278 source t
278 source t
279 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
279 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
280 $ echo conflict > t/t
280 $ echo conflict > t/t
281 $ hg ci -m10
281 $ hg ci -m10
282 committing subrepository t
282 committing subrepository t
283 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
283 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
284 searching for copies back to rev 2
284 searching for copies back to rev 2
285 resolving manifests
285 resolving manifests
286 branchmerge: True, force: False, partial: False
286 branchmerge: True, force: False, partial: False
287 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
287 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
288 .hgsubstate: versions differ -> m
288 .hgsubstate: versions differ -> m
289 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
289 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
290 subrepo t: both sides changed
290 subrepo t: both sides changed
291 subrepository t diverged (local revision: 20a0db6fbf6c, remote revision: 7af322bc1198)
291 subrepository t diverged (local revision: 20a0db6fbf6c, remote revision: 7af322bc1198)
292 (M)erge, keep (l)ocal or keep (r)emote? m
292 (M)erge, keep (l)ocal or keep (r)emote? m
293 merging subrepo t
293 merging subrepo t
294 searching for copies back to rev 2
294 searching for copies back to rev 2
295 resolving manifests
295 resolving manifests
296 branchmerge: True, force: False, partial: False
296 branchmerge: True, force: False, partial: False
297 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
297 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
298 preserving t for resolve of t
298 preserving t for resolve of t
299 t: versions differ -> m
299 t: versions differ -> m
300 picked tool ':merge' for t (binary False symlink False)
300 picked tool ':merge' for t (binary False symlink False)
301 merging t
301 merging t
302 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
302 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
303 picked tool ':merge' for t (binary False symlink False)
304 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
303 warning: conflicts during merge.
305 warning: conflicts during merge.
304 merging t incomplete! (edit conflicts, then use 'hg resolve --mark')
306 merging t incomplete! (edit conflicts, then use 'hg resolve --mark')
305 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
307 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
306 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
308 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
307 subrepo t: merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
309 subrepo t: merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
308 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
309 (branch merge, don't forget to commit)
311 (branch merge, don't forget to commit)
310
312
311 should conflict
313 should conflict
312
314
313 $ cat t/t
315 $ cat t/t
314 <<<<<<< local: 20a0db6fbf6c - test: 10
316 <<<<<<< local: 20a0db6fbf6c - test: 10
315 conflict
317 conflict
316 =======
318 =======
317 t3
319 t3
318 >>>>>>> other: 7af322bc1198 - test: 7
320 >>>>>>> other: 7af322bc1198 - test: 7
319
321
320 11: remove subrepo t
322 11: remove subrepo t
321
323
322 $ hg co -C 5
324 $ hg co -C 5
323 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
325 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
324 $ hg revert -r 4 .hgsub # remove t
326 $ hg revert -r 4 .hgsub # remove t
325 $ hg ci -m11
327 $ hg ci -m11
326 created new head
328 created new head
327 $ hg debugsub
329 $ hg debugsub
328 path s
330 path s
329 source s
331 source s
330 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
332 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
331
333
332 local removed, remote changed, keep changed
334 local removed, remote changed, keep changed
333
335
334 $ hg merge 6
336 $ hg merge 6
335 remote changed subrepository t which local removed
337 remote changed subrepository t which local removed
336 use (c)hanged version or (d)elete? c
338 use (c)hanged version or (d)elete? c
337 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
339 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
338 (branch merge, don't forget to commit)
340 (branch merge, don't forget to commit)
339 BROKEN: should include subrepo t
341 BROKEN: should include subrepo t
340 $ hg debugsub
342 $ hg debugsub
341 path s
343 path s
342 source s
344 source s
343 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
345 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
344 $ cat .hgsubstate
346 $ cat .hgsubstate
345 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
347 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
346 6747d179aa9a688023c4b0cad32e4c92bb7f34ad t
348 6747d179aa9a688023c4b0cad32e4c92bb7f34ad t
347 $ hg ci -m 'local removed, remote changed, keep changed'
349 $ hg ci -m 'local removed, remote changed, keep changed'
348 BROKEN: should include subrepo t
350 BROKEN: should include subrepo t
349 $ hg debugsub
351 $ hg debugsub
350 path s
352 path s
351 source s
353 source s
352 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
354 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
353 BROKEN: should include subrepo t
355 BROKEN: should include subrepo t
354 $ cat .hgsubstate
356 $ cat .hgsubstate
355 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
357 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
356 $ cat t/t
358 $ cat t/t
357 t2
359 t2
358
360
359 local removed, remote changed, keep removed
361 local removed, remote changed, keep removed
360
362
361 $ hg co -C 11
363 $ hg co -C 11
362 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
364 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
363 $ hg merge --config ui.interactive=true 6 <<EOF
365 $ hg merge --config ui.interactive=true 6 <<EOF
364 > d
366 > d
365 > EOF
367 > EOF
366 remote changed subrepository t which local removed
368 remote changed subrepository t which local removed
367 use (c)hanged version or (d)elete? d
369 use (c)hanged version or (d)elete? d
368 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
370 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
369 (branch merge, don't forget to commit)
371 (branch merge, don't forget to commit)
370 $ hg debugsub
372 $ hg debugsub
371 path s
373 path s
372 source s
374 source s
373 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
375 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
374 $ cat .hgsubstate
376 $ cat .hgsubstate
375 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
377 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
376 $ hg ci -m 'local removed, remote changed, keep removed'
378 $ hg ci -m 'local removed, remote changed, keep removed'
377 created new head
379 created new head
378 $ hg debugsub
380 $ hg debugsub
379 path s
381 path s
380 source s
382 source s
381 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
383 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
382 $ cat .hgsubstate
384 $ cat .hgsubstate
383 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
385 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
384
386
385 local changed, remote removed, keep changed
387 local changed, remote removed, keep changed
386
388
387 $ hg co -C 6
389 $ hg co -C 6
388 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
390 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
389 $ hg merge 11
391 $ hg merge 11
390 local changed subrepository t which remote removed
392 local changed subrepository t which remote removed
391 use (c)hanged version or (d)elete? c
393 use (c)hanged version or (d)elete? c
392 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
394 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
393 (branch merge, don't forget to commit)
395 (branch merge, don't forget to commit)
394 BROKEN: should include subrepo t
396 BROKEN: should include subrepo t
395 $ hg debugsub
397 $ hg debugsub
396 path s
398 path s
397 source s
399 source s
398 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
400 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
399 BROKEN: should include subrepo t
401 BROKEN: should include subrepo t
400 $ cat .hgsubstate
402 $ cat .hgsubstate
401 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
403 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
402 $ hg ci -m 'local changed, remote removed, keep changed'
404 $ hg ci -m 'local changed, remote removed, keep changed'
403 created new head
405 created new head
404 BROKEN: should include subrepo t
406 BROKEN: should include subrepo t
405 $ hg debugsub
407 $ hg debugsub
406 path s
408 path s
407 source s
409 source s
408 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
410 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
409 BROKEN: should include subrepo t
411 BROKEN: should include subrepo t
410 $ cat .hgsubstate
412 $ cat .hgsubstate
411 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
413 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
412 $ cat t/t
414 $ cat t/t
413 t2
415 t2
414
416
415 local changed, remote removed, keep removed
417 local changed, remote removed, keep removed
416
418
417 $ hg co -C 6
419 $ hg co -C 6
418 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
420 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
419 $ hg merge --config ui.interactive=true 11 <<EOF
421 $ hg merge --config ui.interactive=true 11 <<EOF
420 > d
422 > d
421 > EOF
423 > EOF
422 local changed subrepository t which remote removed
424 local changed subrepository t which remote removed
423 use (c)hanged version or (d)elete? d
425 use (c)hanged version or (d)elete? d
424 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
426 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
425 (branch merge, don't forget to commit)
427 (branch merge, don't forget to commit)
426 $ hg debugsub
428 $ hg debugsub
427 path s
429 path s
428 source s
430 source s
429 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
431 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
430 $ cat .hgsubstate
432 $ cat .hgsubstate
431 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
433 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
432 $ hg ci -m 'local changed, remote removed, keep removed'
434 $ hg ci -m 'local changed, remote removed, keep removed'
433 created new head
435 created new head
434 $ hg debugsub
436 $ hg debugsub
435 path s
437 path s
436 source s
438 source s
437 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
439 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
438 $ cat .hgsubstate
440 $ cat .hgsubstate
439 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
441 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
440
442
441 clean up to avoid having to fix up the tests below
443 clean up to avoid having to fix up the tests below
442
444
443 $ hg co -C 10
445 $ hg co -C 10
444 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
446 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
445 $ cat >> $HGRCPATH <<EOF
447 $ cat >> $HGRCPATH <<EOF
446 > [extensions]
448 > [extensions]
447 > strip=
449 > strip=
448 > EOF
450 > EOF
449 $ hg strip -r 11:15
451 $ hg strip -r 11:15
450 saved backup bundle to $TESTTMP/t/.hg/strip-backup/*-backup.hg (glob)
452 saved backup bundle to $TESTTMP/t/.hg/strip-backup/*-backup.hg (glob)
451
453
452 clone
454 clone
453
455
454 $ cd ..
456 $ cd ..
455 $ hg clone t tc
457 $ hg clone t tc
456 updating to branch default
458 updating to branch default
457 cloning subrepo s from $TESTTMP/t/s
459 cloning subrepo s from $TESTTMP/t/s
458 cloning subrepo s/ss from $TESTTMP/t/s/ss (glob)
460 cloning subrepo s/ss from $TESTTMP/t/s/ss (glob)
459 cloning subrepo t from $TESTTMP/t/t
461 cloning subrepo t from $TESTTMP/t/t
460 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
462 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
461 $ cd tc
463 $ cd tc
462 $ hg debugsub
464 $ hg debugsub
463 path s
465 path s
464 source s
466 source s
465 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
467 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
466 path t
468 path t
467 source t
469 source t
468 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
470 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
469
471
470 push
472 push
471
473
472 $ echo bah > t/t
474 $ echo bah > t/t
473 $ hg ci -m11
475 $ hg ci -m11
474 committing subrepository t
476 committing subrepository t
475 $ hg push
477 $ hg push
476 pushing to $TESTTMP/t (glob)
478 pushing to $TESTTMP/t (glob)
477 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
479 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
478 no changes made to subrepo s since last push to $TESTTMP/t/s
480 no changes made to subrepo s since last push to $TESTTMP/t/s
479 pushing subrepo t to $TESTTMP/t/t
481 pushing subrepo t to $TESTTMP/t/t
480 searching for changes
482 searching for changes
481 adding changesets
483 adding changesets
482 adding manifests
484 adding manifests
483 adding file changes
485 adding file changes
484 added 1 changesets with 1 changes to 1 files
486 added 1 changesets with 1 changes to 1 files
485 searching for changes
487 searching for changes
486 adding changesets
488 adding changesets
487 adding manifests
489 adding manifests
488 adding file changes
490 adding file changes
489 added 1 changesets with 1 changes to 1 files
491 added 1 changesets with 1 changes to 1 files
490
492
491 push -f
493 push -f
492
494
493 $ echo bah > s/a
495 $ echo bah > s/a
494 $ hg ci -m12
496 $ hg ci -m12
495 committing subrepository s
497 committing subrepository s
496 $ hg push
498 $ hg push
497 pushing to $TESTTMP/t (glob)
499 pushing to $TESTTMP/t (glob)
498 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
500 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
499 pushing subrepo s to $TESTTMP/t/s
501 pushing subrepo s to $TESTTMP/t/s
500 searching for changes
502 searching for changes
501 abort: push creates new remote head 12a213df6fa9! (in subrepo s)
503 abort: push creates new remote head 12a213df6fa9! (in subrepo s)
502 (merge or see "hg help push" for details about pushing new heads)
504 (merge or see "hg help push" for details about pushing new heads)
503 [255]
505 [255]
504 $ hg push -f
506 $ hg push -f
505 pushing to $TESTTMP/t (glob)
507 pushing to $TESTTMP/t (glob)
506 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
508 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
507 searching for changes
509 searching for changes
508 no changes found
510 no changes found
509 pushing subrepo s to $TESTTMP/t/s
511 pushing subrepo s to $TESTTMP/t/s
510 searching for changes
512 searching for changes
511 adding changesets
513 adding changesets
512 adding manifests
514 adding manifests
513 adding file changes
515 adding file changes
514 added 1 changesets with 1 changes to 1 files (+1 heads)
516 added 1 changesets with 1 changes to 1 files (+1 heads)
515 pushing subrepo t to $TESTTMP/t/t
517 pushing subrepo t to $TESTTMP/t/t
516 searching for changes
518 searching for changes
517 no changes found
519 no changes found
518 searching for changes
520 searching for changes
519 adding changesets
521 adding changesets
520 adding manifests
522 adding manifests
521 adding file changes
523 adding file changes
522 added 1 changesets with 1 changes to 1 files
524 added 1 changesets with 1 changes to 1 files
523
525
524 check that unmodified subrepos are not pushed
526 check that unmodified subrepos are not pushed
525
527
526 $ hg clone . ../tcc
528 $ hg clone . ../tcc
527 updating to branch default
529 updating to branch default
528 cloning subrepo s from $TESTTMP/tc/s
530 cloning subrepo s from $TESTTMP/tc/s
529 cloning subrepo s/ss from $TESTTMP/tc/s/ss (glob)
531 cloning subrepo s/ss from $TESTTMP/tc/s/ss (glob)
530 cloning subrepo t from $TESTTMP/tc/t
532 cloning subrepo t from $TESTTMP/tc/t
531 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
533 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
532
534
533 the subrepos on the new clone have nothing to push to its source
535 the subrepos on the new clone have nothing to push to its source
534
536
535 $ hg push -R ../tcc .
537 $ hg push -R ../tcc .
536 pushing to .
538 pushing to .
537 no changes made to subrepo s/ss since last push to s/ss (glob)
539 no changes made to subrepo s/ss since last push to s/ss (glob)
538 no changes made to subrepo s since last push to s
540 no changes made to subrepo s since last push to s
539 no changes made to subrepo t since last push to t
541 no changes made to subrepo t since last push to t
540 searching for changes
542 searching for changes
541 no changes found
543 no changes found
542 [1]
544 [1]
543
545
544 the subrepos on the source do not have a clean store versus the clone target
546 the subrepos on the source do not have a clean store versus the clone target
545 because they were never explicitly pushed to the source
547 because they were never explicitly pushed to the source
546
548
547 $ hg push ../tcc
549 $ hg push ../tcc
548 pushing to ../tcc
550 pushing to ../tcc
549 pushing subrepo s/ss to ../tcc/s/ss (glob)
551 pushing subrepo s/ss to ../tcc/s/ss (glob)
550 searching for changes
552 searching for changes
551 no changes found
553 no changes found
552 pushing subrepo s to ../tcc/s
554 pushing subrepo s to ../tcc/s
553 searching for changes
555 searching for changes
554 no changes found
556 no changes found
555 pushing subrepo t to ../tcc/t
557 pushing subrepo t to ../tcc/t
556 searching for changes
558 searching for changes
557 no changes found
559 no changes found
558 searching for changes
560 searching for changes
559 no changes found
561 no changes found
560 [1]
562 [1]
561
563
562 after push their stores become clean
564 after push their stores become clean
563
565
564 $ hg push ../tcc
566 $ hg push ../tcc
565 pushing to ../tcc
567 pushing to ../tcc
566 no changes made to subrepo s/ss since last push to ../tcc/s/ss (glob)
568 no changes made to subrepo s/ss since last push to ../tcc/s/ss (glob)
567 no changes made to subrepo s since last push to ../tcc/s
569 no changes made to subrepo s since last push to ../tcc/s
568 no changes made to subrepo t since last push to ../tcc/t
570 no changes made to subrepo t since last push to ../tcc/t
569 searching for changes
571 searching for changes
570 no changes found
572 no changes found
571 [1]
573 [1]
572
574
573 updating a subrepo to a different revision or changing
575 updating a subrepo to a different revision or changing
574 its working directory does not make its store dirty
576 its working directory does not make its store dirty
575
577
576 $ hg -R s update '.^'
578 $ hg -R s update '.^'
577 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
579 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
578 $ hg push
580 $ hg push
579 pushing to $TESTTMP/t (glob)
581 pushing to $TESTTMP/t (glob)
580 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
582 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
581 no changes made to subrepo s since last push to $TESTTMP/t/s
583 no changes made to subrepo s since last push to $TESTTMP/t/s
582 no changes made to subrepo t since last push to $TESTTMP/t/t
584 no changes made to subrepo t since last push to $TESTTMP/t/t
583 searching for changes
585 searching for changes
584 no changes found
586 no changes found
585 [1]
587 [1]
586 $ echo foo >> s/a
588 $ echo foo >> s/a
587 $ hg push
589 $ hg push
588 pushing to $TESTTMP/t (glob)
590 pushing to $TESTTMP/t (glob)
589 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
591 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
590 no changes made to subrepo s since last push to $TESTTMP/t/s
592 no changes made to subrepo s since last push to $TESTTMP/t/s
591 no changes made to subrepo t since last push to $TESTTMP/t/t
593 no changes made to subrepo t since last push to $TESTTMP/t/t
592 searching for changes
594 searching for changes
593 no changes found
595 no changes found
594 [1]
596 [1]
595 $ hg -R s update -C tip
597 $ hg -R s update -C tip
596 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
598 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
597
599
598 committing into a subrepo makes its store (but not its parent's store) dirty
600 committing into a subrepo makes its store (but not its parent's store) dirty
599
601
600 $ echo foo >> s/ss/a
602 $ echo foo >> s/ss/a
601 $ hg -R s/ss commit -m 'test dirty store detection'
603 $ hg -R s/ss commit -m 'test dirty store detection'
602
604
603 $ hg out -S -r `hg log -r tip -T "{node|short}"`
605 $ hg out -S -r `hg log -r tip -T "{node|short}"`
604 comparing with $TESTTMP/t (glob)
606 comparing with $TESTTMP/t (glob)
605 searching for changes
607 searching for changes
606 no changes found
608 no changes found
607 comparing with $TESTTMP/t/s
609 comparing with $TESTTMP/t/s
608 searching for changes
610 searching for changes
609 no changes found
611 no changes found
610 comparing with $TESTTMP/t/s/ss
612 comparing with $TESTTMP/t/s/ss
611 searching for changes
613 searching for changes
612 changeset: 1:79ea5566a333
614 changeset: 1:79ea5566a333
613 tag: tip
615 tag: tip
614 user: test
616 user: test
615 date: Thu Jan 01 00:00:00 1970 +0000
617 date: Thu Jan 01 00:00:00 1970 +0000
616 summary: test dirty store detection
618 summary: test dirty store detection
617
619
618 comparing with $TESTTMP/t/t
620 comparing with $TESTTMP/t/t
619 searching for changes
621 searching for changes
620 no changes found
622 no changes found
621
623
622 $ hg push
624 $ hg push
623 pushing to $TESTTMP/t (glob)
625 pushing to $TESTTMP/t (glob)
624 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
626 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
625 searching for changes
627 searching for changes
626 adding changesets
628 adding changesets
627 adding manifests
629 adding manifests
628 adding file changes
630 adding file changes
629 added 1 changesets with 1 changes to 1 files
631 added 1 changesets with 1 changes to 1 files
630 no changes made to subrepo s since last push to $TESTTMP/t/s
632 no changes made to subrepo s since last push to $TESTTMP/t/s
631 no changes made to subrepo t since last push to $TESTTMP/t/t
633 no changes made to subrepo t since last push to $TESTTMP/t/t
632 searching for changes
634 searching for changes
633 no changes found
635 no changes found
634 [1]
636 [1]
635
637
636 a subrepo store may be clean versus one repo but not versus another
638 a subrepo store may be clean versus one repo but not versus another
637
639
638 $ hg push
640 $ hg push
639 pushing to $TESTTMP/t (glob)
641 pushing to $TESTTMP/t (glob)
640 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
642 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
641 no changes made to subrepo s since last push to $TESTTMP/t/s
643 no changes made to subrepo s since last push to $TESTTMP/t/s
642 no changes made to subrepo t since last push to $TESTTMP/t/t
644 no changes made to subrepo t since last push to $TESTTMP/t/t
643 searching for changes
645 searching for changes
644 no changes found
646 no changes found
645 [1]
647 [1]
646 $ hg push ../tcc
648 $ hg push ../tcc
647 pushing to ../tcc
649 pushing to ../tcc
648 pushing subrepo s/ss to ../tcc/s/ss (glob)
650 pushing subrepo s/ss to ../tcc/s/ss (glob)
649 searching for changes
651 searching for changes
650 adding changesets
652 adding changesets
651 adding manifests
653 adding manifests
652 adding file changes
654 adding file changes
653 added 1 changesets with 1 changes to 1 files
655 added 1 changesets with 1 changes to 1 files
654 no changes made to subrepo s since last push to ../tcc/s
656 no changes made to subrepo s since last push to ../tcc/s
655 no changes made to subrepo t since last push to ../tcc/t
657 no changes made to subrepo t since last push to ../tcc/t
656 searching for changes
658 searching for changes
657 no changes found
659 no changes found
658 [1]
660 [1]
659
661
660 update
662 update
661
663
662 $ cd ../t
664 $ cd ../t
663 $ hg up -C # discard our earlier merge
665 $ hg up -C # discard our earlier merge
664 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
666 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
665 $ echo blah > t/t
667 $ echo blah > t/t
666 $ hg ci -m13
668 $ hg ci -m13
667 committing subrepository t
669 committing subrepository t
668
670
669 backout calls revert internally with minimal opts, which should not raise
671 backout calls revert internally with minimal opts, which should not raise
670 KeyError
672 KeyError
671
673
672 $ hg backout ".^"
674 $ hg backout ".^"
673 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
675 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
674 changeset c373c8102e68 backed out, don't forget to commit.
676 changeset c373c8102e68 backed out, don't forget to commit.
675
677
676 $ hg up -C # discard changes
678 $ hg up -C # discard changes
677 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
679 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
678
680
679 pull
681 pull
680
682
681 $ cd ../tc
683 $ cd ../tc
682 $ hg pull
684 $ hg pull
683 pulling from $TESTTMP/t (glob)
685 pulling from $TESTTMP/t (glob)
684 searching for changes
686 searching for changes
685 adding changesets
687 adding changesets
686 adding manifests
688 adding manifests
687 adding file changes
689 adding file changes
688 added 1 changesets with 1 changes to 1 files
690 added 1 changesets with 1 changes to 1 files
689 (run 'hg update' to get a working copy)
691 (run 'hg update' to get a working copy)
690
692
691 should pull t
693 should pull t
692
694
693 $ hg incoming -S -r `hg log -r tip -T "{node|short}"`
695 $ hg incoming -S -r `hg log -r tip -T "{node|short}"`
694 comparing with $TESTTMP/t (glob)
696 comparing with $TESTTMP/t (glob)
695 no changes found
697 no changes found
696 comparing with $TESTTMP/t/s
698 comparing with $TESTTMP/t/s
697 searching for changes
699 searching for changes
698 no changes found
700 no changes found
699 comparing with $TESTTMP/t/s/ss
701 comparing with $TESTTMP/t/s/ss
700 searching for changes
702 searching for changes
701 no changes found
703 no changes found
702 comparing with $TESTTMP/t/t
704 comparing with $TESTTMP/t/t
703 searching for changes
705 searching for changes
704 changeset: 5:52c0adc0515a
706 changeset: 5:52c0adc0515a
705 tag: tip
707 tag: tip
706 user: test
708 user: test
707 date: Thu Jan 01 00:00:00 1970 +0000
709 date: Thu Jan 01 00:00:00 1970 +0000
708 summary: 13
710 summary: 13
709
711
710
712
711 $ hg up
713 $ hg up
712 pulling subrepo t from $TESTTMP/t/t
714 pulling subrepo t from $TESTTMP/t/t
713 searching for changes
715 searching for changes
714 adding changesets
716 adding changesets
715 adding manifests
717 adding manifests
716 adding file changes
718 adding file changes
717 added 1 changesets with 1 changes to 1 files
719 added 1 changesets with 1 changes to 1 files
718 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
720 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
719 $ cat t/t
721 $ cat t/t
720 blah
722 blah
721
723
722 bogus subrepo path aborts
724 bogus subrepo path aborts
723
725
724 $ echo 'bogus=[boguspath' >> .hgsub
726 $ echo 'bogus=[boguspath' >> .hgsub
725 $ hg ci -m 'bogus subrepo path'
727 $ hg ci -m 'bogus subrepo path'
726 abort: missing ] in subrepo source
728 abort: missing ] in subrepo source
727 [255]
729 [255]
728
730
729 Issue1986: merge aborts when trying to merge a subrepo that
731 Issue1986: merge aborts when trying to merge a subrepo that
730 shouldn't need merging
732 shouldn't need merging
731
733
732 # subrepo layout
734 # subrepo layout
733 #
735 #
734 # o 5 br
736 # o 5 br
735 # /|
737 # /|
736 # o | 4 default
738 # o | 4 default
737 # | |
739 # | |
738 # | o 3 br
740 # | o 3 br
739 # |/|
741 # |/|
740 # o | 2 default
742 # o | 2 default
741 # | |
743 # | |
742 # | o 1 br
744 # | o 1 br
743 # |/
745 # |/
744 # o 0 default
746 # o 0 default
745
747
746 $ cd ..
748 $ cd ..
747 $ rm -rf sub
749 $ rm -rf sub
748 $ hg init main
750 $ hg init main
749 $ cd main
751 $ cd main
750 $ hg init s
752 $ hg init s
751 $ cd s
753 $ cd s
752 $ echo a > a
754 $ echo a > a
753 $ hg ci -Am1
755 $ hg ci -Am1
754 adding a
756 adding a
755 $ hg branch br
757 $ hg branch br
756 marked working directory as branch br
758 marked working directory as branch br
757 (branches are permanent and global, did you want a bookmark?)
759 (branches are permanent and global, did you want a bookmark?)
758 $ echo a >> a
760 $ echo a >> a
759 $ hg ci -m1
761 $ hg ci -m1
760 $ hg up default
762 $ hg up default
761 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
763 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
762 $ echo b > b
764 $ echo b > b
763 $ hg ci -Am1
765 $ hg ci -Am1
764 adding b
766 adding b
765 $ hg up br
767 $ hg up br
766 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
768 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
767 $ hg merge tip
769 $ hg merge tip
768 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
770 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
769 (branch merge, don't forget to commit)
771 (branch merge, don't forget to commit)
770 $ hg ci -m1
772 $ hg ci -m1
771 $ hg up 2
773 $ hg up 2
772 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
774 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
773 $ echo c > c
775 $ echo c > c
774 $ hg ci -Am1
776 $ hg ci -Am1
775 adding c
777 adding c
776 $ hg up 3
778 $ hg up 3
777 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
779 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
778 $ hg merge 4
780 $ hg merge 4
779 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
781 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
780 (branch merge, don't forget to commit)
782 (branch merge, don't forget to commit)
781 $ hg ci -m1
783 $ hg ci -m1
782
784
783 # main repo layout:
785 # main repo layout:
784 #
786 #
785 # * <-- try to merge default into br again
787 # * <-- try to merge default into br again
786 # .`|
788 # .`|
787 # . o 5 br --> substate = 5
789 # . o 5 br --> substate = 5
788 # . |
790 # . |
789 # o | 4 default --> substate = 4
791 # o | 4 default --> substate = 4
790 # | |
792 # | |
791 # | o 3 br --> substate = 2
793 # | o 3 br --> substate = 2
792 # |/|
794 # |/|
793 # o | 2 default --> substate = 2
795 # o | 2 default --> substate = 2
794 # | |
796 # | |
795 # | o 1 br --> substate = 3
797 # | o 1 br --> substate = 3
796 # |/
798 # |/
797 # o 0 default --> substate = 2
799 # o 0 default --> substate = 2
798
800
799 $ cd ..
801 $ cd ..
800 $ echo 's = s' > .hgsub
802 $ echo 's = s' > .hgsub
801 $ hg -R s up 2
803 $ hg -R s up 2
802 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
804 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
803 $ hg ci -Am1
805 $ hg ci -Am1
804 adding .hgsub
806 adding .hgsub
805 $ hg branch br
807 $ hg branch br
806 marked working directory as branch br
808 marked working directory as branch br
807 (branches are permanent and global, did you want a bookmark?)
809 (branches are permanent and global, did you want a bookmark?)
808 $ echo b > b
810 $ echo b > b
809 $ hg -R s up 3
811 $ hg -R s up 3
810 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
812 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
811 $ hg ci -Am1
813 $ hg ci -Am1
812 adding b
814 adding b
813 $ hg up default
815 $ hg up default
814 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
816 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
815 $ echo c > c
817 $ echo c > c
816 $ hg ci -Am1
818 $ hg ci -Am1
817 adding c
819 adding c
818 $ hg up 1
820 $ hg up 1
819 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
821 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
820 $ hg merge 2
822 $ hg merge 2
821 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
823 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
822 (branch merge, don't forget to commit)
824 (branch merge, don't forget to commit)
823 $ hg ci -m1
825 $ hg ci -m1
824 $ hg up 2
826 $ hg up 2
825 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
827 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
826 $ hg -R s up 4
828 $ hg -R s up 4
827 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
829 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
828 $ echo d > d
830 $ echo d > d
829 $ hg ci -Am1
831 $ hg ci -Am1
830 adding d
832 adding d
831 $ hg up 3
833 $ hg up 3
832 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
834 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
833 $ hg -R s up 5
835 $ hg -R s up 5
834 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
836 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
835 $ echo e > e
837 $ echo e > e
836 $ hg ci -Am1
838 $ hg ci -Am1
837 adding e
839 adding e
838
840
839 $ hg up 5
841 $ hg up 5
840 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
842 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
841 $ hg merge 4 # try to merge default into br again
843 $ hg merge 4 # try to merge default into br again
842 subrepository s diverged (local revision: f8f13b33206e, remote revision: a3f9062a4f88)
844 subrepository s diverged (local revision: f8f13b33206e, remote revision: a3f9062a4f88)
843 (M)erge, keep (l)ocal or keep (r)emote? m
845 (M)erge, keep (l)ocal or keep (r)emote? m
844 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
846 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
845 (branch merge, don't forget to commit)
847 (branch merge, don't forget to commit)
846 $ cd ..
848 $ cd ..
847
849
848 test subrepo delete from .hgsubstate
850 test subrepo delete from .hgsubstate
849
851
850 $ hg init testdelete
852 $ hg init testdelete
851 $ mkdir testdelete/nested testdelete/nested2
853 $ mkdir testdelete/nested testdelete/nested2
852 $ hg init testdelete/nested
854 $ hg init testdelete/nested
853 $ hg init testdelete/nested2
855 $ hg init testdelete/nested2
854 $ echo test > testdelete/nested/foo
856 $ echo test > testdelete/nested/foo
855 $ echo test > testdelete/nested2/foo
857 $ echo test > testdelete/nested2/foo
856 $ hg -R testdelete/nested add
858 $ hg -R testdelete/nested add
857 adding testdelete/nested/foo (glob)
859 adding testdelete/nested/foo (glob)
858 $ hg -R testdelete/nested2 add
860 $ hg -R testdelete/nested2 add
859 adding testdelete/nested2/foo (glob)
861 adding testdelete/nested2/foo (glob)
860 $ hg -R testdelete/nested ci -m test
862 $ hg -R testdelete/nested ci -m test
861 $ hg -R testdelete/nested2 ci -m test
863 $ hg -R testdelete/nested2 ci -m test
862 $ echo nested = nested > testdelete/.hgsub
864 $ echo nested = nested > testdelete/.hgsub
863 $ echo nested2 = nested2 >> testdelete/.hgsub
865 $ echo nested2 = nested2 >> testdelete/.hgsub
864 $ hg -R testdelete add
866 $ hg -R testdelete add
865 adding testdelete/.hgsub (glob)
867 adding testdelete/.hgsub (glob)
866 $ hg -R testdelete ci -m "nested 1 & 2 added"
868 $ hg -R testdelete ci -m "nested 1 & 2 added"
867 $ echo nested = nested > testdelete/.hgsub
869 $ echo nested = nested > testdelete/.hgsub
868 $ hg -R testdelete ci -m "nested 2 deleted"
870 $ hg -R testdelete ci -m "nested 2 deleted"
869 $ cat testdelete/.hgsubstate
871 $ cat testdelete/.hgsubstate
870 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
872 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
871 $ hg -R testdelete remove testdelete/.hgsub
873 $ hg -R testdelete remove testdelete/.hgsub
872 $ hg -R testdelete ci -m ".hgsub deleted"
874 $ hg -R testdelete ci -m ".hgsub deleted"
873 $ cat testdelete/.hgsubstate
875 $ cat testdelete/.hgsubstate
874 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
876 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
875
877
876 test repository cloning
878 test repository cloning
877
879
878 $ mkdir mercurial mercurial2
880 $ mkdir mercurial mercurial2
879 $ hg init nested_absolute
881 $ hg init nested_absolute
880 $ echo test > nested_absolute/foo
882 $ echo test > nested_absolute/foo
881 $ hg -R nested_absolute add
883 $ hg -R nested_absolute add
882 adding nested_absolute/foo (glob)
884 adding nested_absolute/foo (glob)
883 $ hg -R nested_absolute ci -mtest
885 $ hg -R nested_absolute ci -mtest
884 $ cd mercurial
886 $ cd mercurial
885 $ hg init nested_relative
887 $ hg init nested_relative
886 $ echo test2 > nested_relative/foo2
888 $ echo test2 > nested_relative/foo2
887 $ hg -R nested_relative add
889 $ hg -R nested_relative add
888 adding nested_relative/foo2 (glob)
890 adding nested_relative/foo2 (glob)
889 $ hg -R nested_relative ci -mtest2
891 $ hg -R nested_relative ci -mtest2
890 $ hg init main
892 $ hg init main
891 $ echo "nested_relative = ../nested_relative" > main/.hgsub
893 $ echo "nested_relative = ../nested_relative" > main/.hgsub
892 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
894 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
893 $ hg -R main add
895 $ hg -R main add
894 adding main/.hgsub (glob)
896 adding main/.hgsub (glob)
895 $ hg -R main ci -m "add subrepos"
897 $ hg -R main ci -m "add subrepos"
896 $ cd ..
898 $ cd ..
897 $ hg clone mercurial/main mercurial2/main
899 $ hg clone mercurial/main mercurial2/main
898 updating to branch default
900 updating to branch default
899 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
901 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
900 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
902 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
901 > mercurial2/main/nested_relative/.hg/hgrc
903 > mercurial2/main/nested_relative/.hg/hgrc
902 [paths]
904 [paths]
903 default = $TESTTMP/mercurial/nested_absolute
905 default = $TESTTMP/mercurial/nested_absolute
904 [paths]
906 [paths]
905 default = $TESTTMP/mercurial/nested_relative
907 default = $TESTTMP/mercurial/nested_relative
906 $ rm -rf mercurial mercurial2
908 $ rm -rf mercurial mercurial2
907
909
908 Issue1977: multirepo push should fail if subrepo push fails
910 Issue1977: multirepo push should fail if subrepo push fails
909
911
910 $ hg init repo
912 $ hg init repo
911 $ hg init repo/s
913 $ hg init repo/s
912 $ echo a > repo/s/a
914 $ echo a > repo/s/a
913 $ hg -R repo/s ci -Am0
915 $ hg -R repo/s ci -Am0
914 adding a
916 adding a
915 $ echo s = s > repo/.hgsub
917 $ echo s = s > repo/.hgsub
916 $ hg -R repo ci -Am1
918 $ hg -R repo ci -Am1
917 adding .hgsub
919 adding .hgsub
918 $ hg clone repo repo2
920 $ hg clone repo repo2
919 updating to branch default
921 updating to branch default
920 cloning subrepo s from $TESTTMP/repo/s
922 cloning subrepo s from $TESTTMP/repo/s
921 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
923 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
922 $ hg -q -R repo2 pull -u
924 $ hg -q -R repo2 pull -u
923 $ echo 1 > repo2/s/a
925 $ echo 1 > repo2/s/a
924 $ hg -R repo2/s ci -m2
926 $ hg -R repo2/s ci -m2
925 $ hg -q -R repo2/s push
927 $ hg -q -R repo2/s push
926 $ hg -R repo2/s up -C 0
928 $ hg -R repo2/s up -C 0
927 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
929 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
928 $ echo 2 > repo2/s/b
930 $ echo 2 > repo2/s/b
929 $ hg -R repo2/s ci -m3 -A
931 $ hg -R repo2/s ci -m3 -A
930 adding b
932 adding b
931 created new head
933 created new head
932 $ hg -R repo2 ci -m3
934 $ hg -R repo2 ci -m3
933 $ hg -q -R repo2 push
935 $ hg -q -R repo2 push
934 abort: push creates new remote head cc505f09a8b2! (in subrepo s)
936 abort: push creates new remote head cc505f09a8b2! (in subrepo s)
935 (merge or see "hg help push" for details about pushing new heads)
937 (merge or see "hg help push" for details about pushing new heads)
936 [255]
938 [255]
937 $ hg -R repo update
939 $ hg -R repo update
938 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
940 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
939
941
940 test if untracked file is not overwritten
942 test if untracked file is not overwritten
941
943
942 (this also tests that updated .hgsubstate is treated as "modified",
944 (this also tests that updated .hgsubstate is treated as "modified",
943 when 'merge.update()' is aborted before 'merge.recordupdates()', even
945 when 'merge.update()' is aborted before 'merge.recordupdates()', even
944 if none of mode, size and timestamp of it isn't changed on the
946 if none of mode, size and timestamp of it isn't changed on the
945 filesystem (see also issue4583))
947 filesystem (see also issue4583))
946
948
947 $ echo issue3276_ok > repo/s/b
949 $ echo issue3276_ok > repo/s/b
948 $ hg -R repo2 push -f -q
950 $ hg -R repo2 push -f -q
949 $ touch -t 200001010000 repo/.hgsubstate
951 $ touch -t 200001010000 repo/.hgsubstate
950
952
951 $ cat >> repo/.hg/hgrc <<EOF
953 $ cat >> repo/.hg/hgrc <<EOF
952 > [fakedirstatewritetime]
954 > [fakedirstatewritetime]
953 > # emulate invoking dirstate.write() via repo.status()
955 > # emulate invoking dirstate.write() via repo.status()
954 > # at 2000-01-01 00:00
956 > # at 2000-01-01 00:00
955 > fakenow = 200001010000
957 > fakenow = 200001010000
956 >
958 >
957 > [extensions]
959 > [extensions]
958 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
960 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
959 > EOF
961 > EOF
960 $ hg -R repo update
962 $ hg -R repo update
961 b: untracked file differs
963 b: untracked file differs
962 abort: untracked files in working directory differ from files in requested revision (in subrepo s)
964 abort: untracked files in working directory differ from files in requested revision (in subrepo s)
963 [255]
965 [255]
964 $ cat >> repo/.hg/hgrc <<EOF
966 $ cat >> repo/.hg/hgrc <<EOF
965 > [extensions]
967 > [extensions]
966 > fakedirstatewritetime = !
968 > fakedirstatewritetime = !
967 > EOF
969 > EOF
968
970
969 $ cat repo/s/b
971 $ cat repo/s/b
970 issue3276_ok
972 issue3276_ok
971 $ rm repo/s/b
973 $ rm repo/s/b
972 $ touch -t 200001010000 repo/.hgsubstate
974 $ touch -t 200001010000 repo/.hgsubstate
973 $ hg -R repo revert --all
975 $ hg -R repo revert --all
974 reverting repo/.hgsubstate (glob)
976 reverting repo/.hgsubstate (glob)
975 reverting subrepo s
977 reverting subrepo s
976 $ hg -R repo update
978 $ hg -R repo update
977 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
979 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
978 $ cat repo/s/b
980 $ cat repo/s/b
979 2
981 2
980 $ rm -rf repo2 repo
982 $ rm -rf repo2 repo
981
983
982
984
983 Issue1852 subrepos with relative paths always push/pull relative to default
985 Issue1852 subrepos with relative paths always push/pull relative to default
984
986
985 Prepare a repo with subrepo
987 Prepare a repo with subrepo
986
988
987 $ hg init issue1852a
989 $ hg init issue1852a
988 $ cd issue1852a
990 $ cd issue1852a
989 $ hg init sub/repo
991 $ hg init sub/repo
990 $ echo test > sub/repo/foo
992 $ echo test > sub/repo/foo
991 $ hg -R sub/repo add sub/repo/foo
993 $ hg -R sub/repo add sub/repo/foo
992 $ echo sub/repo = sub/repo > .hgsub
994 $ echo sub/repo = sub/repo > .hgsub
993 $ hg add .hgsub
995 $ hg add .hgsub
994 $ hg ci -mtest
996 $ hg ci -mtest
995 committing subrepository sub/repo (glob)
997 committing subrepository sub/repo (glob)
996 $ echo test >> sub/repo/foo
998 $ echo test >> sub/repo/foo
997 $ hg ci -mtest
999 $ hg ci -mtest
998 committing subrepository sub/repo (glob)
1000 committing subrepository sub/repo (glob)
999 $ hg cat sub/repo/foo
1001 $ hg cat sub/repo/foo
1000 test
1002 test
1001 test
1003 test
1002 $ mkdir -p tmp/sub/repo
1004 $ mkdir -p tmp/sub/repo
1003 $ hg cat -r 0 --output tmp/%p_p sub/repo/foo
1005 $ hg cat -r 0 --output tmp/%p_p sub/repo/foo
1004 $ cat tmp/sub/repo/foo_p
1006 $ cat tmp/sub/repo/foo_p
1005 test
1007 test
1006 $ mv sub/repo sub_
1008 $ mv sub/repo sub_
1007 $ hg cat sub/repo/baz
1009 $ hg cat sub/repo/baz
1008 skipping missing subrepository: sub/repo
1010 skipping missing subrepository: sub/repo
1009 [1]
1011 [1]
1010 $ rm -rf sub/repo
1012 $ rm -rf sub/repo
1011 $ mv sub_ sub/repo
1013 $ mv sub_ sub/repo
1012 $ cd ..
1014 $ cd ..
1013
1015
1014 Create repo without default path, pull top repo, and see what happens on update
1016 Create repo without default path, pull top repo, and see what happens on update
1015
1017
1016 $ hg init issue1852b
1018 $ hg init issue1852b
1017 $ hg -R issue1852b pull issue1852a
1019 $ hg -R issue1852b pull issue1852a
1018 pulling from issue1852a
1020 pulling from issue1852a
1019 requesting all changes
1021 requesting all changes
1020 adding changesets
1022 adding changesets
1021 adding manifests
1023 adding manifests
1022 adding file changes
1024 adding file changes
1023 added 2 changesets with 3 changes to 2 files
1025 added 2 changesets with 3 changes to 2 files
1024 (run 'hg update' to get a working copy)
1026 (run 'hg update' to get a working copy)
1025 $ hg -R issue1852b update
1027 $ hg -R issue1852b update
1026 abort: default path for subrepository not found (in subrepo sub/repo) (glob)
1028 abort: default path for subrepository not found (in subrepo sub/repo) (glob)
1027 [255]
1029 [255]
1028
1030
1029 Ensure a full traceback, not just the SubrepoAbort part
1031 Ensure a full traceback, not just the SubrepoAbort part
1030
1032
1031 $ hg -R issue1852b update --traceback 2>&1 | grep 'raise error\.Abort'
1033 $ hg -R issue1852b update --traceback 2>&1 | grep 'raise error\.Abort'
1032 raise error.Abort(_("default path for subrepository not found"))
1034 raise error.Abort(_("default path for subrepository not found"))
1033
1035
1034 Pull -u now doesn't help
1036 Pull -u now doesn't help
1035
1037
1036 $ hg -R issue1852b pull -u issue1852a
1038 $ hg -R issue1852b pull -u issue1852a
1037 pulling from issue1852a
1039 pulling from issue1852a
1038 searching for changes
1040 searching for changes
1039 no changes found
1041 no changes found
1040
1042
1041 Try the same, but with pull -u
1043 Try the same, but with pull -u
1042
1044
1043 $ hg init issue1852c
1045 $ hg init issue1852c
1044 $ hg -R issue1852c pull -r0 -u issue1852a
1046 $ hg -R issue1852c pull -r0 -u issue1852a
1045 pulling from issue1852a
1047 pulling from issue1852a
1046 adding changesets
1048 adding changesets
1047 adding manifests
1049 adding manifests
1048 adding file changes
1050 adding file changes
1049 added 1 changesets with 2 changes to 2 files
1051 added 1 changesets with 2 changes to 2 files
1050 cloning subrepo sub/repo from issue1852a/sub/repo (glob)
1052 cloning subrepo sub/repo from issue1852a/sub/repo (glob)
1051 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1053 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1052
1054
1053 Try to push from the other side
1055 Try to push from the other side
1054
1056
1055 $ hg -R issue1852a push `pwd`/issue1852c
1057 $ hg -R issue1852a push `pwd`/issue1852c
1056 pushing to $TESTTMP/issue1852c (glob)
1058 pushing to $TESTTMP/issue1852c (glob)
1057 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
1059 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
1058 searching for changes
1060 searching for changes
1059 no changes found
1061 no changes found
1060 searching for changes
1062 searching for changes
1061 adding changesets
1063 adding changesets
1062 adding manifests
1064 adding manifests
1063 adding file changes
1065 adding file changes
1064 added 1 changesets with 1 changes to 1 files
1066 added 1 changesets with 1 changes to 1 files
1065
1067
1066 Incoming and outgoing should not use the default path:
1068 Incoming and outgoing should not use the default path:
1067
1069
1068 $ hg clone -q issue1852a issue1852d
1070 $ hg clone -q issue1852a issue1852d
1069 $ hg -R issue1852d outgoing --subrepos issue1852c
1071 $ hg -R issue1852d outgoing --subrepos issue1852c
1070 comparing with issue1852c
1072 comparing with issue1852c
1071 searching for changes
1073 searching for changes
1072 no changes found
1074 no changes found
1073 comparing with issue1852c/sub/repo
1075 comparing with issue1852c/sub/repo
1074 searching for changes
1076 searching for changes
1075 no changes found
1077 no changes found
1076 [1]
1078 [1]
1077 $ hg -R issue1852d incoming --subrepos issue1852c
1079 $ hg -R issue1852d incoming --subrepos issue1852c
1078 comparing with issue1852c
1080 comparing with issue1852c
1079 searching for changes
1081 searching for changes
1080 no changes found
1082 no changes found
1081 comparing with issue1852c/sub/repo
1083 comparing with issue1852c/sub/repo
1082 searching for changes
1084 searching for changes
1083 no changes found
1085 no changes found
1084 [1]
1086 [1]
1085
1087
1086 Check that merge of a new subrepo doesn't write the uncommitted state to
1088 Check that merge of a new subrepo doesn't write the uncommitted state to
1087 .hgsubstate (issue4622)
1089 .hgsubstate (issue4622)
1088
1090
1089 $ hg init issue1852a/addedsub
1091 $ hg init issue1852a/addedsub
1090 $ echo zzz > issue1852a/addedsub/zz.txt
1092 $ echo zzz > issue1852a/addedsub/zz.txt
1091 $ hg -R issue1852a/addedsub ci -Aqm "initial ZZ"
1093 $ hg -R issue1852a/addedsub ci -Aqm "initial ZZ"
1092
1094
1093 $ hg clone issue1852a/addedsub issue1852d/addedsub
1095 $ hg clone issue1852a/addedsub issue1852d/addedsub
1094 updating to branch default
1096 updating to branch default
1095 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1097 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1096
1098
1097 $ echo def > issue1852a/sub/repo/foo
1099 $ echo def > issue1852a/sub/repo/foo
1098 $ hg -R issue1852a ci -SAm 'tweaked subrepo'
1100 $ hg -R issue1852a ci -SAm 'tweaked subrepo'
1099 adding tmp/sub/repo/foo_p
1101 adding tmp/sub/repo/foo_p
1100 committing subrepository sub/repo (glob)
1102 committing subrepository sub/repo (glob)
1101
1103
1102 $ echo 'addedsub = addedsub' >> issue1852d/.hgsub
1104 $ echo 'addedsub = addedsub' >> issue1852d/.hgsub
1103 $ echo xyz > issue1852d/sub/repo/foo
1105 $ echo xyz > issue1852d/sub/repo/foo
1104 $ hg -R issue1852d pull -u
1106 $ hg -R issue1852d pull -u
1105 pulling from $TESTTMP/issue1852a (glob)
1107 pulling from $TESTTMP/issue1852a (glob)
1106 searching for changes
1108 searching for changes
1107 adding changesets
1109 adding changesets
1108 adding manifests
1110 adding manifests
1109 adding file changes
1111 adding file changes
1110 added 1 changesets with 2 changes to 2 files
1112 added 1 changesets with 2 changes to 2 files
1111 subrepository sub/repo diverged (local revision: f42d5c7504a8, remote revision: 46cd4aac504c)
1113 subrepository sub/repo diverged (local revision: f42d5c7504a8, remote revision: 46cd4aac504c)
1112 (M)erge, keep (l)ocal or keep (r)emote? m
1114 (M)erge, keep (l)ocal or keep (r)emote? m
1113 pulling subrepo sub/repo from $TESTTMP/issue1852a/sub/repo (glob)
1115 pulling subrepo sub/repo from $TESTTMP/issue1852a/sub/repo (glob)
1114 searching for changes
1116 searching for changes
1115 adding changesets
1117 adding changesets
1116 adding manifests
1118 adding manifests
1117 adding file changes
1119 adding file changes
1118 added 1 changesets with 1 changes to 1 files
1120 added 1 changesets with 1 changes to 1 files
1119 subrepository sources for sub/repo differ (glob)
1121 subrepository sources for sub/repo differ (glob)
1120 use (l)ocal source (f42d5c7504a8) or (r)emote source (46cd4aac504c)? l
1122 use (l)ocal source (f42d5c7504a8) or (r)emote source (46cd4aac504c)? l
1121 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1123 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1122 $ cat issue1852d/.hgsubstate
1124 $ cat issue1852d/.hgsubstate
1123 f42d5c7504a811dda50f5cf3e5e16c3330b87172 sub/repo
1125 f42d5c7504a811dda50f5cf3e5e16c3330b87172 sub/repo
1124
1126
1125 Check status of files when none of them belong to the first
1127 Check status of files when none of them belong to the first
1126 subrepository:
1128 subrepository:
1127
1129
1128 $ hg init subrepo-status
1130 $ hg init subrepo-status
1129 $ cd subrepo-status
1131 $ cd subrepo-status
1130 $ hg init subrepo-1
1132 $ hg init subrepo-1
1131 $ hg init subrepo-2
1133 $ hg init subrepo-2
1132 $ cd subrepo-2
1134 $ cd subrepo-2
1133 $ touch file
1135 $ touch file
1134 $ hg add file
1136 $ hg add file
1135 $ cd ..
1137 $ cd ..
1136 $ echo subrepo-1 = subrepo-1 > .hgsub
1138 $ echo subrepo-1 = subrepo-1 > .hgsub
1137 $ echo subrepo-2 = subrepo-2 >> .hgsub
1139 $ echo subrepo-2 = subrepo-2 >> .hgsub
1138 $ hg add .hgsub
1140 $ hg add .hgsub
1139 $ hg ci -m 'Added subrepos'
1141 $ hg ci -m 'Added subrepos'
1140 committing subrepository subrepo-2
1142 committing subrepository subrepo-2
1141 $ hg st subrepo-2/file
1143 $ hg st subrepo-2/file
1142
1144
1143 Check that share works with subrepo
1145 Check that share works with subrepo
1144 $ hg --config extensions.share= share . ../shared
1146 $ hg --config extensions.share= share . ../shared
1145 updating working directory
1147 updating working directory
1146 cloning subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
1148 cloning subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
1147 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1149 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1148 $ test -f ../shared/subrepo-1/.hg/sharedpath
1150 $ test -f ../shared/subrepo-1/.hg/sharedpath
1149 [1]
1151 [1]
1150 $ hg -R ../shared in
1152 $ hg -R ../shared in
1151 abort: repository default not found!
1153 abort: repository default not found!
1152 [255]
1154 [255]
1153 $ hg -R ../shared/subrepo-2 showconfig paths
1155 $ hg -R ../shared/subrepo-2 showconfig paths
1154 paths.default=$TESTTMP/subrepo-status/subrepo-2
1156 paths.default=$TESTTMP/subrepo-status/subrepo-2
1155 $ hg -R ../shared/subrepo-1 sum --remote
1157 $ hg -R ../shared/subrepo-1 sum --remote
1156 parent: -1:000000000000 tip (empty repository)
1158 parent: -1:000000000000 tip (empty repository)
1157 branch: default
1159 branch: default
1158 commit: (clean)
1160 commit: (clean)
1159 update: (current)
1161 update: (current)
1160 remote: (synced)
1162 remote: (synced)
1161
1163
1162 Check hg update --clean
1164 Check hg update --clean
1163 $ cd $TESTTMP/t
1165 $ cd $TESTTMP/t
1164 $ rm -r t/t.orig
1166 $ rm -r t/t.orig
1165 $ hg status -S --all
1167 $ hg status -S --all
1166 C .hgsub
1168 C .hgsub
1167 C .hgsubstate
1169 C .hgsubstate
1168 C a
1170 C a
1169 C s/.hgsub
1171 C s/.hgsub
1170 C s/.hgsubstate
1172 C s/.hgsubstate
1171 C s/a
1173 C s/a
1172 C s/ss/a
1174 C s/ss/a
1173 C t/t
1175 C t/t
1174 $ echo c1 > s/a
1176 $ echo c1 > s/a
1175 $ cd s
1177 $ cd s
1176 $ echo c1 > b
1178 $ echo c1 > b
1177 $ echo c1 > c
1179 $ echo c1 > c
1178 $ hg add b
1180 $ hg add b
1179 $ cd ..
1181 $ cd ..
1180 $ hg status -S
1182 $ hg status -S
1181 M s/a
1183 M s/a
1182 A s/b
1184 A s/b
1183 ? s/c
1185 ? s/c
1184 $ hg update -C
1186 $ hg update -C
1185 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1187 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1186 $ hg status -S
1188 $ hg status -S
1187 ? s/b
1189 ? s/b
1188 ? s/c
1190 ? s/c
1189
1191
1190 Sticky subrepositories, no changes
1192 Sticky subrepositories, no changes
1191 $ cd $TESTTMP/t
1193 $ cd $TESTTMP/t
1192 $ hg id
1194 $ hg id
1193 925c17564ef8 tip
1195 925c17564ef8 tip
1194 $ hg -R s id
1196 $ hg -R s id
1195 12a213df6fa9 tip
1197 12a213df6fa9 tip
1196 $ hg -R t id
1198 $ hg -R t id
1197 52c0adc0515a tip
1199 52c0adc0515a tip
1198 $ hg update 11
1200 $ hg update 11
1199 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1201 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1200 $ hg id
1202 $ hg id
1201 365661e5936a
1203 365661e5936a
1202 $ hg -R s id
1204 $ hg -R s id
1203 fc627a69481f
1205 fc627a69481f
1204 $ hg -R t id
1206 $ hg -R t id
1205 e95bcfa18a35
1207 e95bcfa18a35
1206
1208
1207 Sticky subrepositories, file changes
1209 Sticky subrepositories, file changes
1208 $ touch s/f1
1210 $ touch s/f1
1209 $ touch t/f1
1211 $ touch t/f1
1210 $ hg add -S s/f1
1212 $ hg add -S s/f1
1211 $ hg add -S t/f1
1213 $ hg add -S t/f1
1212 $ hg id
1214 $ hg id
1213 365661e5936a+
1215 365661e5936a+
1214 $ hg -R s id
1216 $ hg -R s id
1215 fc627a69481f+
1217 fc627a69481f+
1216 $ hg -R t id
1218 $ hg -R t id
1217 e95bcfa18a35+
1219 e95bcfa18a35+
1218 $ hg update tip
1220 $ hg update tip
1219 subrepository s diverged (local revision: fc627a69481f, remote revision: 12a213df6fa9)
1221 subrepository s diverged (local revision: fc627a69481f, remote revision: 12a213df6fa9)
1220 (M)erge, keep (l)ocal or keep (r)emote? m
1222 (M)erge, keep (l)ocal or keep (r)emote? m
1221 subrepository sources for s differ
1223 subrepository sources for s differ
1222 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)? l
1224 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)? l
1223 subrepository t diverged (local revision: e95bcfa18a35, remote revision: 52c0adc0515a)
1225 subrepository t diverged (local revision: e95bcfa18a35, remote revision: 52c0adc0515a)
1224 (M)erge, keep (l)ocal or keep (r)emote? m
1226 (M)erge, keep (l)ocal or keep (r)emote? m
1225 subrepository sources for t differ
1227 subrepository sources for t differ
1226 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)? l
1228 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)? l
1227 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1229 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1228 $ hg id
1230 $ hg id
1229 925c17564ef8+ tip
1231 925c17564ef8+ tip
1230 $ hg -R s id
1232 $ hg -R s id
1231 fc627a69481f+
1233 fc627a69481f+
1232 $ hg -R t id
1234 $ hg -R t id
1233 e95bcfa18a35+
1235 e95bcfa18a35+
1234 $ hg update --clean tip
1236 $ hg update --clean tip
1235 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1237 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1236
1238
1237 Sticky subrepository, revision updates
1239 Sticky subrepository, revision updates
1238 $ hg id
1240 $ hg id
1239 925c17564ef8 tip
1241 925c17564ef8 tip
1240 $ hg -R s id
1242 $ hg -R s id
1241 12a213df6fa9 tip
1243 12a213df6fa9 tip
1242 $ hg -R t id
1244 $ hg -R t id
1243 52c0adc0515a tip
1245 52c0adc0515a tip
1244 $ cd s
1246 $ cd s
1245 $ hg update -r -2
1247 $ hg update -r -2
1246 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1247 $ cd ../t
1249 $ cd ../t
1248 $ hg update -r 2
1250 $ hg update -r 2
1249 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1251 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1250 $ cd ..
1252 $ cd ..
1251 $ hg update 10
1253 $ hg update 10
1252 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1254 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1253 (M)erge, keep (l)ocal or keep (r)emote? m
1255 (M)erge, keep (l)ocal or keep (r)emote? m
1254 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 20a0db6fbf6c)
1256 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 20a0db6fbf6c)
1255 (M)erge, keep (l)ocal or keep (r)emote? m
1257 (M)erge, keep (l)ocal or keep (r)emote? m
1256 subrepository sources for t differ (in checked out version)
1258 subrepository sources for t differ (in checked out version)
1257 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)? l
1259 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)? l
1258 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1260 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1259 $ hg id
1261 $ hg id
1260 e45c8b14af55+
1262 e45c8b14af55+
1261 $ hg -R s id
1263 $ hg -R s id
1262 02dcf1d70411
1264 02dcf1d70411
1263 $ hg -R t id
1265 $ hg -R t id
1264 7af322bc1198
1266 7af322bc1198
1265
1267
1266 Sticky subrepository, file changes and revision updates
1268 Sticky subrepository, file changes and revision updates
1267 $ touch s/f1
1269 $ touch s/f1
1268 $ touch t/f1
1270 $ touch t/f1
1269 $ hg add -S s/f1
1271 $ hg add -S s/f1
1270 $ hg add -S t/f1
1272 $ hg add -S t/f1
1271 $ hg id
1273 $ hg id
1272 e45c8b14af55+
1274 e45c8b14af55+
1273 $ hg -R s id
1275 $ hg -R s id
1274 02dcf1d70411+
1276 02dcf1d70411+
1275 $ hg -R t id
1277 $ hg -R t id
1276 7af322bc1198+
1278 7af322bc1198+
1277 $ hg update tip
1279 $ hg update tip
1278 subrepository s diverged (local revision: 12a213df6fa9, remote revision: 12a213df6fa9)
1280 subrepository s diverged (local revision: 12a213df6fa9, remote revision: 12a213df6fa9)
1279 (M)erge, keep (l)ocal or keep (r)emote? m
1281 (M)erge, keep (l)ocal or keep (r)emote? m
1280 subrepository sources for s differ
1282 subrepository sources for s differ
1281 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)? l
1283 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)? l
1282 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 52c0adc0515a)
1284 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 52c0adc0515a)
1283 (M)erge, keep (l)ocal or keep (r)emote? m
1285 (M)erge, keep (l)ocal or keep (r)emote? m
1284 subrepository sources for t differ
1286 subrepository sources for t differ
1285 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)? l
1287 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)? l
1286 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1288 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1287 $ hg id
1289 $ hg id
1288 925c17564ef8+ tip
1290 925c17564ef8+ tip
1289 $ hg -R s id
1291 $ hg -R s id
1290 02dcf1d70411+
1292 02dcf1d70411+
1291 $ hg -R t id
1293 $ hg -R t id
1292 7af322bc1198+
1294 7af322bc1198+
1293
1295
1294 Sticky repository, update --clean
1296 Sticky repository, update --clean
1295 $ hg update --clean tip
1297 $ hg update --clean tip
1296 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1298 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1297 $ hg id
1299 $ hg id
1298 925c17564ef8 tip
1300 925c17564ef8 tip
1299 $ hg -R s id
1301 $ hg -R s id
1300 12a213df6fa9 tip
1302 12a213df6fa9 tip
1301 $ hg -R t id
1303 $ hg -R t id
1302 52c0adc0515a tip
1304 52c0adc0515a tip
1303
1305
1304 Test subrepo already at intended revision:
1306 Test subrepo already at intended revision:
1305 $ cd s
1307 $ cd s
1306 $ hg update fc627a69481f
1308 $ hg update fc627a69481f
1307 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1309 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1308 $ cd ..
1310 $ cd ..
1309 $ hg update 11
1311 $ hg update 11
1310 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1312 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1311 (M)erge, keep (l)ocal or keep (r)emote? m
1313 (M)erge, keep (l)ocal or keep (r)emote? m
1312 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1314 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1313 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1315 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1314 $ hg id -n
1316 $ hg id -n
1315 11+
1317 11+
1316 $ hg -R s id
1318 $ hg -R s id
1317 fc627a69481f
1319 fc627a69481f
1318 $ hg -R t id
1320 $ hg -R t id
1319 e95bcfa18a35
1321 e95bcfa18a35
1320
1322
1321 Test that removing .hgsubstate doesn't break anything:
1323 Test that removing .hgsubstate doesn't break anything:
1322
1324
1323 $ hg rm -f .hgsubstate
1325 $ hg rm -f .hgsubstate
1324 $ hg ci -mrm
1326 $ hg ci -mrm
1325 nothing changed
1327 nothing changed
1326 [1]
1328 [1]
1327 $ hg log -vr tip
1329 $ hg log -vr tip
1328 changeset: 13:925c17564ef8
1330 changeset: 13:925c17564ef8
1329 tag: tip
1331 tag: tip
1330 user: test
1332 user: test
1331 date: Thu Jan 01 00:00:00 1970 +0000
1333 date: Thu Jan 01 00:00:00 1970 +0000
1332 files: .hgsubstate
1334 files: .hgsubstate
1333 description:
1335 description:
1334 13
1336 13
1335
1337
1336
1338
1337
1339
1338 Test that removing .hgsub removes .hgsubstate:
1340 Test that removing .hgsub removes .hgsubstate:
1339
1341
1340 $ hg rm .hgsub
1342 $ hg rm .hgsub
1341 $ hg ci -mrm2
1343 $ hg ci -mrm2
1342 created new head
1344 created new head
1343 $ hg log -vr tip
1345 $ hg log -vr tip
1344 changeset: 14:2400bccd50af
1346 changeset: 14:2400bccd50af
1345 tag: tip
1347 tag: tip
1346 parent: 11:365661e5936a
1348 parent: 11:365661e5936a
1347 user: test
1349 user: test
1348 date: Thu Jan 01 00:00:00 1970 +0000
1350 date: Thu Jan 01 00:00:00 1970 +0000
1349 files: .hgsub .hgsubstate
1351 files: .hgsub .hgsubstate
1350 description:
1352 description:
1351 rm2
1353 rm2
1352
1354
1353
1355
1354 Test issue3153: diff -S with deleted subrepos
1356 Test issue3153: diff -S with deleted subrepos
1355
1357
1356 $ hg diff --nodates -S -c .
1358 $ hg diff --nodates -S -c .
1357 diff -r 365661e5936a -r 2400bccd50af .hgsub
1359 diff -r 365661e5936a -r 2400bccd50af .hgsub
1358 --- a/.hgsub
1360 --- a/.hgsub
1359 +++ /dev/null
1361 +++ /dev/null
1360 @@ -1,2 +0,0 @@
1362 @@ -1,2 +0,0 @@
1361 -s = s
1363 -s = s
1362 -t = t
1364 -t = t
1363 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
1365 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
1364 --- a/.hgsubstate
1366 --- a/.hgsubstate
1365 +++ /dev/null
1367 +++ /dev/null
1366 @@ -1,2 +0,0 @@
1368 @@ -1,2 +0,0 @@
1367 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1369 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1368 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
1370 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
1369
1371
1370 Test behavior of add for explicit path in subrepo:
1372 Test behavior of add for explicit path in subrepo:
1371 $ cd ..
1373 $ cd ..
1372 $ hg init explicit
1374 $ hg init explicit
1373 $ cd explicit
1375 $ cd explicit
1374 $ echo s = s > .hgsub
1376 $ echo s = s > .hgsub
1375 $ hg add .hgsub
1377 $ hg add .hgsub
1376 $ hg init s
1378 $ hg init s
1377 $ hg ci -m0
1379 $ hg ci -m0
1378 Adding with an explicit path in a subrepo adds the file
1380 Adding with an explicit path in a subrepo adds the file
1379 $ echo c1 > f1
1381 $ echo c1 > f1
1380 $ echo c2 > s/f2
1382 $ echo c2 > s/f2
1381 $ hg st -S
1383 $ hg st -S
1382 ? f1
1384 ? f1
1383 ? s/f2
1385 ? s/f2
1384 $ hg add s/f2
1386 $ hg add s/f2
1385 $ hg st -S
1387 $ hg st -S
1386 A s/f2
1388 A s/f2
1387 ? f1
1389 ? f1
1388 $ hg ci -R s -m0
1390 $ hg ci -R s -m0
1389 $ hg ci -Am1
1391 $ hg ci -Am1
1390 adding f1
1392 adding f1
1391 Adding with an explicit path in a subrepo with -S has the same behavior
1393 Adding with an explicit path in a subrepo with -S has the same behavior
1392 $ echo c3 > f3
1394 $ echo c3 > f3
1393 $ echo c4 > s/f4
1395 $ echo c4 > s/f4
1394 $ hg st -S
1396 $ hg st -S
1395 ? f3
1397 ? f3
1396 ? s/f4
1398 ? s/f4
1397 $ hg add -S s/f4
1399 $ hg add -S s/f4
1398 $ hg st -S
1400 $ hg st -S
1399 A s/f4
1401 A s/f4
1400 ? f3
1402 ? f3
1401 $ hg ci -R s -m1
1403 $ hg ci -R s -m1
1402 $ hg ci -Ama2
1404 $ hg ci -Ama2
1403 adding f3
1405 adding f3
1404 Adding without a path or pattern silently ignores subrepos
1406 Adding without a path or pattern silently ignores subrepos
1405 $ echo c5 > f5
1407 $ echo c5 > f5
1406 $ echo c6 > s/f6
1408 $ echo c6 > s/f6
1407 $ echo c7 > s/f7
1409 $ echo c7 > s/f7
1408 $ hg st -S
1410 $ hg st -S
1409 ? f5
1411 ? f5
1410 ? s/f6
1412 ? s/f6
1411 ? s/f7
1413 ? s/f7
1412 $ hg add
1414 $ hg add
1413 adding f5
1415 adding f5
1414 $ hg st -S
1416 $ hg st -S
1415 A f5
1417 A f5
1416 ? s/f6
1418 ? s/f6
1417 ? s/f7
1419 ? s/f7
1418 $ hg ci -R s -Am2
1420 $ hg ci -R s -Am2
1419 adding f6
1421 adding f6
1420 adding f7
1422 adding f7
1421 $ hg ci -m3
1423 $ hg ci -m3
1422 Adding without a path or pattern with -S also adds files in subrepos
1424 Adding without a path or pattern with -S also adds files in subrepos
1423 $ echo c8 > f8
1425 $ echo c8 > f8
1424 $ echo c9 > s/f9
1426 $ echo c9 > s/f9
1425 $ echo c10 > s/f10
1427 $ echo c10 > s/f10
1426 $ hg st -S
1428 $ hg st -S
1427 ? f8
1429 ? f8
1428 ? s/f10
1430 ? s/f10
1429 ? s/f9
1431 ? s/f9
1430 $ hg add -S
1432 $ hg add -S
1431 adding f8
1433 adding f8
1432 adding s/f10 (glob)
1434 adding s/f10 (glob)
1433 adding s/f9 (glob)
1435 adding s/f9 (glob)
1434 $ hg st -S
1436 $ hg st -S
1435 A f8
1437 A f8
1436 A s/f10
1438 A s/f10
1437 A s/f9
1439 A s/f9
1438 $ hg ci -R s -m3
1440 $ hg ci -R s -m3
1439 $ hg ci -m4
1441 $ hg ci -m4
1440 Adding with a pattern silently ignores subrepos
1442 Adding with a pattern silently ignores subrepos
1441 $ echo c11 > fm11
1443 $ echo c11 > fm11
1442 $ echo c12 > fn12
1444 $ echo c12 > fn12
1443 $ echo c13 > s/fm13
1445 $ echo c13 > s/fm13
1444 $ echo c14 > s/fn14
1446 $ echo c14 > s/fn14
1445 $ hg st -S
1447 $ hg st -S
1446 ? fm11
1448 ? fm11
1447 ? fn12
1449 ? fn12
1448 ? s/fm13
1450 ? s/fm13
1449 ? s/fn14
1451 ? s/fn14
1450 $ hg add 'glob:**fm*'
1452 $ hg add 'glob:**fm*'
1451 adding fm11
1453 adding fm11
1452 $ hg st -S
1454 $ hg st -S
1453 A fm11
1455 A fm11
1454 ? fn12
1456 ? fn12
1455 ? s/fm13
1457 ? s/fm13
1456 ? s/fn14
1458 ? s/fn14
1457 $ hg ci -R s -Am4
1459 $ hg ci -R s -Am4
1458 adding fm13
1460 adding fm13
1459 adding fn14
1461 adding fn14
1460 $ hg ci -Am5
1462 $ hg ci -Am5
1461 adding fn12
1463 adding fn12
1462 Adding with a pattern with -S also adds matches in subrepos
1464 Adding with a pattern with -S also adds matches in subrepos
1463 $ echo c15 > fm15
1465 $ echo c15 > fm15
1464 $ echo c16 > fn16
1466 $ echo c16 > fn16
1465 $ echo c17 > s/fm17
1467 $ echo c17 > s/fm17
1466 $ echo c18 > s/fn18
1468 $ echo c18 > s/fn18
1467 $ hg st -S
1469 $ hg st -S
1468 ? fm15
1470 ? fm15
1469 ? fn16
1471 ? fn16
1470 ? s/fm17
1472 ? s/fm17
1471 ? s/fn18
1473 ? s/fn18
1472 $ hg add -S 'glob:**fm*'
1474 $ hg add -S 'glob:**fm*'
1473 adding fm15
1475 adding fm15
1474 adding s/fm17 (glob)
1476 adding s/fm17 (glob)
1475 $ hg st -S
1477 $ hg st -S
1476 A fm15
1478 A fm15
1477 A s/fm17
1479 A s/fm17
1478 ? fn16
1480 ? fn16
1479 ? s/fn18
1481 ? s/fn18
1480 $ hg ci -R s -Am5
1482 $ hg ci -R s -Am5
1481 adding fn18
1483 adding fn18
1482 $ hg ci -Am6
1484 $ hg ci -Am6
1483 adding fn16
1485 adding fn16
1484
1486
1485 Test behavior of forget for explicit path in subrepo:
1487 Test behavior of forget for explicit path in subrepo:
1486 Forgetting an explicit path in a subrepo untracks the file
1488 Forgetting an explicit path in a subrepo untracks the file
1487 $ echo c19 > s/f19
1489 $ echo c19 > s/f19
1488 $ hg add s/f19
1490 $ hg add s/f19
1489 $ hg st -S
1491 $ hg st -S
1490 A s/f19
1492 A s/f19
1491 $ hg forget s/f19
1493 $ hg forget s/f19
1492 $ hg st -S
1494 $ hg st -S
1493 ? s/f19
1495 ? s/f19
1494 $ rm s/f19
1496 $ rm s/f19
1495 $ cd ..
1497 $ cd ..
1496
1498
1497 Courtesy phases synchronisation to publishing server does not block the push
1499 Courtesy phases synchronisation to publishing server does not block the push
1498 (issue3781)
1500 (issue3781)
1499
1501
1500 $ cp -r main issue3781
1502 $ cp -r main issue3781
1501 $ cp -r main issue3781-dest
1503 $ cp -r main issue3781-dest
1502 $ cd issue3781-dest/s
1504 $ cd issue3781-dest/s
1503 $ hg phase tip # show we have draft changeset
1505 $ hg phase tip # show we have draft changeset
1504 5: draft
1506 5: draft
1505 $ chmod a-w .hg/store/phaseroots # prevent phase push
1507 $ chmod a-w .hg/store/phaseroots # prevent phase push
1506 $ cd ../../issue3781
1508 $ cd ../../issue3781
1507 $ cat >> .hg/hgrc << EOF
1509 $ cat >> .hg/hgrc << EOF
1508 > [paths]
1510 > [paths]
1509 > default=../issue3781-dest/
1511 > default=../issue3781-dest/
1510 > EOF
1512 > EOF
1511 $ hg push --config experimental.bundle2-exp=False
1513 $ hg push --config experimental.bundle2-exp=False
1512 pushing to $TESTTMP/issue3781-dest (glob)
1514 pushing to $TESTTMP/issue3781-dest (glob)
1513 pushing subrepo s to $TESTTMP/issue3781-dest/s
1515 pushing subrepo s to $TESTTMP/issue3781-dest/s
1514 searching for changes
1516 searching for changes
1515 no changes found
1517 no changes found
1516 searching for changes
1518 searching for changes
1517 no changes found
1519 no changes found
1518 [1]
1520 [1]
1519 # clean the push cache
1521 # clean the push cache
1520 $ rm s/.hg/cache/storehash/*
1522 $ rm s/.hg/cache/storehash/*
1521 $ hg push --config experimental.bundle2-exp=True
1523 $ hg push --config experimental.bundle2-exp=True
1522 pushing to $TESTTMP/issue3781-dest (glob)
1524 pushing to $TESTTMP/issue3781-dest (glob)
1523 pushing subrepo s to $TESTTMP/issue3781-dest/s
1525 pushing subrepo s to $TESTTMP/issue3781-dest/s
1524 searching for changes
1526 searching for changes
1525 no changes found
1527 no changes found
1526 searching for changes
1528 searching for changes
1527 no changes found
1529 no changes found
1528 [1]
1530 [1]
1529 $ cd ..
1531 $ cd ..
1530
1532
1531 Test phase choice for newly created commit with "phases.subrepochecks"
1533 Test phase choice for newly created commit with "phases.subrepochecks"
1532 configuration
1534 configuration
1533
1535
1534 $ cd t
1536 $ cd t
1535 $ hg update -q -r 12
1537 $ hg update -q -r 12
1536
1538
1537 $ cat >> s/ss/.hg/hgrc <<EOF
1539 $ cat >> s/ss/.hg/hgrc <<EOF
1538 > [phases]
1540 > [phases]
1539 > new-commit = secret
1541 > new-commit = secret
1540 > EOF
1542 > EOF
1541 $ cat >> s/.hg/hgrc <<EOF
1543 $ cat >> s/.hg/hgrc <<EOF
1542 > [phases]
1544 > [phases]
1543 > new-commit = draft
1545 > new-commit = draft
1544 > EOF
1546 > EOF
1545 $ echo phasecheck1 >> s/ss/a
1547 $ echo phasecheck1 >> s/ss/a
1546 $ hg -R s commit -S --config phases.checksubrepos=abort -m phasecheck1
1548 $ hg -R s commit -S --config phases.checksubrepos=abort -m phasecheck1
1547 committing subrepository ss
1549 committing subrepository ss
1548 transaction abort!
1550 transaction abort!
1549 rollback completed
1551 rollback completed
1550 abort: can't commit in draft phase conflicting secret from subrepository ss
1552 abort: can't commit in draft phase conflicting secret from subrepository ss
1551 [255]
1553 [255]
1552 $ echo phasecheck2 >> s/ss/a
1554 $ echo phasecheck2 >> s/ss/a
1553 $ hg -R s commit -S --config phases.checksubrepos=ignore -m phasecheck2
1555 $ hg -R s commit -S --config phases.checksubrepos=ignore -m phasecheck2
1554 committing subrepository ss
1556 committing subrepository ss
1555 $ hg -R s/ss phase tip
1557 $ hg -R s/ss phase tip
1556 3: secret
1558 3: secret
1557 $ hg -R s phase tip
1559 $ hg -R s phase tip
1558 6: draft
1560 6: draft
1559 $ echo phasecheck3 >> s/ss/a
1561 $ echo phasecheck3 >> s/ss/a
1560 $ hg -R s commit -S -m phasecheck3
1562 $ hg -R s commit -S -m phasecheck3
1561 committing subrepository ss
1563 committing subrepository ss
1562 warning: changes are committed in secret phase from subrepository ss
1564 warning: changes are committed in secret phase from subrepository ss
1563 $ hg -R s/ss phase tip
1565 $ hg -R s/ss phase tip
1564 4: secret
1566 4: secret
1565 $ hg -R s phase tip
1567 $ hg -R s phase tip
1566 7: secret
1568 7: secret
1567
1569
1568 $ cat >> t/.hg/hgrc <<EOF
1570 $ cat >> t/.hg/hgrc <<EOF
1569 > [phases]
1571 > [phases]
1570 > new-commit = draft
1572 > new-commit = draft
1571 > EOF
1573 > EOF
1572 $ cat >> .hg/hgrc <<EOF
1574 $ cat >> .hg/hgrc <<EOF
1573 > [phases]
1575 > [phases]
1574 > new-commit = public
1576 > new-commit = public
1575 > EOF
1577 > EOF
1576 $ echo phasecheck4 >> s/ss/a
1578 $ echo phasecheck4 >> s/ss/a
1577 $ echo phasecheck4 >> t/t
1579 $ echo phasecheck4 >> t/t
1578 $ hg commit -S -m phasecheck4
1580 $ hg commit -S -m phasecheck4
1579 committing subrepository s
1581 committing subrepository s
1580 committing subrepository s/ss (glob)
1582 committing subrepository s/ss (glob)
1581 warning: changes are committed in secret phase from subrepository ss
1583 warning: changes are committed in secret phase from subrepository ss
1582 committing subrepository t
1584 committing subrepository t
1583 warning: changes are committed in secret phase from subrepository s
1585 warning: changes are committed in secret phase from subrepository s
1584 created new head
1586 created new head
1585 $ hg -R s/ss phase tip
1587 $ hg -R s/ss phase tip
1586 5: secret
1588 5: secret
1587 $ hg -R s phase tip
1589 $ hg -R s phase tip
1588 8: secret
1590 8: secret
1589 $ hg -R t phase tip
1591 $ hg -R t phase tip
1590 6: draft
1592 6: draft
1591 $ hg phase tip
1593 $ hg phase tip
1592 15: secret
1594 15: secret
1593
1595
1594 $ cd ..
1596 $ cd ..
1595
1597
1596
1598
1597 Test that commit --secret works on both repo and subrepo (issue4182)
1599 Test that commit --secret works on both repo and subrepo (issue4182)
1598
1600
1599 $ cd main
1601 $ cd main
1600 $ echo secret >> b
1602 $ echo secret >> b
1601 $ echo secret >> s/b
1603 $ echo secret >> s/b
1602 $ hg commit --secret --subrepo -m "secret"
1604 $ hg commit --secret --subrepo -m "secret"
1603 committing subrepository s
1605 committing subrepository s
1604 $ hg phase -r .
1606 $ hg phase -r .
1605 6: secret
1607 6: secret
1606 $ cd s
1608 $ cd s
1607 $ hg phase -r .
1609 $ hg phase -r .
1608 6: secret
1610 6: secret
1609 $ cd ../../
1611 $ cd ../../
1610
1612
1611 Test "subrepos" template keyword
1613 Test "subrepos" template keyword
1612
1614
1613 $ cd t
1615 $ cd t
1614 $ hg update -q 15
1616 $ hg update -q 15
1615 $ cat > .hgsub <<EOF
1617 $ cat > .hgsub <<EOF
1616 > s = s
1618 > s = s
1617 > EOF
1619 > EOF
1618 $ hg commit -m "16"
1620 $ hg commit -m "16"
1619 warning: changes are committed in secret phase from subrepository s
1621 warning: changes are committed in secret phase from subrepository s
1620
1622
1621 (addition of ".hgsub" itself)
1623 (addition of ".hgsub" itself)
1622
1624
1623 $ hg diff --nodates -c 1 .hgsubstate
1625 $ hg diff --nodates -c 1 .hgsubstate
1624 diff -r f7b1eb17ad24 -r 7cf8cfea66e4 .hgsubstate
1626 diff -r f7b1eb17ad24 -r 7cf8cfea66e4 .hgsubstate
1625 --- /dev/null
1627 --- /dev/null
1626 +++ b/.hgsubstate
1628 +++ b/.hgsubstate
1627 @@ -0,0 +1,1 @@
1629 @@ -0,0 +1,1 @@
1628 +e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1630 +e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1629 $ hg log -r 1 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1631 $ hg log -r 1 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1630 f7b1eb17ad24 000000000000
1632 f7b1eb17ad24 000000000000
1631 s
1633 s
1632
1634
1633 (modification of existing entry)
1635 (modification of existing entry)
1634
1636
1635 $ hg diff --nodates -c 2 .hgsubstate
1637 $ hg diff --nodates -c 2 .hgsubstate
1636 diff -r 7cf8cfea66e4 -r df30734270ae .hgsubstate
1638 diff -r 7cf8cfea66e4 -r df30734270ae .hgsubstate
1637 --- a/.hgsubstate
1639 --- a/.hgsubstate
1638 +++ b/.hgsubstate
1640 +++ b/.hgsubstate
1639 @@ -1,1 +1,1 @@
1641 @@ -1,1 +1,1 @@
1640 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1642 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1641 +dc73e2e6d2675eb2e41e33c205f4bdab4ea5111d s
1643 +dc73e2e6d2675eb2e41e33c205f4bdab4ea5111d s
1642 $ hg log -r 2 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1644 $ hg log -r 2 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1643 7cf8cfea66e4 000000000000
1645 7cf8cfea66e4 000000000000
1644 s
1646 s
1645
1647
1646 (addition of entry)
1648 (addition of entry)
1647
1649
1648 $ hg diff --nodates -c 5 .hgsubstate
1650 $ hg diff --nodates -c 5 .hgsubstate
1649 diff -r 7cf8cfea66e4 -r 1f14a2e2d3ec .hgsubstate
1651 diff -r 7cf8cfea66e4 -r 1f14a2e2d3ec .hgsubstate
1650 --- a/.hgsubstate
1652 --- a/.hgsubstate
1651 +++ b/.hgsubstate
1653 +++ b/.hgsubstate
1652 @@ -1,1 +1,2 @@
1654 @@ -1,1 +1,2 @@
1653 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1655 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1654 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1656 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1655 $ hg log -r 5 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1657 $ hg log -r 5 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1656 7cf8cfea66e4 000000000000
1658 7cf8cfea66e4 000000000000
1657 t
1659 t
1658
1660
1659 (removal of existing entry)
1661 (removal of existing entry)
1660
1662
1661 $ hg diff --nodates -c 16 .hgsubstate
1663 $ hg diff --nodates -c 16 .hgsubstate
1662 diff -r 8bec38d2bd0b -r f2f70bc3d3c9 .hgsubstate
1664 diff -r 8bec38d2bd0b -r f2f70bc3d3c9 .hgsubstate
1663 --- a/.hgsubstate
1665 --- a/.hgsubstate
1664 +++ b/.hgsubstate
1666 +++ b/.hgsubstate
1665 @@ -1,2 +1,1 @@
1667 @@ -1,2 +1,1 @@
1666 0731af8ca9423976d3743119d0865097c07bdc1b s
1668 0731af8ca9423976d3743119d0865097c07bdc1b s
1667 -e202dc79b04c88a636ea8913d9182a1346d9b3dc t
1669 -e202dc79b04c88a636ea8913d9182a1346d9b3dc t
1668 $ hg log -r 16 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1670 $ hg log -r 16 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1669 8bec38d2bd0b 000000000000
1671 8bec38d2bd0b 000000000000
1670 t
1672 t
1671
1673
1672 (merging)
1674 (merging)
1673
1675
1674 $ hg diff --nodates -c 9 .hgsubstate
1676 $ hg diff --nodates -c 9 .hgsubstate
1675 diff -r f6affe3fbfaa -r f0d2028bf86d .hgsubstate
1677 diff -r f6affe3fbfaa -r f0d2028bf86d .hgsubstate
1676 --- a/.hgsubstate
1678 --- a/.hgsubstate
1677 +++ b/.hgsubstate
1679 +++ b/.hgsubstate
1678 @@ -1,1 +1,2 @@
1680 @@ -1,1 +1,2 @@
1679 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1681 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1680 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1682 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1681 $ hg log -r 9 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1683 $ hg log -r 9 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1682 f6affe3fbfaa 1f14a2e2d3ec
1684 f6affe3fbfaa 1f14a2e2d3ec
1683 t
1685 t
1684
1686
1685 (removal of ".hgsub" itself)
1687 (removal of ".hgsub" itself)
1686
1688
1687 $ hg diff --nodates -c 8 .hgsubstate
1689 $ hg diff --nodates -c 8 .hgsubstate
1688 diff -r f94576341bcf -r 96615c1dad2d .hgsubstate
1690 diff -r f94576341bcf -r 96615c1dad2d .hgsubstate
1689 --- a/.hgsubstate
1691 --- a/.hgsubstate
1690 +++ /dev/null
1692 +++ /dev/null
1691 @@ -1,2 +0,0 @@
1693 @@ -1,2 +0,0 @@
1692 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1694 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1693 -7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4 t
1695 -7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4 t
1694 $ hg log -r 8 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1696 $ hg log -r 8 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1695 f94576341bcf 000000000000
1697 f94576341bcf 000000000000
1696
1698
1697 Test that '[paths]' is configured correctly at subrepo creation
1699 Test that '[paths]' is configured correctly at subrepo creation
1698
1700
1699 $ cd $TESTTMP/tc
1701 $ cd $TESTTMP/tc
1700 $ cat > .hgsub <<EOF
1702 $ cat > .hgsub <<EOF
1701 > # to clear bogus subrepo path 'bogus=[boguspath'
1703 > # to clear bogus subrepo path 'bogus=[boguspath'
1702 > s = s
1704 > s = s
1703 > t = t
1705 > t = t
1704 > EOF
1706 > EOF
1705 $ hg update -q --clean null
1707 $ hg update -q --clean null
1706 $ rm -rf s t
1708 $ rm -rf s t
1707 $ cat >> .hg/hgrc <<EOF
1709 $ cat >> .hg/hgrc <<EOF
1708 > [paths]
1710 > [paths]
1709 > default-push = /foo/bar
1711 > default-push = /foo/bar
1710 > EOF
1712 > EOF
1711 $ hg update -q
1713 $ hg update -q
1712 $ cat s/.hg/hgrc
1714 $ cat s/.hg/hgrc
1713 [paths]
1715 [paths]
1714 default = $TESTTMP/t/s
1716 default = $TESTTMP/t/s
1715 default-push = /foo/bar/s
1717 default-push = /foo/bar/s
1716 $ cat s/ss/.hg/hgrc
1718 $ cat s/ss/.hg/hgrc
1717 [paths]
1719 [paths]
1718 default = $TESTTMP/t/s/ss
1720 default = $TESTTMP/t/s/ss
1719 default-push = /foo/bar/s/ss
1721 default-push = /foo/bar/s/ss
1720 $ cat t/.hg/hgrc
1722 $ cat t/.hg/hgrc
1721 [paths]
1723 [paths]
1722 default = $TESTTMP/t/t
1724 default = $TESTTMP/t/t
1723 default-push = /foo/bar/t
1725 default-push = /foo/bar/t
1724
1726
1725 $ cd $TESTTMP/t
1727 $ cd $TESTTMP/t
1726 $ hg up -qC 0
1728 $ hg up -qC 0
1727 $ echo 'bar' > bar.txt
1729 $ echo 'bar' > bar.txt
1728 $ hg ci -Am 'branch before subrepo add'
1730 $ hg ci -Am 'branch before subrepo add'
1729 adding bar.txt
1731 adding bar.txt
1730 created new head
1732 created new head
1731 $ hg merge -r "first(subrepo('s'))"
1733 $ hg merge -r "first(subrepo('s'))"
1732 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1734 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1733 (branch merge, don't forget to commit)
1735 (branch merge, don't forget to commit)
1734 $ hg status -S -X '.hgsub*'
1736 $ hg status -S -X '.hgsub*'
1735 A s/a
1737 A s/a
1736 ? s/b
1738 ? s/b
1737 ? s/c
1739 ? s/c
1738 ? s/f1
1740 ? s/f1
1739 $ hg status -S --rev 'p2()'
1741 $ hg status -S --rev 'p2()'
1740 A bar.txt
1742 A bar.txt
1741 ? s/b
1743 ? s/b
1742 ? s/c
1744 ? s/c
1743 ? s/f1
1745 ? s/f1
1744 $ hg diff -S -X '.hgsub*' --nodates
1746 $ hg diff -S -X '.hgsub*' --nodates
1745 diff -r 000000000000 s/a
1747 diff -r 000000000000 s/a
1746 --- /dev/null
1748 --- /dev/null
1747 +++ b/s/a
1749 +++ b/s/a
1748 @@ -0,0 +1,1 @@
1750 @@ -0,0 +1,1 @@
1749 +a
1751 +a
1750 $ hg diff -S --rev 'p2()' --nodates
1752 $ hg diff -S --rev 'p2()' --nodates
1751 diff -r 7cf8cfea66e4 bar.txt
1753 diff -r 7cf8cfea66e4 bar.txt
1752 --- /dev/null
1754 --- /dev/null
1753 +++ b/bar.txt
1755 +++ b/bar.txt
1754 @@ -0,0 +1,1 @@
1756 @@ -0,0 +1,1 @@
1755 +bar
1757 +bar
1756
1758
1757 $ cd ..
1759 $ cd ..
@@ -1,222 +1,228 b''
1 $ HGMERGE=true; export HGMERGE
1 $ HGMERGE=true; export HGMERGE
2
2
3 $ hg init r1
3 $ hg init r1
4 $ cd r1
4 $ cd r1
5 $ echo a > a
5 $ echo a > a
6 $ hg addremove
6 $ hg addremove
7 adding a
7 adding a
8 $ hg commit -m "1"
8 $ hg commit -m "1"
9
9
10 $ hg clone . ../r2
10 $ hg clone . ../r2
11 updating to branch default
11 updating to branch default
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 $ cd ../r2
13 $ cd ../r2
14 $ hg up
14 $ hg up
15 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 $ echo abc > a
16 $ echo abc > a
17 $ hg diff --nodates
17 $ hg diff --nodates
18 diff -r c19d34741b0a a
18 diff -r c19d34741b0a a
19 --- a/a
19 --- a/a
20 +++ b/a
20 +++ b/a
21 @@ -1,1 +1,1 @@
21 @@ -1,1 +1,1 @@
22 -a
22 -a
23 +abc
23 +abc
24
24
25 $ cd ../r1
25 $ cd ../r1
26 $ echo b > b
26 $ echo b > b
27 $ echo a2 > a
27 $ echo a2 > a
28 $ hg addremove
28 $ hg addremove
29 adding b
29 adding b
30 $ hg commit -m "2"
30 $ hg commit -m "2"
31
31
32 $ cd ../r2
32 $ cd ../r2
33 $ hg -q pull ../r1
33 $ hg -q pull ../r1
34 $ hg status
34 $ hg status
35 M a
35 M a
36 $ hg parents
36 $ hg parents
37 changeset: 0:c19d34741b0a
37 changeset: 0:c19d34741b0a
38 user: test
38 user: test
39 date: Thu Jan 01 00:00:00 1970 +0000
39 date: Thu Jan 01 00:00:00 1970 +0000
40 summary: 1
40 summary: 1
41
41
42 $ hg --debug up
42 $ hg --debug up
43 searching for copies back to rev 1
43 searching for copies back to rev 1
44 unmatched files in other:
44 unmatched files in other:
45 b
45 b
46 resolving manifests
46 resolving manifests
47 branchmerge: False, force: False, partial: False
47 branchmerge: False, force: False, partial: False
48 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
48 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
49 preserving a for resolve of a
49 preserving a for resolve of a
50 b: remote created -> g
50 b: remote created -> g
51 getting b
51 getting b
52 a: versions differ -> m
52 a: versions differ -> m
53 picked tool 'true' for a (binary False symlink False)
53 picked tool 'true' for a (binary False symlink False)
54 merging a
54 merging a
55 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
55 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
56 launching merge tool: true *$TESTTMP/r2/a* * (glob)
56 picked tool 'true' for a (binary False symlink False)
57 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
58 launching merge tool: true *$TESTTMP/r2/a* * * (glob)
57 merge tool returned: 0
59 merge tool returned: 0
58 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
60 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
59 $ hg parents
61 $ hg parents
60 changeset: 1:1e71731e6fbb
62 changeset: 1:1e71731e6fbb
61 tag: tip
63 tag: tip
62 user: test
64 user: test
63 date: Thu Jan 01 00:00:00 1970 +0000
65 date: Thu Jan 01 00:00:00 1970 +0000
64 summary: 2
66 summary: 2
65
67
66 $ hg --debug up 0
68 $ hg --debug up 0
67 resolving manifests
69 resolving manifests
68 branchmerge: False, force: False, partial: False
70 branchmerge: False, force: False, partial: False
69 ancestor: 1e71731e6fbb, local: 1e71731e6fbb+, remote: c19d34741b0a
71 ancestor: 1e71731e6fbb, local: 1e71731e6fbb+, remote: c19d34741b0a
70 preserving a for resolve of a
72 preserving a for resolve of a
71 b: other deleted -> r
73 b: other deleted -> r
72 removing b
74 removing b
73 a: versions differ -> m
75 a: versions differ -> m
74 picked tool 'true' for a (binary False symlink False)
76 picked tool 'true' for a (binary False symlink False)
75 merging a
77 merging a
76 my a@1e71731e6fbb+ other a@c19d34741b0a ancestor a@1e71731e6fbb
78 my a@1e71731e6fbb+ other a@c19d34741b0a ancestor a@1e71731e6fbb
77 launching merge tool: true *$TESTTMP/r2/a* * (glob)
79 picked tool 'true' for a (binary False symlink False)
80 my a@1e71731e6fbb+ other a@c19d34741b0a ancestor a@1e71731e6fbb
81 launching merge tool: true *$TESTTMP/r2/a* * * (glob)
78 merge tool returned: 0
82 merge tool returned: 0
79 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
83 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
80 $ hg parents
84 $ hg parents
81 changeset: 0:c19d34741b0a
85 changeset: 0:c19d34741b0a
82 user: test
86 user: test
83 date: Thu Jan 01 00:00:00 1970 +0000
87 date: Thu Jan 01 00:00:00 1970 +0000
84 summary: 1
88 summary: 1
85
89
86 $ hg parents
90 $ hg parents
87 changeset: 0:c19d34741b0a
91 changeset: 0:c19d34741b0a
88 user: test
92 user: test
89 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
90 summary: 1
94 summary: 1
91
95
92 $ hg --debug up
96 $ hg --debug up
93 searching for copies back to rev 1
97 searching for copies back to rev 1
94 unmatched files in other:
98 unmatched files in other:
95 b
99 b
96 resolving manifests
100 resolving manifests
97 branchmerge: False, force: False, partial: False
101 branchmerge: False, force: False, partial: False
98 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
102 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
99 preserving a for resolve of a
103 preserving a for resolve of a
100 b: remote created -> g
104 b: remote created -> g
101 getting b
105 getting b
102 a: versions differ -> m
106 a: versions differ -> m
103 picked tool 'true' for a (binary False symlink False)
107 picked tool 'true' for a (binary False symlink False)
104 merging a
108 merging a
105 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
109 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
106 launching merge tool: true *$TESTTMP/r2/a* * (glob)
110 picked tool 'true' for a (binary False symlink False)
111 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
112 launching merge tool: true *$TESTTMP/r2/a* * * (glob)
107 merge tool returned: 0
113 merge tool returned: 0
108 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
114 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
109 $ hg parents
115 $ hg parents
110 changeset: 1:1e71731e6fbb
116 changeset: 1:1e71731e6fbb
111 tag: tip
117 tag: tip
112 user: test
118 user: test
113 date: Thu Jan 01 00:00:00 1970 +0000
119 date: Thu Jan 01 00:00:00 1970 +0000
114 summary: 2
120 summary: 2
115
121
116 $ hg -v history
122 $ hg -v history
117 changeset: 1:1e71731e6fbb
123 changeset: 1:1e71731e6fbb
118 tag: tip
124 tag: tip
119 user: test
125 user: test
120 date: Thu Jan 01 00:00:00 1970 +0000
126 date: Thu Jan 01 00:00:00 1970 +0000
121 files: a b
127 files: a b
122 description:
128 description:
123 2
129 2
124
130
125
131
126 changeset: 0:c19d34741b0a
132 changeset: 0:c19d34741b0a
127 user: test
133 user: test
128 date: Thu Jan 01 00:00:00 1970 +0000
134 date: Thu Jan 01 00:00:00 1970 +0000
129 files: a
135 files: a
130 description:
136 description:
131 1
137 1
132
138
133
139
134 $ hg diff --nodates
140 $ hg diff --nodates
135 diff -r 1e71731e6fbb a
141 diff -r 1e71731e6fbb a
136 --- a/a
142 --- a/a
137 +++ b/a
143 +++ b/a
138 @@ -1,1 +1,1 @@
144 @@ -1,1 +1,1 @@
139 -a2
145 -a2
140 +abc
146 +abc
141
147
142
148
143 create a second head
149 create a second head
144
150
145 $ cd ../r1
151 $ cd ../r1
146 $ hg up 0
152 $ hg up 0
147 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
153 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
148 $ echo b2 > b
154 $ echo b2 > b
149 $ echo a3 > a
155 $ echo a3 > a
150 $ hg addremove
156 $ hg addremove
151 adding b
157 adding b
152 $ hg commit -m "3"
158 $ hg commit -m "3"
153 created new head
159 created new head
154
160
155 $ cd ../r2
161 $ cd ../r2
156 $ hg -q pull ../r1
162 $ hg -q pull ../r1
157 $ hg status
163 $ hg status
158 M a
164 M a
159 $ hg parents
165 $ hg parents
160 changeset: 1:1e71731e6fbb
166 changeset: 1:1e71731e6fbb
161 user: test
167 user: test
162 date: Thu Jan 01 00:00:00 1970 +0000
168 date: Thu Jan 01 00:00:00 1970 +0000
163 summary: 2
169 summary: 2
164
170
165 $ hg --debug up
171 $ hg --debug up
166 abort: uncommitted changes
172 abort: uncommitted changes
167 (commit and merge, or update --clean to discard changes)
173 (commit and merge, or update --clean to discard changes)
168 [255]
174 [255]
169
175
170 test conflicting untracked files
176 test conflicting untracked files
171
177
172 $ hg up -qC 0
178 $ hg up -qC 0
173 $ echo untracked > b
179 $ echo untracked > b
174 $ hg st
180 $ hg st
175 ? b
181 ? b
176 $ hg up 1
182 $ hg up 1
177 b: untracked file differs
183 b: untracked file differs
178 abort: untracked files in working directory differ from files in requested revision
184 abort: untracked files in working directory differ from files in requested revision
179 [255]
185 [255]
180 $ rm b
186 $ rm b
181
187
182 test conflicting untracked ignored file
188 test conflicting untracked ignored file
183
189
184 $ hg up -qC 0
190 $ hg up -qC 0
185 $ echo ignored > .hgignore
191 $ echo ignored > .hgignore
186 $ hg add .hgignore
192 $ hg add .hgignore
187 $ hg ci -m 'add .hgignore'
193 $ hg ci -m 'add .hgignore'
188 created new head
194 created new head
189 $ echo ignored > ignored
195 $ echo ignored > ignored
190 $ hg add ignored
196 $ hg add ignored
191 $ hg ci -m 'add ignored file'
197 $ hg ci -m 'add ignored file'
192
198
193 $ hg up -q 'desc("add .hgignore")'
199 $ hg up -q 'desc("add .hgignore")'
194 $ echo untracked > ignored
200 $ echo untracked > ignored
195 $ hg st
201 $ hg st
196 $ hg up 'desc("add ignored file")'
202 $ hg up 'desc("add ignored file")'
197 ignored: untracked file differs
203 ignored: untracked file differs
198 abort: untracked files in working directory differ from files in requested revision
204 abort: untracked files in working directory differ from files in requested revision
199 [255]
205 [255]
200
206
201 test a local add
207 test a local add
202
208
203 $ cd ..
209 $ cd ..
204 $ hg init a
210 $ hg init a
205 $ hg init b
211 $ hg init b
206 $ echo a > a/a
212 $ echo a > a/a
207 $ echo a > b/a
213 $ echo a > b/a
208 $ hg --cwd a commit -A -m a
214 $ hg --cwd a commit -A -m a
209 adding a
215 adding a
210 $ cd b
216 $ cd b
211 $ hg add a
217 $ hg add a
212 $ hg pull -u ../a
218 $ hg pull -u ../a
213 pulling from ../a
219 pulling from ../a
214 requesting all changes
220 requesting all changes
215 adding changesets
221 adding changesets
216 adding manifests
222 adding manifests
217 adding file changes
223 adding file changes
218 added 1 changesets with 1 changes to 1 files
224 added 1 changesets with 1 changes to 1 files
219 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
225 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 $ hg st
226 $ hg st
221
227
222 $ cd ..
228 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now