##// END OF EJS Templates
copies: print debug information about copies per side/branch...
Martin von Zweigbergk -
r44679:17e12938 default
parent child Browse files
Show More
@@ -1,1150 +1,1151 b''
1 # copies.py - copy detection for Mercurial
1 # copies.py - copy detection for Mercurial
2 #
2 #
3 # Copyright 2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 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 collections
10 import collections
11 import multiprocessing
11 import multiprocessing
12 import os
12 import os
13
13
14 from .i18n import _
14 from .i18n import _
15
15
16
16
17 from .revlogutils.flagutil import REVIDX_SIDEDATA
17 from .revlogutils.flagutil import REVIDX_SIDEDATA
18
18
19 from . import (
19 from . import (
20 error,
20 error,
21 match as matchmod,
21 match as matchmod,
22 node,
22 node,
23 pathutil,
23 pathutil,
24 pycompat,
24 pycompat,
25 util,
25 util,
26 )
26 )
27
27
28 from .revlogutils import sidedata as sidedatamod
28 from .revlogutils import sidedata as sidedatamod
29
29
30 from .utils import stringutil
30 from .utils import stringutil
31
31
32
32
33 def _filter(src, dst, t):
33 def _filter(src, dst, t):
34 """filters out invalid copies after chaining"""
34 """filters out invalid copies after chaining"""
35
35
36 # When _chain()'ing copies in 'a' (from 'src' via some other commit 'mid')
36 # When _chain()'ing copies in 'a' (from 'src' via some other commit 'mid')
37 # with copies in 'b' (from 'mid' to 'dst'), we can get the different cases
37 # with copies in 'b' (from 'mid' to 'dst'), we can get the different cases
38 # in the following table (not including trivial cases). For example, case 2
38 # in the following table (not including trivial cases). For example, case 2
39 # is where a file existed in 'src' and remained under that name in 'mid' and
39 # is where a file existed in 'src' and remained under that name in 'mid' and
40 # then was renamed between 'mid' and 'dst'.
40 # then was renamed between 'mid' and 'dst'.
41 #
41 #
42 # case src mid dst result
42 # case src mid dst result
43 # 1 x y - -
43 # 1 x y - -
44 # 2 x y y x->y
44 # 2 x y y x->y
45 # 3 x y x -
45 # 3 x y x -
46 # 4 x y z x->z
46 # 4 x y z x->z
47 # 5 - x y -
47 # 5 - x y -
48 # 6 x x y x->y
48 # 6 x x y x->y
49 #
49 #
50 # _chain() takes care of chaining the copies in 'a' and 'b', but it
50 # _chain() takes care of chaining the copies in 'a' and 'b', but it
51 # cannot tell the difference between cases 1 and 2, between 3 and 4, or
51 # cannot tell the difference between cases 1 and 2, between 3 and 4, or
52 # between 5 and 6, so it includes all cases in its result.
52 # between 5 and 6, so it includes all cases in its result.
53 # Cases 1, 3, and 5 are then removed by _filter().
53 # Cases 1, 3, and 5 are then removed by _filter().
54
54
55 for k, v in list(t.items()):
55 for k, v in list(t.items()):
56 # remove copies from files that didn't exist
56 # remove copies from files that didn't exist
57 if v not in src:
57 if v not in src:
58 del t[k]
58 del t[k]
59 # remove criss-crossed copies
59 # remove criss-crossed copies
60 elif k in src and v in dst:
60 elif k in src and v in dst:
61 del t[k]
61 del t[k]
62 # remove copies to files that were then removed
62 # remove copies to files that were then removed
63 elif k not in dst:
63 elif k not in dst:
64 del t[k]
64 del t[k]
65
65
66
66
67 def _chain(prefix, suffix):
67 def _chain(prefix, suffix):
68 """chain two sets of copies 'prefix' and 'suffix'"""
68 """chain two sets of copies 'prefix' and 'suffix'"""
69 result = prefix.copy()
69 result = prefix.copy()
70 for key, value in pycompat.iteritems(suffix):
70 for key, value in pycompat.iteritems(suffix):
71 result[key] = prefix.get(value, value)
71 result[key] = prefix.get(value, value)
72 return result
72 return result
73
73
74
74
75 def _tracefile(fctx, am, basemf):
75 def _tracefile(fctx, am, basemf):
76 """return file context that is the ancestor of fctx present in ancestor
76 """return file context that is the ancestor of fctx present in ancestor
77 manifest am
77 manifest am
78
78
79 Note: we used to try and stop after a given limit, however checking if that
79 Note: we used to try and stop after a given limit, however checking if that
80 limit is reached turned out to be very expensive. we are better off
80 limit is reached turned out to be very expensive. we are better off
81 disabling that feature."""
81 disabling that feature."""
82
82
83 for f in fctx.ancestors():
83 for f in fctx.ancestors():
84 path = f.path()
84 path = f.path()
85 if am.get(path, None) == f.filenode():
85 if am.get(path, None) == f.filenode():
86 return path
86 return path
87 if basemf and basemf.get(path, None) == f.filenode():
87 if basemf and basemf.get(path, None) == f.filenode():
88 return path
88 return path
89
89
90
90
91 def _dirstatecopies(repo, match=None):
91 def _dirstatecopies(repo, match=None):
92 ds = repo.dirstate
92 ds = repo.dirstate
93 c = ds.copies().copy()
93 c = ds.copies().copy()
94 for k in list(c):
94 for k in list(c):
95 if ds[k] not in b'anm' or (match and not match(k)):
95 if ds[k] not in b'anm' or (match and not match(k)):
96 del c[k]
96 del c[k]
97 return c
97 return c
98
98
99
99
100 def _computeforwardmissing(a, b, match=None):
100 def _computeforwardmissing(a, b, match=None):
101 """Computes which files are in b but not a.
101 """Computes which files are in b but not a.
102 This is its own function so extensions can easily wrap this call to see what
102 This is its own function so extensions can easily wrap this call to see what
103 files _forwardcopies is about to process.
103 files _forwardcopies is about to process.
104 """
104 """
105 ma = a.manifest()
105 ma = a.manifest()
106 mb = b.manifest()
106 mb = b.manifest()
107 return mb.filesnotin(ma, match=match)
107 return mb.filesnotin(ma, match=match)
108
108
109
109
110 def usechangesetcentricalgo(repo):
110 def usechangesetcentricalgo(repo):
111 """Checks if we should use changeset-centric copy algorithms"""
111 """Checks if we should use changeset-centric copy algorithms"""
112 if repo.filecopiesmode == b'changeset-sidedata':
112 if repo.filecopiesmode == b'changeset-sidedata':
113 return True
113 return True
114 readfrom = repo.ui.config(b'experimental', b'copies.read-from')
114 readfrom = repo.ui.config(b'experimental', b'copies.read-from')
115 changesetsource = (b'changeset-only', b'compatibility')
115 changesetsource = (b'changeset-only', b'compatibility')
116 return readfrom in changesetsource
116 return readfrom in changesetsource
117
117
118
118
119 def _committedforwardcopies(a, b, base, match):
119 def _committedforwardcopies(a, b, base, match):
120 """Like _forwardcopies(), but b.rev() cannot be None (working copy)"""
120 """Like _forwardcopies(), but b.rev() cannot be None (working copy)"""
121 # files might have to be traced back to the fctx parent of the last
121 # files might have to be traced back to the fctx parent of the last
122 # one-side-only changeset, but not further back than that
122 # one-side-only changeset, but not further back than that
123 repo = a._repo
123 repo = a._repo
124
124
125 if usechangesetcentricalgo(repo):
125 if usechangesetcentricalgo(repo):
126 return _changesetforwardcopies(a, b, match)
126 return _changesetforwardcopies(a, b, match)
127
127
128 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
128 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
129 dbg = repo.ui.debug
129 dbg = repo.ui.debug
130 if debug:
130 if debug:
131 dbg(b'debug.copies: looking into rename from %s to %s\n' % (a, b))
131 dbg(b'debug.copies: looking into rename from %s to %s\n' % (a, b))
132 am = a.manifest()
132 am = a.manifest()
133 basemf = None if base is None else base.manifest()
133 basemf = None if base is None else base.manifest()
134
134
135 # find where new files came from
135 # find where new files came from
136 # we currently don't try to find where old files went, too expensive
136 # we currently don't try to find where old files went, too expensive
137 # this means we can miss a case like 'hg rm b; hg cp a b'
137 # this means we can miss a case like 'hg rm b; hg cp a b'
138 cm = {}
138 cm = {}
139
139
140 # Computing the forward missing is quite expensive on large manifests, since
140 # Computing the forward missing is quite expensive on large manifests, since
141 # it compares the entire manifests. We can optimize it in the common use
141 # it compares the entire manifests. We can optimize it in the common use
142 # case of computing what copies are in a commit versus its parent (like
142 # case of computing what copies are in a commit versus its parent (like
143 # during a rebase or histedit). Note, we exclude merge commits from this
143 # during a rebase or histedit). Note, we exclude merge commits from this
144 # optimization, since the ctx.files() for a merge commit is not correct for
144 # optimization, since the ctx.files() for a merge commit is not correct for
145 # this comparison.
145 # this comparison.
146 forwardmissingmatch = match
146 forwardmissingmatch = match
147 if b.p1() == a and b.p2().node() == node.nullid:
147 if b.p1() == a and b.p2().node() == node.nullid:
148 filesmatcher = matchmod.exact(b.files())
148 filesmatcher = matchmod.exact(b.files())
149 forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
149 forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
150 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
150 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
151
151
152 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
152 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
153
153
154 if debug:
154 if debug:
155 dbg(b'debug.copies: missing files to search: %d\n' % len(missing))
155 dbg(b'debug.copies: missing files to search: %d\n' % len(missing))
156
156
157 for f in sorted(missing):
157 for f in sorted(missing):
158 if debug:
158 if debug:
159 dbg(b'debug.copies: tracing file: %s\n' % f)
159 dbg(b'debug.copies: tracing file: %s\n' % f)
160 fctx = b[f]
160 fctx = b[f]
161 fctx._ancestrycontext = ancestrycontext
161 fctx._ancestrycontext = ancestrycontext
162
162
163 if debug:
163 if debug:
164 start = util.timer()
164 start = util.timer()
165 opath = _tracefile(fctx, am, basemf)
165 opath = _tracefile(fctx, am, basemf)
166 if opath:
166 if opath:
167 if debug:
167 if debug:
168 dbg(b'debug.copies: rename of: %s\n' % opath)
168 dbg(b'debug.copies: rename of: %s\n' % opath)
169 cm[f] = opath
169 cm[f] = opath
170 if debug:
170 if debug:
171 dbg(
171 dbg(
172 b'debug.copies: time: %f seconds\n'
172 b'debug.copies: time: %f seconds\n'
173 % (util.timer() - start)
173 % (util.timer() - start)
174 )
174 )
175 return cm
175 return cm
176
176
177
177
178 def _revinfogetter(repo):
178 def _revinfogetter(repo):
179 """return a function that return multiple data given a <rev>"i
179 """return a function that return multiple data given a <rev>"i
180
180
181 * p1: revision number of first parent
181 * p1: revision number of first parent
182 * p2: revision number of first parent
182 * p2: revision number of first parent
183 * p1copies: mapping of copies from p1
183 * p1copies: mapping of copies from p1
184 * p2copies: mapping of copies from p2
184 * p2copies: mapping of copies from p2
185 * removed: a list of removed files
185 * removed: a list of removed files
186 """
186 """
187 cl = repo.changelog
187 cl = repo.changelog
188 parents = cl.parentrevs
188 parents = cl.parentrevs
189
189
190 if repo.filecopiesmode == b'changeset-sidedata':
190 if repo.filecopiesmode == b'changeset-sidedata':
191 changelogrevision = cl.changelogrevision
191 changelogrevision = cl.changelogrevision
192 flags = cl.flags
192 flags = cl.flags
193
193
194 # A small cache to avoid doing the work twice for merges
194 # A small cache to avoid doing the work twice for merges
195 #
195 #
196 # In the vast majority of cases, if we ask information for a revision
196 # In the vast majority of cases, if we ask information for a revision
197 # about 1 parent, we'll later ask it for the other. So it make sense to
197 # about 1 parent, we'll later ask it for the other. So it make sense to
198 # keep the information around when reaching the first parent of a merge
198 # keep the information around when reaching the first parent of a merge
199 # and dropping it after it was provided for the second parents.
199 # and dropping it after it was provided for the second parents.
200 #
200 #
201 # It exists cases were only one parent of the merge will be walked. It
201 # It exists cases were only one parent of the merge will be walked. It
202 # happens when the "destination" the copy tracing is descendant from a
202 # happens when the "destination" the copy tracing is descendant from a
203 # new root, not common with the "source". In that case, we will only walk
203 # new root, not common with the "source". In that case, we will only walk
204 # through merge parents that are descendant of changesets common
204 # through merge parents that are descendant of changesets common
205 # between "source" and "destination".
205 # between "source" and "destination".
206 #
206 #
207 # With the current case implementation if such changesets have a copy
207 # With the current case implementation if such changesets have a copy
208 # information, we'll keep them in memory until the end of
208 # information, we'll keep them in memory until the end of
209 # _changesetforwardcopies. We don't expect the case to be frequent
209 # _changesetforwardcopies. We don't expect the case to be frequent
210 # enough to matters.
210 # enough to matters.
211 #
211 #
212 # In addition, it would be possible to reach pathological case, were
212 # In addition, it would be possible to reach pathological case, were
213 # many first parent are met before any second parent is reached. In
213 # many first parent are met before any second parent is reached. In
214 # that case the cache could grow. If this even become an issue one can
214 # that case the cache could grow. If this even become an issue one can
215 # safely introduce a maximum cache size. This would trade extra CPU/IO
215 # safely introduce a maximum cache size. This would trade extra CPU/IO
216 # time to save memory.
216 # time to save memory.
217 merge_caches = {}
217 merge_caches = {}
218
218
219 def revinfo(rev):
219 def revinfo(rev):
220 p1, p2 = parents(rev)
220 p1, p2 = parents(rev)
221 if flags(rev) & REVIDX_SIDEDATA:
221 if flags(rev) & REVIDX_SIDEDATA:
222 e = merge_caches.pop(rev, None)
222 e = merge_caches.pop(rev, None)
223 if e is not None:
223 if e is not None:
224 return e
224 return e
225 c = changelogrevision(rev)
225 c = changelogrevision(rev)
226 p1copies = c.p1copies
226 p1copies = c.p1copies
227 p2copies = c.p2copies
227 p2copies = c.p2copies
228 removed = c.filesremoved
228 removed = c.filesremoved
229 if p1 != node.nullrev and p2 != node.nullrev:
229 if p1 != node.nullrev and p2 != node.nullrev:
230 # XXX some case we over cache, IGNORE
230 # XXX some case we over cache, IGNORE
231 merge_caches[rev] = (p1, p2, p1copies, p2copies, removed)
231 merge_caches[rev] = (p1, p2, p1copies, p2copies, removed)
232 else:
232 else:
233 p1copies = {}
233 p1copies = {}
234 p2copies = {}
234 p2copies = {}
235 removed = []
235 removed = []
236 return p1, p2, p1copies, p2copies, removed
236 return p1, p2, p1copies, p2copies, removed
237
237
238 else:
238 else:
239
239
240 def revinfo(rev):
240 def revinfo(rev):
241 p1, p2 = parents(rev)
241 p1, p2 = parents(rev)
242 ctx = repo[rev]
242 ctx = repo[rev]
243 p1copies, p2copies = ctx._copies
243 p1copies, p2copies = ctx._copies
244 removed = ctx.filesremoved()
244 removed = ctx.filesremoved()
245 return p1, p2, p1copies, p2copies, removed
245 return p1, p2, p1copies, p2copies, removed
246
246
247 return revinfo
247 return revinfo
248
248
249
249
250 def _changesetforwardcopies(a, b, match):
250 def _changesetforwardcopies(a, b, match):
251 if a.rev() in (node.nullrev, b.rev()):
251 if a.rev() in (node.nullrev, b.rev()):
252 return {}
252 return {}
253
253
254 repo = a.repo().unfiltered()
254 repo = a.repo().unfiltered()
255 children = {}
255 children = {}
256 revinfo = _revinfogetter(repo)
256 revinfo = _revinfogetter(repo)
257
257
258 cl = repo.changelog
258 cl = repo.changelog
259 missingrevs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
259 missingrevs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
260 mrset = set(missingrevs)
260 mrset = set(missingrevs)
261 roots = set()
261 roots = set()
262 for r in missingrevs:
262 for r in missingrevs:
263 for p in cl.parentrevs(r):
263 for p in cl.parentrevs(r):
264 if p == node.nullrev:
264 if p == node.nullrev:
265 continue
265 continue
266 if p not in children:
266 if p not in children:
267 children[p] = [r]
267 children[p] = [r]
268 else:
268 else:
269 children[p].append(r)
269 children[p].append(r)
270 if p not in mrset:
270 if p not in mrset:
271 roots.add(p)
271 roots.add(p)
272 if not roots:
272 if not roots:
273 # no common revision to track copies from
273 # no common revision to track copies from
274 return {}
274 return {}
275 min_root = min(roots)
275 min_root = min(roots)
276
276
277 from_head = set(
277 from_head = set(
278 cl.reachableroots(min_root, [b.rev()], list(roots), includepath=True)
278 cl.reachableroots(min_root, [b.rev()], list(roots), includepath=True)
279 )
279 )
280
280
281 iterrevs = set(from_head)
281 iterrevs = set(from_head)
282 iterrevs &= mrset
282 iterrevs &= mrset
283 iterrevs.update(roots)
283 iterrevs.update(roots)
284 iterrevs.remove(b.rev())
284 iterrevs.remove(b.rev())
285 revs = sorted(iterrevs)
285 revs = sorted(iterrevs)
286 return _combinechangesetcopies(revs, children, b.rev(), revinfo, match)
286 return _combinechangesetcopies(revs, children, b.rev(), revinfo, match)
287
287
288
288
289 def _combinechangesetcopies(revs, children, targetrev, revinfo, match):
289 def _combinechangesetcopies(revs, children, targetrev, revinfo, match):
290 """combine the copies information for each item of iterrevs
290 """combine the copies information for each item of iterrevs
291
291
292 revs: sorted iterable of revision to visit
292 revs: sorted iterable of revision to visit
293 children: a {parent: [children]} mapping.
293 children: a {parent: [children]} mapping.
294 targetrev: the final copies destination revision (not in iterrevs)
294 targetrev: the final copies destination revision (not in iterrevs)
295 revinfo(rev): a function that return (p1, p2, p1copies, p2copies, removed)
295 revinfo(rev): a function that return (p1, p2, p1copies, p2copies, removed)
296 match: a matcher
296 match: a matcher
297
297
298 It returns the aggregated copies information for `targetrev`.
298 It returns the aggregated copies information for `targetrev`.
299 """
299 """
300 all_copies = {}
300 all_copies = {}
301 alwaysmatch = match.always()
301 alwaysmatch = match.always()
302 for r in revs:
302 for r in revs:
303 copies = all_copies.pop(r, None)
303 copies = all_copies.pop(r, None)
304 if copies is None:
304 if copies is None:
305 # this is a root
305 # this is a root
306 copies = {}
306 copies = {}
307 for i, c in enumerate(children[r]):
307 for i, c in enumerate(children[r]):
308 p1, p2, p1copies, p2copies, removed = revinfo(c)
308 p1, p2, p1copies, p2copies, removed = revinfo(c)
309 if r == p1:
309 if r == p1:
310 parent = 1
310 parent = 1
311 childcopies = p1copies
311 childcopies = p1copies
312 else:
312 else:
313 assert r == p2
313 assert r == p2
314 parent = 2
314 parent = 2
315 childcopies = p2copies
315 childcopies = p2copies
316 if not alwaysmatch:
316 if not alwaysmatch:
317 childcopies = {
317 childcopies = {
318 dst: src for dst, src in childcopies.items() if match(dst)
318 dst: src for dst, src in childcopies.items() if match(dst)
319 }
319 }
320 newcopies = copies
320 newcopies = copies
321 if childcopies:
321 if childcopies:
322 newcopies = _chain(newcopies, childcopies)
322 newcopies = _chain(newcopies, childcopies)
323 # _chain makes a copies, we can avoid doing so in some
323 # _chain makes a copies, we can avoid doing so in some
324 # simple/linear cases.
324 # simple/linear cases.
325 assert newcopies is not copies
325 assert newcopies is not copies
326 for f in removed:
326 for f in removed:
327 if f in newcopies:
327 if f in newcopies:
328 if newcopies is copies:
328 if newcopies is copies:
329 # copy on write to avoid affecting potential other
329 # copy on write to avoid affecting potential other
330 # branches. when there are no other branches, this
330 # branches. when there are no other branches, this
331 # could be avoided.
331 # could be avoided.
332 newcopies = copies.copy()
332 newcopies = copies.copy()
333 del newcopies[f]
333 del newcopies[f]
334 othercopies = all_copies.get(c)
334 othercopies = all_copies.get(c)
335 if othercopies is None:
335 if othercopies is None:
336 all_copies[c] = newcopies
336 all_copies[c] = newcopies
337 else:
337 else:
338 # we are the second parent to work on c, we need to merge our
338 # we are the second parent to work on c, we need to merge our
339 # work with the other.
339 # work with the other.
340 #
340 #
341 # Unlike when copies are stored in the filelog, we consider
341 # Unlike when copies are stored in the filelog, we consider
342 # it a copy even if the destination already existed on the
342 # it a copy even if the destination already existed on the
343 # other branch. It's simply too expensive to check if the
343 # other branch. It's simply too expensive to check if the
344 # file existed in the manifest.
344 # file existed in the manifest.
345 #
345 #
346 # In case of conflict, parent 1 take precedence over parent 2.
346 # In case of conflict, parent 1 take precedence over parent 2.
347 # This is an arbitrary choice made anew when implementing
347 # This is an arbitrary choice made anew when implementing
348 # changeset based copies. It was made without regards with
348 # changeset based copies. It was made without regards with
349 # potential filelog related behavior.
349 # potential filelog related behavior.
350 if parent == 1:
350 if parent == 1:
351 othercopies.update(newcopies)
351 othercopies.update(newcopies)
352 else:
352 else:
353 newcopies.update(othercopies)
353 newcopies.update(othercopies)
354 all_copies[c] = newcopies
354 all_copies[c] = newcopies
355 return all_copies[targetrev]
355 return all_copies[targetrev]
356
356
357
357
358 def _forwardcopies(a, b, base=None, match=None):
358 def _forwardcopies(a, b, base=None, match=None):
359 """find {dst@b: src@a} copy mapping where a is an ancestor of b"""
359 """find {dst@b: src@a} copy mapping where a is an ancestor of b"""
360
360
361 if base is None:
361 if base is None:
362 base = a
362 base = a
363 match = a.repo().narrowmatch(match)
363 match = a.repo().narrowmatch(match)
364 # check for working copy
364 # check for working copy
365 if b.rev() is None:
365 if b.rev() is None:
366 cm = _committedforwardcopies(a, b.p1(), base, match)
366 cm = _committedforwardcopies(a, b.p1(), base, match)
367 # combine copies from dirstate if necessary
367 # combine copies from dirstate if necessary
368 copies = _chain(cm, _dirstatecopies(b._repo, match))
368 copies = _chain(cm, _dirstatecopies(b._repo, match))
369 else:
369 else:
370 copies = _committedforwardcopies(a, b, base, match)
370 copies = _committedforwardcopies(a, b, base, match)
371 return copies
371 return copies
372
372
373
373
374 def _backwardrenames(a, b, match):
374 def _backwardrenames(a, b, match):
375 if a._repo.ui.config(b'experimental', b'copytrace') == b'off':
375 if a._repo.ui.config(b'experimental', b'copytrace') == b'off':
376 return {}
376 return {}
377
377
378 # Even though we're not taking copies into account, 1:n rename situations
378 # Even though we're not taking copies into account, 1:n rename situations
379 # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
379 # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
380 # arbitrarily pick one of the renames.
380 # arbitrarily pick one of the renames.
381 # We don't want to pass in "match" here, since that would filter
381 # We don't want to pass in "match" here, since that would filter
382 # the destination by it. Since we're reversing the copies, we want
382 # the destination by it. Since we're reversing the copies, we want
383 # to filter the source instead.
383 # to filter the source instead.
384 f = _forwardcopies(b, a)
384 f = _forwardcopies(b, a)
385 r = {}
385 r = {}
386 for k, v in sorted(pycompat.iteritems(f)):
386 for k, v in sorted(pycompat.iteritems(f)):
387 if match and not match(v):
387 if match and not match(v):
388 continue
388 continue
389 # remove copies
389 # remove copies
390 if v in a:
390 if v in a:
391 continue
391 continue
392 r[v] = k
392 r[v] = k
393 return r
393 return r
394
394
395
395
396 def pathcopies(x, y, match=None):
396 def pathcopies(x, y, match=None):
397 """find {dst@y: src@x} copy mapping for directed compare"""
397 """find {dst@y: src@x} copy mapping for directed compare"""
398 repo = x._repo
398 repo = x._repo
399 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
399 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
400 if debug:
400 if debug:
401 repo.ui.debug(
401 repo.ui.debug(
402 b'debug.copies: searching copies from %s to %s\n' % (x, y)
402 b'debug.copies: searching copies from %s to %s\n' % (x, y)
403 )
403 )
404 if x == y or not x or not y:
404 if x == y or not x or not y:
405 return {}
405 return {}
406 a = y.ancestor(x)
406 a = y.ancestor(x)
407 if a == x:
407 if a == x:
408 if debug:
408 if debug:
409 repo.ui.debug(b'debug.copies: search mode: forward\n')
409 repo.ui.debug(b'debug.copies: search mode: forward\n')
410 if y.rev() is None and x == y.p1():
410 if y.rev() is None and x == y.p1():
411 # short-circuit to avoid issues with merge states
411 # short-circuit to avoid issues with merge states
412 return _dirstatecopies(repo, match)
412 return _dirstatecopies(repo, match)
413 copies = _forwardcopies(x, y, match=match)
413 copies = _forwardcopies(x, y, match=match)
414 elif a == y:
414 elif a == y:
415 if debug:
415 if debug:
416 repo.ui.debug(b'debug.copies: search mode: backward\n')
416 repo.ui.debug(b'debug.copies: search mode: backward\n')
417 copies = _backwardrenames(x, y, match=match)
417 copies = _backwardrenames(x, y, match=match)
418 else:
418 else:
419 if debug:
419 if debug:
420 repo.ui.debug(b'debug.copies: search mode: combined\n')
420 repo.ui.debug(b'debug.copies: search mode: combined\n')
421 base = None
421 base = None
422 if a.rev() != node.nullrev:
422 if a.rev() != node.nullrev:
423 base = x
423 base = x
424 copies = _chain(
424 copies = _chain(
425 _backwardrenames(x, a, match=match),
425 _backwardrenames(x, a, match=match),
426 _forwardcopies(a, y, base, match=match),
426 _forwardcopies(a, y, base, match=match),
427 )
427 )
428 _filter(x, y, copies)
428 _filter(x, y, copies)
429 return copies
429 return copies
430
430
431
431
432 def mergecopies(repo, c1, c2, base):
432 def mergecopies(repo, c1, c2, base):
433 """
433 """
434 Finds moves and copies between context c1 and c2 that are relevant for
434 Finds moves and copies between context c1 and c2 that are relevant for
435 merging. 'base' will be used as the merge base.
435 merging. 'base' will be used as the merge base.
436
436
437 Copytracing is used in commands like rebase, merge, unshelve, etc to merge
437 Copytracing is used in commands like rebase, merge, unshelve, etc to merge
438 files that were moved/ copied in one merge parent and modified in another.
438 files that were moved/ copied in one merge parent and modified in another.
439 For example:
439 For example:
440
440
441 o ---> 4 another commit
441 o ---> 4 another commit
442 |
442 |
443 | o ---> 3 commit that modifies a.txt
443 | o ---> 3 commit that modifies a.txt
444 | /
444 | /
445 o / ---> 2 commit that moves a.txt to b.txt
445 o / ---> 2 commit that moves a.txt to b.txt
446 |/
446 |/
447 o ---> 1 merge base
447 o ---> 1 merge base
448
448
449 If we try to rebase revision 3 on revision 4, since there is no a.txt in
449 If we try to rebase revision 3 on revision 4, since there is no a.txt in
450 revision 4, and if user have copytrace disabled, we prints the following
450 revision 4, and if user have copytrace disabled, we prints the following
451 message:
451 message:
452
452
453 ```other changed <file> which local deleted```
453 ```other changed <file> which local deleted```
454
454
455 Returns five dicts: "copy", "movewithdir", "diverge", "renamedelete" and
455 Returns five dicts: "copy", "movewithdir", "diverge", "renamedelete" and
456 "dirmove".
456 "dirmove".
457
457
458 "copy" is a mapping from destination name -> source name,
458 "copy" is a mapping from destination name -> source name,
459 where source is in c1 and destination is in c2 or vice-versa.
459 where source is in c1 and destination is in c2 or vice-versa.
460
460
461 "movewithdir" is a mapping from source name -> destination name,
461 "movewithdir" is a mapping from source name -> destination name,
462 where the file at source present in one context but not the other
462 where the file at source present in one context but not the other
463 needs to be moved to destination by the merge process, because the
463 needs to be moved to destination by the merge process, because the
464 other context moved the directory it is in.
464 other context moved the directory it is in.
465
465
466 "diverge" is a mapping of source name -> list of destination names
466 "diverge" is a mapping of source name -> list of destination names
467 for divergent renames.
467 for divergent renames.
468
468
469 "renamedelete" is a mapping of source name -> list of destination
469 "renamedelete" is a mapping of source name -> list of destination
470 names for files deleted in c1 that were renamed in c2 or vice-versa.
470 names for files deleted in c1 that were renamed in c2 or vice-versa.
471
471
472 "dirmove" is a mapping of detected source dir -> destination dir renames.
472 "dirmove" is a mapping of detected source dir -> destination dir renames.
473 This is needed for handling changes to new files previously grafted into
473 This is needed for handling changes to new files previously grafted into
474 renamed directories.
474 renamed directories.
475
475
476 This function calls different copytracing algorithms based on config.
476 This function calls different copytracing algorithms based on config.
477 """
477 """
478 # avoid silly behavior for update from empty dir
478 # avoid silly behavior for update from empty dir
479 if not c1 or not c2 or c1 == c2:
479 if not c1 or not c2 or c1 == c2:
480 return {}, {}, {}, {}, {}
480 return {}, {}, {}, {}, {}
481
481
482 narrowmatch = c1.repo().narrowmatch()
482 narrowmatch = c1.repo().narrowmatch()
483
483
484 # avoid silly behavior for parent -> working dir
484 # avoid silly behavior for parent -> working dir
485 if c2.node() is None and c1.node() == repo.dirstate.p1():
485 if c2.node() is None and c1.node() == repo.dirstate.p1():
486 return _dirstatecopies(repo, narrowmatch), {}, {}, {}, {}
486 return _dirstatecopies(repo, narrowmatch), {}, {}, {}, {}
487
487
488 copytracing = repo.ui.config(b'experimental', b'copytrace')
488 copytracing = repo.ui.config(b'experimental', b'copytrace')
489 if stringutil.parsebool(copytracing) is False:
489 if stringutil.parsebool(copytracing) is False:
490 # stringutil.parsebool() returns None when it is unable to parse the
490 # stringutil.parsebool() returns None when it is unable to parse the
491 # value, so we should rely on making sure copytracing is on such cases
491 # value, so we should rely on making sure copytracing is on such cases
492 return {}, {}, {}, {}, {}
492 return {}, {}, {}, {}, {}
493
493
494 if usechangesetcentricalgo(repo):
494 if usechangesetcentricalgo(repo):
495 # The heuristics don't make sense when we need changeset-centric algos
495 # The heuristics don't make sense when we need changeset-centric algos
496 return _fullcopytracing(repo, c1, c2, base)
496 return _fullcopytracing(repo, c1, c2, base)
497
497
498 # Copy trace disabling is explicitly below the node == p1 logic above
498 # Copy trace disabling is explicitly below the node == p1 logic above
499 # because the logic above is required for a simple copy to be kept across a
499 # because the logic above is required for a simple copy to be kept across a
500 # rebase.
500 # rebase.
501 if copytracing == b'heuristics':
501 if copytracing == b'heuristics':
502 # Do full copytracing if only non-public revisions are involved as
502 # Do full copytracing if only non-public revisions are involved as
503 # that will be fast enough and will also cover the copies which could
503 # that will be fast enough and will also cover the copies which could
504 # be missed by heuristics
504 # be missed by heuristics
505 if _isfullcopytraceable(repo, c1, base):
505 if _isfullcopytraceable(repo, c1, base):
506 return _fullcopytracing(repo, c1, c2, base)
506 return _fullcopytracing(repo, c1, c2, base)
507 return _heuristicscopytracing(repo, c1, c2, base)
507 return _heuristicscopytracing(repo, c1, c2, base)
508 else:
508 else:
509 return _fullcopytracing(repo, c1, c2, base)
509 return _fullcopytracing(repo, c1, c2, base)
510
510
511
511
512 def _isfullcopytraceable(repo, c1, base):
512 def _isfullcopytraceable(repo, c1, base):
513 """ Checks that if base, source and destination are all no-public branches,
513 """ Checks that if base, source and destination are all no-public branches,
514 if yes let's use the full copytrace algorithm for increased capabilities
514 if yes let's use the full copytrace algorithm for increased capabilities
515 since it will be fast enough.
515 since it will be fast enough.
516
516
517 `experimental.copytrace.sourcecommitlimit` can be used to set a limit for
517 `experimental.copytrace.sourcecommitlimit` can be used to set a limit for
518 number of changesets from c1 to base such that if number of changesets are
518 number of changesets from c1 to base such that if number of changesets are
519 more than the limit, full copytracing algorithm won't be used.
519 more than the limit, full copytracing algorithm won't be used.
520 """
520 """
521 if c1.rev() is None:
521 if c1.rev() is None:
522 c1 = c1.p1()
522 c1 = c1.p1()
523 if c1.mutable() and base.mutable():
523 if c1.mutable() and base.mutable():
524 sourcecommitlimit = repo.ui.configint(
524 sourcecommitlimit = repo.ui.configint(
525 b'experimental', b'copytrace.sourcecommitlimit'
525 b'experimental', b'copytrace.sourcecommitlimit'
526 )
526 )
527 commits = len(repo.revs(b'%d::%d', base.rev(), c1.rev()))
527 commits = len(repo.revs(b'%d::%d', base.rev(), c1.rev()))
528 return commits < sourcecommitlimit
528 return commits < sourcecommitlimit
529 return False
529 return False
530
530
531
531
532 def _checksinglesidecopies(
532 def _checksinglesidecopies(
533 src, dsts1, m1, m2, mb, c2, base, copy, renamedelete
533 src, dsts1, m1, m2, mb, c2, base, copy, renamedelete
534 ):
534 ):
535 if src not in m2:
535 if src not in m2:
536 # deleted on side 2
536 # deleted on side 2
537 if src not in m1:
537 if src not in m1:
538 # renamed on side 1, deleted on side 2
538 # renamed on side 1, deleted on side 2
539 renamedelete[src] = dsts1
539 renamedelete[src] = dsts1
540 elif m2[src] != mb[src]:
540 elif m2[src] != mb[src]:
541 if not _related(c2[src], base[src]):
541 if not _related(c2[src], base[src]):
542 return
542 return
543 # modified on side 2
543 # modified on side 2
544 for dst in dsts1:
544 for dst in dsts1:
545 if dst not in m2:
545 if dst not in m2:
546 # dst not added on side 2 (handle as regular
546 # dst not added on side 2 (handle as regular
547 # "both created" case in manifestmerge otherwise)
547 # "both created" case in manifestmerge otherwise)
548 copy[dst] = src
548 copy[dst] = src
549
549
550
550
551 def _fullcopytracing(repo, c1, c2, base):
551 def _fullcopytracing(repo, c1, c2, base):
552 """ The full copytracing algorithm which finds all the new files that were
552 """ The full copytracing algorithm which finds all the new files that were
553 added from merge base up to the top commit and for each file it checks if
553 added from merge base up to the top commit and for each file it checks if
554 this file was copied from another file.
554 this file was copied from another file.
555
555
556 This is pretty slow when a lot of changesets are involved but will track all
556 This is pretty slow when a lot of changesets are involved but will track all
557 the copies.
557 the copies.
558 """
558 """
559 m1 = c1.manifest()
559 m1 = c1.manifest()
560 m2 = c2.manifest()
560 m2 = c2.manifest()
561 mb = base.manifest()
561 mb = base.manifest()
562
562
563 copies1 = pathcopies(base, c1)
563 copies1 = pathcopies(base, c1)
564 copies2 = pathcopies(base, c2)
564 copies2 = pathcopies(base, c2)
565
565
566 if not (copies1 or copies2):
566 if not (copies1 or copies2):
567 return {}, {}, {}, {}, {}
567 return {}, {}, {}, {}, {}
568
568
569 inversecopies1 = {}
569 inversecopies1 = {}
570 inversecopies2 = {}
570 inversecopies2 = {}
571 for dst, src in copies1.items():
571 for dst, src in copies1.items():
572 inversecopies1.setdefault(src, []).append(dst)
572 inversecopies1.setdefault(src, []).append(dst)
573 for dst, src in copies2.items():
573 for dst, src in copies2.items():
574 inversecopies2.setdefault(src, []).append(dst)
574 inversecopies2.setdefault(src, []).append(dst)
575
575
576 copy1 = {}
576 copy1 = {}
577 copy2 = {}
577 copy2 = {}
578 diverge = {}
578 diverge = {}
579 renamedelete1 = {}
579 renamedelete1 = {}
580 renamedelete2 = {}
580 renamedelete2 = {}
581 allsources = set(inversecopies1) | set(inversecopies2)
581 allsources = set(inversecopies1) | set(inversecopies2)
582 for src in allsources:
582 for src in allsources:
583 dsts1 = inversecopies1.get(src)
583 dsts1 = inversecopies1.get(src)
584 dsts2 = inversecopies2.get(src)
584 dsts2 = inversecopies2.get(src)
585 if dsts1 and dsts2:
585 if dsts1 and dsts2:
586 # copied/renamed on both sides
586 # copied/renamed on both sides
587 if src not in m1 and src not in m2:
587 if src not in m1 and src not in m2:
588 # renamed on both sides
588 # renamed on both sides
589 dsts1 = set(dsts1)
589 dsts1 = set(dsts1)
590 dsts2 = set(dsts2)
590 dsts2 = set(dsts2)
591 # If there's some overlap in the rename destinations, we
591 # If there's some overlap in the rename destinations, we
592 # consider it not divergent. For example, if side 1 copies 'a'
592 # consider it not divergent. For example, if side 1 copies 'a'
593 # to 'b' and 'c' and deletes 'a', and side 2 copies 'a' to 'c'
593 # to 'b' and 'c' and deletes 'a', and side 2 copies 'a' to 'c'
594 # and 'd' and deletes 'a'.
594 # and 'd' and deletes 'a'.
595 if dsts1 & dsts2:
595 if dsts1 & dsts2:
596 for dst in dsts1 & dsts2:
596 for dst in dsts1 & dsts2:
597 copy1[dst] = src
597 copy1[dst] = src
598 copy2[dst] = src
598 copy2[dst] = src
599 else:
599 else:
600 diverge[src] = sorted(dsts1 | dsts2)
600 diverge[src] = sorted(dsts1 | dsts2)
601 elif src in m1 and src in m2:
601 elif src in m1 and src in m2:
602 # copied on both sides
602 # copied on both sides
603 dsts1 = set(dsts1)
603 dsts1 = set(dsts1)
604 dsts2 = set(dsts2)
604 dsts2 = set(dsts2)
605 for dst in dsts1 & dsts2:
605 for dst in dsts1 & dsts2:
606 copy1[dst] = src
606 copy1[dst] = src
607 copy2[dst] = src
607 copy2[dst] = src
608 # TODO: Handle cases where it was renamed on one side and copied
608 # TODO: Handle cases where it was renamed on one side and copied
609 # on the other side
609 # on the other side
610 elif dsts1:
610 elif dsts1:
611 # copied/renamed only on side 1
611 # copied/renamed only on side 1
612 _checksinglesidecopies(
612 _checksinglesidecopies(
613 src, dsts1, m1, m2, mb, c2, base, copy1, renamedelete1
613 src, dsts1, m1, m2, mb, c2, base, copy1, renamedelete1
614 )
614 )
615 elif dsts2:
615 elif dsts2:
616 # copied/renamed only on side 2
616 # copied/renamed only on side 2
617 _checksinglesidecopies(
617 _checksinglesidecopies(
618 src, dsts2, m2, m1, mb, c1, base, copy2, renamedelete2
618 src, dsts2, m2, m1, mb, c1, base, copy2, renamedelete2
619 )
619 )
620
620
621 # find interesting file sets from manifests
621 # find interesting file sets from manifests
622 addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
622 addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
623 addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
623 addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
624 u1 = sorted(addedinm1 - addedinm2)
624 u1 = sorted(addedinm1 - addedinm2)
625 u2 = sorted(addedinm2 - addedinm1)
625 u2 = sorted(addedinm2 - addedinm1)
626
626
627 header = b" unmatched files in %s"
627 header = b" unmatched files in %s"
628 if u1:
628 if u1:
629 repo.ui.debug(b"%s:\n %s\n" % (header % b'local', b"\n ".join(u1)))
629 repo.ui.debug(b"%s:\n %s\n" % (header % b'local', b"\n ".join(u1)))
630 if u2:
630 if u2:
631 repo.ui.debug(b"%s:\n %s\n" % (header % b'other', b"\n ".join(u2)))
631 repo.ui.debug(b"%s:\n %s\n" % (header % b'other', b"\n ".join(u2)))
632
632
633 fullcopy = copies1.copy()
634 fullcopy.update(copies2)
635
636 if repo.ui.debugflag:
633 if repo.ui.debugflag:
637 renamedeleteset = set()
634 renamedeleteset = set()
638 divergeset = set()
635 divergeset = set()
639 for dsts in diverge.values():
636 for dsts in diverge.values():
640 divergeset.update(dsts)
637 divergeset.update(dsts)
641 for dsts in renamedelete1.values():
638 for dsts in renamedelete1.values():
642 renamedeleteset.update(dsts)
639 renamedeleteset.update(dsts)
643 for dsts in renamedelete2.values():
640 for dsts in renamedelete2.values():
644 renamedeleteset.update(dsts)
641 renamedeleteset.update(dsts)
645
642
646 repo.ui.debug(
643 repo.ui.debug(
647 b" all copies found (* = to merge, ! = divergent, "
644 b" all copies found (* = to merge, ! = divergent, "
648 b"% = renamed and deleted):\n"
645 b"% = renamed and deleted):\n"
649 )
646 )
650 for f in sorted(fullcopy):
647 for side, copies in ((b"local", copies1), (b"remote", copies2)):
651 note = b""
648 if not copies:
652 if f in copy1 or f in copy2:
649 continue
653 note += b"*"
650 repo.ui.debug(b" on %s side:\n" % side)
654 if f in divergeset:
651 for f in sorted(copies):
655 note += b"!"
652 note = b""
656 if f in renamedeleteset:
653 if f in copy1 or f in copy2:
657 note += b"%"
654 note += b"*"
658 repo.ui.debug(
655 if f in divergeset:
659 b" src: '%s' -> dst: '%s' %s\n" % (fullcopy[f], f, note)
656 note += b"!"
660 )
657 if f in renamedeleteset:
658 note += b"%"
659 repo.ui.debug(
660 b" src: '%s' -> dst: '%s' %s\n" % (copies[f], f, note)
661 )
661 del renamedeleteset
662 del renamedeleteset
662 del divergeset
663 del divergeset
663
664
664 repo.ui.debug(b" checking for directory renames\n")
665 repo.ui.debug(b" checking for directory renames\n")
665
666
666 dirmove1, movewithdir2 = _dir_renames(repo, c1, copy1, copies1, u2)
667 dirmove1, movewithdir2 = _dir_renames(repo, c1, copy1, copies1, u2)
667 dirmove2, movewithdir1 = _dir_renames(repo, c2, copy2, copies2, u1)
668 dirmove2, movewithdir1 = _dir_renames(repo, c2, copy2, copies2, u1)
668
669
669 copy1.update(copy2)
670 copy1.update(copy2)
670 renamedelete1.update(renamedelete2)
671 renamedelete1.update(renamedelete2)
671 movewithdir1.update(movewithdir2)
672 movewithdir1.update(movewithdir2)
672 dirmove1.update(dirmove2)
673 dirmove1.update(dirmove2)
673
674
674 return copy1, movewithdir1, diverge, renamedelete1, dirmove1
675 return copy1, movewithdir1, diverge, renamedelete1, dirmove1
675
676
676
677
677 def _dir_renames(repo, ctx, copy, fullcopy, addedfiles):
678 def _dir_renames(repo, ctx, copy, fullcopy, addedfiles):
678 """Finds moved directories and files that should move with them.
679 """Finds moved directories and files that should move with them.
679
680
680 ctx: the context for one of the sides
681 ctx: the context for one of the sides
681 copy: files copied on the same side (as ctx)
682 copy: files copied on the same side (as ctx)
682 fullcopy: files copied on the same side (as ctx), including those that
683 fullcopy: files copied on the same side (as ctx), including those that
683 merge.manifestmerge() won't care about
684 merge.manifestmerge() won't care about
684 addedfiles: added files on the other side (compared to ctx)
685 addedfiles: added files on the other side (compared to ctx)
685 """
686 """
686 # generate a directory move map
687 # generate a directory move map
687 d = ctx.dirs()
688 d = ctx.dirs()
688 invalid = set()
689 invalid = set()
689 dirmove = {}
690 dirmove = {}
690
691
691 # examine each file copy for a potential directory move, which is
692 # examine each file copy for a potential directory move, which is
692 # when all the files in a directory are moved to a new directory
693 # when all the files in a directory are moved to a new directory
693 for dst, src in pycompat.iteritems(fullcopy):
694 for dst, src in pycompat.iteritems(fullcopy):
694 dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
695 dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
695 if dsrc in invalid:
696 if dsrc in invalid:
696 # already seen to be uninteresting
697 # already seen to be uninteresting
697 continue
698 continue
698 elif dsrc in d and ddst in d:
699 elif dsrc in d and ddst in d:
699 # directory wasn't entirely moved locally
700 # directory wasn't entirely moved locally
700 invalid.add(dsrc)
701 invalid.add(dsrc)
701 elif dsrc in dirmove and dirmove[dsrc] != ddst:
702 elif dsrc in dirmove and dirmove[dsrc] != ddst:
702 # files from the same directory moved to two different places
703 # files from the same directory moved to two different places
703 invalid.add(dsrc)
704 invalid.add(dsrc)
704 else:
705 else:
705 # looks good so far
706 # looks good so far
706 dirmove[dsrc] = ddst
707 dirmove[dsrc] = ddst
707
708
708 for i in invalid:
709 for i in invalid:
709 if i in dirmove:
710 if i in dirmove:
710 del dirmove[i]
711 del dirmove[i]
711 del d, invalid
712 del d, invalid
712
713
713 if not dirmove:
714 if not dirmove:
714 return {}, {}
715 return {}, {}
715
716
716 dirmove = {k + b"/": v + b"/" for k, v in pycompat.iteritems(dirmove)}
717 dirmove = {k + b"/": v + b"/" for k, v in pycompat.iteritems(dirmove)}
717
718
718 for d in dirmove:
719 for d in dirmove:
719 repo.ui.debug(
720 repo.ui.debug(
720 b" discovered dir src: '%s' -> dst: '%s'\n" % (d, dirmove[d])
721 b" discovered dir src: '%s' -> dst: '%s'\n" % (d, dirmove[d])
721 )
722 )
722
723
723 movewithdir = {}
724 movewithdir = {}
724 # check unaccounted nonoverlapping files against directory moves
725 # check unaccounted nonoverlapping files against directory moves
725 for f in addedfiles:
726 for f in addedfiles:
726 if f not in fullcopy:
727 if f not in fullcopy:
727 for d in dirmove:
728 for d in dirmove:
728 if f.startswith(d):
729 if f.startswith(d):
729 # new file added in a directory that was moved, move it
730 # new file added in a directory that was moved, move it
730 df = dirmove[d] + f[len(d) :]
731 df = dirmove[d] + f[len(d) :]
731 if df not in copy:
732 if df not in copy:
732 movewithdir[f] = df
733 movewithdir[f] = df
733 repo.ui.debug(
734 repo.ui.debug(
734 b" pending file src: '%s' -> dst: '%s'\n"
735 b" pending file src: '%s' -> dst: '%s'\n"
735 % (f, df)
736 % (f, df)
736 )
737 )
737 break
738 break
738
739
739 return dirmove, movewithdir
740 return dirmove, movewithdir
740
741
741
742
742 def _heuristicscopytracing(repo, c1, c2, base):
743 def _heuristicscopytracing(repo, c1, c2, base):
743 """ Fast copytracing using filename heuristics
744 """ Fast copytracing using filename heuristics
744
745
745 Assumes that moves or renames are of following two types:
746 Assumes that moves or renames are of following two types:
746
747
747 1) Inside a directory only (same directory name but different filenames)
748 1) Inside a directory only (same directory name but different filenames)
748 2) Move from one directory to another
749 2) Move from one directory to another
749 (same filenames but different directory names)
750 (same filenames but different directory names)
750
751
751 Works only when there are no merge commits in the "source branch".
752 Works only when there are no merge commits in the "source branch".
752 Source branch is commits from base up to c2 not including base.
753 Source branch is commits from base up to c2 not including base.
753
754
754 If merge is involved it fallbacks to _fullcopytracing().
755 If merge is involved it fallbacks to _fullcopytracing().
755
756
756 Can be used by setting the following config:
757 Can be used by setting the following config:
757
758
758 [experimental]
759 [experimental]
759 copytrace = heuristics
760 copytrace = heuristics
760
761
761 In some cases the copy/move candidates found by heuristics can be very large
762 In some cases the copy/move candidates found by heuristics can be very large
762 in number and that will make the algorithm slow. The number of possible
763 in number and that will make the algorithm slow. The number of possible
763 candidates to check can be limited by using the config
764 candidates to check can be limited by using the config
764 `experimental.copytrace.movecandidateslimit` which defaults to 100.
765 `experimental.copytrace.movecandidateslimit` which defaults to 100.
765 """
766 """
766
767
767 if c1.rev() is None:
768 if c1.rev() is None:
768 c1 = c1.p1()
769 c1 = c1.p1()
769 if c2.rev() is None:
770 if c2.rev() is None:
770 c2 = c2.p1()
771 c2 = c2.p1()
771
772
772 copies = {}
773 copies = {}
773
774
774 changedfiles = set()
775 changedfiles = set()
775 m1 = c1.manifest()
776 m1 = c1.manifest()
776 if not repo.revs(b'%d::%d', base.rev(), c2.rev()):
777 if not repo.revs(b'%d::%d', base.rev(), c2.rev()):
777 # If base is not in c2 branch, we switch to fullcopytracing
778 # If base is not in c2 branch, we switch to fullcopytracing
778 repo.ui.debug(
779 repo.ui.debug(
779 b"switching to full copytracing as base is not "
780 b"switching to full copytracing as base is not "
780 b"an ancestor of c2\n"
781 b"an ancestor of c2\n"
781 )
782 )
782 return _fullcopytracing(repo, c1, c2, base)
783 return _fullcopytracing(repo, c1, c2, base)
783
784
784 ctx = c2
785 ctx = c2
785 while ctx != base:
786 while ctx != base:
786 if len(ctx.parents()) == 2:
787 if len(ctx.parents()) == 2:
787 # To keep things simple let's not handle merges
788 # To keep things simple let's not handle merges
788 repo.ui.debug(b"switching to full copytracing because of merges\n")
789 repo.ui.debug(b"switching to full copytracing because of merges\n")
789 return _fullcopytracing(repo, c1, c2, base)
790 return _fullcopytracing(repo, c1, c2, base)
790 changedfiles.update(ctx.files())
791 changedfiles.update(ctx.files())
791 ctx = ctx.p1()
792 ctx = ctx.p1()
792
793
793 cp = _forwardcopies(base, c2)
794 cp = _forwardcopies(base, c2)
794 for dst, src in pycompat.iteritems(cp):
795 for dst, src in pycompat.iteritems(cp):
795 if src in m1:
796 if src in m1:
796 copies[dst] = src
797 copies[dst] = src
797
798
798 # file is missing if it isn't present in the destination, but is present in
799 # file is missing if it isn't present in the destination, but is present in
799 # the base and present in the source.
800 # the base and present in the source.
800 # Presence in the base is important to exclude added files, presence in the
801 # Presence in the base is important to exclude added files, presence in the
801 # source is important to exclude removed files.
802 # source is important to exclude removed files.
802 filt = lambda f: f not in m1 and f in base and f in c2
803 filt = lambda f: f not in m1 and f in base and f in c2
803 missingfiles = [f for f in changedfiles if filt(f)]
804 missingfiles = [f for f in changedfiles if filt(f)]
804
805
805 if missingfiles:
806 if missingfiles:
806 basenametofilename = collections.defaultdict(list)
807 basenametofilename = collections.defaultdict(list)
807 dirnametofilename = collections.defaultdict(list)
808 dirnametofilename = collections.defaultdict(list)
808
809
809 for f in m1.filesnotin(base.manifest()):
810 for f in m1.filesnotin(base.manifest()):
810 basename = os.path.basename(f)
811 basename = os.path.basename(f)
811 dirname = os.path.dirname(f)
812 dirname = os.path.dirname(f)
812 basenametofilename[basename].append(f)
813 basenametofilename[basename].append(f)
813 dirnametofilename[dirname].append(f)
814 dirnametofilename[dirname].append(f)
814
815
815 for f in missingfiles:
816 for f in missingfiles:
816 basename = os.path.basename(f)
817 basename = os.path.basename(f)
817 dirname = os.path.dirname(f)
818 dirname = os.path.dirname(f)
818 samebasename = basenametofilename[basename]
819 samebasename = basenametofilename[basename]
819 samedirname = dirnametofilename[dirname]
820 samedirname = dirnametofilename[dirname]
820 movecandidates = samebasename + samedirname
821 movecandidates = samebasename + samedirname
821 # f is guaranteed to be present in c2, that's why
822 # f is guaranteed to be present in c2, that's why
822 # c2.filectx(f) won't fail
823 # c2.filectx(f) won't fail
823 f2 = c2.filectx(f)
824 f2 = c2.filectx(f)
824 # we can have a lot of candidates which can slow down the heuristics
825 # we can have a lot of candidates which can slow down the heuristics
825 # config value to limit the number of candidates moves to check
826 # config value to limit the number of candidates moves to check
826 maxcandidates = repo.ui.configint(
827 maxcandidates = repo.ui.configint(
827 b'experimental', b'copytrace.movecandidateslimit'
828 b'experimental', b'copytrace.movecandidateslimit'
828 )
829 )
829
830
830 if len(movecandidates) > maxcandidates:
831 if len(movecandidates) > maxcandidates:
831 repo.ui.status(
832 repo.ui.status(
832 _(
833 _(
833 b"skipping copytracing for '%s', more "
834 b"skipping copytracing for '%s', more "
834 b"candidates than the limit: %d\n"
835 b"candidates than the limit: %d\n"
835 )
836 )
836 % (f, len(movecandidates))
837 % (f, len(movecandidates))
837 )
838 )
838 continue
839 continue
839
840
840 for candidate in movecandidates:
841 for candidate in movecandidates:
841 f1 = c1.filectx(candidate)
842 f1 = c1.filectx(candidate)
842 if _related(f1, f2):
843 if _related(f1, f2):
843 # if there are a few related copies then we'll merge
844 # if there are a few related copies then we'll merge
844 # changes into all of them. This matches the behaviour
845 # changes into all of them. This matches the behaviour
845 # of upstream copytracing
846 # of upstream copytracing
846 copies[candidate] = f
847 copies[candidate] = f
847
848
848 return copies, {}, {}, {}, {}
849 return copies, {}, {}, {}, {}
849
850
850
851
851 def _related(f1, f2):
852 def _related(f1, f2):
852 """return True if f1 and f2 filectx have a common ancestor
853 """return True if f1 and f2 filectx have a common ancestor
853
854
854 Walk back to common ancestor to see if the two files originate
855 Walk back to common ancestor to see if the two files originate
855 from the same file. Since workingfilectx's rev() is None it messes
856 from the same file. Since workingfilectx's rev() is None it messes
856 up the integer comparison logic, hence the pre-step check for
857 up the integer comparison logic, hence the pre-step check for
857 None (f1 and f2 can only be workingfilectx's initially).
858 None (f1 and f2 can only be workingfilectx's initially).
858 """
859 """
859
860
860 if f1 == f2:
861 if f1 == f2:
861 return True # a match
862 return True # a match
862
863
863 g1, g2 = f1.ancestors(), f2.ancestors()
864 g1, g2 = f1.ancestors(), f2.ancestors()
864 try:
865 try:
865 f1r, f2r = f1.linkrev(), f2.linkrev()
866 f1r, f2r = f1.linkrev(), f2.linkrev()
866
867
867 if f1r is None:
868 if f1r is None:
868 f1 = next(g1)
869 f1 = next(g1)
869 if f2r is None:
870 if f2r is None:
870 f2 = next(g2)
871 f2 = next(g2)
871
872
872 while True:
873 while True:
873 f1r, f2r = f1.linkrev(), f2.linkrev()
874 f1r, f2r = f1.linkrev(), f2.linkrev()
874 if f1r > f2r:
875 if f1r > f2r:
875 f1 = next(g1)
876 f1 = next(g1)
876 elif f2r > f1r:
877 elif f2r > f1r:
877 f2 = next(g2)
878 f2 = next(g2)
878 else: # f1 and f2 point to files in the same linkrev
879 else: # f1 and f2 point to files in the same linkrev
879 return f1 == f2 # true if they point to the same file
880 return f1 == f2 # true if they point to the same file
880 except StopIteration:
881 except StopIteration:
881 return False
882 return False
882
883
883
884
884 def graftcopies(wctx, ctx, base):
885 def graftcopies(wctx, ctx, base):
885 """reproduce copies between base and ctx in the wctx
886 """reproduce copies between base and ctx in the wctx
886
887
887 Unlike mergecopies(), this function will only consider copies between base
888 Unlike mergecopies(), this function will only consider copies between base
888 and ctx; it will ignore copies between base and wctx. Also unlike
889 and ctx; it will ignore copies between base and wctx. Also unlike
889 mergecopies(), this function will apply copies to the working copy (instead
890 mergecopies(), this function will apply copies to the working copy (instead
890 of just returning information about the copies). That makes it cheaper
891 of just returning information about the copies). That makes it cheaper
891 (especially in the common case of base==ctx.p1()) and useful also when
892 (especially in the common case of base==ctx.p1()) and useful also when
892 experimental.copytrace=off.
893 experimental.copytrace=off.
893
894
894 merge.update() will have already marked most copies, but it will only
895 merge.update() will have already marked most copies, but it will only
895 mark copies if it thinks the source files are related (see
896 mark copies if it thinks the source files are related (see
896 merge._related()). It will also not mark copies if the file wasn't modified
897 merge._related()). It will also not mark copies if the file wasn't modified
897 on the local side. This function adds the copies that were "missed"
898 on the local side. This function adds the copies that were "missed"
898 by merge.update().
899 by merge.update().
899 """
900 """
900 new_copies = pathcopies(base, ctx)
901 new_copies = pathcopies(base, ctx)
901 _filter(wctx.p1(), wctx, new_copies)
902 _filter(wctx.p1(), wctx, new_copies)
902 for dst, src in pycompat.iteritems(new_copies):
903 for dst, src in pycompat.iteritems(new_copies):
903 wctx[dst].markcopied(src)
904 wctx[dst].markcopied(src)
904
905
905
906
906 def computechangesetfilesadded(ctx):
907 def computechangesetfilesadded(ctx):
907 """return the list of files added in a changeset
908 """return the list of files added in a changeset
908 """
909 """
909 added = []
910 added = []
910 for f in ctx.files():
911 for f in ctx.files():
911 if not any(f in p for p in ctx.parents()):
912 if not any(f in p for p in ctx.parents()):
912 added.append(f)
913 added.append(f)
913 return added
914 return added
914
915
915
916
916 def computechangesetfilesremoved(ctx):
917 def computechangesetfilesremoved(ctx):
917 """return the list of files removed in a changeset
918 """return the list of files removed in a changeset
918 """
919 """
919 removed = []
920 removed = []
920 for f in ctx.files():
921 for f in ctx.files():
921 if f not in ctx:
922 if f not in ctx:
922 removed.append(f)
923 removed.append(f)
923 return removed
924 return removed
924
925
925
926
926 def computechangesetcopies(ctx):
927 def computechangesetcopies(ctx):
927 """return the copies data for a changeset
928 """return the copies data for a changeset
928
929
929 The copies data are returned as a pair of dictionnary (p1copies, p2copies).
930 The copies data are returned as a pair of dictionnary (p1copies, p2copies).
930
931
931 Each dictionnary are in the form: `{newname: oldname}`
932 Each dictionnary are in the form: `{newname: oldname}`
932 """
933 """
933 p1copies = {}
934 p1copies = {}
934 p2copies = {}
935 p2copies = {}
935 p1 = ctx.p1()
936 p1 = ctx.p1()
936 p2 = ctx.p2()
937 p2 = ctx.p2()
937 narrowmatch = ctx._repo.narrowmatch()
938 narrowmatch = ctx._repo.narrowmatch()
938 for dst in ctx.files():
939 for dst in ctx.files():
939 if not narrowmatch(dst) or dst not in ctx:
940 if not narrowmatch(dst) or dst not in ctx:
940 continue
941 continue
941 copied = ctx[dst].renamed()
942 copied = ctx[dst].renamed()
942 if not copied:
943 if not copied:
943 continue
944 continue
944 src, srcnode = copied
945 src, srcnode = copied
945 if src in p1 and p1[src].filenode() == srcnode:
946 if src in p1 and p1[src].filenode() == srcnode:
946 p1copies[dst] = src
947 p1copies[dst] = src
947 elif src in p2 and p2[src].filenode() == srcnode:
948 elif src in p2 and p2[src].filenode() == srcnode:
948 p2copies[dst] = src
949 p2copies[dst] = src
949 return p1copies, p2copies
950 return p1copies, p2copies
950
951
951
952
952 def encodecopies(files, copies):
953 def encodecopies(files, copies):
953 items = []
954 items = []
954 for i, dst in enumerate(files):
955 for i, dst in enumerate(files):
955 if dst in copies:
956 if dst in copies:
956 items.append(b'%d\0%s' % (i, copies[dst]))
957 items.append(b'%d\0%s' % (i, copies[dst]))
957 if len(items) != len(copies):
958 if len(items) != len(copies):
958 raise error.ProgrammingError(
959 raise error.ProgrammingError(
959 b'some copy targets missing from file list'
960 b'some copy targets missing from file list'
960 )
961 )
961 return b"\n".join(items)
962 return b"\n".join(items)
962
963
963
964
964 def decodecopies(files, data):
965 def decodecopies(files, data):
965 try:
966 try:
966 copies = {}
967 copies = {}
967 if not data:
968 if not data:
968 return copies
969 return copies
969 for l in data.split(b'\n'):
970 for l in data.split(b'\n'):
970 strindex, src = l.split(b'\0')
971 strindex, src = l.split(b'\0')
971 i = int(strindex)
972 i = int(strindex)
972 dst = files[i]
973 dst = files[i]
973 copies[dst] = src
974 copies[dst] = src
974 return copies
975 return copies
975 except (ValueError, IndexError):
976 except (ValueError, IndexError):
976 # Perhaps someone had chosen the same key name (e.g. "p1copies") and
977 # Perhaps someone had chosen the same key name (e.g. "p1copies") and
977 # used different syntax for the value.
978 # used different syntax for the value.
978 return None
979 return None
979
980
980
981
981 def encodefileindices(files, subset):
982 def encodefileindices(files, subset):
982 subset = set(subset)
983 subset = set(subset)
983 indices = []
984 indices = []
984 for i, f in enumerate(files):
985 for i, f in enumerate(files):
985 if f in subset:
986 if f in subset:
986 indices.append(b'%d' % i)
987 indices.append(b'%d' % i)
987 return b'\n'.join(indices)
988 return b'\n'.join(indices)
988
989
989
990
990 def decodefileindices(files, data):
991 def decodefileindices(files, data):
991 try:
992 try:
992 subset = []
993 subset = []
993 if not data:
994 if not data:
994 return subset
995 return subset
995 for strindex in data.split(b'\n'):
996 for strindex in data.split(b'\n'):
996 i = int(strindex)
997 i = int(strindex)
997 if i < 0 or i >= len(files):
998 if i < 0 or i >= len(files):
998 return None
999 return None
999 subset.append(files[i])
1000 subset.append(files[i])
1000 return subset
1001 return subset
1001 except (ValueError, IndexError):
1002 except (ValueError, IndexError):
1002 # Perhaps someone had chosen the same key name (e.g. "added") and
1003 # Perhaps someone had chosen the same key name (e.g. "added") and
1003 # used different syntax for the value.
1004 # used different syntax for the value.
1004 return None
1005 return None
1005
1006
1006
1007
1007 def _getsidedata(srcrepo, rev):
1008 def _getsidedata(srcrepo, rev):
1008 ctx = srcrepo[rev]
1009 ctx = srcrepo[rev]
1009 filescopies = computechangesetcopies(ctx)
1010 filescopies = computechangesetcopies(ctx)
1010 filesadded = computechangesetfilesadded(ctx)
1011 filesadded = computechangesetfilesadded(ctx)
1011 filesremoved = computechangesetfilesremoved(ctx)
1012 filesremoved = computechangesetfilesremoved(ctx)
1012 sidedata = {}
1013 sidedata = {}
1013 if any([filescopies, filesadded, filesremoved]):
1014 if any([filescopies, filesadded, filesremoved]):
1014 sortedfiles = sorted(ctx.files())
1015 sortedfiles = sorted(ctx.files())
1015 p1copies, p2copies = filescopies
1016 p1copies, p2copies = filescopies
1016 p1copies = encodecopies(sortedfiles, p1copies)
1017 p1copies = encodecopies(sortedfiles, p1copies)
1017 p2copies = encodecopies(sortedfiles, p2copies)
1018 p2copies = encodecopies(sortedfiles, p2copies)
1018 filesadded = encodefileindices(sortedfiles, filesadded)
1019 filesadded = encodefileindices(sortedfiles, filesadded)
1019 filesremoved = encodefileindices(sortedfiles, filesremoved)
1020 filesremoved = encodefileindices(sortedfiles, filesremoved)
1020 if p1copies:
1021 if p1copies:
1021 sidedata[sidedatamod.SD_P1COPIES] = p1copies
1022 sidedata[sidedatamod.SD_P1COPIES] = p1copies
1022 if p2copies:
1023 if p2copies:
1023 sidedata[sidedatamod.SD_P2COPIES] = p2copies
1024 sidedata[sidedatamod.SD_P2COPIES] = p2copies
1024 if filesadded:
1025 if filesadded:
1025 sidedata[sidedatamod.SD_FILESADDED] = filesadded
1026 sidedata[sidedatamod.SD_FILESADDED] = filesadded
1026 if filesremoved:
1027 if filesremoved:
1027 sidedata[sidedatamod.SD_FILESREMOVED] = filesremoved
1028 sidedata[sidedatamod.SD_FILESREMOVED] = filesremoved
1028 return sidedata
1029 return sidedata
1029
1030
1030
1031
1031 def getsidedataadder(srcrepo, destrepo):
1032 def getsidedataadder(srcrepo, destrepo):
1032 use_w = srcrepo.ui.configbool(b'experimental', b'worker.repository-upgrade')
1033 use_w = srcrepo.ui.configbool(b'experimental', b'worker.repository-upgrade')
1033 if pycompat.iswindows or not use_w:
1034 if pycompat.iswindows or not use_w:
1034 return _get_simple_sidedata_adder(srcrepo, destrepo)
1035 return _get_simple_sidedata_adder(srcrepo, destrepo)
1035 else:
1036 else:
1036 return _get_worker_sidedata_adder(srcrepo, destrepo)
1037 return _get_worker_sidedata_adder(srcrepo, destrepo)
1037
1038
1038
1039
1039 def _sidedata_worker(srcrepo, revs_queue, sidedata_queue, tokens):
1040 def _sidedata_worker(srcrepo, revs_queue, sidedata_queue, tokens):
1040 """The function used by worker precomputing sidedata
1041 """The function used by worker precomputing sidedata
1041
1042
1042 It read an input queue containing revision numbers
1043 It read an input queue containing revision numbers
1043 It write in an output queue containing (rev, <sidedata-map>)
1044 It write in an output queue containing (rev, <sidedata-map>)
1044
1045
1045 The `None` input value is used as a stop signal.
1046 The `None` input value is used as a stop signal.
1046
1047
1047 The `tokens` semaphore is user to avoid having too many unprocessed
1048 The `tokens` semaphore is user to avoid having too many unprocessed
1048 entries. The workers needs to acquire one token before fetching a task.
1049 entries. The workers needs to acquire one token before fetching a task.
1049 They will be released by the consumer of the produced data.
1050 They will be released by the consumer of the produced data.
1050 """
1051 """
1051 tokens.acquire()
1052 tokens.acquire()
1052 rev = revs_queue.get()
1053 rev = revs_queue.get()
1053 while rev is not None:
1054 while rev is not None:
1054 data = _getsidedata(srcrepo, rev)
1055 data = _getsidedata(srcrepo, rev)
1055 sidedata_queue.put((rev, data))
1056 sidedata_queue.put((rev, data))
1056 tokens.acquire()
1057 tokens.acquire()
1057 rev = revs_queue.get()
1058 rev = revs_queue.get()
1058 # processing of `None` is completed, release the token.
1059 # processing of `None` is completed, release the token.
1059 tokens.release()
1060 tokens.release()
1060
1061
1061
1062
1062 BUFF_PER_WORKER = 50
1063 BUFF_PER_WORKER = 50
1063
1064
1064
1065
1065 def _get_worker_sidedata_adder(srcrepo, destrepo):
1066 def _get_worker_sidedata_adder(srcrepo, destrepo):
1066 """The parallel version of the sidedata computation
1067 """The parallel version of the sidedata computation
1067
1068
1068 This code spawn a pool of worker that precompute a buffer of sidedata
1069 This code spawn a pool of worker that precompute a buffer of sidedata
1069 before we actually need them"""
1070 before we actually need them"""
1070 # avoid circular import copies -> scmutil -> worker -> copies
1071 # avoid circular import copies -> scmutil -> worker -> copies
1071 from . import worker
1072 from . import worker
1072
1073
1073 nbworkers = worker._numworkers(srcrepo.ui)
1074 nbworkers = worker._numworkers(srcrepo.ui)
1074
1075
1075 tokens = multiprocessing.BoundedSemaphore(nbworkers * BUFF_PER_WORKER)
1076 tokens = multiprocessing.BoundedSemaphore(nbworkers * BUFF_PER_WORKER)
1076 revsq = multiprocessing.Queue()
1077 revsq = multiprocessing.Queue()
1077 sidedataq = multiprocessing.Queue()
1078 sidedataq = multiprocessing.Queue()
1078
1079
1079 assert srcrepo.filtername is None
1080 assert srcrepo.filtername is None
1080 # queue all tasks beforehand, revision numbers are small and it make
1081 # queue all tasks beforehand, revision numbers are small and it make
1081 # synchronisation simpler
1082 # synchronisation simpler
1082 #
1083 #
1083 # Since the computation for each node can be quite expensive, the overhead
1084 # Since the computation for each node can be quite expensive, the overhead
1084 # of using a single queue is not revelant. In practice, most computation
1085 # of using a single queue is not revelant. In practice, most computation
1085 # are fast but some are very expensive and dominate all the other smaller
1086 # are fast but some are very expensive and dominate all the other smaller
1086 # cost.
1087 # cost.
1087 for r in srcrepo.changelog.revs():
1088 for r in srcrepo.changelog.revs():
1088 revsq.put(r)
1089 revsq.put(r)
1089 # queue the "no more tasks" markers
1090 # queue the "no more tasks" markers
1090 for i in range(nbworkers):
1091 for i in range(nbworkers):
1091 revsq.put(None)
1092 revsq.put(None)
1092
1093
1093 allworkers = []
1094 allworkers = []
1094 for i in range(nbworkers):
1095 for i in range(nbworkers):
1095 args = (srcrepo, revsq, sidedataq, tokens)
1096 args = (srcrepo, revsq, sidedataq, tokens)
1096 w = multiprocessing.Process(target=_sidedata_worker, args=args)
1097 w = multiprocessing.Process(target=_sidedata_worker, args=args)
1097 allworkers.append(w)
1098 allworkers.append(w)
1098 w.start()
1099 w.start()
1099
1100
1100 # dictionnary to store results for revision higher than we one we are
1101 # dictionnary to store results for revision higher than we one we are
1101 # looking for. For example, if we need the sidedatamap for 42, and 43 is
1102 # looking for. For example, if we need the sidedatamap for 42, and 43 is
1102 # received, when shelve 43 for later use.
1103 # received, when shelve 43 for later use.
1103 staging = {}
1104 staging = {}
1104
1105
1105 def sidedata_companion(revlog, rev):
1106 def sidedata_companion(revlog, rev):
1106 sidedata = {}
1107 sidedata = {}
1107 if util.safehasattr(revlog, b'filteredrevs'): # this is a changelog
1108 if util.safehasattr(revlog, b'filteredrevs'): # this is a changelog
1108 # Is the data previously shelved ?
1109 # Is the data previously shelved ?
1109 sidedata = staging.pop(rev, None)
1110 sidedata = staging.pop(rev, None)
1110 if sidedata is None:
1111 if sidedata is None:
1111 # look at the queued result until we find the one we are lookig
1112 # look at the queued result until we find the one we are lookig
1112 # for (shelve the other ones)
1113 # for (shelve the other ones)
1113 r, sidedata = sidedataq.get()
1114 r, sidedata = sidedataq.get()
1114 while r != rev:
1115 while r != rev:
1115 staging[r] = sidedata
1116 staging[r] = sidedata
1116 r, sidedata = sidedataq.get()
1117 r, sidedata = sidedataq.get()
1117 tokens.release()
1118 tokens.release()
1118 return False, (), sidedata
1119 return False, (), sidedata
1119
1120
1120 return sidedata_companion
1121 return sidedata_companion
1121
1122
1122
1123
1123 def _get_simple_sidedata_adder(srcrepo, destrepo):
1124 def _get_simple_sidedata_adder(srcrepo, destrepo):
1124 """The simple version of the sidedata computation
1125 """The simple version of the sidedata computation
1125
1126
1126 It just compute it in the same thread on request"""
1127 It just compute it in the same thread on request"""
1127
1128
1128 def sidedatacompanion(revlog, rev):
1129 def sidedatacompanion(revlog, rev):
1129 sidedata = {}
1130 sidedata = {}
1130 if util.safehasattr(revlog, 'filteredrevs'): # this is a changelog
1131 if util.safehasattr(revlog, 'filteredrevs'): # this is a changelog
1131 sidedata = _getsidedata(srcrepo, rev)
1132 sidedata = _getsidedata(srcrepo, rev)
1132 return False, (), sidedata
1133 return False, (), sidedata
1133
1134
1134 return sidedatacompanion
1135 return sidedatacompanion
1135
1136
1136
1137
1137 def getsidedataremover(srcrepo, destrepo):
1138 def getsidedataremover(srcrepo, destrepo):
1138 def sidedatacompanion(revlog, rev):
1139 def sidedatacompanion(revlog, rev):
1139 f = ()
1140 f = ()
1140 if util.safehasattr(revlog, 'filteredrevs'): # this is a changelog
1141 if util.safehasattr(revlog, 'filteredrevs'): # this is a changelog
1141 if revlog.flags(rev) & REVIDX_SIDEDATA:
1142 if revlog.flags(rev) & REVIDX_SIDEDATA:
1142 f = (
1143 f = (
1143 sidedatamod.SD_P1COPIES,
1144 sidedatamod.SD_P1COPIES,
1144 sidedatamod.SD_P2COPIES,
1145 sidedatamod.SD_P2COPIES,
1145 sidedatamod.SD_FILESADDED,
1146 sidedatamod.SD_FILESADDED,
1146 sidedatamod.SD_FILESREMOVED,
1147 sidedatamod.SD_FILESREMOVED,
1147 )
1148 )
1148 return False, f, {}
1149 return False, f, {}
1149
1150
1150 return sidedatacompanion
1151 return sidedatacompanion
@@ -1,171 +1,172 b''
1 Test for the full copytracing algorithm
1 Test for the full copytracing algorithm
2 =======================================
2 =======================================
3
3
4 $ hg init t
4 $ hg init t
5 $ cd t
5 $ cd t
6
6
7 $ echo 1 > a
7 $ echo 1 > a
8 $ hg ci -qAm "first"
8 $ hg ci -qAm "first"
9
9
10 $ hg cp a b
10 $ hg cp a b
11 $ hg mv a c
11 $ hg mv a c
12 $ echo 2 >> b
12 $ echo 2 >> b
13 $ echo 2 >> c
13 $ echo 2 >> c
14
14
15 $ hg ci -qAm "second"
15 $ hg ci -qAm "second"
16
16
17 $ hg co -C 0
17 $ hg co -C 0
18 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
18 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
19
19
20 $ echo 0 > a
20 $ echo 0 > a
21 $ echo 1 >> a
21 $ echo 1 >> a
22
22
23 $ hg ci -qAm "other"
23 $ hg ci -qAm "other"
24
24
25 $ hg merge --debug
25 $ hg merge --debug
26 unmatched files in other:
26 unmatched files in other:
27 b
27 b
28 c
28 c
29 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
29 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
30 src: 'a' -> dst: 'b' *
30 on remote side:
31 src: 'a' -> dst: 'c' *
31 src: 'a' -> dst: 'b' *
32 src: 'a' -> dst: 'c' *
32 checking for directory renames
33 checking for directory renames
33 resolving manifests
34 resolving manifests
34 branchmerge: True, force: False, partial: False
35 branchmerge: True, force: False, partial: False
35 ancestor: b8bf91eeebbc, local: add3f11052fa+, remote: 17c05bb7fcb6
36 ancestor: b8bf91eeebbc, local: add3f11052fa+, remote: 17c05bb7fcb6
36 preserving a for resolve of b
37 preserving a for resolve of b
37 preserving a for resolve of c
38 preserving a for resolve of c
38 removing a
39 removing a
39 starting 4 threads for background file closing (?)
40 starting 4 threads for background file closing (?)
40 b: remote moved from a -> m (premerge)
41 b: remote moved from a -> m (premerge)
41 picked tool ':merge' for b (binary False symlink False changedelete False)
42 picked tool ':merge' for b (binary False symlink False changedelete False)
42 merging a and b to b
43 merging a and b to b
43 my b@add3f11052fa+ other b@17c05bb7fcb6 ancestor a@b8bf91eeebbc
44 my b@add3f11052fa+ other b@17c05bb7fcb6 ancestor a@b8bf91eeebbc
44 premerge successful
45 premerge successful
45 c: remote moved from a -> m (premerge)
46 c: remote moved from a -> m (premerge)
46 picked tool ':merge' for c (binary False symlink False changedelete False)
47 picked tool ':merge' for c (binary False symlink False changedelete False)
47 merging a and c to c
48 merging a and c to c
48 my c@add3f11052fa+ other c@17c05bb7fcb6 ancestor a@b8bf91eeebbc
49 my c@add3f11052fa+ other c@17c05bb7fcb6 ancestor a@b8bf91eeebbc
49 premerge successful
50 premerge successful
50 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
51 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
51 (branch merge, don't forget to commit)
52 (branch merge, don't forget to commit)
52
53
53 file b
54 file b
54 $ cat b
55 $ cat b
55 0
56 0
56 1
57 1
57 2
58 2
58
59
59 file c
60 file c
60 $ cat c
61 $ cat c
61 0
62 0
62 1
63 1
63 2
64 2
64
65
65 Test disabling copy tracing
66 Test disabling copy tracing
66
67
67 - first verify copy metadata was kept
68 - first verify copy metadata was kept
68
69
69 $ hg up -qC 2
70 $ hg up -qC 2
70 $ hg rebase --keep -d 1 -b 2 --config extensions.rebase=
71 $ hg rebase --keep -d 1 -b 2 --config extensions.rebase=
71 rebasing 2:add3f11052fa "other" (tip)
72 rebasing 2:add3f11052fa "other" (tip)
72 merging b and a to b
73 merging b and a to b
73 merging c and a to c
74 merging c and a to c
74
75
75 $ cat b
76 $ cat b
76 0
77 0
77 1
78 1
78 2
79 2
79
80
80 - next verify copy metadata is lost when disabled
81 - next verify copy metadata is lost when disabled
81
82
82 $ hg strip -r . --config extensions.strip=
83 $ hg strip -r . --config extensions.strip=
83 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 saved backup bundle to $TESTTMP/t/.hg/strip-backup/550bd84c0cd3-fc575957-backup.hg
85 saved backup bundle to $TESTTMP/t/.hg/strip-backup/550bd84c0cd3-fc575957-backup.hg
85 $ hg up -qC 2
86 $ hg up -qC 2
86 $ hg rebase --keep -d 1 -b 2 --config extensions.rebase= --config experimental.copytrace=off --config ui.interactive=True << EOF
87 $ hg rebase --keep -d 1 -b 2 --config extensions.rebase= --config experimental.copytrace=off --config ui.interactive=True << EOF
87 > c
88 > c
88 > EOF
89 > EOF
89 rebasing 2:add3f11052fa "other" (tip)
90 rebasing 2:add3f11052fa "other" (tip)
90 file 'a' was deleted in local [dest] but was modified in other [source].
91 file 'a' was deleted in local [dest] but was modified in other [source].
91 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
92 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
92 What do you want to do? c
93 What do you want to do? c
93
94
94 $ cat b
95 $ cat b
95 1
96 1
96 2
97 2
97
98
98 $ cd ..
99 $ cd ..
99
100
100 Verify disabling copy tracing still keeps copies from rebase source
101 Verify disabling copy tracing still keeps copies from rebase source
101
102
102 $ hg init copydisable
103 $ hg init copydisable
103 $ cd copydisable
104 $ cd copydisable
104 $ touch a
105 $ touch a
105 $ hg ci -Aqm 'add a'
106 $ hg ci -Aqm 'add a'
106 $ touch b
107 $ touch b
107 $ hg ci -Aqm 'add b, c'
108 $ hg ci -Aqm 'add b, c'
108 $ hg cp b x
109 $ hg cp b x
109 $ echo x >> x
110 $ echo x >> x
110 $ hg ci -qm 'copy b->x'
111 $ hg ci -qm 'copy b->x'
111 $ hg up -q 1
112 $ hg up -q 1
112 $ touch z
113 $ touch z
113 $ hg ci -Aqm 'add z'
114 $ hg ci -Aqm 'add z'
114 $ hg log -G -T '{rev} {desc}\n'
115 $ hg log -G -T '{rev} {desc}\n'
115 @ 3 add z
116 @ 3 add z
116 |
117 |
117 | o 2 copy b->x
118 | o 2 copy b->x
118 |/
119 |/
119 o 1 add b, c
120 o 1 add b, c
120 |
121 |
121 o 0 add a
122 o 0 add a
122
123
123 $ hg rebase -d . -b 2 --config extensions.rebase= --config experimental.copytrace=off
124 $ hg rebase -d . -b 2 --config extensions.rebase= --config experimental.copytrace=off
124 rebasing 2:6adcf8c12e7d "copy b->x"
125 rebasing 2:6adcf8c12e7d "copy b->x"
125 saved backup bundle to $TESTTMP/copydisable/.hg/strip-backup/6adcf8c12e7d-ce4b3e75-rebase.hg
126 saved backup bundle to $TESTTMP/copydisable/.hg/strip-backup/6adcf8c12e7d-ce4b3e75-rebase.hg
126 $ hg up -q 3
127 $ hg up -q 3
127 $ hg log -f x -T '{rev} {desc}\n'
128 $ hg log -f x -T '{rev} {desc}\n'
128 3 copy b->x
129 3 copy b->x
129 1 add b, c
130 1 add b, c
130
131
131 $ cd ../
132 $ cd ../
132
133
133 Verify we duplicate existing copies, instead of detecting them
134 Verify we duplicate existing copies, instead of detecting them
134
135
135 $ hg init copydisable3
136 $ hg init copydisable3
136 $ cd copydisable3
137 $ cd copydisable3
137 $ touch a
138 $ touch a
138 $ hg ci -Aqm 'add a'
139 $ hg ci -Aqm 'add a'
139 $ hg cp a b
140 $ hg cp a b
140 $ hg ci -Aqm 'copy a->b'
141 $ hg ci -Aqm 'copy a->b'
141 $ hg mv b c
142 $ hg mv b c
142 $ hg ci -Aqm 'move b->c'
143 $ hg ci -Aqm 'move b->c'
143 $ hg up -q 0
144 $ hg up -q 0
144 $ hg cp a b
145 $ hg cp a b
145 $ echo b >> b
146 $ echo b >> b
146 $ hg ci -Aqm 'copy a->b (2)'
147 $ hg ci -Aqm 'copy a->b (2)'
147 $ hg log -G -T '{rev} {desc}\n'
148 $ hg log -G -T '{rev} {desc}\n'
148 @ 3 copy a->b (2)
149 @ 3 copy a->b (2)
149 |
150 |
150 | o 2 move b->c
151 | o 2 move b->c
151 | |
152 | |
152 | o 1 copy a->b
153 | o 1 copy a->b
153 |/
154 |/
154 o 0 add a
155 o 0 add a
155
156
156 $ hg rebase -d 2 -s 3 --config extensions.rebase= --config experimental.copytrace=off
157 $ hg rebase -d 2 -s 3 --config extensions.rebase= --config experimental.copytrace=off
157 rebasing 3:47e1a9e6273b "copy a->b (2)" (tip)
158 rebasing 3:47e1a9e6273b "copy a->b (2)" (tip)
158 saved backup bundle to $TESTTMP/copydisable3/.hg/strip-backup/47e1a9e6273b-2d099c59-rebase.hg
159 saved backup bundle to $TESTTMP/copydisable3/.hg/strip-backup/47e1a9e6273b-2d099c59-rebase.hg
159
160
160 $ hg log -G -f b
161 $ hg log -G -f b
161 @ changeset: 3:76024fb4b05b
162 @ changeset: 3:76024fb4b05b
162 : tag: tip
163 : tag: tip
163 : user: test
164 : user: test
164 : date: Thu Jan 01 00:00:00 1970 +0000
165 : date: Thu Jan 01 00:00:00 1970 +0000
165 : summary: copy a->b (2)
166 : summary: copy a->b (2)
166 :
167 :
167 o changeset: 0:ac82d8b1f7c4
168 o changeset: 0:ac82d8b1f7c4
168 user: test
169 user: test
169 date: Thu Jan 01 00:00:00 1970 +0000
170 date: Thu Jan 01 00:00:00 1970 +0000
170 summary: add a
171 summary: add a
171
172
@@ -1,65 +1,66 b''
1 $ hg init repo
1 $ hg init repo
2 $ cd repo
2 $ cd repo
3
3
4 $ echo line 1 > foo
4 $ echo line 1 > foo
5 $ hg ci -qAm 'add foo'
5 $ hg ci -qAm 'add foo'
6
6
7 copy foo to bar and change both files
7 copy foo to bar and change both files
8 $ hg cp foo bar
8 $ hg cp foo bar
9 $ echo line 2-1 >> foo
9 $ echo line 2-1 >> foo
10 $ echo line 2-2 >> bar
10 $ echo line 2-2 >> bar
11 $ hg ci -m 'cp foo bar; change both'
11 $ hg ci -m 'cp foo bar; change both'
12
12
13 in another branch, change foo in a way that doesn't conflict with
13 in another branch, change foo in a way that doesn't conflict with
14 the other changes
14 the other changes
15 $ hg up -qC 0
15 $ hg up -qC 0
16 $ echo line 0 > foo
16 $ echo line 0 > foo
17 $ hg cat foo >> foo
17 $ hg cat foo >> foo
18 $ hg ci -m 'change foo'
18 $ hg ci -m 'change foo'
19 created new head
19 created new head
20
20
21 we get conflicts that shouldn't be there
21 we get conflicts that shouldn't be there
22 $ hg merge -P
22 $ hg merge -P
23 changeset: 1:484bf6903104
23 changeset: 1:484bf6903104
24 user: test
24 user: test
25 date: Thu Jan 01 00:00:00 1970 +0000
25 date: Thu Jan 01 00:00:00 1970 +0000
26 summary: cp foo bar; change both
26 summary: cp foo bar; change both
27
27
28 $ hg merge --debug
28 $ hg merge --debug
29 unmatched files in other:
29 unmatched files in other:
30 bar
30 bar
31 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
31 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
32 src: 'foo' -> dst: 'bar' *
32 on remote side:
33 src: 'foo' -> dst: 'bar' *
33 checking for directory renames
34 checking for directory renames
34 resolving manifests
35 resolving manifests
35 branchmerge: True, force: False, partial: False
36 branchmerge: True, force: False, partial: False
36 ancestor: e6dc8efe11cc, local: 6a0df1dad128+, remote: 484bf6903104
37 ancestor: e6dc8efe11cc, local: 6a0df1dad128+, remote: 484bf6903104
37 preserving foo for resolve of bar
38 preserving foo for resolve of bar
38 preserving foo for resolve of foo
39 preserving foo for resolve of foo
39 starting 4 threads for background file closing (?)
40 starting 4 threads for background file closing (?)
40 bar: remote copied from foo -> m (premerge)
41 bar: remote copied from foo -> m (premerge)
41 picked tool ':merge' for bar (binary False symlink False changedelete False)
42 picked tool ':merge' for bar (binary False symlink False changedelete False)
42 merging foo and bar to bar
43 merging foo and bar to bar
43 my bar@6a0df1dad128+ other bar@484bf6903104 ancestor foo@e6dc8efe11cc
44 my bar@6a0df1dad128+ other bar@484bf6903104 ancestor foo@e6dc8efe11cc
44 premerge successful
45 premerge successful
45 foo: versions differ -> m (premerge)
46 foo: versions differ -> m (premerge)
46 picked tool ':merge' for foo (binary False symlink False changedelete False)
47 picked tool ':merge' for foo (binary False symlink False changedelete False)
47 merging foo
48 merging foo
48 my foo@6a0df1dad128+ other foo@484bf6903104 ancestor foo@e6dc8efe11cc
49 my foo@6a0df1dad128+ other foo@484bf6903104 ancestor foo@e6dc8efe11cc
49 premerge successful
50 premerge successful
50 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
51 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
51 (branch merge, don't forget to commit)
52 (branch merge, don't forget to commit)
52
53
53 contents of foo
54 contents of foo
54 $ cat foo
55 $ cat foo
55 line 0
56 line 0
56 line 1
57 line 1
57 line 2-1
58 line 2-1
58
59
59 contents of bar
60 contents of bar
60 $ cat bar
61 $ cat bar
61 line 0
62 line 0
62 line 1
63 line 1
63 line 2-2
64 line 2-2
64
65
65 $ cd ..
66 $ cd ..
@@ -1,906 +1,912 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extdiff]
2 > [extdiff]
3 > # for portability:
3 > # for portability:
4 > pdiff = sh "$RUNTESTDIR/pdiff"
4 > pdiff = sh "$RUNTESTDIR/pdiff"
5 > EOF
5 > EOF
6
6
7 Create a repo with some stuff in it:
7 Create a repo with some stuff in it:
8
8
9 $ hg init a
9 $ hg init a
10 $ cd a
10 $ cd a
11 $ echo a > a
11 $ echo a > a
12 $ echo a > d
12 $ echo a > d
13 $ echo a > e
13 $ echo a > e
14 $ hg ci -qAm0
14 $ hg ci -qAm0
15 $ echo b > a
15 $ echo b > a
16 $ hg ci -m1 -u bar
16 $ hg ci -m1 -u bar
17 $ hg mv a b
17 $ hg mv a b
18 $ hg ci -m2
18 $ hg ci -m2
19 $ hg cp b c
19 $ hg cp b c
20 $ hg ci -m3 -u baz
20 $ hg ci -m3 -u baz
21 $ echo b > d
21 $ echo b > d
22 $ echo f > e
22 $ echo f > e
23 $ hg ci -m4
23 $ hg ci -m4
24 $ hg up -q 3
24 $ hg up -q 3
25 $ echo b > e
25 $ echo b > e
26 $ hg branch -q stable
26 $ hg branch -q stable
27 $ hg ci -m5
27 $ hg ci -m5
28 $ hg merge -q default --tool internal:local # for conflicts in e, choose 5 and ignore 4
28 $ hg merge -q default --tool internal:local # for conflicts in e, choose 5 and ignore 4
29 $ hg branch -q default
29 $ hg branch -q default
30 $ hg ci -m6
30 $ hg ci -m6
31 $ hg phase --public 3
31 $ hg phase --public 3
32 $ hg phase --force --secret 6
32 $ hg phase --force --secret 6
33
33
34 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
34 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
35 @ test@6.secret: 6
35 @ test@6.secret: 6
36 |\
36 |\
37 | o test@5.draft: 5
37 | o test@5.draft: 5
38 | |
38 | |
39 o | test@4.draft: 4
39 o | test@4.draft: 4
40 |/
40 |/
41 o baz@3.public: 3
41 o baz@3.public: 3
42 |
42 |
43 o test@2.public: 2
43 o test@2.public: 2
44 |
44 |
45 o bar@1.public: 1
45 o bar@1.public: 1
46 |
46 |
47 o test@0.public: 0
47 o test@0.public: 0
48
48
49 Test --base for grafting the merge of 4 from the perspective of 5, thus only getting the change to d
49 Test --base for grafting the merge of 4 from the perspective of 5, thus only getting the change to d
50
50
51 $ hg up -cqr 3
51 $ hg up -cqr 3
52 $ hg graft -r 6 --base 5
52 $ hg graft -r 6 --base 5
53 grafting 6:25a2b029d3ae "6" (tip)
53 grafting 6:25a2b029d3ae "6" (tip)
54 merging e
54 merging e
55 $ hg st --change .
55 $ hg st --change .
56 M d
56 M d
57
57
58 $ hg -q strip . --config extensions.strip=
58 $ hg -q strip . --config extensions.strip=
59
59
60 Test --base for collapsing changesets 2 and 3, thus getting both b and c
60 Test --base for collapsing changesets 2 and 3, thus getting both b and c
61
61
62 $ hg up -cqr 0
62 $ hg up -cqr 0
63 $ hg graft -r 3 --base 1
63 $ hg graft -r 3 --base 1
64 grafting 3:4c60f11aa304 "3"
64 grafting 3:4c60f11aa304 "3"
65 merging a and b to b
65 merging a and b to b
66 merging a and c to c
66 merging a and c to c
67 $ hg st --change .
67 $ hg st --change .
68 A b
68 A b
69 A c
69 A c
70 R a
70 R a
71
71
72 $ hg -q strip . --config extensions.strip=
72 $ hg -q strip . --config extensions.strip=
73
73
74 Specifying child as --base revision fails safely (perhaps slightly confusing, but consistent)
74 Specifying child as --base revision fails safely (perhaps slightly confusing, but consistent)
75
75
76 $ hg graft -r 2 --base 3
76 $ hg graft -r 2 --base 3
77 grafting 2:5c095ad7e90f "2"
77 grafting 2:5c095ad7e90f "2"
78 note: possible conflict - c was deleted and renamed to:
78 note: possible conflict - c was deleted and renamed to:
79 a
79 a
80 note: graft of 2:5c095ad7e90f created no changes to commit
80 note: graft of 2:5c095ad7e90f created no changes to commit
81
81
82 Can't continue without starting:
82 Can't continue without starting:
83
83
84 $ hg -q up -cr tip
84 $ hg -q up -cr tip
85 $ hg rm -q e
85 $ hg rm -q e
86 $ hg graft --continue
86 $ hg graft --continue
87 abort: no graft in progress
87 abort: no graft in progress
88 [255]
88 [255]
89 $ hg revert -r . -q e
89 $ hg revert -r . -q e
90
90
91 Need to specify a rev:
91 Need to specify a rev:
92
92
93 $ hg graft
93 $ hg graft
94 abort: no revisions specified
94 abort: no revisions specified
95 [255]
95 [255]
96
96
97 Can't graft ancestor:
97 Can't graft ancestor:
98
98
99 $ hg graft 1 2
99 $ hg graft 1 2
100 skipping ancestor revision 1:5d205f8b35b6
100 skipping ancestor revision 1:5d205f8b35b6
101 skipping ancestor revision 2:5c095ad7e90f
101 skipping ancestor revision 2:5c095ad7e90f
102 [255]
102 [255]
103
103
104 Specify revisions with -r:
104 Specify revisions with -r:
105
105
106 $ hg graft -r 1 -r 2
106 $ hg graft -r 1 -r 2
107 skipping ancestor revision 1:5d205f8b35b6
107 skipping ancestor revision 1:5d205f8b35b6
108 skipping ancestor revision 2:5c095ad7e90f
108 skipping ancestor revision 2:5c095ad7e90f
109 [255]
109 [255]
110
110
111 $ hg graft -r 1 2
111 $ hg graft -r 1 2
112 warning: inconsistent use of --rev might give unexpected revision ordering!
112 warning: inconsistent use of --rev might give unexpected revision ordering!
113 skipping ancestor revision 2:5c095ad7e90f
113 skipping ancestor revision 2:5c095ad7e90f
114 skipping ancestor revision 1:5d205f8b35b6
114 skipping ancestor revision 1:5d205f8b35b6
115 [255]
115 [255]
116
116
117 Conflicting date/user options:
117 Conflicting date/user options:
118
118
119 $ hg up -q 0
119 $ hg up -q 0
120 $ hg graft -U --user foo 2
120 $ hg graft -U --user foo 2
121 abort: cannot specify both --user and --currentuser
121 abort: cannot specify both --user and --currentuser
122 [255]
122 [255]
123 $ hg graft -D --date '0 0' 2
123 $ hg graft -D --date '0 0' 2
124 abort: cannot specify both --date and --currentdate
124 abort: cannot specify both --date and --currentdate
125 [255]
125 [255]
126
126
127 Can't graft with dirty wd:
127 Can't graft with dirty wd:
128
128
129 $ hg up -q 0
129 $ hg up -q 0
130 $ echo foo > a
130 $ echo foo > a
131 $ hg graft 1
131 $ hg graft 1
132 abort: uncommitted changes
132 abort: uncommitted changes
133 [255]
133 [255]
134 $ hg revert a
134 $ hg revert a
135
135
136 Graft a rename:
136 Graft a rename:
137 (this also tests that editor is invoked if '--edit' is specified)
137 (this also tests that editor is invoked if '--edit' is specified)
138
138
139 $ hg status --rev "2^1" --rev 2
139 $ hg status --rev "2^1" --rev 2
140 A b
140 A b
141 R a
141 R a
142 $ HGEDITOR=cat hg graft 2 -u foo --edit
142 $ HGEDITOR=cat hg graft 2 -u foo --edit
143 grafting 2:5c095ad7e90f "2"
143 grafting 2:5c095ad7e90f "2"
144 merging a and b to b
144 merging a and b to b
145 2
145 2
146
146
147
147
148 HG: Enter commit message. Lines beginning with 'HG:' are removed.
148 HG: Enter commit message. Lines beginning with 'HG:' are removed.
149 HG: Leave message empty to abort commit.
149 HG: Leave message empty to abort commit.
150 HG: --
150 HG: --
151 HG: user: foo
151 HG: user: foo
152 HG: branch 'default'
152 HG: branch 'default'
153 HG: added b
153 HG: added b
154 HG: removed a
154 HG: removed a
155 $ hg export tip --git
155 $ hg export tip --git
156 # HG changeset patch
156 # HG changeset patch
157 # User foo
157 # User foo
158 # Date 0 0
158 # Date 0 0
159 # Thu Jan 01 00:00:00 1970 +0000
159 # Thu Jan 01 00:00:00 1970 +0000
160 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
160 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
161 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
161 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
162 2
162 2
163
163
164 diff --git a/a b/b
164 diff --git a/a b/b
165 rename from a
165 rename from a
166 rename to b
166 rename to b
167
167
168 Look for extra:source
168 Look for extra:source
169
169
170 $ hg log --debug -r tip
170 $ hg log --debug -r tip
171 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
171 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
172 tag: tip
172 tag: tip
173 phase: draft
173 phase: draft
174 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
174 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
175 parent: -1:0000000000000000000000000000000000000000
175 parent: -1:0000000000000000000000000000000000000000
176 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
176 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
177 user: foo
177 user: foo
178 date: Thu Jan 01 00:00:00 1970 +0000
178 date: Thu Jan 01 00:00:00 1970 +0000
179 files+: b
179 files+: b
180 files-: a
180 files-: a
181 extra: branch=default
181 extra: branch=default
182 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
182 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
183 description:
183 description:
184 2
184 2
185
185
186
186
187
187
188 Graft out of order, skipping a merge and a duplicate
188 Graft out of order, skipping a merge and a duplicate
189 (this also tests that editor is not invoked if '--edit' is not specified)
189 (this also tests that editor is not invoked if '--edit' is not specified)
190
190
191 $ hg graft 1 5 4 3 'merge()' 2 -n
191 $ hg graft 1 5 4 3 'merge()' 2 -n
192 skipping ungraftable merge revision 6
192 skipping ungraftable merge revision 6
193 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
193 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
194 grafting 1:5d205f8b35b6 "1"
194 grafting 1:5d205f8b35b6 "1"
195 grafting 5:97f8bfe72746 "5"
195 grafting 5:97f8bfe72746 "5"
196 grafting 4:9c233e8e184d "4"
196 grafting 4:9c233e8e184d "4"
197 grafting 3:4c60f11aa304 "3"
197 grafting 3:4c60f11aa304 "3"
198
198
199 $ HGEDITOR=cat hg graft 1 5 'merge()' 2 --debug
199 $ HGEDITOR=cat hg graft 1 5 'merge()' 2 --debug
200 skipping ungraftable merge revision 6
200 skipping ungraftable merge revision 6
201 scanning for duplicate grafts
201 scanning for duplicate grafts
202 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
202 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
203 grafting 1:5d205f8b35b6 "1"
203 grafting 1:5d205f8b35b6 "1"
204 unmatched files in local:
204 unmatched files in local:
205 b
205 b
206 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
206 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
207 src: 'a' -> dst: 'b' *
207 on local side:
208 src: 'a' -> dst: 'b' *
208 checking for directory renames
209 checking for directory renames
209 resolving manifests
210 resolving manifests
210 branchmerge: True, force: True, partial: False
211 branchmerge: True, force: True, partial: False
211 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
212 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
212 preserving b for resolve of b
213 preserving b for resolve of b
213 starting 4 threads for background file closing (?)
214 starting 4 threads for background file closing (?)
214 b: local copied/moved from a -> m (premerge)
215 b: local copied/moved from a -> m (premerge)
215 picked tool ':merge' for b (binary False symlink False changedelete False)
216 picked tool ':merge' for b (binary False symlink False changedelete False)
216 merging b and a to b
217 merging b and a to b
217 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
218 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
218 premerge successful
219 premerge successful
219 committing files:
220 committing files:
220 b
221 b
221 committing manifest
222 committing manifest
222 committing changelog
223 committing changelog
223 updating the branch cache
224 updating the branch cache
224 grafting 5:97f8bfe72746 "5"
225 grafting 5:97f8bfe72746 "5"
225 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
226 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
226 src: 'c' -> dst: 'b'
227 on local side:
228 src: 'c' -> dst: 'b'
227 checking for directory renames
229 checking for directory renames
228 resolving manifests
230 resolving manifests
229 branchmerge: True, force: True, partial: False
231 branchmerge: True, force: True, partial: False
230 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
232 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
231 e: remote is newer -> g
233 e: remote is newer -> g
232 getting e
234 getting e
233 committing files:
235 committing files:
234 e
236 e
235 committing manifest
237 committing manifest
236 committing changelog
238 committing changelog
237 updating the branch cache
239 updating the branch cache
238 $ HGEDITOR=cat hg graft 4 3 --log --debug
240 $ HGEDITOR=cat hg graft 4 3 --log --debug
239 scanning for duplicate grafts
241 scanning for duplicate grafts
240 grafting 4:9c233e8e184d "4"
242 grafting 4:9c233e8e184d "4"
241 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
243 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
242 src: 'c' -> dst: 'b'
244 on local side:
245 src: 'c' -> dst: 'b'
243 checking for directory renames
246 checking for directory renames
244 resolving manifests
247 resolving manifests
245 branchmerge: True, force: True, partial: False
248 branchmerge: True, force: True, partial: False
246 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
249 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
247 preserving e for resolve of e
250 preserving e for resolve of e
248 d: remote is newer -> g
251 d: remote is newer -> g
249 getting d
252 getting d
250 e: versions differ -> m (premerge)
253 e: versions differ -> m (premerge)
251 picked tool ':merge' for e (binary False symlink False changedelete False)
254 picked tool ':merge' for e (binary False symlink False changedelete False)
252 merging e
255 merging e
253 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
256 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
254 e: versions differ -> m (merge)
257 e: versions differ -> m (merge)
255 picked tool ':merge' for e (binary False symlink False changedelete False)
258 picked tool ':merge' for e (binary False symlink False changedelete False)
256 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
259 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
257 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
260 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
258 abort: unresolved conflicts, can't continue
261 abort: unresolved conflicts, can't continue
259 (use 'hg resolve' and 'hg graft --continue')
262 (use 'hg resolve' and 'hg graft --continue')
260 [255]
263 [255]
261
264
262 Summary should mention graft:
265 Summary should mention graft:
263
266
264 $ hg summary |grep graft
267 $ hg summary |grep graft
265 commit: 2 modified, 2 unknown, 1 unresolved (graft in progress)
268 commit: 2 modified, 2 unknown, 1 unresolved (graft in progress)
266
269
267 Using status to get more context
270 Using status to get more context
268
271
269 $ hg status --verbose
272 $ hg status --verbose
270 M d
273 M d
271 M e
274 M e
272 ? a.orig
275 ? a.orig
273 ? e.orig
276 ? e.orig
274 # The repository is in an unfinished *graft* state.
277 # The repository is in an unfinished *graft* state.
275
278
276 # Unresolved merge conflicts:
279 # Unresolved merge conflicts:
277 #
280 #
278 # e
281 # e
279 #
282 #
280 # To mark files as resolved: hg resolve --mark FILE
283 # To mark files as resolved: hg resolve --mark FILE
281
284
282 # To continue: hg graft --continue
285 # To continue: hg graft --continue
283 # To abort: hg graft --abort
286 # To abort: hg graft --abort
284 # To stop: hg graft --stop
287 # To stop: hg graft --stop
285
288
286
289
287 Commit while interrupted should fail:
290 Commit while interrupted should fail:
288
291
289 $ hg ci -m 'commit interrupted graft'
292 $ hg ci -m 'commit interrupted graft'
290 abort: graft in progress
293 abort: graft in progress
291 (use 'hg graft --continue' or 'hg graft --stop' to stop)
294 (use 'hg graft --continue' or 'hg graft --stop' to stop)
292 [255]
295 [255]
293
296
294 Abort the graft and try committing:
297 Abort the graft and try committing:
295
298
296 $ hg up -C .
299 $ hg up -C .
297 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
300 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
298 $ echo c >> e
301 $ echo c >> e
299 $ hg ci -mtest
302 $ hg ci -mtest
300
303
301 $ hg strip . --config extensions.strip=
304 $ hg strip . --config extensions.strip=
302 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
305 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
303 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
306 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
304
307
305 Graft again:
308 Graft again:
306
309
307 $ hg graft 1 5 4 3 'merge()' 2
310 $ hg graft 1 5 4 3 'merge()' 2
308 skipping ungraftable merge revision 6
311 skipping ungraftable merge revision 6
309 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
312 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
310 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
313 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
311 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
314 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
312 grafting 4:9c233e8e184d "4"
315 grafting 4:9c233e8e184d "4"
313 merging e
316 merging e
314 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
317 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
315 abort: unresolved conflicts, can't continue
318 abort: unresolved conflicts, can't continue
316 (use 'hg resolve' and 'hg graft --continue')
319 (use 'hg resolve' and 'hg graft --continue')
317 [255]
320 [255]
318
321
319 Continue without resolve should fail:
322 Continue without resolve should fail:
320
323
321 $ hg graft -c
324 $ hg graft -c
322 grafting 4:9c233e8e184d "4"
325 grafting 4:9c233e8e184d "4"
323 abort: unresolved merge conflicts (see 'hg help resolve')
326 abort: unresolved merge conflicts (see 'hg help resolve')
324 [255]
327 [255]
325
328
326 Fix up:
329 Fix up:
327
330
328 $ echo b > e
331 $ echo b > e
329 $ hg resolve -m e
332 $ hg resolve -m e
330 (no more unresolved files)
333 (no more unresolved files)
331 continue: hg graft --continue
334 continue: hg graft --continue
332
335
333 Continue with a revision should fail:
336 Continue with a revision should fail:
334
337
335 $ hg graft -c 6
338 $ hg graft -c 6
336 abort: can't specify --continue and revisions
339 abort: can't specify --continue and revisions
337 [255]
340 [255]
338
341
339 $ hg graft -c -r 6
342 $ hg graft -c -r 6
340 abort: can't specify --continue and revisions
343 abort: can't specify --continue and revisions
341 [255]
344 [255]
342
345
343 Continue for real, clobber usernames
346 Continue for real, clobber usernames
344
347
345 $ hg graft -c -U
348 $ hg graft -c -U
346 grafting 4:9c233e8e184d "4"
349 grafting 4:9c233e8e184d "4"
347 grafting 3:4c60f11aa304 "3"
350 grafting 3:4c60f11aa304 "3"
348
351
349 Compare with original:
352 Compare with original:
350
353
351 $ hg diff -r 6
354 $ hg diff -r 6
352 $ hg status --rev 0:. -C
355 $ hg status --rev 0:. -C
353 M d
356 M d
354 M e
357 M e
355 A b
358 A b
356 a
359 a
357 A c
360 A c
358 a
361 a
359 R a
362 R a
360
363
361 View graph:
364 View graph:
362
365
363 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
366 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
364 @ test@11.draft: 3
367 @ test@11.draft: 3
365 |
368 |
366 o test@10.draft: 4
369 o test@10.draft: 4
367 |
370 |
368 o test@9.draft: 5
371 o test@9.draft: 5
369 |
372 |
370 o bar@8.draft: 1
373 o bar@8.draft: 1
371 |
374 |
372 o foo@7.draft: 2
375 o foo@7.draft: 2
373 |
376 |
374 | o test@6.secret: 6
377 | o test@6.secret: 6
375 | |\
378 | |\
376 | | o test@5.draft: 5
379 | | o test@5.draft: 5
377 | | |
380 | | |
378 | o | test@4.draft: 4
381 | o | test@4.draft: 4
379 | |/
382 | |/
380 | o baz@3.public: 3
383 | o baz@3.public: 3
381 | |
384 | |
382 | o test@2.public: 2
385 | o test@2.public: 2
383 | |
386 | |
384 | o bar@1.public: 1
387 | o bar@1.public: 1
385 |/
388 |/
386 o test@0.public: 0
389 o test@0.public: 0
387
390
388 Graft again onto another branch should preserve the original source
391 Graft again onto another branch should preserve the original source
389 $ hg up -q 0
392 $ hg up -q 0
390 $ echo 'g'>g
393 $ echo 'g'>g
391 $ hg add g
394 $ hg add g
392 $ hg ci -m 7
395 $ hg ci -m 7
393 created new head
396 created new head
394 $ hg graft 7
397 $ hg graft 7
395 grafting 7:ef0ef43d49e7 "2"
398 grafting 7:ef0ef43d49e7 "2"
396
399
397 $ hg log -r 7 --template '{rev}:{node}\n'
400 $ hg log -r 7 --template '{rev}:{node}\n'
398 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
401 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
399 $ hg log -r 2 --template '{rev}:{node}\n'
402 $ hg log -r 2 --template '{rev}:{node}\n'
400 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
403 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
401
404
402 $ hg log --debug -r tip
405 $ hg log --debug -r tip
403 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
406 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
404 tag: tip
407 tag: tip
405 phase: draft
408 phase: draft
406 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
409 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
407 parent: -1:0000000000000000000000000000000000000000
410 parent: -1:0000000000000000000000000000000000000000
408 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
411 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
409 user: foo
412 user: foo
410 date: Thu Jan 01 00:00:00 1970 +0000
413 date: Thu Jan 01 00:00:00 1970 +0000
411 files+: b
414 files+: b
412 files-: a
415 files-: a
413 extra: branch=default
416 extra: branch=default
414 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
417 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
415 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
418 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
416 description:
419 description:
417 2
420 2
418
421
419
422
420 Disallow grafting an already grafted cset onto its original branch
423 Disallow grafting an already grafted cset onto its original branch
421 $ hg up -q 6
424 $ hg up -q 6
422 $ hg graft 7
425 $ hg graft 7
423 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
426 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
424 [255]
427 [255]
425
428
426 $ hg pdiff --config extensions.extdiff= --patch -r 2 -r 13
429 $ hg pdiff --config extensions.extdiff= --patch -r 2 -r 13
427 --- */hg-5c095ad7e90f.patch * (glob)
430 --- */hg-5c095ad7e90f.patch * (glob)
428 +++ */hg-7a4785234d87.patch * (glob)
431 +++ */hg-7a4785234d87.patch * (glob)
429 @@ -1,18 +1,18 @@
432 @@ -1,18 +1,18 @@
430 # HG changeset patch
433 # HG changeset patch
431 -# User test
434 -# User test
432 +# User foo
435 +# User foo
433 # Date 0 0
436 # Date 0 0
434 # Thu Jan 01 00:00:00 1970 +0000
437 # Thu Jan 01 00:00:00 1970 +0000
435 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
438 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
436 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
439 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
437 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
440 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
438 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
441 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
439 2
442 2
440
443
441 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
444 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
442 +diff -r b592ea63bb0c -r 7a4785234d87 a
445 +diff -r b592ea63bb0c -r 7a4785234d87 a
443 --- a/a Thu Jan 01 00:00:00 1970 +0000
446 --- a/a Thu Jan 01 00:00:00 1970 +0000
444 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
447 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
445 @@ -1,1 +0,0 @@
448 @@ -1,1 +0,0 @@
446 --b
449 --b
447 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
450 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
448 +-a
451 +-a
449 +diff -r b592ea63bb0c -r 7a4785234d87 b
452 +diff -r b592ea63bb0c -r 7a4785234d87 b
450 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
453 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
451 +++ b/b Thu Jan 01 00:00:00 1970 +0000
454 +++ b/b Thu Jan 01 00:00:00 1970 +0000
452 @@ -0,0 +1,1 @@
455 @@ -0,0 +1,1 @@
453 -+b
456 -+b
454 ++a
457 ++a
455 [1]
458 [1]
456
459
457 $ hg pdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
460 $ hg pdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
458 --- */hg-5c095ad7e90f.patch * (glob)
461 --- */hg-5c095ad7e90f.patch * (glob)
459 +++ */hg-7a4785234d87.patch * (glob)
462 +++ */hg-7a4785234d87.patch * (glob)
460 @@ -1,8 +1,8 @@
463 @@ -1,8 +1,8 @@
461 # HG changeset patch
464 # HG changeset patch
462 -# User test
465 -# User test
463 +# User foo
466 +# User foo
464 # Date 0 0
467 # Date 0 0
465 # Thu Jan 01 00:00:00 1970 +0000
468 # Thu Jan 01 00:00:00 1970 +0000
466 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
469 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
467 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
470 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
468 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
471 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
469 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
472 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
470 2
473 2
471
474
472 [1]
475 [1]
473
476
474 Disallow grafting already grafted csets with the same origin onto each other
477 Disallow grafting already grafted csets with the same origin onto each other
475 $ hg up -q 13
478 $ hg up -q 13
476 $ hg graft 2
479 $ hg graft 2
477 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
480 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
478 [255]
481 [255]
479 $ hg graft 7
482 $ hg graft 7
480 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
483 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
481 [255]
484 [255]
482
485
483 $ hg up -q 7
486 $ hg up -q 7
484 $ hg graft 2
487 $ hg graft 2
485 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
488 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
486 [255]
489 [255]
487 $ hg graft tip
490 $ hg graft tip
488 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
491 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
489 [255]
492 [255]
490
493
491 Graft with --log
494 Graft with --log
492
495
493 $ hg up -Cq 1
496 $ hg up -Cq 1
494 $ hg graft 3 --log -u foo
497 $ hg graft 3 --log -u foo
495 grafting 3:4c60f11aa304 "3"
498 grafting 3:4c60f11aa304 "3"
496 $ hg log --template '{rev}:{node|short} {parents} {desc}\n' -r tip
499 $ hg log --template '{rev}:{node|short} {parents} {desc}\n' -r tip
497 14:0c921c65ef1e 1:5d205f8b35b6 3
500 14:0c921c65ef1e 1:5d205f8b35b6 3
498 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
501 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
499
502
500 Resolve conflicted graft
503 Resolve conflicted graft
501 $ hg up -q 0
504 $ hg up -q 0
502 $ echo b > a
505 $ echo b > a
503 $ hg ci -m 8
506 $ hg ci -m 8
504 created new head
507 created new head
505 $ echo c > a
508 $ echo c > a
506 $ hg ci -m 9
509 $ hg ci -m 9
507 $ hg graft 1 --tool internal:fail
510 $ hg graft 1 --tool internal:fail
508 grafting 1:5d205f8b35b6 "1"
511 grafting 1:5d205f8b35b6 "1"
509 abort: unresolved conflicts, can't continue
512 abort: unresolved conflicts, can't continue
510 (use 'hg resolve' and 'hg graft --continue')
513 (use 'hg resolve' and 'hg graft --continue')
511 [255]
514 [255]
512 $ hg resolve --all
515 $ hg resolve --all
513 merging a
516 merging a
514 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
517 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
515 [1]
518 [1]
516 $ cat a
519 $ cat a
517 <<<<<<< local: aaa4406d4f0a - test: 9
520 <<<<<<< local: aaa4406d4f0a - test: 9
518 c
521 c
519 =======
522 =======
520 b
523 b
521 >>>>>>> graft: 5d205f8b35b6 - bar: 1
524 >>>>>>> graft: 5d205f8b35b6 - bar: 1
522 $ echo b > a
525 $ echo b > a
523 $ hg resolve -m a
526 $ hg resolve -m a
524 (no more unresolved files)
527 (no more unresolved files)
525 continue: hg graft --continue
528 continue: hg graft --continue
526 $ hg graft -c
529 $ hg graft -c
527 grafting 1:5d205f8b35b6 "1"
530 grafting 1:5d205f8b35b6 "1"
528 $ hg export tip --git
531 $ hg export tip --git
529 # HG changeset patch
532 # HG changeset patch
530 # User bar
533 # User bar
531 # Date 0 0
534 # Date 0 0
532 # Thu Jan 01 00:00:00 1970 +0000
535 # Thu Jan 01 00:00:00 1970 +0000
533 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
536 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
534 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
537 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
535 1
538 1
536
539
537 diff --git a/a b/a
540 diff --git a/a b/a
538 --- a/a
541 --- a/a
539 +++ b/a
542 +++ b/a
540 @@ -1,1 +1,1 @@
543 @@ -1,1 +1,1 @@
541 -c
544 -c
542 +b
545 +b
543
546
544 Resolve conflicted graft with rename
547 Resolve conflicted graft with rename
545 $ echo c > a
548 $ echo c > a
546 $ hg ci -m 10
549 $ hg ci -m 10
547 $ hg graft 2 --tool internal:fail
550 $ hg graft 2 --tool internal:fail
548 grafting 2:5c095ad7e90f "2"
551 grafting 2:5c095ad7e90f "2"
549 abort: unresolved conflicts, can't continue
552 abort: unresolved conflicts, can't continue
550 (use 'hg resolve' and 'hg graft --continue')
553 (use 'hg resolve' and 'hg graft --continue')
551 [255]
554 [255]
552 $ hg resolve --all
555 $ hg resolve --all
553 merging a and b to b
556 merging a and b to b
554 (no more unresolved files)
557 (no more unresolved files)
555 continue: hg graft --continue
558 continue: hg graft --continue
556 $ hg graft -c
559 $ hg graft -c
557 grafting 2:5c095ad7e90f "2"
560 grafting 2:5c095ad7e90f "2"
558 $ hg export tip --git
561 $ hg export tip --git
559 # HG changeset patch
562 # HG changeset patch
560 # User test
563 # User test
561 # Date 0 0
564 # Date 0 0
562 # Thu Jan 01 00:00:00 1970 +0000
565 # Thu Jan 01 00:00:00 1970 +0000
563 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
566 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
564 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
567 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
565 2
568 2
566
569
567 diff --git a/a b/b
570 diff --git a/a b/b
568 rename from a
571 rename from a
569 rename to b
572 rename to b
570
573
571 Test simple origin(), with and without args
574 Test simple origin(), with and without args
572 $ hg log -r 'origin()'
575 $ hg log -r 'origin()'
573 changeset: 1:5d205f8b35b6
576 changeset: 1:5d205f8b35b6
574 user: bar
577 user: bar
575 date: Thu Jan 01 00:00:00 1970 +0000
578 date: Thu Jan 01 00:00:00 1970 +0000
576 summary: 1
579 summary: 1
577
580
578 changeset: 2:5c095ad7e90f
581 changeset: 2:5c095ad7e90f
579 user: test
582 user: test
580 date: Thu Jan 01 00:00:00 1970 +0000
583 date: Thu Jan 01 00:00:00 1970 +0000
581 summary: 2
584 summary: 2
582
585
583 changeset: 3:4c60f11aa304
586 changeset: 3:4c60f11aa304
584 user: baz
587 user: baz
585 date: Thu Jan 01 00:00:00 1970 +0000
588 date: Thu Jan 01 00:00:00 1970 +0000
586 summary: 3
589 summary: 3
587
590
588 changeset: 4:9c233e8e184d
591 changeset: 4:9c233e8e184d
589 user: test
592 user: test
590 date: Thu Jan 01 00:00:00 1970 +0000
593 date: Thu Jan 01 00:00:00 1970 +0000
591 summary: 4
594 summary: 4
592
595
593 changeset: 5:97f8bfe72746
596 changeset: 5:97f8bfe72746
594 branch: stable
597 branch: stable
595 parent: 3:4c60f11aa304
598 parent: 3:4c60f11aa304
596 user: test
599 user: test
597 date: Thu Jan 01 00:00:00 1970 +0000
600 date: Thu Jan 01 00:00:00 1970 +0000
598 summary: 5
601 summary: 5
599
602
600 $ hg log -r 'origin(7)'
603 $ hg log -r 'origin(7)'
601 changeset: 2:5c095ad7e90f
604 changeset: 2:5c095ad7e90f
602 user: test
605 user: test
603 date: Thu Jan 01 00:00:00 1970 +0000
606 date: Thu Jan 01 00:00:00 1970 +0000
604 summary: 2
607 summary: 2
605
608
606 Now transplant a graft to test following through copies
609 Now transplant a graft to test following through copies
607 $ hg up -q 0
610 $ hg up -q 0
608 $ hg branch -q dev
611 $ hg branch -q dev
609 $ hg ci -qm "dev branch"
612 $ hg ci -qm "dev branch"
610 $ hg --config extensions.transplant= transplant -q 7
613 $ hg --config extensions.transplant= transplant -q 7
611 $ hg log -r 'origin(.)'
614 $ hg log -r 'origin(.)'
612 changeset: 2:5c095ad7e90f
615 changeset: 2:5c095ad7e90f
613 user: test
616 user: test
614 date: Thu Jan 01 00:00:00 1970 +0000
617 date: Thu Jan 01 00:00:00 1970 +0000
615 summary: 2
618 summary: 2
616
619
617 Test that the graft and transplant markers in extra are converted, allowing
620 Test that the graft and transplant markers in extra are converted, allowing
618 origin() to still work. Note that these recheck the immediately preceeding two
621 origin() to still work. Note that these recheck the immediately preceeding two
619 tests.
622 tests.
620 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
623 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
621
624
622 The graft case
625 The graft case
623 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
626 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
624 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
627 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
625 branch=default
628 branch=default
626 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
629 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
627 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
630 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
628 $ hg -R ../converted log -r 'origin(7)'
631 $ hg -R ../converted log -r 'origin(7)'
629 changeset: 2:e0213322b2c1
632 changeset: 2:e0213322b2c1
630 user: test
633 user: test
631 date: Thu Jan 01 00:00:00 1970 +0000
634 date: Thu Jan 01 00:00:00 1970 +0000
632 summary: 2
635 summary: 2
633
636
634 Test that template correctly expands more than one 'extra' (issue4362), and that
637 Test that template correctly expands more than one 'extra' (issue4362), and that
635 'intermediate-source' is converted.
638 'intermediate-source' is converted.
636 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
639 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
637 Extra: branch=default
640 Extra: branch=default
638 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
641 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
639 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
642 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
640 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
643 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
641
644
642 The transplant case
645 The transplant case
643 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
646 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
644 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
647 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
645 branch=dev
648 branch=dev
646 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
649 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
647 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac\n`h\x9b
650 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac\n`h\x9b
648 $ hg -R ../converted log -r 'origin(tip)'
651 $ hg -R ../converted log -r 'origin(tip)'
649 changeset: 2:e0213322b2c1
652 changeset: 2:e0213322b2c1
650 user: test
653 user: test
651 date: Thu Jan 01 00:00:00 1970 +0000
654 date: Thu Jan 01 00:00:00 1970 +0000
652 summary: 2
655 summary: 2
653
656
654
657
655 Test simple destination
658 Test simple destination
656 $ hg log -r 'destination()'
659 $ hg log -r 'destination()'
657 changeset: 7:ef0ef43d49e7
660 changeset: 7:ef0ef43d49e7
658 parent: 0:68795b066622
661 parent: 0:68795b066622
659 user: foo
662 user: foo
660 date: Thu Jan 01 00:00:00 1970 +0000
663 date: Thu Jan 01 00:00:00 1970 +0000
661 summary: 2
664 summary: 2
662
665
663 changeset: 8:6b9e5368ca4e
666 changeset: 8:6b9e5368ca4e
664 user: bar
667 user: bar
665 date: Thu Jan 01 00:00:00 1970 +0000
668 date: Thu Jan 01 00:00:00 1970 +0000
666 summary: 1
669 summary: 1
667
670
668 changeset: 9:1905859650ec
671 changeset: 9:1905859650ec
669 user: test
672 user: test
670 date: Thu Jan 01 00:00:00 1970 +0000
673 date: Thu Jan 01 00:00:00 1970 +0000
671 summary: 5
674 summary: 5
672
675
673 changeset: 10:52dc0b4c6907
676 changeset: 10:52dc0b4c6907
674 user: test
677 user: test
675 date: Thu Jan 01 00:00:00 1970 +0000
678 date: Thu Jan 01 00:00:00 1970 +0000
676 summary: 4
679 summary: 4
677
680
678 changeset: 11:882b35362a6b
681 changeset: 11:882b35362a6b
679 user: test
682 user: test
680 date: Thu Jan 01 00:00:00 1970 +0000
683 date: Thu Jan 01 00:00:00 1970 +0000
681 summary: 3
684 summary: 3
682
685
683 changeset: 13:7a4785234d87
686 changeset: 13:7a4785234d87
684 user: foo
687 user: foo
685 date: Thu Jan 01 00:00:00 1970 +0000
688 date: Thu Jan 01 00:00:00 1970 +0000
686 summary: 2
689 summary: 2
687
690
688 changeset: 14:0c921c65ef1e
691 changeset: 14:0c921c65ef1e
689 parent: 1:5d205f8b35b6
692 parent: 1:5d205f8b35b6
690 user: foo
693 user: foo
691 date: Thu Jan 01 00:00:00 1970 +0000
694 date: Thu Jan 01 00:00:00 1970 +0000
692 summary: 3
695 summary: 3
693
696
694 changeset: 17:f67661df0c48
697 changeset: 17:f67661df0c48
695 user: bar
698 user: bar
696 date: Thu Jan 01 00:00:00 1970 +0000
699 date: Thu Jan 01 00:00:00 1970 +0000
697 summary: 1
700 summary: 1
698
701
699 changeset: 19:9627f653b421
702 changeset: 19:9627f653b421
700 user: test
703 user: test
701 date: Thu Jan 01 00:00:00 1970 +0000
704 date: Thu Jan 01 00:00:00 1970 +0000
702 summary: 2
705 summary: 2
703
706
704 changeset: 21:7e61b508e709
707 changeset: 21:7e61b508e709
705 branch: dev
708 branch: dev
706 tag: tip
709 tag: tip
707 user: foo
710 user: foo
708 date: Thu Jan 01 00:00:00 1970 +0000
711 date: Thu Jan 01 00:00:00 1970 +0000
709 summary: 2
712 summary: 2
710
713
711 $ hg log -r 'destination(2)'
714 $ hg log -r 'destination(2)'
712 changeset: 7:ef0ef43d49e7
715 changeset: 7:ef0ef43d49e7
713 parent: 0:68795b066622
716 parent: 0:68795b066622
714 user: foo
717 user: foo
715 date: Thu Jan 01 00:00:00 1970 +0000
718 date: Thu Jan 01 00:00:00 1970 +0000
716 summary: 2
719 summary: 2
717
720
718 changeset: 13:7a4785234d87
721 changeset: 13:7a4785234d87
719 user: foo
722 user: foo
720 date: Thu Jan 01 00:00:00 1970 +0000
723 date: Thu Jan 01 00:00:00 1970 +0000
721 summary: 2
724 summary: 2
722
725
723 changeset: 19:9627f653b421
726 changeset: 19:9627f653b421
724 user: test
727 user: test
725 date: Thu Jan 01 00:00:00 1970 +0000
728 date: Thu Jan 01 00:00:00 1970 +0000
726 summary: 2
729 summary: 2
727
730
728 changeset: 21:7e61b508e709
731 changeset: 21:7e61b508e709
729 branch: dev
732 branch: dev
730 tag: tip
733 tag: tip
731 user: foo
734 user: foo
732 date: Thu Jan 01 00:00:00 1970 +0000
735 date: Thu Jan 01 00:00:00 1970 +0000
733 summary: 2
736 summary: 2
734
737
735 Transplants of grafts can find a destination...
738 Transplants of grafts can find a destination...
736 $ hg log -r 'destination(7)'
739 $ hg log -r 'destination(7)'
737 changeset: 21:7e61b508e709
740 changeset: 21:7e61b508e709
738 branch: dev
741 branch: dev
739 tag: tip
742 tag: tip
740 user: foo
743 user: foo
741 date: Thu Jan 01 00:00:00 1970 +0000
744 date: Thu Jan 01 00:00:00 1970 +0000
742 summary: 2
745 summary: 2
743
746
744 ... grafts of grafts unfortunately can't
747 ... grafts of grafts unfortunately can't
745 $ hg graft -q 13 --debug
748 $ hg graft -q 13 --debug
746 scanning for duplicate grafts
749 scanning for duplicate grafts
747 grafting 13:7a4785234d87 "2"
750 grafting 13:7a4785234d87 "2"
748 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
751 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
749 src: 'a' -> dst: 'b' *
752 on local side:
753 src: 'a' -> dst: 'b' *
754 on remote side:
755 src: 'a' -> dst: 'b' *
750 checking for directory renames
756 checking for directory renames
751 resolving manifests
757 resolving manifests
752 branchmerge: True, force: True, partial: False
758 branchmerge: True, force: True, partial: False
753 ancestor: b592ea63bb0c, local: 7e61b508e709+, remote: 7a4785234d87
759 ancestor: b592ea63bb0c, local: 7e61b508e709+, remote: 7a4785234d87
754 starting 4 threads for background file closing (?)
760 starting 4 threads for background file closing (?)
755 note: graft of 13:7a4785234d87 created no changes to commit
761 note: graft of 13:7a4785234d87 created no changes to commit
756 $ hg log -r 'destination(13)'
762 $ hg log -r 'destination(13)'
757 All copies of a cset
763 All copies of a cset
758 $ hg log -r 'origin(13) or destination(origin(13))'
764 $ hg log -r 'origin(13) or destination(origin(13))'
759 changeset: 2:5c095ad7e90f
765 changeset: 2:5c095ad7e90f
760 user: test
766 user: test
761 date: Thu Jan 01 00:00:00 1970 +0000
767 date: Thu Jan 01 00:00:00 1970 +0000
762 summary: 2
768 summary: 2
763
769
764 changeset: 7:ef0ef43d49e7
770 changeset: 7:ef0ef43d49e7
765 parent: 0:68795b066622
771 parent: 0:68795b066622
766 user: foo
772 user: foo
767 date: Thu Jan 01 00:00:00 1970 +0000
773 date: Thu Jan 01 00:00:00 1970 +0000
768 summary: 2
774 summary: 2
769
775
770 changeset: 13:7a4785234d87
776 changeset: 13:7a4785234d87
771 user: foo
777 user: foo
772 date: Thu Jan 01 00:00:00 1970 +0000
778 date: Thu Jan 01 00:00:00 1970 +0000
773 summary: 2
779 summary: 2
774
780
775 changeset: 19:9627f653b421
781 changeset: 19:9627f653b421
776 user: test
782 user: test
777 date: Thu Jan 01 00:00:00 1970 +0000
783 date: Thu Jan 01 00:00:00 1970 +0000
778 summary: 2
784 summary: 2
779
785
780 changeset: 21:7e61b508e709
786 changeset: 21:7e61b508e709
781 branch: dev
787 branch: dev
782 tag: tip
788 tag: tip
783 user: foo
789 user: foo
784 date: Thu Jan 01 00:00:00 1970 +0000
790 date: Thu Jan 01 00:00:00 1970 +0000
785 summary: 2
791 summary: 2
786
792
787
793
788 graft skips ancestors
794 graft skips ancestors
789
795
790 $ hg graft 21 3
796 $ hg graft 21 3
791 skipping ancestor revision 21:7e61b508e709
797 skipping ancestor revision 21:7e61b508e709
792 grafting 3:4c60f11aa304 "3"
798 grafting 3:4c60f11aa304 "3"
793 merging b and c to c
799 merging b and c to c
794
800
795 graft with --force (still doesn't graft merges)
801 graft with --force (still doesn't graft merges)
796
802
797 $ hg graft 19 0 6
803 $ hg graft 19 0 6
798 skipping ungraftable merge revision 6
804 skipping ungraftable merge revision 6
799 skipping ancestor revision 0:68795b066622
805 skipping ancestor revision 0:68795b066622
800 grafting 19:9627f653b421 "2"
806 grafting 19:9627f653b421 "2"
801 merging b
807 merging b
802 note: graft of 19:9627f653b421 created no changes to commit
808 note: graft of 19:9627f653b421 created no changes to commit
803 $ hg graft 19 0 6 --force
809 $ hg graft 19 0 6 --force
804 skipping ungraftable merge revision 6
810 skipping ungraftable merge revision 6
805 grafting 19:9627f653b421 "2"
811 grafting 19:9627f653b421 "2"
806 merging b
812 merging b
807 note: graft of 19:9627f653b421 created no changes to commit
813 note: graft of 19:9627f653b421 created no changes to commit
808 grafting 0:68795b066622 "0"
814 grafting 0:68795b066622 "0"
809
815
810 graft --force after backout
816 graft --force after backout
811
817
812 $ echo abc > a
818 $ echo abc > a
813 $ hg ci -m 24
819 $ hg ci -m 24
814 $ hg backout 24
820 $ hg backout 24
815 reverting a
821 reverting a
816 changeset 25:71c4e63d4f98 backs out changeset 24:2e7ea477be26
822 changeset 25:71c4e63d4f98 backs out changeset 24:2e7ea477be26
817 $ hg graft 24
823 $ hg graft 24
818 skipping ancestor revision 24:2e7ea477be26
824 skipping ancestor revision 24:2e7ea477be26
819 [255]
825 [255]
820 $ hg graft 24 --force
826 $ hg graft 24 --force
821 grafting 24:2e7ea477be26 "24"
827 grafting 24:2e7ea477be26 "24"
822 merging a
828 merging a
823 $ cat a
829 $ cat a
824 abc
830 abc
825
831
826 graft --continue after --force
832 graft --continue after --force
827
833
828 $ echo def > a
834 $ echo def > a
829 $ hg ci -m 27
835 $ hg ci -m 27
830 $ hg graft 24 --force --tool internal:fail
836 $ hg graft 24 --force --tool internal:fail
831 grafting 24:2e7ea477be26 "24"
837 grafting 24:2e7ea477be26 "24"
832 abort: unresolved conflicts, can't continue
838 abort: unresolved conflicts, can't continue
833 (use 'hg resolve' and 'hg graft --continue')
839 (use 'hg resolve' and 'hg graft --continue')
834 [255]
840 [255]
835 $ hg resolve --all
841 $ hg resolve --all
836 merging a
842 merging a
837 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
843 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
838 [1]
844 [1]
839 $ echo abc > a
845 $ echo abc > a
840 $ hg resolve -m a
846 $ hg resolve -m a
841 (no more unresolved files)
847 (no more unresolved files)
842 continue: hg graft --continue
848 continue: hg graft --continue
843 $ hg graft -c
849 $ hg graft -c
844 grafting 24:2e7ea477be26 "24"
850 grafting 24:2e7ea477be26 "24"
845 $ cat a
851 $ cat a
846 abc
852 abc
847
853
848 Continue testing same origin policy, using revision numbers from test above
854 Continue testing same origin policy, using revision numbers from test above
849 but do some destructive editing of the repo:
855 but do some destructive editing of the repo:
850
856
851 $ hg up -qC 7
857 $ hg up -qC 7
852 $ hg tag -l -r 13 tmp
858 $ hg tag -l -r 13 tmp
853 $ hg --config extensions.strip= strip 2
859 $ hg --config extensions.strip= strip 2
854 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg
860 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg
855 $ hg graft tmp
861 $ hg graft tmp
856 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
862 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
857 [255]
863 [255]
858
864
859 Empty graft
865 Empty graft
860
866
861 $ hg up -qr 22
867 $ hg up -qr 22
862 $ hg tag -f something
868 $ hg tag -f something
863 $ hg graft -qr 23
869 $ hg graft -qr 23
864 $ hg graft -f 23
870 $ hg graft -f 23
865 grafting 23:72d9c7c75bcc "24"
871 grafting 23:72d9c7c75bcc "24"
866 note: graft of 23:72d9c7c75bcc created no changes to commit
872 note: graft of 23:72d9c7c75bcc created no changes to commit
867
873
868 $ cd ..
874 $ cd ..
869
875
870 Graft to duplicate a commit
876 Graft to duplicate a commit
871
877
872 $ hg init graftsibling
878 $ hg init graftsibling
873 $ cd graftsibling
879 $ cd graftsibling
874 $ touch a
880 $ touch a
875 $ hg commit -qAm a
881 $ hg commit -qAm a
876 $ touch b
882 $ touch b
877 $ hg commit -qAm b
883 $ hg commit -qAm b
878 $ hg log -G -T '{rev}\n'
884 $ hg log -G -T '{rev}\n'
879 @ 1
885 @ 1
880 |
886 |
881 o 0
887 o 0
882
888
883 $ hg up -q 0
889 $ hg up -q 0
884 $ hg graft -r 1
890 $ hg graft -r 1
885 grafting 1:0e067c57feba "b" (tip)
891 grafting 1:0e067c57feba "b" (tip)
886 $ hg log -G -T '{rev}\n'
892 $ hg log -G -T '{rev}\n'
887 @ 2
893 @ 2
888 |
894 |
889 | o 1
895 | o 1
890 |/
896 |/
891 o 0
897 o 0
892
898
893 Graft to duplicate a commit twice
899 Graft to duplicate a commit twice
894
900
895 $ hg up -q 0
901 $ hg up -q 0
896 $ hg graft -r 2
902 $ hg graft -r 2
897 grafting 2:044ec77f6389 "b" (tip)
903 grafting 2:044ec77f6389 "b" (tip)
898 $ hg log -G -T '{rev}\n'
904 $ hg log -G -T '{rev}\n'
899 @ 3
905 @ 3
900 |
906 |
901 | o 2
907 | o 2
902 |/
908 |/
903 | o 1
909 | o 1
904 |/
910 |/
905 o 0
911 o 0
906
912
@@ -1,96 +1,99 b''
1 https://bz.mercurial-scm.org/672
1 https://bz.mercurial-scm.org/672
2
2
3 # 0-2-4
3 # 0-2-4
4 # \ \ \
4 # \ \ \
5 # 1-3-5
5 # 1-3-5
6 #
6 #
7 # rename in #1, content change in #4.
7 # rename in #1, content change in #4.
8
8
9 $ hg init
9 $ hg init
10
10
11 $ touch 1
11 $ touch 1
12 $ touch 2
12 $ touch 2
13 $ hg commit -Am init # 0
13 $ hg commit -Am init # 0
14 adding 1
14 adding 1
15 adding 2
15 adding 2
16
16
17 $ hg rename 1 1a
17 $ hg rename 1 1a
18 $ hg commit -m rename # 1
18 $ hg commit -m rename # 1
19
19
20 $ hg co -C 0
20 $ hg co -C 0
21 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
22
22
23 $ echo unrelated >> 2
23 $ echo unrelated >> 2
24 $ hg ci -m unrelated1 # 2
24 $ hg ci -m unrelated1 # 2
25 created new head
25 created new head
26
26
27 $ hg merge --debug 1
27 $ hg merge --debug 1
28 unmatched files in other:
28 unmatched files in other:
29 1a
29 1a
30 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
30 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
31 src: '1' -> dst: '1a'
31 on remote side:
32 src: '1' -> dst: '1a'
32 checking for directory renames
33 checking for directory renames
33 resolving manifests
34 resolving manifests
34 branchmerge: True, force: False, partial: False
35 branchmerge: True, force: False, partial: False
35 ancestor: 81f4b099af3d, local: c64f439569a9+, remote: c12dcd37c90a
36 ancestor: 81f4b099af3d, local: c64f439569a9+, remote: c12dcd37c90a
36 1: other deleted -> r
37 1: other deleted -> r
37 removing 1
38 removing 1
38 1a: remote created -> g
39 1a: remote created -> g
39 getting 1a
40 getting 1a
40 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
41 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
41 (branch merge, don't forget to commit)
42 (branch merge, don't forget to commit)
42
43
43 $ hg ci -m merge1 # 3
44 $ hg ci -m merge1 # 3
44
45
45 $ hg co -C 2
46 $ hg co -C 2
46 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
47 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
47
48
48 $ echo hello >> 1
49 $ echo hello >> 1
49 $ hg ci -m unrelated2 # 4
50 $ hg ci -m unrelated2 # 4
50 created new head
51 created new head
51
52
52 $ hg co -C 3
53 $ hg co -C 3
53 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
54 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
54
55
55 $ hg merge -y --debug 4
56 $ hg merge -y --debug 4
56 unmatched files in local:
57 unmatched files in local:
57 1a
58 1a
58 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
59 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
59 src: '1' -> dst: '1a' *
60 on local side:
61 src: '1' -> dst: '1a' *
60 checking for directory renames
62 checking for directory renames
61 resolving manifests
63 resolving manifests
62 branchmerge: True, force: False, partial: False
64 branchmerge: True, force: False, partial: False
63 ancestor: c64f439569a9, local: f4a9cff3cd0b+, remote: 746e9549ea96
65 ancestor: c64f439569a9, local: f4a9cff3cd0b+, remote: 746e9549ea96
64 preserving 1a for resolve of 1a
66 preserving 1a for resolve of 1a
65 starting 4 threads for background file closing (?)
67 starting 4 threads for background file closing (?)
66 1a: local copied/moved from 1 -> m (premerge)
68 1a: local copied/moved from 1 -> m (premerge)
67 picked tool ':merge' for 1a (binary False symlink False changedelete False)
69 picked tool ':merge' for 1a (binary False symlink False changedelete False)
68 merging 1a and 1 to 1a
70 merging 1a and 1 to 1a
69 my 1a@f4a9cff3cd0b+ other 1@746e9549ea96 ancestor 1@c64f439569a9
71 my 1a@f4a9cff3cd0b+ other 1@746e9549ea96 ancestor 1@c64f439569a9
70 premerge successful
72 premerge successful
71 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
73 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
72 (branch merge, don't forget to commit)
74 (branch merge, don't forget to commit)
73
75
74 $ hg co -C 4
76 $ hg co -C 4
75 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
77 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
76
78
77 $ hg merge -y --debug 3
79 $ hg merge -y --debug 3
78 unmatched files in other:
80 unmatched files in other:
79 1a
81 1a
80 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
82 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
81 src: '1' -> dst: '1a' *
83 on remote side:
84 src: '1' -> dst: '1a' *
82 checking for directory renames
85 checking for directory renames
83 resolving manifests
86 resolving manifests
84 branchmerge: True, force: False, partial: False
87 branchmerge: True, force: False, partial: False
85 ancestor: c64f439569a9, local: 746e9549ea96+, remote: f4a9cff3cd0b
88 ancestor: c64f439569a9, local: 746e9549ea96+, remote: f4a9cff3cd0b
86 preserving 1 for resolve of 1a
89 preserving 1 for resolve of 1a
87 removing 1
90 removing 1
88 starting 4 threads for background file closing (?)
91 starting 4 threads for background file closing (?)
89 1a: remote moved from 1 -> m (premerge)
92 1a: remote moved from 1 -> m (premerge)
90 picked tool ':merge' for 1a (binary False symlink False changedelete False)
93 picked tool ':merge' for 1a (binary False symlink False changedelete False)
91 merging 1 and 1a to 1a
94 merging 1 and 1a to 1a
92 my 1a@746e9549ea96+ other 1a@f4a9cff3cd0b ancestor 1@c64f439569a9
95 my 1a@746e9549ea96+ other 1a@f4a9cff3cd0b ancestor 1@c64f439569a9
93 premerge successful
96 premerge successful
94 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
97 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
95 (branch merge, don't forget to commit)
98 (branch merge, don't forget to commit)
96
99
@@ -1,445 +1,446 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 resolving manifests
78 resolving manifests
79 branchmerge: True, force: False, partial: False
79 branchmerge: True, force: False, partial: False
80 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
80 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
81 preserving f2 for resolve of f2
81 preserving f2 for resolve of f2
82 f1: remote is newer -> g
82 f1: remote is newer -> g
83 getting f1
83 getting f1
84 f2: versions differ -> m (premerge)
84 f2: versions differ -> m (premerge)
85 picked tool ':dump' for f2 (binary False symlink False changedelete False)
85 picked tool ':dump' for f2 (binary False symlink False changedelete False)
86 merging f2
86 merging f2
87 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
87 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
88 f2: versions differ -> m (merge)
88 f2: versions differ -> m (merge)
89 picked tool ':dump' for f2 (binary False symlink False changedelete False)
89 picked tool ':dump' for f2 (binary False symlink False changedelete False)
90 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
90 my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
91 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
92 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
92 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
93 [1]
93 [1]
94
94
95 $ f --dump *
95 $ f --dump *
96 f1:
96 f1:
97 >>>
97 >>>
98 5 second change
98 5 second change
99 <<<
99 <<<
100 f2:
100 f2:
101 >>>
101 >>>
102 6 second change
102 6 second change
103 <<<
103 <<<
104 f2.base:
104 f2.base:
105 >>>
105 >>>
106 0 base
106 0 base
107 <<<
107 <<<
108 f2.local:
108 f2.local:
109 >>>
109 >>>
110 6 second change
110 6 second change
111 <<<
111 <<<
112 f2.orig:
112 f2.orig:
113 >>>
113 >>>
114 6 second change
114 6 second change
115 <<<
115 <<<
116 f2.other:
116 f2.other:
117 >>>
117 >>>
118 2 first change
118 2 first change
119 <<<
119 <<<
120
120
121 $ hg up -qC .
121 $ hg up -qC .
122 $ hg merge -v --tool internal:dump 5 --config merge.preferancestor="null 40663881 3b08d"
122 $ hg merge -v --tool internal:dump 5 --config merge.preferancestor="null 40663881 3b08d"
123 note: using 40663881a6dd as ancestor of 3b08d01b0ab5 and adfe50279922
123 note: using 40663881a6dd as ancestor of 3b08d01b0ab5 and adfe50279922
124 alternatively, use --config merge.preferancestor=0f6b37dbe527
124 alternatively, use --config merge.preferancestor=0f6b37dbe527
125 resolving manifests
125 resolving manifests
126 merging f1
126 merging f1
127 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
127 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
128 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
128 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
129 [1]
129 [1]
130
130
131 Redo merge with merge.preferancestor="*" to enable bid merge
131 Redo merge with merge.preferancestor="*" to enable bid merge
132
132
133 $ rm f*
133 $ rm f*
134 $ hg up -qC .
134 $ hg up -qC .
135 $ hg merge -v --debug --tool internal:dump 5 --config merge.preferancestor="*"
135 $ hg merge -v --debug --tool internal:dump 5 --config merge.preferancestor="*"
136 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
136 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
137
137
138 calculating bids for ancestor 0f6b37dbe527
138 calculating bids for ancestor 0f6b37dbe527
139 resolving manifests
139 resolving manifests
140 branchmerge: True, force: False, partial: False
140 branchmerge: True, force: False, partial: False
141 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
141 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
142 f1: remote is newer -> g
142 f1: remote is newer -> g
143 f2: versions differ -> m
143 f2: versions differ -> m
144
144
145 calculating bids for ancestor 40663881a6dd
145 calculating bids for ancestor 40663881a6dd
146 resolving manifests
146 resolving manifests
147 branchmerge: True, force: False, partial: False
147 branchmerge: True, force: False, partial: False
148 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
148 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
149 f1: versions differ -> m
149 f1: versions differ -> m
150 f2: remote unchanged -> k
150 f2: remote unchanged -> k
151
151
152 auction for merging merge bids
152 auction for merging merge bids
153 f1: picking 'get' action
153 f1: picking 'get' action
154 f2: picking 'keep' action
154 f2: picking 'keep' action
155 end of auction
155 end of auction
156
156
157 f1: remote is newer -> g
157 f1: remote is newer -> g
158 getting f1
158 getting f1
159 f2: remote unchanged -> k
159 f2: remote unchanged -> k
160 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
161 (branch merge, don't forget to commit)
161 (branch merge, don't forget to commit)
162
162
163 $ f --dump *
163 $ f --dump *
164 f1:
164 f1:
165 >>>
165 >>>
166 5 second change
166 5 second change
167 <<<
167 <<<
168 f2:
168 f2:
169 >>>
169 >>>
170 6 second change
170 6 second change
171 <<<
171 <<<
172
172
173
173
174 The other way around:
174 The other way around:
175
175
176 $ hg up -C -r5
176 $ hg up -C -r5
177 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
177 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 $ hg merge -v --debug --config merge.preferancestor="*"
178 $ hg merge -v --debug --config merge.preferancestor="*"
179 note: merging adfe50279922+ and 3b08d01b0ab5 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
179 note: merging adfe50279922+ and 3b08d01b0ab5 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
180
180
181 calculating bids for ancestor 0f6b37dbe527
181 calculating bids for ancestor 0f6b37dbe527
182 resolving manifests
182 resolving manifests
183 branchmerge: True, force: False, partial: False
183 branchmerge: True, force: False, partial: False
184 ancestor: 0f6b37dbe527, local: adfe50279922+, remote: 3b08d01b0ab5
184 ancestor: 0f6b37dbe527, local: adfe50279922+, remote: 3b08d01b0ab5
185 f1: remote unchanged -> k
185 f1: remote unchanged -> k
186 f2: versions differ -> m
186 f2: versions differ -> m
187
187
188 calculating bids for ancestor 40663881a6dd
188 calculating bids for ancestor 40663881a6dd
189 resolving manifests
189 resolving manifests
190 branchmerge: True, force: False, partial: False
190 branchmerge: True, force: False, partial: False
191 ancestor: 40663881a6dd, local: adfe50279922+, remote: 3b08d01b0ab5
191 ancestor: 40663881a6dd, local: adfe50279922+, remote: 3b08d01b0ab5
192 f1: versions differ -> m
192 f1: versions differ -> m
193 f2: remote is newer -> g
193 f2: remote is newer -> g
194
194
195 auction for merging merge bids
195 auction for merging merge bids
196 f1: picking 'keep' action
196 f1: picking 'keep' action
197 f2: picking 'get' action
197 f2: picking 'get' action
198 end of auction
198 end of auction
199
199
200 f2: remote is newer -> g
200 f2: remote is newer -> g
201 getting f2
201 getting f2
202 f1: remote unchanged -> k
202 f1: remote unchanged -> k
203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 (branch merge, don't forget to commit)
204 (branch merge, don't forget to commit)
205
205
206 $ f --dump *
206 $ f --dump *
207 f1:
207 f1:
208 >>>
208 >>>
209 5 second change
209 5 second change
210 <<<
210 <<<
211 f2:
211 f2:
212 >>>
212 >>>
213 6 second change
213 6 second change
214 <<<
214 <<<
215
215
216 Verify how the output looks and and how verbose it is:
216 Verify how the output looks and and how verbose it is:
217
217
218 $ hg up -qC
218 $ hg up -qC
219 $ hg merge
219 $ hg merge
220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 (branch merge, don't forget to commit)
221 (branch merge, don't forget to commit)
222
222
223 $ hg up -qC tip
223 $ hg up -qC tip
224 $ hg merge -v
224 $ hg merge -v
225 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
225 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
226
226
227 calculating bids for ancestor 0f6b37dbe527
227 calculating bids for ancestor 0f6b37dbe527
228 resolving manifests
228 resolving manifests
229
229
230 calculating bids for ancestor 40663881a6dd
230 calculating bids for ancestor 40663881a6dd
231 resolving manifests
231 resolving manifests
232
232
233 auction for merging merge bids
233 auction for merging merge bids
234 f1: picking 'get' action
234 f1: picking 'get' action
235 f2: picking 'keep' action
235 f2: picking 'keep' action
236 end of auction
236 end of auction
237
237
238 getting f1
238 getting f1
239 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
239 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
240 (branch merge, don't forget to commit)
240 (branch merge, don't forget to commit)
241
241
242 $ hg up -qC
242 $ hg up -qC
243 $ hg merge -v --debug --config merge.preferancestor="*"
243 $ hg merge -v --debug --config merge.preferancestor="*"
244 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
244 note: merging 3b08d01b0ab5+ and adfe50279922 using bids from ancestors 0f6b37dbe527 and 40663881a6dd
245
245
246 calculating bids for ancestor 0f6b37dbe527
246 calculating bids for ancestor 0f6b37dbe527
247 resolving manifests
247 resolving manifests
248 branchmerge: True, force: False, partial: False
248 branchmerge: True, force: False, partial: False
249 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
249 ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
250 f1: remote is newer -> g
250 f1: remote is newer -> g
251 f2: versions differ -> m
251 f2: versions differ -> m
252
252
253 calculating bids for ancestor 40663881a6dd
253 calculating bids for ancestor 40663881a6dd
254 resolving manifests
254 resolving manifests
255 branchmerge: True, force: False, partial: False
255 branchmerge: True, force: False, partial: False
256 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
256 ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
257 f1: versions differ -> m
257 f1: versions differ -> m
258 f2: remote unchanged -> k
258 f2: remote unchanged -> k
259
259
260 auction for merging merge bids
260 auction for merging merge bids
261 f1: picking 'get' action
261 f1: picking 'get' action
262 f2: picking 'keep' action
262 f2: picking 'keep' action
263 end of auction
263 end of auction
264
264
265 f1: remote is newer -> g
265 f1: remote is newer -> g
266 getting f1
266 getting f1
267 f2: remote unchanged -> k
267 f2: remote unchanged -> k
268 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
268 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
269 (branch merge, don't forget to commit)
269 (branch merge, don't forget to commit)
270
270
271 Test the greatest common ancestor returning multiple changesets
271 Test the greatest common ancestor returning multiple changesets
272
272
273 $ hg log -r 'heads(commonancestors(head()))'
273 $ hg log -r 'heads(commonancestors(head()))'
274 changeset: 1:0f6b37dbe527
274 changeset: 1:0f6b37dbe527
275 user: test
275 user: test
276 date: Thu Jan 01 00:00:00 1970 +0000
276 date: Thu Jan 01 00:00:00 1970 +0000
277 summary: 1 first change f1
277 summary: 1 first change f1
278
278
279 changeset: 2:40663881a6dd
279 changeset: 2:40663881a6dd
280 parent: 0:40494bf2444c
280 parent: 0:40494bf2444c
281 user: test
281 user: test
282 date: Thu Jan 01 00:00:00 1970 +0000
282 date: Thu Jan 01 00:00:00 1970 +0000
283 summary: 2 first change f2
283 summary: 2 first change f2
284
284
285
285
286 $ cd ..
286 $ cd ..
287
287
288 http://stackoverflow.com/questions/9350005/how-do-i-specify-a-merge-base-to-use-in-a-hg-merge/9430810
288 http://stackoverflow.com/questions/9350005/how-do-i-specify-a-merge-base-to-use-in-a-hg-merge/9430810
289
289
290 $ hg init ancestor-merging
290 $ hg init ancestor-merging
291 $ cd ancestor-merging
291 $ cd ancestor-merging
292 $ echo a > x
292 $ echo a > x
293 $ hg commit -A -m a x
293 $ hg commit -A -m a x
294 $ hg update -q 0
294 $ hg update -q 0
295 $ echo b >> x
295 $ echo b >> x
296 $ hg commit -m b
296 $ hg commit -m b
297 $ hg update -q 0
297 $ hg update -q 0
298 $ echo c >> x
298 $ echo c >> x
299 $ hg commit -qm c
299 $ hg commit -qm c
300 $ hg update -q 1
300 $ hg update -q 1
301 $ hg merge -q --tool internal:local 2
301 $ hg merge -q --tool internal:local 2
302 $ echo c >> x
302 $ echo c >> x
303 $ hg commit -m bc
303 $ hg commit -m bc
304 $ hg update -q 2
304 $ hg update -q 2
305 $ hg merge -q --tool internal:local 1
305 $ hg merge -q --tool internal:local 1
306 $ echo b >> x
306 $ echo b >> x
307 $ hg commit -qm cb
307 $ hg commit -qm cb
308
308
309 $ hg merge --config merge.preferancestor='!'
309 $ hg merge --config merge.preferancestor='!'
310 note: using 70008a2163f6 as ancestor of 0d355fdef312 and 4b8b546a3eef
310 note: using 70008a2163f6 as ancestor of 0d355fdef312 and 4b8b546a3eef
311 alternatively, use --config merge.preferancestor=b211bbc6eb3c
311 alternatively, use --config merge.preferancestor=b211bbc6eb3c
312 merging x
312 merging x
313 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
313 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
314 (branch merge, don't forget to commit)
314 (branch merge, don't forget to commit)
315 $ cat x
315 $ cat x
316 a
316 a
317 c
317 c
318 b
318 b
319 c
319 c
320
320
321 $ hg up -qC .
321 $ hg up -qC .
322
322
323 $ hg merge --config merge.preferancestor=b211bbc6eb3c
323 $ hg merge --config merge.preferancestor=b211bbc6eb3c
324 note: using b211bbc6eb3c as ancestor of 0d355fdef312 and 4b8b546a3eef
324 note: using b211bbc6eb3c as ancestor of 0d355fdef312 and 4b8b546a3eef
325 alternatively, use --config merge.preferancestor=70008a2163f6
325 alternatively, use --config merge.preferancestor=70008a2163f6
326 merging x
326 merging x
327 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
327 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
328 (branch merge, don't forget to commit)
328 (branch merge, don't forget to commit)
329 $ cat x
329 $ cat x
330 a
330 a
331 b
331 b
332 c
332 c
333 b
333 b
334
334
335 $ hg up -qC .
335 $ hg up -qC .
336
336
337 $ hg merge -v --config merge.preferancestor="*"
337 $ hg merge -v --config merge.preferancestor="*"
338 note: merging 0d355fdef312+ and 4b8b546a3eef using bids from ancestors 70008a2163f6 and b211bbc6eb3c
338 note: merging 0d355fdef312+ and 4b8b546a3eef using bids from ancestors 70008a2163f6 and b211bbc6eb3c
339
339
340 calculating bids for ancestor 70008a2163f6
340 calculating bids for ancestor 70008a2163f6
341 resolving manifests
341 resolving manifests
342
342
343 calculating bids for ancestor b211bbc6eb3c
343 calculating bids for ancestor b211bbc6eb3c
344 resolving manifests
344 resolving manifests
345
345
346 auction for merging merge bids
346 auction for merging merge bids
347 x: multiple bids for merge action:
347 x: multiple bids for merge action:
348 versions differ -> m
348 versions differ -> m
349 versions differ -> m
349 versions differ -> m
350 x: ambiguous merge - picked m action
350 x: ambiguous merge - picked m action
351 end of auction
351 end of auction
352
352
353 merging x
353 merging x
354 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
354 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
355 (branch merge, don't forget to commit)
355 (branch merge, don't forget to commit)
356 $ cat x
356 $ cat x
357 a
357 a
358 c
358 c
359 b
359 b
360 c
360 c
361
361
362 Verify that the old context ancestor works with / despite preferancestor:
362 Verify that the old context ancestor works with / despite preferancestor:
363
363
364 $ hg log -r 'ancestor(head())' --config merge.preferancestor=1 -T '{rev}\n'
364 $ hg log -r 'ancestor(head())' --config merge.preferancestor=1 -T '{rev}\n'
365 1
365 1
366 $ hg log -r 'ancestor(head())' --config merge.preferancestor=2 -T '{rev}\n'
366 $ hg log -r 'ancestor(head())' --config merge.preferancestor=2 -T '{rev}\n'
367 2
367 2
368 $ hg log -r 'ancestor(head())' --config merge.preferancestor=3 -T '{rev}\n'
368 $ hg log -r 'ancestor(head())' --config merge.preferancestor=3 -T '{rev}\n'
369 1
369 1
370 $ hg log -r 'ancestor(head())' --config merge.preferancestor='1337 * - 2' -T '{rev}\n'
370 $ hg log -r 'ancestor(head())' --config merge.preferancestor='1337 * - 2' -T '{rev}\n'
371 2
371 2
372
372
373 $ cd ..
373 $ cd ..
374
374
375 $ hg init issue5020
375 $ hg init issue5020
376 $ cd issue5020
376 $ cd issue5020
377
377
378 $ echo a > noop
378 $ echo a > noop
379 $ hg ci -qAm initial
379 $ hg ci -qAm initial
380
380
381 $ echo b > noop
381 $ echo b > noop
382 $ hg ci -qAm 'uninteresting change'
382 $ hg ci -qAm 'uninteresting change'
383
383
384 $ hg up -q 0
384 $ hg up -q 0
385 $ mkdir d1
385 $ mkdir d1
386 $ echo a > d1/a
386 $ echo a > d1/a
387 $ echo b > d1/b
387 $ echo b > d1/b
388 $ hg ci -qAm 'add d1/a and d1/b'
388 $ hg ci -qAm 'add d1/a and d1/b'
389
389
390 $ hg merge -q 1
390 $ hg merge -q 1
391 $ hg rm d1/a
391 $ hg rm d1/a
392 $ hg mv -q d1 d2
392 $ hg mv -q d1 d2
393 $ hg ci -qm 'merge while removing d1/a and moving d1/b to d2/b'
393 $ hg ci -qm 'merge while removing d1/a and moving d1/b to d2/b'
394
394
395 $ hg up -q 1
395 $ hg up -q 1
396 $ hg merge -q 2
396 $ hg merge -q 2
397 $ hg ci -qm 'merge (no changes while merging)'
397 $ hg ci -qm 'merge (no changes while merging)'
398 $ hg log -G -T '{rev}:{node|short} {desc}'
398 $ hg log -G -T '{rev}:{node|short} {desc}'
399 @ 4:c0ef19750a22 merge (no changes while merging)
399 @ 4:c0ef19750a22 merge (no changes while merging)
400 |\
400 |\
401 +---o 3:6ca01f7342b9 merge while removing d1/a and moving d1/b to d2/b
401 +---o 3:6ca01f7342b9 merge while removing d1/a and moving d1/b to d2/b
402 | |/
402 | |/
403 | o 2:154e6000f54e add d1/a and d1/b
403 | o 2:154e6000f54e add d1/a and d1/b
404 | |
404 | |
405 o | 1:11b5b303e36c uninteresting change
405 o | 1:11b5b303e36c uninteresting change
406 |/
406 |/
407 o 0:7b54db1ebf33 initial
407 o 0:7b54db1ebf33 initial
408
408
409 $ hg merge 3 --debug
409 $ hg merge 3 --debug
410 note: merging c0ef19750a22+ and 6ca01f7342b9 using bids from ancestors 11b5b303e36c and 154e6000f54e
410 note: merging c0ef19750a22+ and 6ca01f7342b9 using bids from ancestors 11b5b303e36c and 154e6000f54e
411
411
412 calculating bids for ancestor 11b5b303e36c
412 calculating bids for ancestor 11b5b303e36c
413 resolving manifests
413 resolving manifests
414 branchmerge: True, force: False, partial: False
414 branchmerge: True, force: False, partial: False
415 ancestor: 11b5b303e36c, local: c0ef19750a22+, remote: 6ca01f7342b9
415 ancestor: 11b5b303e36c, local: c0ef19750a22+, remote: 6ca01f7342b9
416 d2/b: remote created -> g
416 d2/b: remote created -> g
417
417
418 calculating bids for ancestor 154e6000f54e
418 calculating bids for ancestor 154e6000f54e
419 unmatched files in other:
419 unmatched files in other:
420 d2/b
420 d2/b
421 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
421 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
422 src: 'd1/b' -> dst: 'd2/b'
422 on remote side:
423 src: 'd1/b' -> dst: 'd2/b'
423 checking for directory renames
424 checking for directory renames
424 discovered dir src: 'd1/' -> dst: 'd2/'
425 discovered dir src: 'd1/' -> dst: 'd2/'
425 resolving manifests
426 resolving manifests
426 branchmerge: True, force: False, partial: False
427 branchmerge: True, force: False, partial: False
427 ancestor: 154e6000f54e, local: c0ef19750a22+, remote: 6ca01f7342b9
428 ancestor: 154e6000f54e, local: c0ef19750a22+, remote: 6ca01f7342b9
428 d1/a: other deleted -> r
429 d1/a: other deleted -> r
429 d1/b: other deleted -> r
430 d1/b: other deleted -> r
430 d2/b: remote created -> g
431 d2/b: remote created -> g
431
432
432 auction for merging merge bids
433 auction for merging merge bids
433 d1/a: consensus for r
434 d1/a: consensus for r
434 d1/b: consensus for r
435 d1/b: consensus for r
435 d2/b: consensus for g
436 d2/b: consensus for g
436 end of auction
437 end of auction
437
438
438 d1/a: other deleted -> r
439 d1/a: other deleted -> r
439 removing d1/a
440 removing d1/a
440 d1/b: other deleted -> r
441 d1/b: other deleted -> r
441 removing d1/b
442 removing d1/b
442 d2/b: remote created -> g
443 d2/b: remote created -> g
443 getting d2/b
444 getting d2/b
444 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
445 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
445 (branch merge, don't forget to commit)
446 (branch merge, don't forget to commit)
@@ -1,294 +1,296 b''
1 $ hg init t
1 $ hg init t
2 $ cd t
2 $ cd t
3
3
4 $ mkdir a
4 $ mkdir a
5 $ echo foo > a/a
5 $ echo foo > a/a
6 $ echo bar > a/b
6 $ echo bar > a/b
7 $ hg ci -Am "0"
7 $ hg ci -Am "0"
8 adding a/a
8 adding a/a
9 adding a/b
9 adding a/b
10
10
11 $ hg co -C 0
11 $ hg co -C 0
12 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 $ hg mv a b
13 $ hg mv a b
14 moving a/a to b/a
14 moving a/a to b/a
15 moving a/b to b/b
15 moving a/b to b/b
16 $ hg ci -m "1 mv a/ b/"
16 $ hg ci -m "1 mv a/ b/"
17
17
18 $ hg co -C 0
18 $ hg co -C 0
19 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
19 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
20 $ echo baz > a/c
20 $ echo baz > a/c
21 $ echo quux > a/d
21 $ echo quux > a/d
22 $ hg add a/c
22 $ hg add a/c
23 $ hg ci -m "2 add a/c"
23 $ hg ci -m "2 add a/c"
24 created new head
24 created new head
25
25
26 $ hg merge --debug 1
26 $ hg merge --debug 1
27 unmatched files in local:
27 unmatched files in local:
28 a/c
28 a/c
29 unmatched files in other:
29 unmatched files in other:
30 b/a
30 b/a
31 b/b
31 b/b
32 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
32 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
33 src: 'a/a' -> dst: 'b/a'
33 on remote side:
34 src: 'a/b' -> dst: 'b/b'
34 src: 'a/a' -> dst: 'b/a'
35 src: 'a/b' -> dst: 'b/b'
35 checking for directory renames
36 checking for directory renames
36 discovered dir src: 'a/' -> dst: 'b/'
37 discovered dir src: 'a/' -> dst: 'b/'
37 pending file src: 'a/c' -> dst: 'b/c'
38 pending file src: 'a/c' -> dst: 'b/c'
38 resolving manifests
39 resolving manifests
39 branchmerge: True, force: False, partial: False
40 branchmerge: True, force: False, partial: False
40 ancestor: f9b20c0d4c51, local: ce36d17b18fb+, remote: 397f8b00a740
41 ancestor: f9b20c0d4c51, local: ce36d17b18fb+, remote: 397f8b00a740
41 a/a: other deleted -> r
42 a/a: other deleted -> r
42 removing a/a
43 removing a/a
43 a/b: other deleted -> r
44 a/b: other deleted -> r
44 removing a/b
45 removing a/b
45 b/a: remote created -> g
46 b/a: remote created -> g
46 getting b/a
47 getting b/a
47 b/b: remote created -> g
48 b/b: remote created -> g
48 getting b/b
49 getting b/b
49 b/c: remote directory rename - move from a/c -> dm
50 b/c: remote directory rename - move from a/c -> dm
50 moving a/c to b/c
51 moving a/c to b/c
51 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
52 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
52 (branch merge, don't forget to commit)
53 (branch merge, don't forget to commit)
53
54
54 $ echo a/* b/*
55 $ echo a/* b/*
55 a/d b/a b/b b/c
56 a/d b/a b/b b/c
56 $ hg st -C
57 $ hg st -C
57 M b/a
58 M b/a
58 M b/b
59 M b/b
59 A b/c
60 A b/c
60 a/c
61 a/c
61 R a/a
62 R a/a
62 R a/b
63 R a/b
63 R a/c
64 R a/c
64 ? a/d
65 ? a/d
65 $ hg ci -m "3 merge 2+1"
66 $ hg ci -m "3 merge 2+1"
66 $ hg debugrename b/c
67 $ hg debugrename b/c
67 b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
68 b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
68
69
69 $ hg co -C 1
70 $ hg co -C 1
70 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
71 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
71 $ hg merge --debug 2
72 $ hg merge --debug 2
72 unmatched files in local:
73 unmatched files in local:
73 b/a
74 b/a
74 b/b
75 b/b
75 unmatched files in other:
76 unmatched files in other:
76 a/c
77 a/c
77 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
78 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
78 src: 'a/a' -> dst: 'b/a'
79 on local side:
79 src: 'a/b' -> dst: 'b/b'
80 src: 'a/a' -> dst: 'b/a'
81 src: 'a/b' -> dst: 'b/b'
80 checking for directory renames
82 checking for directory renames
81 discovered dir src: 'a/' -> dst: 'b/'
83 discovered dir src: 'a/' -> dst: 'b/'
82 pending file src: 'a/c' -> dst: 'b/c'
84 pending file src: 'a/c' -> dst: 'b/c'
83 resolving manifests
85 resolving manifests
84 branchmerge: True, force: False, partial: False
86 branchmerge: True, force: False, partial: False
85 ancestor: f9b20c0d4c51, local: 397f8b00a740+, remote: ce36d17b18fb
87 ancestor: f9b20c0d4c51, local: 397f8b00a740+, remote: ce36d17b18fb
86 starting 4 threads for background file closing (?)
88 starting 4 threads for background file closing (?)
87 b/c: local directory rename - get from a/c -> dg
89 b/c: local directory rename - get from a/c -> dg
88 getting a/c to b/c
90 getting a/c to b/c
89 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 (branch merge, don't forget to commit)
92 (branch merge, don't forget to commit)
91
93
92 $ echo a/* b/*
94 $ echo a/* b/*
93 a/d b/a b/b b/c
95 a/d b/a b/b b/c
94 $ hg st -C
96 $ hg st -C
95 A b/c
97 A b/c
96 a/c
98 a/c
97 ? a/d
99 ? a/d
98 $ hg ci -m "4 merge 1+2"
100 $ hg ci -m "4 merge 1+2"
99 created new head
101 created new head
100 $ hg debugrename b/c
102 $ hg debugrename b/c
101 b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
103 b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
102
104
103 Local directory rename with conflicting file added in remote source directory
105 Local directory rename with conflicting file added in remote source directory
104 and untracked in local target directory.
106 and untracked in local target directory.
105
107
106 $ hg co -qC 1
108 $ hg co -qC 1
107 $ echo target > b/c
109 $ echo target > b/c
108 $ hg merge 2
110 $ hg merge 2
109 b/c: untracked file differs
111 b/c: untracked file differs
110 abort: untracked files in working directory differ from files in requested revision
112 abort: untracked files in working directory differ from files in requested revision
111 [255]
113 [255]
112 $ cat b/c
114 $ cat b/c
113 target
115 target
114 but it should succeed if the content matches
116 but it should succeed if the content matches
115 $ hg cat -r 2 a/c > b/c
117 $ hg cat -r 2 a/c > b/c
116 $ hg merge 2
118 $ hg merge 2
117 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
119 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
118 (branch merge, don't forget to commit)
120 (branch merge, don't forget to commit)
119 $ hg st -C
121 $ hg st -C
120 A b/c
122 A b/c
121 a/c
123 a/c
122 ? a/d
124 ? a/d
123
125
124 Local directory rename with conflicting file added in remote source directory
126 Local directory rename with conflicting file added in remote source directory
125 and committed in local target directory.
127 and committed in local target directory.
126
128
127 $ hg co -qC 1
129 $ hg co -qC 1
128 $ echo target > b/c
130 $ echo target > b/c
129 $ hg add b/c
131 $ hg add b/c
130 $ hg commit -qm 'new file in target directory'
132 $ hg commit -qm 'new file in target directory'
131 $ hg merge 2
133 $ hg merge 2
132 merging b/c and a/c to b/c
134 merging b/c and a/c to b/c
133 warning: conflicts while merging b/c! (edit, then use 'hg resolve --mark')
135 warning: conflicts while merging b/c! (edit, then use 'hg resolve --mark')
134 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
136 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
135 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
137 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
136 [1]
138 [1]
137 $ hg st -A
139 $ hg st -A
138 M b/c
140 M b/c
139 a/c
141 a/c
140 ? a/d
142 ? a/d
141 ? b/c.orig
143 ? b/c.orig
142 C b/a
144 C b/a
143 C b/b
145 C b/b
144 $ cat b/c
146 $ cat b/c
145 <<<<<<< working copy: f1c50ca4f127 - test: new file in target directory
147 <<<<<<< working copy: f1c50ca4f127 - test: new file in target directory
146 target
148 target
147 =======
149 =======
148 baz
150 baz
149 >>>>>>> merge rev: ce36d17b18fb - test: 2 add a/c
151 >>>>>>> merge rev: ce36d17b18fb - test: 2 add a/c
150 $ rm b/c.orig
152 $ rm b/c.orig
151
153
152 Remote directory rename with conflicting file added in remote target directory
154 Remote directory rename with conflicting file added in remote target directory
153 and committed in local source directory.
155 and committed in local source directory.
154
156
155 $ hg co -qC 2
157 $ hg co -qC 2
156 $ hg st -A
158 $ hg st -A
157 ? a/d
159 ? a/d
158 C a/a
160 C a/a
159 C a/b
161 C a/b
160 C a/c
162 C a/c
161 $ hg merge 5
163 $ hg merge 5
162 merging a/c and b/c to b/c
164 merging a/c and b/c to b/c
163 warning: conflicts while merging b/c! (edit, then use 'hg resolve --mark')
165 warning: conflicts while merging b/c! (edit, then use 'hg resolve --mark')
164 2 files updated, 0 files merged, 2 files removed, 1 files unresolved
166 2 files updated, 0 files merged, 2 files removed, 1 files unresolved
165 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
167 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
166 [1]
168 [1]
167 $ hg st -A
169 $ hg st -A
168 M b/a
170 M b/a
169 M b/b
171 M b/b
170 M b/c
172 M b/c
171 a/c
173 a/c
172 R a/a
174 R a/a
173 R a/b
175 R a/b
174 R a/c
176 R a/c
175 ? a/d
177 ? a/d
176 ? b/c.orig
178 ? b/c.orig
177 $ cat b/c
179 $ cat b/c
178 <<<<<<< working copy: ce36d17b18fb - test: 2 add a/c
180 <<<<<<< working copy: ce36d17b18fb - test: 2 add a/c
179 baz
181 baz
180 =======
182 =======
181 target
183 target
182 >>>>>>> merge rev: f1c50ca4f127 - test: new file in target directory
184 >>>>>>> merge rev: f1c50ca4f127 - test: new file in target directory
183
185
184 Second scenario with two repos:
186 Second scenario with two repos:
185
187
186 $ cd ..
188 $ cd ..
187 $ hg init r1
189 $ hg init r1
188 $ cd r1
190 $ cd r1
189 $ mkdir a
191 $ mkdir a
190 $ echo foo > a/f
192 $ echo foo > a/f
191 $ hg add a
193 $ hg add a
192 adding a/f
194 adding a/f
193 $ hg ci -m "a/f == foo"
195 $ hg ci -m "a/f == foo"
194 $ cd ..
196 $ cd ..
195
197
196 $ hg clone r1 r2
198 $ hg clone r1 r2
197 updating to branch default
199 updating to branch default
198 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
200 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
199 $ cd r2
201 $ cd r2
200 $ hg mv a b
202 $ hg mv a b
201 moving a/f to b/f
203 moving a/f to b/f
202 $ echo foo1 > b/f
204 $ echo foo1 > b/f
203 $ hg ci -m" a -> b, b/f == foo1"
205 $ hg ci -m" a -> b, b/f == foo1"
204 $ cd ..
206 $ cd ..
205
207
206 $ cd r1
208 $ cd r1
207 $ mkdir a/aa
209 $ mkdir a/aa
208 $ echo bar > a/aa/g
210 $ echo bar > a/aa/g
209 $ hg add a/aa
211 $ hg add a/aa
210 adding a/aa/g
212 adding a/aa/g
211 $ hg ci -m "a/aa/g"
213 $ hg ci -m "a/aa/g"
212 $ hg pull ../r2
214 $ hg pull ../r2
213 pulling from ../r2
215 pulling from ../r2
214 searching for changes
216 searching for changes
215 adding changesets
217 adding changesets
216 adding manifests
218 adding manifests
217 adding file changes
219 adding file changes
218 added 1 changesets with 1 changes to 1 files (+1 heads)
220 added 1 changesets with 1 changes to 1 files (+1 heads)
219 new changesets 7d51ed18da25
221 new changesets 7d51ed18da25
220 1 local changesets published
222 1 local changesets published
221 (run 'hg heads' to see heads, 'hg merge' to merge)
223 (run 'hg heads' to see heads, 'hg merge' to merge)
222
224
223 $ hg merge
225 $ hg merge
224 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
226 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
225 (branch merge, don't forget to commit)
227 (branch merge, don't forget to commit)
226
228
227 $ hg st -C
229 $ hg st -C
228 M b/f
230 M b/f
229 A b/aa/g
231 A b/aa/g
230 a/aa/g
232 a/aa/g
231 R a/aa/g
233 R a/aa/g
232 R a/f
234 R a/f
233
235
234 $ cd ..
236 $ cd ..
235
237
236 Test renames to separate directories
238 Test renames to separate directories
237
239
238 $ hg init a
240 $ hg init a
239 $ cd a
241 $ cd a
240 $ mkdir a
242 $ mkdir a
241 $ touch a/s
243 $ touch a/s
242 $ touch a/t
244 $ touch a/t
243 $ hg ci -Am0
245 $ hg ci -Am0
244 adding a/s
246 adding a/s
245 adding a/t
247 adding a/t
246
248
247 Add more files
249 Add more files
248
250
249 $ touch a/s2
251 $ touch a/s2
250 $ touch a/t2
252 $ touch a/t2
251 $ hg ci -Am1
253 $ hg ci -Am1
252 adding a/s2
254 adding a/s2
253 adding a/t2
255 adding a/t2
254
256
255 Do moves on a branch
257 Do moves on a branch
256
258
257 $ hg up 0
259 $ hg up 0
258 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
260 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
259 $ mkdir s
261 $ mkdir s
260 $ mkdir t
262 $ mkdir t
261 $ hg mv a/s s
263 $ hg mv a/s s
262 $ hg mv a/t t
264 $ hg mv a/t t
263 $ hg ci -Am2
265 $ hg ci -Am2
264 created new head
266 created new head
265 $ hg st --copies --change .
267 $ hg st --copies --change .
266 A s/s
268 A s/s
267 a/s
269 a/s
268 A t/t
270 A t/t
269 a/t
271 a/t
270 R a/s
272 R a/s
271 R a/t
273 R a/t
272
274
273 Merge shouldn't move s2, t2
275 Merge shouldn't move s2, t2
274
276
275 $ hg merge
277 $ hg merge
276 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
278 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 (branch merge, don't forget to commit)
279 (branch merge, don't forget to commit)
278 $ hg st --copies
280 $ hg st --copies
279 M a/s2
281 M a/s2
280 M a/t2
282 M a/t2
281
283
282 Try the merge in the other direction. It may or may not be appropriate for
284 Try the merge in the other direction. It may or may not be appropriate for
283 status to list copies here.
285 status to list copies here.
284
286
285 $ hg up -C 1
287 $ hg up -C 1
286 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
288 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
287 $ hg merge
289 $ hg merge
288 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
290 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
289 (branch merge, don't forget to commit)
291 (branch merge, don't forget to commit)
290 $ hg st --copies
292 $ hg st --copies
291 M s/s
293 M s/s
292 M t/t
294 M t/t
293 R a/s
295 R a/s
294 R a/t
296 R a/t
@@ -1,256 +1,262 b''
1 $ hg init
1 $ hg init
2
2
3 $ echo "[merge]" >> .hg/hgrc
3 $ echo "[merge]" >> .hg/hgrc
4 $ echo "followcopies = 1" >> .hg/hgrc
4 $ echo "followcopies = 1" >> .hg/hgrc
5
5
6 $ echo foo > a
6 $ echo foo > a
7 $ echo foo > a2
7 $ echo foo > a2
8 $ hg add a a2
8 $ hg add a a2
9 $ hg ci -m "start"
9 $ hg ci -m "start"
10
10
11 $ hg mv a b
11 $ hg mv a b
12 $ hg mv a2 b2
12 $ hg mv a2 b2
13 $ hg ci -m "rename"
13 $ hg ci -m "rename"
14
14
15 $ hg co 0
15 $ hg co 0
16 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
16 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
17
17
18 $ echo blahblah > a
18 $ echo blahblah > a
19 $ echo blahblah > a2
19 $ echo blahblah > a2
20 $ hg mv a2 c2
20 $ hg mv a2 c2
21 $ hg ci -m "modify"
21 $ hg ci -m "modify"
22 created new head
22 created new head
23
23
24 $ hg merge -y --debug
24 $ hg merge -y --debug
25 unmatched files in local:
25 unmatched files in local:
26 c2
26 c2
27 unmatched files in other:
27 unmatched files in other:
28 b
28 b
29 b2
29 b2
30 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
30 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
31 src: 'a' -> dst: 'b' *
31 on local side:
32 src: 'a2' -> dst: 'b2' !
32 src: 'a2' -> dst: 'c2' !
33 src: 'a2' -> dst: 'c2' !
33 on remote side:
34 src: 'a' -> dst: 'b' *
35 src: 'a2' -> dst: 'b2' !
34 checking for directory renames
36 checking for directory renames
35 resolving manifests
37 resolving manifests
36 branchmerge: True, force: False, partial: False
38 branchmerge: True, force: False, partial: False
37 ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
39 ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
38 note: possible conflict - a2 was renamed multiple times to:
40 note: possible conflict - a2 was renamed multiple times to:
39 b2
41 b2
40 c2
42 c2
41 preserving a for resolve of b
43 preserving a for resolve of b
42 removing a
44 removing a
43 b2: remote created -> g
45 b2: remote created -> g
44 getting b2
46 getting b2
45 b: remote moved from a -> m (premerge)
47 b: remote moved from a -> m (premerge)
46 picked tool ':merge' for b (binary False symlink False changedelete False)
48 picked tool ':merge' for b (binary False symlink False changedelete False)
47 merging a and b to b
49 merging a and b to b
48 my b@044f8520aeeb+ other b@85c198ef2f6c ancestor a@af1939970a1c
50 my b@044f8520aeeb+ other b@85c198ef2f6c ancestor a@af1939970a1c
49 premerge successful
51 premerge successful
50 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
52 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
51 (branch merge, don't forget to commit)
53 (branch merge, don't forget to commit)
52
54
53 $ hg status -AC
55 $ hg status -AC
54 M b
56 M b
55 a
57 a
56 M b2
58 M b2
57 R a
59 R a
58 C c2
60 C c2
59
61
60 $ cat b
62 $ cat b
61 blahblah
63 blahblah
62
64
63 $ hg ci -m "merge"
65 $ hg ci -m "merge"
64
66
65 $ hg debugindex b
67 $ hg debugindex b
66 rev linkrev nodeid p1 p2
68 rev linkrev nodeid p1 p2
67 0 1 57eacc201a7f 000000000000 000000000000
69 0 1 57eacc201a7f 000000000000 000000000000
68 1 3 4727ba907962 000000000000 57eacc201a7f
70 1 3 4727ba907962 000000000000 57eacc201a7f
69
71
70 $ hg debugrename b
72 $ hg debugrename b
71 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
73 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
72
74
73 This used to trigger a "divergent renames" warning, despite no renames
75 This used to trigger a "divergent renames" warning, despite no renames
74
76
75 $ hg cp b b3
77 $ hg cp b b3
76 $ hg cp b b4
78 $ hg cp b b4
77 $ hg ci -A -m 'copy b twice'
79 $ hg ci -A -m 'copy b twice'
78 $ hg up '.^'
80 $ hg up '.^'
79 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
81 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
80 $ hg up
82 $ hg up
81 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
83 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 $ hg rm b3 b4
84 $ hg rm b3 b4
83 $ hg ci -m 'clean up a bit of our mess'
85 $ hg ci -m 'clean up a bit of our mess'
84
86
85 We'd rather not warn on divergent renames done in the same changeset (issue2113)
87 We'd rather not warn on divergent renames done in the same changeset (issue2113)
86
88
87 $ hg cp b b3
89 $ hg cp b b3
88 $ hg mv b b4
90 $ hg mv b b4
89 $ hg ci -A -m 'divergent renames in same changeset'
91 $ hg ci -A -m 'divergent renames in same changeset'
90 $ hg up '.^'
92 $ hg up '.^'
91 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
93 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
92 $ hg up
94 $ hg up
93 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
95 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
94
96
95 Check for issue2642
97 Check for issue2642
96
98
97 $ hg init t
99 $ hg init t
98 $ cd t
100 $ cd t
99
101
100 $ echo c0 > f1
102 $ echo c0 > f1
101 $ hg ci -Aqm0
103 $ hg ci -Aqm0
102
104
103 $ hg up null -q
105 $ hg up null -q
104 $ echo c1 > f1 # backport
106 $ echo c1 > f1 # backport
105 $ hg ci -Aqm1
107 $ hg ci -Aqm1
106 $ hg mv f1 f2
108 $ hg mv f1 f2
107 $ hg ci -qm2
109 $ hg ci -qm2
108
110
109 $ hg up 0 -q
111 $ hg up 0 -q
110 $ hg merge 1 -q --tool internal:local
112 $ hg merge 1 -q --tool internal:local
111 $ hg ci -qm3
113 $ hg ci -qm3
112
114
113 $ hg merge 2
115 $ hg merge 2
114 merging f1 and f2 to f2
116 merging f1 and f2 to f2
115 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
117 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
116 (branch merge, don't forget to commit)
118 (branch merge, don't forget to commit)
117
119
118 $ cat f2
120 $ cat f2
119 c0
121 c0
120
122
121 $ cd ..
123 $ cd ..
122
124
123 Check for issue2089
125 Check for issue2089
124
126
125 $ hg init repo2089
127 $ hg init repo2089
126 $ cd repo2089
128 $ cd repo2089
127
129
128 $ echo c0 > f1
130 $ echo c0 > f1
129 $ hg ci -Aqm0
131 $ hg ci -Aqm0
130
132
131 $ hg up null -q
133 $ hg up null -q
132 $ echo c1 > f1
134 $ echo c1 > f1
133 $ hg ci -Aqm1
135 $ hg ci -Aqm1
134
136
135 $ hg up 0 -q
137 $ hg up 0 -q
136 $ hg merge 1 -q --tool internal:local
138 $ hg merge 1 -q --tool internal:local
137 $ echo c2 > f1
139 $ echo c2 > f1
138 $ hg ci -qm2
140 $ hg ci -qm2
139
141
140 $ hg up 1 -q
142 $ hg up 1 -q
141 $ hg mv f1 f2
143 $ hg mv f1 f2
142 $ hg ci -Aqm3
144 $ hg ci -Aqm3
143
145
144 $ hg up 2 -q
146 $ hg up 2 -q
145 $ hg merge 3
147 $ hg merge 3
146 merging f1 and f2 to f2
148 merging f1 and f2 to f2
147 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
149 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
148 (branch merge, don't forget to commit)
150 (branch merge, don't forget to commit)
149
151
150 $ cat f2
152 $ cat f2
151 c2
153 c2
152
154
153 $ cd ..
155 $ cd ..
154
156
155 Check for issue3074
157 Check for issue3074
156
158
157 $ hg init repo3074
159 $ hg init repo3074
158 $ cd repo3074
160 $ cd repo3074
159 $ echo foo > file
161 $ echo foo > file
160 $ hg add file
162 $ hg add file
161 $ hg commit -m "added file"
163 $ hg commit -m "added file"
162 $ hg mv file newfile
164 $ hg mv file newfile
163 $ hg commit -m "renamed file"
165 $ hg commit -m "renamed file"
164 $ hg update 0
166 $ hg update 0
165 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
167 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
166 $ hg rm file
168 $ hg rm file
167 $ hg commit -m "deleted file"
169 $ hg commit -m "deleted file"
168 created new head
170 created new head
169 $ hg merge --debug
171 $ hg merge --debug
170 unmatched files in other:
172 unmatched files in other:
171 newfile
173 newfile
172 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
174 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
173 src: 'file' -> dst: 'newfile' %
175 on remote side:
176 src: 'file' -> dst: 'newfile' %
174 checking for directory renames
177 checking for directory renames
175 resolving manifests
178 resolving manifests
176 branchmerge: True, force: False, partial: False
179 branchmerge: True, force: False, partial: False
177 ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
180 ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
178 note: possible conflict - file was deleted and renamed to:
181 note: possible conflict - file was deleted and renamed to:
179 newfile
182 newfile
180 newfile: remote created -> g
183 newfile: remote created -> g
181 getting newfile
184 getting newfile
182 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
185 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
183 (branch merge, don't forget to commit)
186 (branch merge, don't forget to commit)
184 $ hg status
187 $ hg status
185 M newfile
188 M newfile
186 $ cd ..
189 $ cd ..
187
190
188 Create x and y, then modify y and rename x to z on one side of merge, and
191 Create x and y, then modify y and rename x to z on one side of merge, and
189 modify x and rename y to z on the other side.
192 modify x and rename y to z on the other side.
190 $ hg init conflicting-target
193 $ hg init conflicting-target
191 $ cd conflicting-target
194 $ cd conflicting-target
192 $ echo x > x
195 $ echo x > x
193 $ echo y > y
196 $ echo y > y
194 $ hg ci -Aqm 'add x and y'
197 $ hg ci -Aqm 'add x and y'
195 $ hg mv x z
198 $ hg mv x z
196 $ echo foo >> y
199 $ echo foo >> y
197 $ hg ci -qm 'modify y, rename x to z'
200 $ hg ci -qm 'modify y, rename x to z'
198 $ hg co -q 0
201 $ hg co -q 0
199 $ hg mv y z
202 $ hg mv y z
200 $ echo foo >> x
203 $ echo foo >> x
201 $ hg ci -qm 'modify x, rename y to z'
204 $ hg ci -qm 'modify x, rename y to z'
202 # We should probably tell the user about the conflicting rename sources.
205 # We should probably tell the user about the conflicting rename sources.
203 # Depending on which side they pick, we should take that rename and get
206 # Depending on which side they pick, we should take that rename and get
204 # the changes to the source from the other side. The unchanged file should
207 # the changes to the source from the other side. The unchanged file should
205 # remain.
208 # remain.
206 # we should not get the prompts about modify/delete conflicts
209 # we should not get the prompts about modify/delete conflicts
207 $ hg merge --debug 1 -t :merge3
210 $ hg merge --debug 1 -t :merge3
208 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
211 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
209 src: 'x' -> dst: 'z'
212 on local side:
213 src: 'y' -> dst: 'z'
214 on remote side:
215 src: 'x' -> dst: 'z'
210 checking for directory renames
216 checking for directory renames
211 resolving manifests
217 resolving manifests
212 branchmerge: True, force: False, partial: False
218 branchmerge: True, force: False, partial: False
213 ancestor: 5151c134577e, local: 07fcbc9a74ed+, remote: f21419739508
219 ancestor: 5151c134577e, local: 07fcbc9a74ed+, remote: f21419739508
214 preserving x for resolve of x
220 preserving x for resolve of x
215 preserving z for resolve of z
221 preserving z for resolve of z
216 starting 4 threads for background file closing (?)
222 starting 4 threads for background file closing (?)
217 x: prompt changed/deleted -> m (premerge)
223 x: prompt changed/deleted -> m (premerge)
218 picked tool ':prompt' for x (binary False symlink False changedelete True)
224 picked tool ':prompt' for x (binary False symlink False changedelete True)
219 file 'x' was deleted in other [merge rev] but was modified in local [working copy].
225 file 'x' was deleted in other [merge rev] but was modified in local [working copy].
220 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
226 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
221 What do you want to do? u
227 What do you want to do? u
222 y: prompt deleted/changed -> m (premerge)
228 y: prompt deleted/changed -> m (premerge)
223 picked tool ':prompt' for y (binary False symlink False changedelete True)
229 picked tool ':prompt' for y (binary False symlink False changedelete True)
224 file 'y' was deleted in local [working copy] but was modified in other [merge rev].
230 file 'y' was deleted in local [working copy] but was modified in other [merge rev].
225 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
231 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
226 What do you want to do? u
232 What do you want to do? u
227 z: both created -> m (premerge)
233 z: both created -> m (premerge)
228 picked tool ':merge3' for z (binary False symlink False changedelete False)
234 picked tool ':merge3' for z (binary False symlink False changedelete False)
229 merging z
235 merging z
230 my z@07fcbc9a74ed+ other z@f21419739508 ancestor z@000000000000
236 my z@07fcbc9a74ed+ other z@f21419739508 ancestor z@000000000000
231 z: both created -> m (merge)
237 z: both created -> m (merge)
232 picked tool ':merge3' for z (binary False symlink False changedelete False)
238 picked tool ':merge3' for z (binary False symlink False changedelete False)
233 my z@07fcbc9a74ed+ other z@f21419739508 ancestor z@000000000000
239 my z@07fcbc9a74ed+ other z@f21419739508 ancestor z@000000000000
234 warning: conflicts while merging z! (edit, then use 'hg resolve --mark')
240 warning: conflicts while merging z! (edit, then use 'hg resolve --mark')
235 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
241 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
236 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
242 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
237 [1]
243 [1]
238 $ ls
244 $ ls
239 x
245 x
240 y
246 y
241 z
247 z
242 z.orig
248 z.orig
243 $ cat x
249 $ cat x
244 x
250 x
245 foo
251 foo
246 $ cat y
252 $ cat y
247 y
253 y
248 foo
254 foo
249 # 'z' should have had the added 'foo' line
255 # 'z' should have had the added 'foo' line
250 $ cat z
256 $ cat z
251 <<<<<<< working copy: 07fcbc9a74ed - test: modify x, rename y to z
257 <<<<<<< working copy: 07fcbc9a74ed - test: modify x, rename y to z
252 y
258 y
253 ||||||| base
259 ||||||| base
254 =======
260 =======
255 x
261 x
256 >>>>>>> merge rev: f21419739508 - test: modify y, rename x to z
262 >>>>>>> merge rev: f21419739508 - test: modify y, rename x to z
@@ -1,1055 +1,1082 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], "w")
6 > f = open(sys.argv[1], "w")
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 $ um() { up $1; hg mv $1 $2; }
71 $ um() { up $1; hg mv $1 $2; }
72 $ nc() { hg cp $1 $2; } # just copy
72 $ nc() { hg cp $1 $2; } # just copy
73 $ nm() { hg mv $1 $2; } # just move
73 $ nm() { hg mv $1 $2; } # just move
74 $ tm "up a " "nc a b" " " "1 get local a to b"
74 $ tm "up a " "nc a b" " " "1 get local a to b"
75 created new head
75 created new head
76 --------------
76 --------------
77 test L:up a R:nc a b W: - 1 get local a to b
77 test L:up a R:nc a b W: - 1 get local a to b
78 --------------
78 --------------
79 unmatched files in other:
79 unmatched files in other:
80 b
80 b
81 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
81 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
82 src: 'a' -> dst: 'b' *
82 on remote side:
83 src: 'a' -> dst: 'b' *
83 checking for directory renames
84 checking for directory renames
84 resolving manifests
85 resolving manifests
85 branchmerge: True, force: False, partial: False
86 branchmerge: True, force: False, partial: False
86 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
87 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
87 preserving a for resolve of b
88 preserving a for resolve of b
88 preserving rev for resolve of rev
89 preserving rev for resolve of rev
89 starting 4 threads for background file closing (?)
90 starting 4 threads for background file closing (?)
90 b: remote copied from a -> m (premerge)
91 b: remote copied from a -> m (premerge)
91 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
92 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
92 merging a and b to b
93 merging a and b to b
93 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
94 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
94 premerge successful
95 premerge successful
95 rev: versions differ -> m (premerge)
96 rev: versions differ -> m (premerge)
96 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
97 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
97 merging rev
98 merging rev
98 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
99 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
99 rev: versions differ -> m (merge)
100 rev: versions differ -> m (merge)
100 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
101 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
101 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
102 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
102 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
103 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
103 merge tool returned: 0
104 merge tool returned: 0
104 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
105 (branch merge, don't forget to commit)
106 (branch merge, don't forget to commit)
106 --------------
107 --------------
107 M b
108 M b
108 a
109 a
109 C a
110 C a
110 --------------
111 --------------
111
112
112 $ 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"
113 created new head
114 created new head
114 --------------
115 --------------
115 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
116 --------------
117 --------------
117 unmatched files in local:
118 unmatched files in local:
118 b
119 b
119 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
120 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
120 src: 'a' -> dst: 'b' *
121 on local side:
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 (premerge)
131 b: local copied/moved from a -> m (premerge)
130 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
132 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
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 (premerge)
136 rev: versions differ -> m (premerge)
135 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
137 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
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 rev: versions differ -> m (merge)
140 rev: versions differ -> m (merge)
139 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
141 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
140 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
142 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
141 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
143 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
142 merge tool returned: 0
144 merge tool returned: 0
143 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
145 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
144 (branch merge, don't forget to commit)
146 (branch merge, don't forget to commit)
145 --------------
147 --------------
146 M a
148 M a
147 M b
149 M b
148 a
150 a
149 --------------
151 --------------
150
152
151 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
153 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
152 created new head
154 created new head
153 --------------
155 --------------
154 test L:up a R:nm a b W: - 3 get local a change to b, remove a
156 test L:up a R:nm a b W: - 3 get local a change to b, remove a
155 --------------
157 --------------
156 unmatched files in other:
158 unmatched files in other:
157 b
159 b
158 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
160 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
159 src: 'a' -> dst: 'b' *
161 on remote side:
162 src: 'a' -> dst: 'b' *
160 checking for directory renames
163 checking for directory renames
161 resolving manifests
164 resolving manifests
162 branchmerge: True, force: False, partial: False
165 branchmerge: True, force: False, partial: False
163 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
166 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
164 preserving a for resolve of b
167 preserving a for resolve of b
165 preserving rev for resolve of rev
168 preserving rev for resolve of rev
166 removing a
169 removing a
167 starting 4 threads for background file closing (?)
170 starting 4 threads for background file closing (?)
168 b: remote moved from a -> m (premerge)
171 b: remote moved from a -> m (premerge)
169 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
172 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
170 merging a and b to b
173 merging a and b to b
171 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
174 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
172 premerge successful
175 premerge successful
173 rev: versions differ -> m (premerge)
176 rev: versions differ -> m (premerge)
174 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
177 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
175 merging rev
178 merging rev
176 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
179 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
177 rev: versions differ -> m (merge)
180 rev: versions differ -> m (merge)
178 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
181 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
179 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
182 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
180 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
183 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
181 merge tool returned: 0
184 merge tool returned: 0
182 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
185 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
183 (branch merge, don't forget to commit)
186 (branch merge, don't forget to commit)
184 --------------
187 --------------
185 M b
188 M b
186 a
189 a
187 --------------
190 --------------
188
191
189 $ tm "nm a b" "up a " " " "4 get remote change to b"
192 $ tm "nm a b" "up a " " " "4 get remote change to b"
190 created new head
193 created new head
191 --------------
194 --------------
192 test L:nm a b R:up a W: - 4 get remote change to b
195 test L:nm a b R:up a W: - 4 get remote change to b
193 --------------
196 --------------
194 unmatched files in local:
197 unmatched files in local:
195 b
198 b
196 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
199 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
197 src: 'a' -> dst: 'b' *
200 on local side:
201 src: 'a' -> dst: 'b' *
198 checking for directory renames
202 checking for directory renames
199 resolving manifests
203 resolving manifests
200 branchmerge: True, force: False, partial: False
204 branchmerge: True, force: False, partial: False
201 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
205 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
202 preserving b for resolve of b
206 preserving b for resolve of b
203 preserving rev for resolve of rev
207 preserving rev for resolve of rev
204 starting 4 threads for background file closing (?)
208 starting 4 threads for background file closing (?)
205 b: local copied/moved from a -> m (premerge)
209 b: local copied/moved from a -> m (premerge)
206 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
210 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
207 merging b and a to b
211 merging b and a to b
208 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
212 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
209 premerge successful
213 premerge successful
210 rev: versions differ -> m (premerge)
214 rev: versions differ -> m (premerge)
211 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
215 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
212 merging rev
216 merging rev
213 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
217 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
214 rev: versions differ -> m (merge)
218 rev: versions differ -> m (merge)
215 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
219 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
216 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
220 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
217 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
221 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
218 merge tool returned: 0
222 merge tool returned: 0
219 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
223 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
220 (branch merge, don't forget to commit)
224 (branch merge, don't forget to commit)
221 --------------
225 --------------
222 M b
226 M b
223 a
227 a
224 --------------
228 --------------
225
229
226 $ tm " " "nc a b" " " "5 get b"
230 $ tm " " "nc a b" " " "5 get b"
227 created new head
231 created new head
228 --------------
232 --------------
229 test L: R:nc a b W: - 5 get b
233 test L: R:nc a b W: - 5 get b
230 --------------
234 --------------
231 unmatched files in other:
235 unmatched files in other:
232 b
236 b
233 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
237 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
234 src: 'a' -> dst: 'b'
238 on remote side:
239 src: 'a' -> dst: 'b'
235 checking for directory renames
240 checking for directory renames
236 resolving manifests
241 resolving manifests
237 branchmerge: True, force: False, partial: False
242 branchmerge: True, force: False, partial: False
238 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
243 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
239 preserving rev for resolve of rev
244 preserving rev for resolve of rev
240 b: remote created -> g
245 b: remote created -> g
241 getting b
246 getting b
242 rev: versions differ -> m (premerge)
247 rev: versions differ -> m (premerge)
243 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
248 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
244 merging rev
249 merging rev
245 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
250 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
246 rev: versions differ -> m (merge)
251 rev: versions differ -> m (merge)
247 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
252 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
248 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
253 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
249 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
254 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
250 merge tool returned: 0
255 merge tool returned: 0
251 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
256 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
252 (branch merge, don't forget to commit)
257 (branch merge, don't forget to commit)
253 --------------
258 --------------
254 M b
259 M b
255 C a
260 C a
256 --------------
261 --------------
257
262
258 $ tm "nc a b" " " " " "6 nothing"
263 $ tm "nc a b" " " " " "6 nothing"
259 created new head
264 created new head
260 --------------
265 --------------
261 test L:nc a b R: W: - 6 nothing
266 test L:nc a b R: W: - 6 nothing
262 --------------
267 --------------
263 unmatched files in local:
268 unmatched files in local:
264 b
269 b
265 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
270 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
266 src: 'a' -> dst: 'b'
271 on local side:
272 src: 'a' -> dst: 'b'
267 checking for directory renames
273 checking for directory renames
268 resolving manifests
274 resolving manifests
269 branchmerge: True, force: False, partial: False
275 branchmerge: True, force: False, partial: False
270 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
276 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
271 preserving rev for resolve of rev
277 preserving rev for resolve of rev
272 starting 4 threads for background file closing (?)
278 starting 4 threads for background file closing (?)
273 rev: versions differ -> m (premerge)
279 rev: versions differ -> m (premerge)
274 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
280 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
275 merging rev
281 merging rev
276 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
282 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
277 rev: versions differ -> m (merge)
283 rev: versions differ -> m (merge)
278 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
284 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
279 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
285 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
280 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
286 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
281 merge tool returned: 0
287 merge tool returned: 0
282 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
288 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
283 (branch merge, don't forget to commit)
289 (branch merge, don't forget to commit)
284 --------------
290 --------------
285 C a
291 C a
286 C b
292 C b
287 --------------
293 --------------
288
294
289 $ tm " " "nm a b" " " "7 get b"
295 $ tm " " "nm a b" " " "7 get b"
290 created new head
296 created new head
291 --------------
297 --------------
292 test L: R:nm a b W: - 7 get b
298 test L: R:nm a b W: - 7 get b
293 --------------
299 --------------
294 unmatched files in other:
300 unmatched files in other:
295 b
301 b
296 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
302 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
297 src: 'a' -> dst: 'b'
303 on remote side:
304 src: 'a' -> dst: 'b'
298 checking for directory renames
305 checking for directory renames
299 resolving manifests
306 resolving manifests
300 branchmerge: True, force: False, partial: False
307 branchmerge: True, force: False, partial: False
301 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
308 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
302 preserving rev for resolve of rev
309 preserving rev for resolve of rev
303 a: other deleted -> r
310 a: other deleted -> r
304 removing a
311 removing a
305 b: remote created -> g
312 b: remote created -> g
306 getting b
313 getting b
307 rev: versions differ -> m (premerge)
314 rev: versions differ -> m (premerge)
308 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
315 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
309 merging rev
316 merging rev
310 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
317 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
311 rev: versions differ -> m (merge)
318 rev: versions differ -> m (merge)
312 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
319 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
313 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
320 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
314 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
321 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
315 merge tool returned: 0
322 merge tool returned: 0
316 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
323 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
317 (branch merge, don't forget to commit)
324 (branch merge, don't forget to commit)
318 --------------
325 --------------
319 M b
326 M b
320 --------------
327 --------------
321
328
322 $ tm "nm a b" " " " " "8 nothing"
329 $ tm "nm a b" " " " " "8 nothing"
323 created new head
330 created new head
324 --------------
331 --------------
325 test L:nm a b R: W: - 8 nothing
332 test L:nm a b R: W: - 8 nothing
326 --------------
333 --------------
327 unmatched files in local:
334 unmatched files in local:
328 b
335 b
329 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
336 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
330 src: 'a' -> dst: 'b'
337 on local side:
338 src: 'a' -> dst: 'b'
331 checking for directory renames
339 checking for directory renames
332 resolving manifests
340 resolving manifests
333 branchmerge: True, force: False, partial: False
341 branchmerge: True, force: False, partial: False
334 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
342 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
335 preserving rev for resolve of rev
343 preserving rev for resolve of rev
336 starting 4 threads for background file closing (?)
344 starting 4 threads for background file closing (?)
337 rev: versions differ -> m (premerge)
345 rev: versions differ -> m (premerge)
338 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
346 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
339 merging rev
347 merging rev
340 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
348 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
341 rev: versions differ -> m (merge)
349 rev: versions differ -> m (merge)
342 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
350 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
343 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
351 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
344 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
352 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
345 merge tool returned: 0
353 merge tool returned: 0
346 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
354 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
347 (branch merge, don't forget to commit)
355 (branch merge, don't forget to commit)
348 --------------
356 --------------
349 C b
357 C b
350 --------------
358 --------------
351
359
352 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
360 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
353 created new head
361 created new head
354 --------------
362 --------------
355 test L:um a b R:um a b W: - 9 do merge with ancestor in a
363 test L:um a b R:um a b W: - 9 do merge with ancestor in a
356 --------------
364 --------------
357 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
365 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
358 src: 'a' -> dst: 'b' *
366 on local side:
367 src: 'a' -> dst: 'b' *
368 on remote side:
369 src: 'a' -> dst: 'b' *
359 checking for directory renames
370 checking for directory renames
360 resolving manifests
371 resolving manifests
361 branchmerge: True, force: False, partial: False
372 branchmerge: True, force: False, partial: False
362 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
373 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
363 preserving b for resolve of b
374 preserving b for resolve of b
364 preserving rev for resolve of rev
375 preserving rev for resolve of rev
365 starting 4 threads for background file closing (?)
376 starting 4 threads for background file closing (?)
366 b: both renamed from a -> m (premerge)
377 b: both renamed from a -> m (premerge)
367 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
378 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
368 merging b
379 merging b
369 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
380 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
370 rev: versions differ -> m (premerge)
381 rev: versions differ -> m (premerge)
371 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
382 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
372 merging rev
383 merging rev
373 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
384 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
374 b: both renamed from a -> m (merge)
385 b: both renamed from a -> m (merge)
375 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
386 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
376 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
387 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
377 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
388 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
378 merge tool returned: 0
389 merge tool returned: 0
379 rev: versions differ -> m (merge)
390 rev: versions differ -> m (merge)
380 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
391 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
381 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
392 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
382 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
393 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
383 merge tool returned: 0
394 merge tool returned: 0
384 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
395 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
385 (branch merge, don't forget to commit)
396 (branch merge, don't forget to commit)
386 --------------
397 --------------
387 M b
398 M b
388 --------------
399 --------------
389
400
390
401
391 m "um a c" "um x c" " " "10 do merge with no ancestor"
402 m "um a c" "um x c" " " "10 do merge with no ancestor"
392
403
393 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
404 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
394 created new head
405 created new head
395 --------------
406 --------------
396 test L:nm a b R:nm a c W: - 11 get c, keep b
407 test L:nm a b R:nm a c W: - 11 get c, keep b
397 --------------
408 --------------
398 unmatched files in local:
409 unmatched files in local:
399 b
410 b
400 unmatched files in other:
411 unmatched files in other:
401 c
412 c
402 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
413 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
403 src: 'a' -> dst: 'b' !
414 on local side:
404 src: 'a' -> dst: 'c' !
415 src: 'a' -> dst: 'b' !
416 on remote side:
417 src: 'a' -> dst: 'c' !
405 checking for directory renames
418 checking for directory renames
406 resolving manifests
419 resolving manifests
407 branchmerge: True, force: False, partial: False
420 branchmerge: True, force: False, partial: False
408 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
421 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
409 note: possible conflict - a was renamed multiple times to:
422 note: possible conflict - a was renamed multiple times to:
410 b
423 b
411 c
424 c
412 preserving rev for resolve of rev
425 preserving rev for resolve of rev
413 c: remote created -> g
426 c: remote created -> g
414 getting c
427 getting c
415 rev: versions differ -> m (premerge)
428 rev: versions differ -> m (premerge)
416 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
429 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
417 merging rev
430 merging rev
418 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
431 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
419 rev: versions differ -> m (merge)
432 rev: versions differ -> m (merge)
420 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
433 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
421 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
434 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
422 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
435 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
423 merge tool returned: 0
436 merge tool returned: 0
424 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
437 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
425 (branch merge, don't forget to commit)
438 (branch merge, don't forget to commit)
426 --------------
439 --------------
427 M c
440 M c
428 C b
441 C b
429 --------------
442 --------------
430
443
431 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
444 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
432 created new head
445 created new head
433 --------------
446 --------------
434 test L:nc a b R:up b W: - 12 merge b no ancestor
447 test L:nc a b R:up b W: - 12 merge b no ancestor
435 --------------
448 --------------
436 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
449 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
437 src: 'a' -> dst: 'b'
450 on local side:
451 src: 'a' -> dst: 'b'
438 checking for directory renames
452 checking for directory renames
439 resolving manifests
453 resolving manifests
440 branchmerge: True, force: False, partial: False
454 branchmerge: True, force: False, partial: False
441 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
455 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
442 preserving b for resolve of b
456 preserving b for resolve of b
443 preserving rev for resolve of rev
457 preserving rev for resolve of rev
444 starting 4 threads for background file closing (?)
458 starting 4 threads for background file closing (?)
445 b: both created -> m (premerge)
459 b: both created -> m (premerge)
446 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
460 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
447 merging b
461 merging b
448 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
462 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
449 rev: versions differ -> m (premerge)
463 rev: versions differ -> m (premerge)
450 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
464 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
451 merging rev
465 merging rev
452 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
466 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
453 b: both created -> m (merge)
467 b: both created -> m (merge)
454 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
468 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
455 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
469 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
456 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
470 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
457 merge tool returned: 0
471 merge tool returned: 0
458 rev: versions differ -> m (merge)
472 rev: versions differ -> m (merge)
459 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
473 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
460 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
474 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
461 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
475 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
462 merge tool returned: 0
476 merge tool returned: 0
463 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
477 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
464 (branch merge, don't forget to commit)
478 (branch merge, don't forget to commit)
465 --------------
479 --------------
466 M b
480 M b
467 C a
481 C a
468 --------------
482 --------------
469
483
470 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
484 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
471 created new head
485 created new head
472 --------------
486 --------------
473 test L:up b R:nm a b W: - 13 merge b no ancestor
487 test L:up b R:nm a b W: - 13 merge b no ancestor
474 --------------
488 --------------
475 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
489 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
476 src: 'a' -> dst: 'b'
490 on remote side:
491 src: 'a' -> dst: 'b'
477 checking for directory renames
492 checking for directory renames
478 resolving manifests
493 resolving manifests
479 branchmerge: True, force: False, partial: False
494 branchmerge: True, force: False, partial: False
480 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
495 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
481 preserving b for resolve of b
496 preserving b for resolve of b
482 preserving rev for resolve of rev
497 preserving rev for resolve of rev
483 a: other deleted -> r
498 a: other deleted -> r
484 removing a
499 removing a
485 starting 4 threads for background file closing (?)
500 starting 4 threads for background file closing (?)
486 b: both created -> m (premerge)
501 b: both created -> m (premerge)
487 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
502 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
488 merging b
503 merging b
489 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
504 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
490 rev: versions differ -> m (premerge)
505 rev: versions differ -> m (premerge)
491 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
506 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
492 merging rev
507 merging rev
493 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
508 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
494 b: both created -> m (merge)
509 b: both created -> m (merge)
495 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
510 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
496 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
511 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
497 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
512 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
498 merge tool returned: 0
513 merge tool returned: 0
499 rev: versions differ -> m (merge)
514 rev: versions differ -> m (merge)
500 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
515 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
501 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
516 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
502 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
517 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
503 merge tool returned: 0
518 merge tool returned: 0
504 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
519 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
505 (branch merge, don't forget to commit)
520 (branch merge, don't forget to commit)
506 --------------
521 --------------
507 M b
522 M b
508 --------------
523 --------------
509
524
510 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
525 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
511 created new head
526 created new head
512 --------------
527 --------------
513 test L:nc a b R:up a b W: - 14 merge b no ancestor
528 test L:nc a b R:up a b W: - 14 merge b no ancestor
514 --------------
529 --------------
515 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
530 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
516 src: 'a' -> dst: 'b'
531 on local side:
532 src: 'a' -> dst: 'b'
517 checking for directory renames
533 checking for directory renames
518 resolving manifests
534 resolving manifests
519 branchmerge: True, force: False, partial: False
535 branchmerge: True, force: False, partial: False
520 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
536 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
521 preserving b for resolve of b
537 preserving b for resolve of b
522 preserving rev for resolve of rev
538 preserving rev for resolve of rev
523 a: remote is newer -> g
539 a: remote is newer -> g
524 getting a
540 getting a
525 b: both created -> m (premerge)
541 b: both created -> m (premerge)
526 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
542 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
527 merging b
543 merging b
528 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
544 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
529 rev: versions differ -> m (premerge)
545 rev: versions differ -> m (premerge)
530 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
546 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
531 merging rev
547 merging rev
532 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
548 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
533 b: both created -> m (merge)
549 b: both created -> m (merge)
534 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
550 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
535 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
551 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
536 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
552 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
537 merge tool returned: 0
553 merge tool returned: 0
538 rev: versions differ -> m (merge)
554 rev: versions differ -> m (merge)
539 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
555 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
540 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
556 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
541 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
557 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
542 merge tool returned: 0
558 merge tool returned: 0
543 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
559 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
544 (branch merge, don't forget to commit)
560 (branch merge, don't forget to commit)
545 --------------
561 --------------
546 M a
562 M a
547 M b
563 M b
548 --------------
564 --------------
549
565
550 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
566 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
551 created new head
567 created new head
552 --------------
568 --------------
553 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
569 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
554 --------------
570 --------------
555 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
571 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
556 src: 'a' -> dst: 'b'
572 on remote side:
573 src: 'a' -> dst: 'b'
557 checking for directory renames
574 checking for directory renames
558 resolving manifests
575 resolving manifests
559 branchmerge: True, force: False, partial: False
576 branchmerge: True, force: False, partial: False
560 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
577 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
561 preserving b for resolve of b
578 preserving b for resolve of b
562 preserving rev for resolve of rev
579 preserving rev for resolve of rev
563 a: other deleted -> r
580 a: other deleted -> r
564 removing a
581 removing a
565 starting 4 threads for background file closing (?)
582 starting 4 threads for background file closing (?)
566 b: both created -> m (premerge)
583 b: both created -> m (premerge)
567 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
584 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
568 merging b
585 merging b
569 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
586 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
570 rev: versions differ -> m (premerge)
587 rev: versions differ -> m (premerge)
571 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
588 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
572 merging rev
589 merging rev
573 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
590 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
574 b: both created -> m (merge)
591 b: both created -> m (merge)
575 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
592 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
576 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
593 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
577 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
594 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
578 merge tool returned: 0
595 merge tool returned: 0
579 rev: versions differ -> m (merge)
596 rev: versions differ -> m (merge)
580 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
597 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
581 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
598 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
582 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
599 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
583 merge tool returned: 0
600 merge tool returned: 0
584 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
601 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
585 (branch merge, don't forget to commit)
602 (branch merge, don't forget to commit)
586 --------------
603 --------------
587 M b
604 M b
588 --------------
605 --------------
589
606
590 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
607 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
591 created new head
608 created new head
592 --------------
609 --------------
593 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
610 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
594 --------------
611 --------------
595 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
612 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
596 src: 'a' -> dst: 'b'
613 on local side:
614 src: 'a' -> dst: 'b'
597 checking for directory renames
615 checking for directory renames
598 resolving manifests
616 resolving manifests
599 branchmerge: True, force: False, partial: False
617 branchmerge: True, force: False, partial: False
600 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
618 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
601 preserving b for resolve of b
619 preserving b for resolve of b
602 preserving rev for resolve of rev
620 preserving rev for resolve of rev
603 a: remote is newer -> g
621 a: remote is newer -> g
604 getting a
622 getting a
605 b: both created -> m (premerge)
623 b: both created -> m (premerge)
606 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
624 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
607 merging b
625 merging b
608 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
626 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
609 rev: versions differ -> m (premerge)
627 rev: versions differ -> m (premerge)
610 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
628 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
611 merging rev
629 merging rev
612 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
630 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
613 b: both created -> m (merge)
631 b: both created -> m (merge)
614 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
632 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
615 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
633 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
616 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
634 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
617 merge tool returned: 0
635 merge tool returned: 0
618 rev: versions differ -> m (merge)
636 rev: versions differ -> m (merge)
619 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
637 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
620 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
638 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
621 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
639 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
622 merge tool returned: 0
640 merge tool returned: 0
623 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
641 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
624 (branch merge, don't forget to commit)
642 (branch merge, don't forget to commit)
625 --------------
643 --------------
626 M a
644 M a
627 M b
645 M b
628 --------------
646 --------------
629
647
630 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
648 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
631 created new head
649 created new head
632 --------------
650 --------------
633 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
651 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
634 --------------
652 --------------
635 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
653 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
636 src: 'a' -> dst: 'b'
654 on remote side:
655 src: 'a' -> dst: 'b'
637 checking for directory renames
656 checking for directory renames
638 resolving manifests
657 resolving manifests
639 branchmerge: True, force: False, partial: False
658 branchmerge: True, force: False, partial: False
640 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
659 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
641 preserving b for resolve of b
660 preserving b for resolve of b
642 preserving rev for resolve of rev
661 preserving rev for resolve of rev
643 starting 4 threads for background file closing (?)
662 starting 4 threads for background file closing (?)
644 b: both created -> m (premerge)
663 b: both created -> m (premerge)
645 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
664 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
646 merging b
665 merging b
647 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
666 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
648 rev: versions differ -> m (premerge)
667 rev: versions differ -> m (premerge)
649 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
668 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
650 merging rev
669 merging rev
651 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
670 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
652 b: both created -> m (merge)
671 b: both created -> m (merge)
653 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
672 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
654 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
673 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
655 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
674 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
656 merge tool returned: 0
675 merge tool returned: 0
657 rev: versions differ -> m (merge)
676 rev: versions differ -> m (merge)
658 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
677 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
659 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
678 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
660 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
679 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
661 merge tool returned: 0
680 merge tool returned: 0
662 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
681 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
663 (branch merge, don't forget to commit)
682 (branch merge, don't forget to commit)
664 --------------
683 --------------
665 M b
684 M b
666 C a
685 C a
667 --------------
686 --------------
668
687
669 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
688 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
670 created new head
689 created new head
671 --------------
690 --------------
672 test L:nm a b R:up a b W: - 18 merge b no ancestor
691 test L:nm a b R:up a b W: - 18 merge b no ancestor
673 --------------
692 --------------
674 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
693 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
675 src: 'a' -> dst: 'b'
694 on local side:
695 src: 'a' -> dst: 'b'
676 checking for directory renames
696 checking for directory renames
677 resolving manifests
697 resolving manifests
678 branchmerge: True, force: False, partial: False
698 branchmerge: True, force: False, partial: False
679 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
699 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
680 preserving b for resolve of b
700 preserving b for resolve of b
681 preserving rev for resolve of rev
701 preserving rev for resolve of rev
682 starting 4 threads for background file closing (?)
702 starting 4 threads for background file closing (?)
683 a: prompt deleted/changed -> m (premerge)
703 a: prompt deleted/changed -> m (premerge)
684 picked tool ':prompt' for a (binary False symlink False changedelete True)
704 picked tool ':prompt' for a (binary False symlink False changedelete True)
685 file 'a' was deleted in local [working copy] but was modified in other [merge rev].
705 file 'a' was deleted in local [working copy] but was modified in other [merge rev].
686 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
706 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
687 What do you want to do? u
707 What do you want to do? u
688 b: both created -> m (premerge)
708 b: both created -> m (premerge)
689 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
709 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
690 merging b
710 merging b
691 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
711 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
692 rev: versions differ -> m (premerge)
712 rev: versions differ -> m (premerge)
693 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
713 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
694 merging rev
714 merging rev
695 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
715 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
696 b: both created -> m (merge)
716 b: both created -> m (merge)
697 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
717 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
698 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
718 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
699 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
719 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
700 merge tool returned: 0
720 merge tool returned: 0
701 rev: versions differ -> m (merge)
721 rev: versions differ -> m (merge)
702 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
722 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
703 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
723 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
704 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
724 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
705 merge tool returned: 0
725 merge tool returned: 0
706 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
726 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
707 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
727 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
708 --------------
728 --------------
709 M a
729 M a
710 M b
730 M b
711 abort: unresolved merge conflicts (see 'hg help resolve')
731 abort: unresolved merge conflicts (see 'hg help resolve')
712 --------------
732 --------------
713
733
714 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
734 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
715 created new head
735 created new head
716 --------------
736 --------------
717 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
737 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
718 --------------
738 --------------
719 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
739 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
720 src: 'a' -> dst: 'b'
740 on remote side:
741 src: 'a' -> dst: 'b'
721 checking for directory renames
742 checking for directory renames
722 resolving manifests
743 resolving manifests
723 branchmerge: True, force: False, partial: False
744 branchmerge: True, force: False, partial: False
724 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
745 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
725 preserving a for resolve of a
746 preserving a for resolve of a
726 preserving b for resolve of b
747 preserving b for resolve of b
727 preserving rev for resolve of rev
748 preserving rev for resolve of rev
728 starting 4 threads for background file closing (?)
749 starting 4 threads for background file closing (?)
729 a: prompt changed/deleted -> m (premerge)
750 a: prompt changed/deleted -> m (premerge)
730 picked tool ':prompt' for a (binary False symlink False changedelete True)
751 picked tool ':prompt' for a (binary False symlink False changedelete True)
731 file 'a' was deleted in other [merge rev] but was modified in local [working copy].
752 file 'a' was deleted in other [merge rev] but was modified in local [working copy].
732 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
753 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
733 What do you want to do? u
754 What do you want to do? u
734 b: both created -> m (premerge)
755 b: both created -> m (premerge)
735 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
756 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
736 merging b
757 merging b
737 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
758 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
738 rev: versions differ -> m (premerge)
759 rev: versions differ -> m (premerge)
739 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
760 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
740 merging rev
761 merging rev
741 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
762 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
742 b: both created -> m (merge)
763 b: both created -> m (merge)
743 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
764 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
744 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
765 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
745 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
766 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
746 merge tool returned: 0
767 merge tool returned: 0
747 rev: versions differ -> m (merge)
768 rev: versions differ -> m (merge)
748 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
769 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
749 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
770 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
750 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
771 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
751 merge tool returned: 0
772 merge tool returned: 0
752 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
773 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
753 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
774 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
754 --------------
775 --------------
755 M b
776 M b
756 C a
777 C a
757 abort: unresolved merge conflicts (see 'hg help resolve')
778 abort: unresolved merge conflicts (see 'hg help resolve')
758 --------------
779 --------------
759
780
760 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
781 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
761 created new head
782 created new head
762 --------------
783 --------------
763 test L:up a R:um a b W: - 20 merge a and b to b, remove a
784 test L:up a R:um a b W: - 20 merge a and b to b, remove a
764 --------------
785 --------------
765 unmatched files in other:
786 unmatched files in other:
766 b
787 b
767 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
788 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
768 src: 'a' -> dst: 'b' *
789 on remote side:
790 src: 'a' -> dst: 'b' *
769 checking for directory renames
791 checking for directory renames
770 resolving manifests
792 resolving manifests
771 branchmerge: True, force: False, partial: False
793 branchmerge: True, force: False, partial: False
772 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
794 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
773 preserving a for resolve of b
795 preserving a for resolve of b
774 preserving rev for resolve of rev
796 preserving rev for resolve of rev
775 removing a
797 removing a
776 starting 4 threads for background file closing (?)
798 starting 4 threads for background file closing (?)
777 b: remote moved from a -> m (premerge)
799 b: remote moved from a -> m (premerge)
778 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
800 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
779 merging a and b to b
801 merging a and b to b
780 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
802 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
781 rev: versions differ -> m (premerge)
803 rev: versions differ -> m (premerge)
782 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
804 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
783 merging rev
805 merging rev
784 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
806 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
785 b: remote moved from a -> m (merge)
807 b: remote moved from a -> m (merge)
786 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
808 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
787 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
809 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
788 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
810 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
789 merge tool returned: 0
811 merge tool returned: 0
790 rev: versions differ -> m (merge)
812 rev: versions differ -> m (merge)
791 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
813 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
792 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
814 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
793 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
815 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
794 merge tool returned: 0
816 merge tool returned: 0
795 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
817 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
796 (branch merge, don't forget to commit)
818 (branch merge, don't forget to commit)
797 --------------
819 --------------
798 M b
820 M b
799 a
821 a
800 --------------
822 --------------
801
823
802 $ tm "um a b" "up a " " " "21 merge a and b to b"
824 $ tm "um a b" "up a " " " "21 merge a and b to b"
803 created new head
825 created new head
804 --------------
826 --------------
805 test L:um a b R:up a W: - 21 merge a and b to b
827 test L:um a b R:up a W: - 21 merge a and b to b
806 --------------
828 --------------
807 unmatched files in local:
829 unmatched files in local:
808 b
830 b
809 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
831 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
810 src: 'a' -> dst: 'b' *
832 on local side:
833 src: 'a' -> dst: 'b' *
811 checking for directory renames
834 checking for directory renames
812 resolving manifests
835 resolving manifests
813 branchmerge: True, force: False, partial: False
836 branchmerge: True, force: False, partial: False
814 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
837 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
815 preserving b for resolve of b
838 preserving b for resolve of b
816 preserving rev for resolve of rev
839 preserving rev for resolve of rev
817 starting 4 threads for background file closing (?)
840 starting 4 threads for background file closing (?)
818 b: local copied/moved from a -> m (premerge)
841 b: local copied/moved from a -> m (premerge)
819 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
842 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
820 merging b and a to b
843 merging b and a to b
821 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
844 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
822 rev: versions differ -> m (premerge)
845 rev: versions differ -> m (premerge)
823 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
846 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
824 merging rev
847 merging rev
825 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
848 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
826 b: local copied/moved from a -> m (merge)
849 b: local copied/moved from a -> m (merge)
827 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
850 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
828 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
851 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
829 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
852 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
830 merge tool returned: 0
853 merge tool returned: 0
831 rev: versions differ -> m (merge)
854 rev: versions differ -> m (merge)
832 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
855 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
833 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
856 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
834 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
857 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
835 merge tool returned: 0
858 merge tool returned: 0
836 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
859 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
837 (branch merge, don't forget to commit)
860 (branch merge, don't forget to commit)
838 --------------
861 --------------
839 M b
862 M b
840 a
863 a
841 --------------
864 --------------
842
865
843
866
844 m "nm a b" "um x a" " " "22 get a, keep b"
867 m "nm a b" "um x a" " " "22 get a, keep b"
845
868
846 $ tm "nm a b" "up a c" " " "23 get c, keep b"
869 $ tm "nm a b" "up a c" " " "23 get c, keep b"
847 created new head
870 created new head
848 --------------
871 --------------
849 test L:nm a b R:up a c W: - 23 get c, keep b
872 test L:nm a b R:up a c W: - 23 get c, keep b
850 --------------
873 --------------
851 unmatched files in local:
874 unmatched files in local:
852 b
875 b
853 unmatched files in other:
876 unmatched files in other:
854 c
877 c
855 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
878 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
856 src: 'a' -> dst: 'b' *
879 on local side:
880 src: 'a' -> dst: 'b' *
857 checking for directory renames
881 checking for directory renames
858 resolving manifests
882 resolving manifests
859 branchmerge: True, force: False, partial: False
883 branchmerge: True, force: False, partial: False
860 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
884 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
861 preserving b for resolve of b
885 preserving b for resolve of b
862 preserving rev for resolve of rev
886 preserving rev for resolve of rev
863 c: remote created -> g
887 c: remote created -> g
864 getting c
888 getting c
865 b: local copied/moved from a -> m (premerge)
889 b: local copied/moved from a -> m (premerge)
866 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
890 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
867 merging b and a to b
891 merging b and a to b
868 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
892 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
869 premerge successful
893 premerge successful
870 rev: versions differ -> m (premerge)
894 rev: versions differ -> m (premerge)
871 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
895 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
872 merging rev
896 merging rev
873 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
897 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
874 rev: versions differ -> m (merge)
898 rev: versions differ -> m (merge)
875 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
899 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
876 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
900 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
877 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
901 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
878 merge tool returned: 0
902 merge tool returned: 0
879 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
903 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
880 (branch merge, don't forget to commit)
904 (branch merge, don't forget to commit)
881 --------------
905 --------------
882 M b
906 M b
883 a
907 a
884 M c
908 M c
885 --------------
909 --------------
886
910
887
911
888 $ cd ..
912 $ cd ..
889
913
890
914
891 Systematic and terse testing of merge merges and ancestor calculation:
915 Systematic and terse testing of merge merges and ancestor calculation:
892
916
893 Expected result:
917 Expected result:
894
918
895 \ a m1 m2 dst
919 \ a m1 m2 dst
896 0 - f f f "versions differ"
920 0 - f f f "versions differ"
897 1 f g g g "versions differ"
921 1 f g g g "versions differ"
898 2 f f f f "versions differ"
922 2 f f f f "versions differ"
899 3 f f g f+g "remote copied to " + f
923 3 f f g f+g "remote copied to " + f
900 4 f f g g "remote moved to " + f
924 4 f f g g "remote moved to " + f
901 5 f g f f+g "local copied to " + f2
925 5 f g f f+g "local copied to " + f2
902 6 f g f g "local moved to " + f2
926 6 f g f g "local moved to " + f2
903 7 - (f) f f "remote differs from untracked local"
927 7 - (f) f f "remote differs from untracked local"
904 8 f (f) f f "remote differs from untracked local"
928 8 f (f) f f "remote differs from untracked local"
905
929
906 $ hg init ancestortest
930 $ hg init ancestortest
907 $ cd ancestortest
931 $ cd ancestortest
908 $ for x in 1 2 3 4 5 6 8; do mkdir $x; echo a > $x/f; done
932 $ for x in 1 2 3 4 5 6 8; do mkdir $x; echo a > $x/f; done
909 $ hg ci -Aqm "a"
933 $ hg ci -Aqm "a"
910 $ mkdir 0
934 $ mkdir 0
911 $ touch 0/f
935 $ touch 0/f
912 $ hg mv 1/f 1/g
936 $ hg mv 1/f 1/g
913 $ hg cp 5/f 5/g
937 $ hg cp 5/f 5/g
914 $ hg mv 6/f 6/g
938 $ hg mv 6/f 6/g
915 $ hg rm 8/f
939 $ hg rm 8/f
916 $ for x in */*; do echo m1 > $x; done
940 $ for x in */*; do echo m1 > $x; done
917 $ hg ci -Aqm "m1"
941 $ hg ci -Aqm "m1"
918 $ hg up -qr0
942 $ hg up -qr0
919 $ mkdir 0 7
943 $ mkdir 0 7
920 $ touch 0/f 7/f
944 $ touch 0/f 7/f
921 $ hg mv 1/f 1/g
945 $ hg mv 1/f 1/g
922 $ hg cp 3/f 3/g
946 $ hg cp 3/f 3/g
923 $ hg mv 4/f 4/g
947 $ hg mv 4/f 4/g
924 $ for x in */*; do echo m2 > $x; done
948 $ for x in */*; do echo m2 > $x; done
925 $ hg ci -Aqm "m2"
949 $ hg ci -Aqm "m2"
926 $ hg up -qr1
950 $ hg up -qr1
927 $ mkdir 7 8
951 $ mkdir 7 8
928 $ echo m > 7/f
952 $ echo m > 7/f
929 $ echo m > 8/f
953 $ echo m > 8/f
930 $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^resolving manifests/,$d' 2> /dev/null
954 $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^resolving manifests/,$d' 2> /dev/null
931 unmatched files in local:
955 unmatched files in local:
932 5/g
956 5/g
933 6/g
957 6/g
934 unmatched files in other:
958 unmatched files in other:
935 3/g
959 3/g
936 4/g
960 4/g
937 7/f
961 7/f
938 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
962 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
939 src: '1/f' -> dst: '1/g' *
963 on local side:
940 src: '3/f' -> dst: '3/g' *
964 src: '1/f' -> dst: '1/g' *
941 src: '4/f' -> dst: '4/g' *
965 src: '5/f' -> dst: '5/g' *
942 src: '5/f' -> dst: '5/g' *
966 src: '6/f' -> dst: '6/g' *
943 src: '6/f' -> dst: '6/g' *
967 on remote side:
968 src: '1/f' -> dst: '1/g' *
969 src: '3/f' -> dst: '3/g' *
970 src: '4/f' -> dst: '4/g' *
944 checking for directory renames
971 checking for directory renames
945 $ hg mani
972 $ hg mani
946 0/f
973 0/f
947 1/g
974 1/g
948 2/f
975 2/f
949 3/f
976 3/f
950 4/f
977 4/f
951 5/f
978 5/f
952 5/g
979 5/g
953 6/g
980 6/g
954 $ for f in */*; do echo $f:; cat $f; done
981 $ for f in */*; do echo $f:; cat $f; done
955 0/f:
982 0/f:
956 m1
983 m1
957 0/f.base:
984 0/f.base:
958 0/f.local:
985 0/f.local:
959 m1
986 m1
960 0/f.orig:
987 0/f.orig:
961 m1
988 m1
962 0/f.other:
989 0/f.other:
963 m2
990 m2
964 1/g:
991 1/g:
965 m1
992 m1
966 1/g.base:
993 1/g.base:
967 a
994 a
968 1/g.local:
995 1/g.local:
969 m1
996 m1
970 1/g.orig:
997 1/g.orig:
971 m1
998 m1
972 1/g.other:
999 1/g.other:
973 m2
1000 m2
974 2/f:
1001 2/f:
975 m1
1002 m1
976 2/f.base:
1003 2/f.base:
977 a
1004 a
978 2/f.local:
1005 2/f.local:
979 m1
1006 m1
980 2/f.orig:
1007 2/f.orig:
981 m1
1008 m1
982 2/f.other:
1009 2/f.other:
983 m2
1010 m2
984 3/f:
1011 3/f:
985 m1
1012 m1
986 3/f.base:
1013 3/f.base:
987 a
1014 a
988 3/f.local:
1015 3/f.local:
989 m1
1016 m1
990 3/f.orig:
1017 3/f.orig:
991 m1
1018 m1
992 3/f.other:
1019 3/f.other:
993 m2
1020 m2
994 3/g:
1021 3/g:
995 m1
1022 m1
996 3/g.base:
1023 3/g.base:
997 a
1024 a
998 3/g.local:
1025 3/g.local:
999 m1
1026 m1
1000 3/g.orig:
1027 3/g.orig:
1001 m1
1028 m1
1002 3/g.other:
1029 3/g.other:
1003 m2
1030 m2
1004 4/g:
1031 4/g:
1005 m1
1032 m1
1006 4/g.base:
1033 4/g.base:
1007 a
1034 a
1008 4/g.local:
1035 4/g.local:
1009 m1
1036 m1
1010 4/g.orig:
1037 4/g.orig:
1011 m1
1038 m1
1012 4/g.other:
1039 4/g.other:
1013 m2
1040 m2
1014 5/f:
1041 5/f:
1015 m1
1042 m1
1016 5/f.base:
1043 5/f.base:
1017 a
1044 a
1018 5/f.local:
1045 5/f.local:
1019 m1
1046 m1
1020 5/f.orig:
1047 5/f.orig:
1021 m1
1048 m1
1022 5/f.other:
1049 5/f.other:
1023 m2
1050 m2
1024 5/g:
1051 5/g:
1025 m1
1052 m1
1026 5/g.base:
1053 5/g.base:
1027 a
1054 a
1028 5/g.local:
1055 5/g.local:
1029 m1
1056 m1
1030 5/g.orig:
1057 5/g.orig:
1031 m1
1058 m1
1032 5/g.other:
1059 5/g.other:
1033 m2
1060 m2
1034 6/g:
1061 6/g:
1035 m1
1062 m1
1036 6/g.base:
1063 6/g.base:
1037 a
1064 a
1038 6/g.local:
1065 6/g.local:
1039 m1
1066 m1
1040 6/g.orig:
1067 6/g.orig:
1041 m1
1068 m1
1042 6/g.other:
1069 6/g.other:
1043 m2
1070 m2
1044 7/f:
1071 7/f:
1045 m
1072 m
1046 7/f.base:
1073 7/f.base:
1047 7/f.local:
1074 7/f.local:
1048 m
1075 m
1049 7/f.orig:
1076 7/f.orig:
1050 m
1077 m
1051 7/f.other:
1078 7/f.other:
1052 m2
1079 m2
1053 8/f:
1080 8/f:
1054 m2
1081 m2
1055 $ cd ..
1082 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now