##// END OF EJS Templates
copies: report found copies sorted
Mads Kiilerich -
r18362:5a4f220f default
parent child Browse files
Show More
@@ -1,386 +1,386 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 import util
8 import util
9 import heapq
9 import heapq
10
10
11 def _nonoverlap(d1, d2, d3):
11 def _nonoverlap(d1, d2, d3):
12 "Return list of elements in d1 not in d2 or d3"
12 "Return list of elements in d1 not in d2 or d3"
13 return sorted([d for d in d1 if d not in d3 and d not in d2])
13 return sorted([d for d in d1 if d not in d3 and d not in d2])
14
14
15 def _dirname(f):
15 def _dirname(f):
16 s = f.rfind("/")
16 s = f.rfind("/")
17 if s == -1:
17 if s == -1:
18 return ""
18 return ""
19 return f[:s]
19 return f[:s]
20
20
21 def _findlimit(repo, a, b):
21 def _findlimit(repo, a, b):
22 """Find the earliest revision that's an ancestor of a or b but not both,
22 """Find the earliest revision that's an ancestor of a or b but not both,
23 None if no such revision exists.
23 None if no such revision exists.
24 """
24 """
25 # basic idea:
25 # basic idea:
26 # - mark a and b with different sides
26 # - mark a and b with different sides
27 # - if a parent's children are all on the same side, the parent is
27 # - if a parent's children are all on the same side, the parent is
28 # on that side, otherwise it is on no side
28 # on that side, otherwise it is on no side
29 # - walk the graph in topological order with the help of a heap;
29 # - walk the graph in topological order with the help of a heap;
30 # - add unseen parents to side map
30 # - add unseen parents to side map
31 # - clear side of any parent that has children on different sides
31 # - clear side of any parent that has children on different sides
32 # - track number of interesting revs that might still be on a side
32 # - track number of interesting revs that might still be on a side
33 # - track the lowest interesting rev seen
33 # - track the lowest interesting rev seen
34 # - quit when interesting revs is zero
34 # - quit when interesting revs is zero
35
35
36 cl = repo.changelog
36 cl = repo.changelog
37 working = len(cl) # pseudo rev for the working directory
37 working = len(cl) # pseudo rev for the working directory
38 if a is None:
38 if a is None:
39 a = working
39 a = working
40 if b is None:
40 if b is None:
41 b = working
41 b = working
42
42
43 side = {a: -1, b: 1}
43 side = {a: -1, b: 1}
44 visit = [-a, -b]
44 visit = [-a, -b]
45 heapq.heapify(visit)
45 heapq.heapify(visit)
46 interesting = len(visit)
46 interesting = len(visit)
47 hascommonancestor = False
47 hascommonancestor = False
48 limit = working
48 limit = working
49
49
50 while interesting:
50 while interesting:
51 r = -heapq.heappop(visit)
51 r = -heapq.heappop(visit)
52 if r == working:
52 if r == working:
53 parents = [cl.rev(p) for p in repo.dirstate.parents()]
53 parents = [cl.rev(p) for p in repo.dirstate.parents()]
54 else:
54 else:
55 parents = cl.parentrevs(r)
55 parents = cl.parentrevs(r)
56 for p in parents:
56 for p in parents:
57 if p < 0:
57 if p < 0:
58 continue
58 continue
59 if p not in side:
59 if p not in side:
60 # first time we see p; add it to visit
60 # first time we see p; add it to visit
61 side[p] = side[r]
61 side[p] = side[r]
62 if side[p]:
62 if side[p]:
63 interesting += 1
63 interesting += 1
64 heapq.heappush(visit, -p)
64 heapq.heappush(visit, -p)
65 elif side[p] and side[p] != side[r]:
65 elif side[p] and side[p] != side[r]:
66 # p was interesting but now we know better
66 # p was interesting but now we know better
67 side[p] = 0
67 side[p] = 0
68 interesting -= 1
68 interesting -= 1
69 hascommonancestor = True
69 hascommonancestor = True
70 if side[r]:
70 if side[r]:
71 limit = r # lowest rev visited
71 limit = r # lowest rev visited
72 interesting -= 1
72 interesting -= 1
73
73
74 if not hascommonancestor:
74 if not hascommonancestor:
75 return None
75 return None
76 return limit
76 return limit
77
77
78 def _chain(src, dst, a, b):
78 def _chain(src, dst, a, b):
79 '''chain two sets of copies a->b'''
79 '''chain two sets of copies a->b'''
80 t = a.copy()
80 t = a.copy()
81 for k, v in b.iteritems():
81 for k, v in b.iteritems():
82 if v in t:
82 if v in t:
83 # found a chain
83 # found a chain
84 if t[v] != k:
84 if t[v] != k:
85 # file wasn't renamed back to itself
85 # file wasn't renamed back to itself
86 t[k] = t[v]
86 t[k] = t[v]
87 if v not in dst:
87 if v not in dst:
88 # chain was a rename, not a copy
88 # chain was a rename, not a copy
89 del t[v]
89 del t[v]
90 if v in src:
90 if v in src:
91 # file is a copy of an existing file
91 # file is a copy of an existing file
92 t[k] = v
92 t[k] = v
93
93
94 # remove criss-crossed copies
94 # remove criss-crossed copies
95 for k, v in t.items():
95 for k, v in t.items():
96 if k in src and v in dst:
96 if k in src and v in dst:
97 del t[k]
97 del t[k]
98
98
99 return t
99 return t
100
100
101 def _tracefile(fctx, actx):
101 def _tracefile(fctx, actx):
102 '''return file context that is the ancestor of fctx present in actx'''
102 '''return file context that is the ancestor of fctx present in actx'''
103 stop = actx.rev()
103 stop = actx.rev()
104 am = actx.manifest()
104 am = actx.manifest()
105
105
106 for f in fctx.ancestors():
106 for f in fctx.ancestors():
107 if am.get(f.path(), None) == f.filenode():
107 if am.get(f.path(), None) == f.filenode():
108 return f
108 return f
109 if f.rev() < stop:
109 if f.rev() < stop:
110 return None
110 return None
111
111
112 def _dirstatecopies(d):
112 def _dirstatecopies(d):
113 ds = d._repo.dirstate
113 ds = d._repo.dirstate
114 c = ds.copies().copy()
114 c = ds.copies().copy()
115 for k in c.keys():
115 for k in c.keys():
116 if ds[k] not in 'anm':
116 if ds[k] not in 'anm':
117 del c[k]
117 del c[k]
118 return c
118 return c
119
119
120 def _forwardcopies(a, b):
120 def _forwardcopies(a, b):
121 '''find {dst@b: src@a} copy mapping where a is an ancestor of b'''
121 '''find {dst@b: src@a} copy mapping where a is an ancestor of b'''
122
122
123 # check for working copy
123 # check for working copy
124 w = None
124 w = None
125 if b.rev() is None:
125 if b.rev() is None:
126 w = b
126 w = b
127 b = w.p1()
127 b = w.p1()
128 if a == b:
128 if a == b:
129 # short-circuit to avoid issues with merge states
129 # short-circuit to avoid issues with merge states
130 return _dirstatecopies(w)
130 return _dirstatecopies(w)
131
131
132 # find where new files came from
132 # find where new files came from
133 # we currently don't try to find where old files went, too expensive
133 # we currently don't try to find where old files went, too expensive
134 # this means we can miss a case like 'hg rm b; hg cp a b'
134 # this means we can miss a case like 'hg rm b; hg cp a b'
135 cm = {}
135 cm = {}
136 for f in b:
136 for f in b:
137 if f not in a:
137 if f not in a:
138 ofctx = _tracefile(b[f], a)
138 ofctx = _tracefile(b[f], a)
139 if ofctx:
139 if ofctx:
140 cm[f] = ofctx.path()
140 cm[f] = ofctx.path()
141
141
142 # combine copies from dirstate if necessary
142 # combine copies from dirstate if necessary
143 if w is not None:
143 if w is not None:
144 cm = _chain(a, w, cm, _dirstatecopies(w))
144 cm = _chain(a, w, cm, _dirstatecopies(w))
145
145
146 return cm
146 return cm
147
147
148 def _backwardrenames(a, b):
148 def _backwardrenames(a, b):
149 # Even though we're not taking copies into account, 1:n rename situations
149 # Even though we're not taking copies into account, 1:n rename situations
150 # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
150 # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
151 # arbitrarily pick one of the renames.
151 # arbitrarily pick one of the renames.
152 f = _forwardcopies(b, a)
152 f = _forwardcopies(b, a)
153 r = {}
153 r = {}
154 for k, v in sorted(f.iteritems()):
154 for k, v in sorted(f.iteritems()):
155 # remove copies
155 # remove copies
156 if v in a:
156 if v in a:
157 continue
157 continue
158 r[v] = k
158 r[v] = k
159 return r
159 return r
160
160
161 def pathcopies(x, y):
161 def pathcopies(x, y):
162 '''find {dst@y: src@x} copy mapping for directed compare'''
162 '''find {dst@y: src@x} copy mapping for directed compare'''
163 if x == y or not x or not y:
163 if x == y or not x or not y:
164 return {}
164 return {}
165 a = y.ancestor(x)
165 a = y.ancestor(x)
166 if a == x:
166 if a == x:
167 return _forwardcopies(x, y)
167 return _forwardcopies(x, y)
168 if a == y:
168 if a == y:
169 return _backwardrenames(x, y)
169 return _backwardrenames(x, y)
170 return _chain(x, y, _backwardrenames(x, a), _forwardcopies(a, y))
170 return _chain(x, y, _backwardrenames(x, a), _forwardcopies(a, y))
171
171
172 def mergecopies(repo, c1, c2, ca):
172 def mergecopies(repo, c1, c2, ca):
173 """
173 """
174 Find moves and copies between context c1 and c2 that are relevant
174 Find moves and copies between context c1 and c2 that are relevant
175 for merging.
175 for merging.
176
176
177 Returns four dicts: "copy", "movewithdir", "diverge", and
177 Returns four dicts: "copy", "movewithdir", "diverge", and
178 "renamedelete".
178 "renamedelete".
179
179
180 "copy" is a mapping from destination name -> source name,
180 "copy" is a mapping from destination name -> source name,
181 where source is in c1 and destination is in c2 or vice-versa.
181 where source is in c1 and destination is in c2 or vice-versa.
182
182
183 "movewithdir" is a mapping from source name -> destination name,
183 "movewithdir" is a mapping from source name -> destination name,
184 where the file at source present in one context but not the other
184 where the file at source present in one context but not the other
185 needs to be moved to destination by the merge process, because the
185 needs to be moved to destination by the merge process, because the
186 other context moved the directory it is in.
186 other context moved the directory it is in.
187
187
188 "diverge" is a mapping of source name -> list of destination names
188 "diverge" is a mapping of source name -> list of destination names
189 for divergent renames.
189 for divergent renames.
190
190
191 "renamedelete" is a mapping of source name -> list of destination
191 "renamedelete" is a mapping of source name -> list of destination
192 names for files deleted in c1 that were renamed in c2 or vice-versa.
192 names for files deleted in c1 that were renamed in c2 or vice-versa.
193 """
193 """
194 # avoid silly behavior for update from empty dir
194 # avoid silly behavior for update from empty dir
195 if not c1 or not c2 or c1 == c2:
195 if not c1 or not c2 or c1 == c2:
196 return {}, {}, {}, {}
196 return {}, {}, {}, {}
197
197
198 # avoid silly behavior for parent -> working dir
198 # avoid silly behavior for parent -> working dir
199 if c2.node() is None and c1.node() == repo.dirstate.p1():
199 if c2.node() is None and c1.node() == repo.dirstate.p1():
200 return repo.dirstate.copies(), {}, {}, {}
200 return repo.dirstate.copies(), {}, {}, {}
201
201
202 limit = _findlimit(repo, c1.rev(), c2.rev())
202 limit = _findlimit(repo, c1.rev(), c2.rev())
203 if limit is None:
203 if limit is None:
204 # no common ancestor, no copies
204 # no common ancestor, no copies
205 return {}, {}, {}, {}
205 return {}, {}, {}, {}
206 m1 = c1.manifest()
206 m1 = c1.manifest()
207 m2 = c2.manifest()
207 m2 = c2.manifest()
208 ma = ca.manifest()
208 ma = ca.manifest()
209
209
210 def makectx(f, n):
210 def makectx(f, n):
211 if len(n) != 20: # in a working context?
211 if len(n) != 20: # in a working context?
212 if c1.rev() is None:
212 if c1.rev() is None:
213 return c1.filectx(f)
213 return c1.filectx(f)
214 return c2.filectx(f)
214 return c2.filectx(f)
215 return repo.filectx(f, fileid=n)
215 return repo.filectx(f, fileid=n)
216
216
217 ctx = util.lrucachefunc(makectx)
217 ctx = util.lrucachefunc(makectx)
218 copy = {}
218 copy = {}
219 movewithdir = {}
219 movewithdir = {}
220 fullcopy = {}
220 fullcopy = {}
221 diverge = {}
221 diverge = {}
222
222
223 def related(f1, f2, limit):
223 def related(f1, f2, limit):
224 # Walk back to common ancestor to see if the two files originate
224 # Walk back to common ancestor to see if the two files originate
225 # from the same file. Since workingfilectx's rev() is None it messes
225 # from the same file. Since workingfilectx's rev() is None it messes
226 # up the integer comparison logic, hence the pre-step check for
226 # up the integer comparison logic, hence the pre-step check for
227 # None (f1 and f2 can only be workingfilectx's initially).
227 # None (f1 and f2 can only be workingfilectx's initially).
228
228
229 if f1 == f2:
229 if f1 == f2:
230 return f1 # a match
230 return f1 # a match
231
231
232 g1, g2 = f1.ancestors(), f2.ancestors()
232 g1, g2 = f1.ancestors(), f2.ancestors()
233 try:
233 try:
234 f1r, f2r = f1.rev(), f2.rev()
234 f1r, f2r = f1.rev(), f2.rev()
235
235
236 if f1r is None:
236 if f1r is None:
237 f1 = g1.next()
237 f1 = g1.next()
238 if f2r is None:
238 if f2r is None:
239 f2 = g2.next()
239 f2 = g2.next()
240
240
241 while True:
241 while True:
242 f1r, f2r = f1.rev(), f2.rev()
242 f1r, f2r = f1.rev(), f2.rev()
243 if f1r > f2r:
243 if f1r > f2r:
244 f1 = g1.next()
244 f1 = g1.next()
245 elif f2r > f1r:
245 elif f2r > f1r:
246 f2 = g2.next()
246 f2 = g2.next()
247 elif f1 == f2:
247 elif f1 == f2:
248 return f1 # a match
248 return f1 # a match
249 elif f1r == f2r or f1r < limit or f2r < limit:
249 elif f1r == f2r or f1r < limit or f2r < limit:
250 return False # copy no longer relevant
250 return False # copy no longer relevant
251 except StopIteration:
251 except StopIteration:
252 return False
252 return False
253
253
254 def checkcopies(f, m1, m2):
254 def checkcopies(f, m1, m2):
255 '''check possible copies of f from m1 to m2'''
255 '''check possible copies of f from m1 to m2'''
256 of = None
256 of = None
257 seen = set([f])
257 seen = set([f])
258 for oc in ctx(f, m1[f]).ancestors():
258 for oc in ctx(f, m1[f]).ancestors():
259 ocr = oc.rev()
259 ocr = oc.rev()
260 of = oc.path()
260 of = oc.path()
261 if of in seen:
261 if of in seen:
262 # check limit late - grab last rename before
262 # check limit late - grab last rename before
263 if ocr < limit:
263 if ocr < limit:
264 break
264 break
265 continue
265 continue
266 seen.add(of)
266 seen.add(of)
267
267
268 fullcopy[f] = of # remember for dir rename detection
268 fullcopy[f] = of # remember for dir rename detection
269 if of not in m2:
269 if of not in m2:
270 continue # no match, keep looking
270 continue # no match, keep looking
271 if m2[of] == ma.get(of):
271 if m2[of] == ma.get(of):
272 break # no merge needed, quit early
272 break # no merge needed, quit early
273 c2 = ctx(of, m2[of])
273 c2 = ctx(of, m2[of])
274 cr = related(oc, c2, ca.rev())
274 cr = related(oc, c2, ca.rev())
275 if cr and (of == f or of == c2.path()): # non-divergent
275 if cr and (of == f or of == c2.path()): # non-divergent
276 copy[f] = of
276 copy[f] = of
277 of = None
277 of = None
278 break
278 break
279
279
280 if of in ma:
280 if of in ma:
281 diverge.setdefault(of, []).append(f)
281 diverge.setdefault(of, []).append(f)
282
282
283 repo.ui.debug(" searching for copies back to rev %d\n" % limit)
283 repo.ui.debug(" searching for copies back to rev %d\n" % limit)
284
284
285 u1 = _nonoverlap(m1, m2, ma)
285 u1 = _nonoverlap(m1, m2, ma)
286 u2 = _nonoverlap(m2, m1, ma)
286 u2 = _nonoverlap(m2, m1, ma)
287
287
288 if u1:
288 if u1:
289 repo.ui.debug(" unmatched files in local:\n %s\n"
289 repo.ui.debug(" unmatched files in local:\n %s\n"
290 % "\n ".join(u1))
290 % "\n ".join(u1))
291 if u2:
291 if u2:
292 repo.ui.debug(" unmatched files in other:\n %s\n"
292 repo.ui.debug(" unmatched files in other:\n %s\n"
293 % "\n ".join(u2))
293 % "\n ".join(u2))
294
294
295 for f in u1:
295 for f in u1:
296 checkcopies(f, m1, m2)
296 checkcopies(f, m1, m2)
297 for f in u2:
297 for f in u2:
298 checkcopies(f, m2, m1)
298 checkcopies(f, m2, m1)
299
299
300 renamedelete = {}
300 renamedelete = {}
301 renamedelete2 = set()
301 renamedelete2 = set()
302 diverge2 = set()
302 diverge2 = set()
303 for of, fl in diverge.items():
303 for of, fl in diverge.items():
304 if len(fl) == 1 or of in c1 or of in c2:
304 if len(fl) == 1 or of in c1 or of in c2:
305 del diverge[of] # not actually divergent, or not a rename
305 del diverge[of] # not actually divergent, or not a rename
306 if of not in c1 and of not in c2:
306 if of not in c1 and of not in c2:
307 # renamed on one side, deleted on the other side, but filter
307 # renamed on one side, deleted on the other side, but filter
308 # out files that have been renamed and then deleted
308 # out files that have been renamed and then deleted
309 renamedelete[of] = [f for f in fl if f in c1 or f in c2]
309 renamedelete[of] = [f for f in fl if f in c1 or f in c2]
310 renamedelete2.update(fl) # reverse map for below
310 renamedelete2.update(fl) # reverse map for below
311 else:
311 else:
312 diverge2.update(fl) # reverse map for below
312 diverge2.update(fl) # reverse map for below
313
313
314 if fullcopy:
314 if fullcopy:
315 repo.ui.debug(" all copies found (* = to merge, ! = divergent, "
315 repo.ui.debug(" all copies found (* = to merge, ! = divergent, "
316 "% = renamed and deleted):\n")
316 "% = renamed and deleted):\n")
317 for f in fullcopy:
317 for f in sorted(fullcopy):
318 note = ""
318 note = ""
319 if f in copy:
319 if f in copy:
320 note += "*"
320 note += "*"
321 if f in diverge2:
321 if f in diverge2:
322 note += "!"
322 note += "!"
323 if f in renamedelete2:
323 if f in renamedelete2:
324 note += "%"
324 note += "%"
325 repo.ui.debug(" src: '%s' -> dst: '%s' %s\n" % (fullcopy[f], f,
325 repo.ui.debug(" src: '%s' -> dst: '%s' %s\n" % (fullcopy[f], f,
326 note))
326 note))
327 del diverge2
327 del diverge2
328
328
329 if not fullcopy:
329 if not fullcopy:
330 return copy, movewithdir, diverge, renamedelete
330 return copy, movewithdir, diverge, renamedelete
331
331
332 repo.ui.debug(" checking for directory renames\n")
332 repo.ui.debug(" checking for directory renames\n")
333
333
334 # generate a directory move map
334 # generate a directory move map
335 d1, d2 = c1.dirs(), c2.dirs()
335 d1, d2 = c1.dirs(), c2.dirs()
336 d1.add('')
336 d1.add('')
337 d2.add('')
337 d2.add('')
338 invalid = set()
338 invalid = set()
339 dirmove = {}
339 dirmove = {}
340
340
341 # examine each file copy for a potential directory move, which is
341 # examine each file copy for a potential directory move, which is
342 # when all the files in a directory are moved to a new directory
342 # when all the files in a directory are moved to a new directory
343 for dst, src in fullcopy.iteritems():
343 for dst, src in fullcopy.iteritems():
344 dsrc, ddst = _dirname(src), _dirname(dst)
344 dsrc, ddst = _dirname(src), _dirname(dst)
345 if dsrc in invalid:
345 if dsrc in invalid:
346 # already seen to be uninteresting
346 # already seen to be uninteresting
347 continue
347 continue
348 elif dsrc in d1 and ddst in d1:
348 elif dsrc in d1 and ddst in d1:
349 # directory wasn't entirely moved locally
349 # directory wasn't entirely moved locally
350 invalid.add(dsrc)
350 invalid.add(dsrc)
351 elif dsrc in d2 and ddst in d2:
351 elif dsrc in d2 and ddst in d2:
352 # directory wasn't entirely moved remotely
352 # directory wasn't entirely moved remotely
353 invalid.add(dsrc)
353 invalid.add(dsrc)
354 elif dsrc in dirmove and dirmove[dsrc] != ddst:
354 elif dsrc in dirmove and dirmove[dsrc] != ddst:
355 # files from the same directory moved to two different places
355 # files from the same directory moved to two different places
356 invalid.add(dsrc)
356 invalid.add(dsrc)
357 else:
357 else:
358 # looks good so far
358 # looks good so far
359 dirmove[dsrc + "/"] = ddst + "/"
359 dirmove[dsrc + "/"] = ddst + "/"
360
360
361 for i in invalid:
361 for i in invalid:
362 if i in dirmove:
362 if i in dirmove:
363 del dirmove[i]
363 del dirmove[i]
364 del d1, d2, invalid
364 del d1, d2, invalid
365
365
366 if not dirmove:
366 if not dirmove:
367 return copy, movewithdir, diverge, renamedelete
367 return copy, movewithdir, diverge, renamedelete
368
368
369 for d in dirmove:
369 for d in dirmove:
370 repo.ui.debug(" discovered dir src: '%s' -> dst: '%s'\n" %
370 repo.ui.debug(" discovered dir src: '%s' -> dst: '%s'\n" %
371 (d, dirmove[d]))
371 (d, dirmove[d]))
372
372
373 # check unaccounted nonoverlapping files against directory moves
373 # check unaccounted nonoverlapping files against directory moves
374 for f in u1 + u2:
374 for f in u1 + u2:
375 if f not in fullcopy:
375 if f not in fullcopy:
376 for d in dirmove:
376 for d in dirmove:
377 if f.startswith(d):
377 if f.startswith(d):
378 # new file added in a directory that was moved, move it
378 # new file added in a directory that was moved, move it
379 df = dirmove[d] + f[len(d):]
379 df = dirmove[d] + f[len(d):]
380 if df not in copy:
380 if df not in copy:
381 movewithdir[f] = df
381 movewithdir[f] = df
382 repo.ui.debug((" pending file src: '%s' -> "
382 repo.ui.debug((" pending file src: '%s' -> "
383 "dst: '%s'\n") % (f, df))
383 "dst: '%s'\n") % (f, df))
384 break
384 break
385
385
386 return copy, movewithdir, diverge, renamedelete
386 return copy, movewithdir, diverge, renamedelete
@@ -1,64 +1,64 b''
1 $ hg init t
1 $ hg init t
2 $ cd t
2 $ cd t
3
3
4 $ echo 1 > a
4 $ echo 1 > a
5 $ hg ci -qAm "first"
5 $ hg ci -qAm "first"
6
6
7 $ hg cp a b
7 $ hg cp a b
8 $ hg mv a c
8 $ hg mv a c
9 $ echo 2 >> b
9 $ echo 2 >> b
10 $ echo 2 >> c
10 $ echo 2 >> c
11
11
12 $ hg ci -qAm "second"
12 $ hg ci -qAm "second"
13
13
14 $ hg co -C 0
14 $ hg co -C 0
15 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
15 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
16
16
17 $ echo 0 > a
17 $ echo 0 > a
18 $ echo 1 >> a
18 $ echo 1 >> a
19
19
20 $ hg ci -qAm "other"
20 $ hg ci -qAm "other"
21
21
22 $ hg merge --debug
22 $ hg merge --debug
23 searching for copies back to rev 1
23 searching for copies back to rev 1
24 unmatched files in other:
24 unmatched files in other:
25 b
25 b
26 c
26 c
27 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
27 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
28 src: 'a' -> dst: 'b' *
28 src: 'a' -> dst: 'c' *
29 src: 'a' -> dst: 'c' *
29 src: 'a' -> dst: 'b' *
30 checking for directory renames
30 checking for directory renames
31 resolving manifests
31 resolving manifests
32 overwrite: False, partial: False
32 overwrite: False, partial: False
33 ancestor: b8bf91eeebbc, local: add3f11052fa+, remote: 17c05bb7fcb6
33 ancestor: b8bf91eeebbc, local: add3f11052fa+, remote: 17c05bb7fcb6
34 a: remote moved to b -> m
34 a: remote moved to b -> m
35 a: remote moved to c -> m
35 a: remote moved to c -> m
36 preserving a for resolve of b
36 preserving a for resolve of b
37 preserving a for resolve of c
37 preserving a for resolve of c
38 removing a
38 removing a
39 updating: a 1/2 files (50.00%)
39 updating: a 1/2 files (50.00%)
40 picked tool 'internal:merge' for b (binary False symlink False)
40 picked tool 'internal:merge' for b (binary False symlink False)
41 merging a and b to b
41 merging a and b to b
42 my b@add3f11052fa+ other b@17c05bb7fcb6 ancestor a@b8bf91eeebbc
42 my b@add3f11052fa+ other b@17c05bb7fcb6 ancestor a@b8bf91eeebbc
43 premerge successful
43 premerge successful
44 updating: a 2/2 files (100.00%)
44 updating: a 2/2 files (100.00%)
45 picked tool 'internal:merge' for c (binary False symlink False)
45 picked tool 'internal:merge' for c (binary False symlink False)
46 merging a and c to c
46 merging a and c to c
47 my c@add3f11052fa+ other c@17c05bb7fcb6 ancestor a@b8bf91eeebbc
47 my c@add3f11052fa+ other c@17c05bb7fcb6 ancestor a@b8bf91eeebbc
48 premerge successful
48 premerge successful
49 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
49 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
50 (branch merge, don't forget to commit)
50 (branch merge, don't forget to commit)
51
51
52 file b
52 file b
53 $ cat b
53 $ cat b
54 0
54 0
55 1
55 1
56 2
56 2
57
57
58 file c
58 file c
59 $ cat c
59 $ cat c
60 0
60 0
61 1
61 1
62 2
62 2
63
63
64 $ cd ..
64 $ cd ..
@@ -1,195 +1,195 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 searching for copies back to rev 1
25 searching for copies back to rev 1
26 unmatched files in local:
26 unmatched files in local:
27 c2
27 c2
28 unmatched files in other:
28 unmatched files in other:
29 b
29 b
30 b2
30 b2
31 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
31 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
32 src: 'a2' -> dst: 'c2' !
33 src: 'a' -> dst: 'b' *
32 src: 'a' -> dst: 'b' *
34 src: 'a2' -> dst: 'b2' !
33 src: 'a2' -> dst: 'b2' !
34 src: 'a2' -> dst: 'c2' !
35 checking for directory renames
35 checking for directory renames
36 a2: divergent renames -> dr
36 a2: divergent renames -> dr
37 resolving manifests
37 resolving manifests
38 overwrite: False, partial: False
38 overwrite: False, partial: False
39 ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
39 ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
40 a: remote moved to b -> m
40 a: remote moved to b -> m
41 b2: remote created -> g
41 b2: remote created -> g
42 preserving a for resolve of b
42 preserving a for resolve of b
43 removing a
43 removing a
44 updating: a 1/3 files (33.33%)
44 updating: a 1/3 files (33.33%)
45 picked tool 'internal:merge' for b (binary False symlink False)
45 picked tool 'internal:merge' for b (binary False symlink False)
46 merging a and b to b
46 merging a and b to b
47 my b@044f8520aeeb+ other b@85c198ef2f6c ancestor a@af1939970a1c
47 my b@044f8520aeeb+ other b@85c198ef2f6c ancestor a@af1939970a1c
48 premerge successful
48 premerge successful
49 updating: a2 2/3 files (66.67%)
49 updating: a2 2/3 files (66.67%)
50 note: possible conflict - a2 was renamed multiple times to:
50 note: possible conflict - a2 was renamed multiple times to:
51 c2
51 c2
52 b2
52 b2
53 updating: b2 3/3 files (100.00%)
53 updating: b2 3/3 files (100.00%)
54 getting b2
54 getting b2
55 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
55 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
56 (branch merge, don't forget to commit)
56 (branch merge, don't forget to commit)
57
57
58 $ hg status -AC
58 $ hg status -AC
59 M b
59 M b
60 a
60 a
61 M b2
61 M b2
62 R a
62 R a
63 C c2
63 C c2
64
64
65 $ cat b
65 $ cat b
66 blahblah
66 blahblah
67
67
68 $ hg ci -m "merge"
68 $ hg ci -m "merge"
69
69
70 $ hg debugindex b
70 $ hg debugindex b
71 rev offset length ..... linkrev nodeid p1 p2 (re)
71 rev offset length ..... linkrev nodeid p1 p2 (re)
72 0 0 67 ..... 1 57eacc201a7f 000000000000 000000000000 (re)
72 0 0 67 ..... 1 57eacc201a7f 000000000000 000000000000 (re)
73 1 67 72 ..... 3 4727ba907962 000000000000 57eacc201a7f (re)
73 1 67 72 ..... 3 4727ba907962 000000000000 57eacc201a7f (re)
74
74
75 $ hg debugrename b
75 $ hg debugrename b
76 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
76 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
77
77
78 This used to trigger a "divergent renames" warning, despite no renames
78 This used to trigger a "divergent renames" warning, despite no renames
79
79
80 $ hg cp b b3
80 $ hg cp b b3
81 $ hg cp b b4
81 $ hg cp b b4
82 $ hg ci -A -m 'copy b twice'
82 $ hg ci -A -m 'copy b twice'
83 $ hg up eb92d88a9712
83 $ hg up eb92d88a9712
84 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
84 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
85 $ hg up
85 $ hg up
86 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
86 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 $ hg rm b3 b4
87 $ hg rm b3 b4
88 $ hg ci -m 'clean up a bit of our mess'
88 $ hg ci -m 'clean up a bit of our mess'
89
89
90 We'd rather not warn on divergent renames done in the same changeset (issue2113)
90 We'd rather not warn on divergent renames done in the same changeset (issue2113)
91
91
92 $ hg cp b b3
92 $ hg cp b b3
93 $ hg mv b b4
93 $ hg mv b b4
94 $ hg ci -A -m 'divergent renames in same changeset'
94 $ hg ci -A -m 'divergent renames in same changeset'
95 $ hg up c761c6948de0
95 $ hg up c761c6948de0
96 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
96 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
97 $ hg up
97 $ hg up
98 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
98 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
99
99
100 Check for issue2642
100 Check for issue2642
101
101
102 $ hg init t
102 $ hg init t
103 $ cd t
103 $ cd t
104
104
105 $ echo c0 > f1
105 $ echo c0 > f1
106 $ hg ci -Aqm0
106 $ hg ci -Aqm0
107
107
108 $ hg up null -q
108 $ hg up null -q
109 $ echo c1 > f1 # backport
109 $ echo c1 > f1 # backport
110 $ hg ci -Aqm1
110 $ hg ci -Aqm1
111 $ hg mv f1 f2
111 $ hg mv f1 f2
112 $ hg ci -qm2
112 $ hg ci -qm2
113
113
114 $ hg up 0 -q
114 $ hg up 0 -q
115 $ hg merge 1 -q --tool internal:local
115 $ hg merge 1 -q --tool internal:local
116 $ hg ci -qm3
116 $ hg ci -qm3
117
117
118 $ hg merge 2
118 $ hg merge 2
119 merging f1 and f2 to f2
119 merging f1 and f2 to f2
120 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
120 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
121 (branch merge, don't forget to commit)
121 (branch merge, don't forget to commit)
122
122
123 $ cat f2
123 $ cat f2
124 c0
124 c0
125
125
126 $ cd ..
126 $ cd ..
127
127
128 Check for issue2089
128 Check for issue2089
129
129
130 $ hg init repo2089
130 $ hg init repo2089
131 $ cd repo2089
131 $ cd repo2089
132
132
133 $ echo c0 > f1
133 $ echo c0 > f1
134 $ hg ci -Aqm0
134 $ hg ci -Aqm0
135
135
136 $ hg up null -q
136 $ hg up null -q
137 $ echo c1 > f1
137 $ echo c1 > f1
138 $ hg ci -Aqm1
138 $ hg ci -Aqm1
139
139
140 $ hg up 0 -q
140 $ hg up 0 -q
141 $ hg merge 1 -q --tool internal:local
141 $ hg merge 1 -q --tool internal:local
142 $ echo c2 > f1
142 $ echo c2 > f1
143 $ hg ci -qm2
143 $ hg ci -qm2
144
144
145 $ hg up 1 -q
145 $ hg up 1 -q
146 $ hg mv f1 f2
146 $ hg mv f1 f2
147 $ hg ci -Aqm3
147 $ hg ci -Aqm3
148
148
149 $ hg up 2 -q
149 $ hg up 2 -q
150 $ hg merge 3
150 $ hg merge 3
151 merging f1 and f2 to f2
151 merging f1 and f2 to f2
152 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
152 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
153 (branch merge, don't forget to commit)
153 (branch merge, don't forget to commit)
154
154
155 $ cat f2
155 $ cat f2
156 c2
156 c2
157
157
158 $ cd ..
158 $ cd ..
159
159
160 Check for issue3074
160 Check for issue3074
161
161
162 $ hg init repo3074
162 $ hg init repo3074
163 $ cd repo3074
163 $ cd repo3074
164 $ echo foo > file
164 $ echo foo > file
165 $ hg add file
165 $ hg add file
166 $ hg commit -m "added file"
166 $ hg commit -m "added file"
167 $ hg mv file newfile
167 $ hg mv file newfile
168 $ hg commit -m "renamed file"
168 $ hg commit -m "renamed file"
169 $ hg update 0
169 $ hg update 0
170 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
170 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
171 $ hg rm file
171 $ hg rm file
172 $ hg commit -m "deleted file"
172 $ hg commit -m "deleted file"
173 created new head
173 created new head
174 $ hg merge --debug
174 $ hg merge --debug
175 searching for copies back to rev 1
175 searching for copies back to rev 1
176 unmatched files in other:
176 unmatched files in other:
177 newfile
177 newfile
178 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
178 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
179 src: 'file' -> dst: 'newfile' %
179 src: 'file' -> dst: 'newfile' %
180 checking for directory renames
180 checking for directory renames
181 file: rename and delete -> rd
181 file: rename and delete -> rd
182 resolving manifests
182 resolving manifests
183 overwrite: False, partial: False
183 overwrite: False, partial: False
184 ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
184 ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
185 newfile: remote created -> g
185 newfile: remote created -> g
186 updating: file 1/2 files (50.00%)
186 updating: file 1/2 files (50.00%)
187 note: possible conflict - file was deleted and renamed to:
187 note: possible conflict - file was deleted and renamed to:
188 newfile
188 newfile
189 updating: newfile 2/2 files (100.00%)
189 updating: newfile 2/2 files (100.00%)
190 getting newfile
190 getting newfile
191 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 (branch merge, don't forget to commit)
192 (branch merge, don't forget to commit)
193 $ hg status
193 $ hg status
194 M newfile
194 M newfile
195 $ cd ..
195 $ cd ..
@@ -1,754 +1,754 b''
1
1
2 $ mkdir -p t
2 $ mkdir -p t
3 $ cd t
3 $ cd t
4 $ cat <<EOF > merge
4 $ cat <<EOF > merge
5 > import sys, os
5 > import sys, os
6 > f = open(sys.argv[1], "wb")
6 > f = open(sys.argv[1], "wb")
7 > f.write("merge %s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
7 > f.write("merge %s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
8 > f.close()
8 > f.close()
9 > EOF
9 > EOF
10
10
11 perform a test merge with possible renaming
11 perform a test merge with possible renaming
12 args:
12 args:
13 $1 = action in local branch
13 $1 = action in local branch
14 $2 = action in remote branch
14 $2 = action in remote branch
15 $3 = action in working dir
15 $3 = action in working dir
16 $4 = expected result
16 $4 = expected result
17
17
18 $ tm()
18 $ tm()
19 > {
19 > {
20 > hg init t
20 > hg init t
21 > cd t
21 > cd t
22 > echo "[merge]" >> .hg/hgrc
22 > echo "[merge]" >> .hg/hgrc
23 > echo "followcopies = 1" >> .hg/hgrc
23 > echo "followcopies = 1" >> .hg/hgrc
24 >
24 >
25 > # base
25 > # base
26 > echo base > a
26 > echo base > a
27 > echo base > rev # used to force commits
27 > echo base > rev # used to force commits
28 > hg add a rev
28 > hg add a rev
29 > hg ci -m "base"
29 > hg ci -m "base"
30 >
30 >
31 > # remote
31 > # remote
32 > echo remote > rev
32 > echo remote > rev
33 > if [ "$2" != "" ] ; then $2 ; fi
33 > if [ "$2" != "" ] ; then $2 ; fi
34 > hg ci -m "remote"
34 > hg ci -m "remote"
35 >
35 >
36 > # local
36 > # local
37 > hg co -q 0
37 > hg co -q 0
38 > echo local > rev
38 > echo local > rev
39 > if [ "$1" != "" ] ; then $1 ; fi
39 > if [ "$1" != "" ] ; then $1 ; fi
40 > hg ci -m "local"
40 > hg ci -m "local"
41 >
41 >
42 > # working dir
42 > # working dir
43 > echo local > rev
43 > echo local > rev
44 > if [ "$3" != "" ] ; then $3 ; fi
44 > if [ "$3" != "" ] ; then $3 ; fi
45 >
45 >
46 > # merge
46 > # merge
47 > echo "--------------"
47 > echo "--------------"
48 > echo "test L:$1 R:$2 W:$3 - $4"
48 > echo "test L:$1 R:$2 W:$3 - $4"
49 > echo "--------------"
49 > echo "--------------"
50 > hg merge -y --debug --traceback --tool="python ../merge"
50 > hg merge -y --debug --traceback --tool="python ../merge"
51 >
51 >
52 > echo "--------------"
52 > echo "--------------"
53 > hg status -camC -X rev
53 > hg status -camC -X rev
54 >
54 >
55 > hg ci -m "merge"
55 > hg ci -m "merge"
56 >
56 >
57 > echo "--------------"
57 > echo "--------------"
58 > echo
58 > echo
59 >
59 >
60 > cd ..
60 > cd ..
61 > rm -r t
61 > rm -r t
62 > }
62 > }
63 $ up() {
63 $ up() {
64 > cp rev $1
64 > cp rev $1
65 > hg add $1 2> /dev/null
65 > hg add $1 2> /dev/null
66 > if [ "$2" != "" ] ; then
66 > if [ "$2" != "" ] ; then
67 > cp rev $2
67 > cp rev $2
68 > hg add $2 2> /dev/null
68 > hg add $2 2> /dev/null
69 > fi
69 > fi
70 > }
70 > }
71 $ uc() { up $1; hg cp $1 $2; } # update + copy
71 $ uc() { up $1; hg cp $1 $2; } # update + copy
72 $ um() { up $1; hg mv $1 $2; }
72 $ um() { up $1; hg mv $1 $2; }
73 $ nc() { hg cp $1 $2; } # just copy
73 $ nc() { hg cp $1 $2; } # just copy
74 $ nm() { hg mv $1 $2; } # just move
74 $ nm() { hg mv $1 $2; } # just move
75 $ tm "up a " "nc a b" " " "1 get local a to b"
75 $ tm "up a " "nc a b" " " "1 get local a to b"
76 created new head
76 created new head
77 --------------
77 --------------
78 test L:up a R:nc a b W: - 1 get local a to b
78 test L:up a R:nc a b W: - 1 get local a to b
79 --------------
79 --------------
80 searching for copies back to rev 1
80 searching for copies back to rev 1
81 unmatched files in other:
81 unmatched files in other:
82 b
82 b
83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
84 src: 'a' -> dst: 'b' *
84 src: 'a' -> dst: 'b' *
85 checking for directory renames
85 checking for directory renames
86 resolving manifests
86 resolving manifests
87 overwrite: False, partial: False
87 overwrite: False, partial: False
88 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
88 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
89 rev: versions differ -> m
89 rev: versions differ -> m
90 a: remote copied to b -> m
90 a: remote copied to b -> m
91 preserving a for resolve of b
91 preserving a for resolve of b
92 preserving rev for resolve of rev
92 preserving rev for resolve of rev
93 updating: a 1/2 files (50.00%)
93 updating: a 1/2 files (50.00%)
94 picked tool 'python ../merge' for b (binary False symlink False)
94 picked tool 'python ../merge' for b (binary False symlink False)
95 merging a and b to b
95 merging a and b to b
96 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
96 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
97 premerge successful
97 premerge successful
98 updating: rev 2/2 files (100.00%)
98 updating: rev 2/2 files (100.00%)
99 picked tool 'python ../merge' for rev (binary False symlink False)
99 picked tool 'python ../merge' for rev (binary False symlink False)
100 merging rev
100 merging rev
101 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
101 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
102 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
102 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
103 (branch merge, don't forget to commit)
103 (branch merge, don't forget to commit)
104 --------------
104 --------------
105 M b
105 M b
106 a
106 a
107 C a
107 C a
108 --------------
108 --------------
109
109
110 $ tm "nc a b" "up a " " " "2 get rem change to a and b"
110 $ tm "nc a b" "up a " " " "2 get rem change to a and b"
111 created new head
111 created new head
112 --------------
112 --------------
113 test L:nc a b R:up a W: - 2 get rem change to a and b
113 test L:nc a b R:up a W: - 2 get rem change to a and b
114 --------------
114 --------------
115 searching for copies back to rev 1
115 searching for copies back to rev 1
116 unmatched files in local:
116 unmatched files in local:
117 b
117 b
118 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
118 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
119 src: 'a' -> dst: 'b' *
119 src: 'a' -> dst: 'b' *
120 checking for directory renames
120 checking for directory renames
121 resolving manifests
121 resolving manifests
122 overwrite: False, partial: False
122 overwrite: False, partial: False
123 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
123 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
124 a: remote is newer -> g
124 a: remote is newer -> g
125 b: local copied/moved to a -> m
125 b: local copied/moved to a -> m
126 rev: versions differ -> m
126 rev: versions differ -> m
127 preserving b for resolve of b
127 preserving b for resolve of b
128 preserving rev for resolve of rev
128 preserving rev for resolve of rev
129 updating: a 1/3 files (33.33%)
129 updating: a 1/3 files (33.33%)
130 getting a
130 getting a
131 updating: b 2/3 files (66.67%)
131 updating: b 2/3 files (66.67%)
132 picked tool 'python ../merge' for b (binary False symlink False)
132 picked tool 'python ../merge' for b (binary False symlink False)
133 merging b and a to b
133 merging b and a to b
134 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
134 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
135 premerge successful
135 premerge successful
136 updating: rev 3/3 files (100.00%)
136 updating: rev 3/3 files (100.00%)
137 picked tool 'python ../merge' for rev (binary False symlink False)
137 picked tool 'python ../merge' for rev (binary False symlink False)
138 merging rev
138 merging rev
139 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
139 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
140 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
140 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
141 (branch merge, don't forget to commit)
141 (branch merge, don't forget to commit)
142 --------------
142 --------------
143 M a
143 M a
144 M b
144 M b
145 a
145 a
146 --------------
146 --------------
147
147
148 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
148 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
149 created new head
149 created new head
150 --------------
150 --------------
151 test L:up a R:nm a b W: - 3 get local a change to b, remove a
151 test L:up a R:nm a b W: - 3 get local a change to b, remove a
152 --------------
152 --------------
153 searching for copies back to rev 1
153 searching for copies back to rev 1
154 unmatched files in other:
154 unmatched files in other:
155 b
155 b
156 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
156 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
157 src: 'a' -> dst: 'b' *
157 src: 'a' -> dst: 'b' *
158 checking for directory renames
158 checking for directory renames
159 resolving manifests
159 resolving manifests
160 overwrite: False, partial: False
160 overwrite: False, partial: False
161 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
161 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
162 rev: versions differ -> m
162 rev: versions differ -> m
163 a: remote moved to b -> m
163 a: remote moved to b -> m
164 preserving a for resolve of b
164 preserving a for resolve of b
165 preserving rev for resolve of rev
165 preserving rev for resolve of rev
166 removing a
166 removing a
167 updating: a 1/2 files (50.00%)
167 updating: a 1/2 files (50.00%)
168 picked tool 'python ../merge' for b (binary False symlink False)
168 picked tool 'python ../merge' for b (binary False symlink False)
169 merging a and b to b
169 merging a and b to b
170 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
170 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
171 premerge successful
171 premerge successful
172 updating: rev 2/2 files (100.00%)
172 updating: rev 2/2 files (100.00%)
173 picked tool 'python ../merge' for rev (binary False symlink False)
173 picked tool 'python ../merge' for rev (binary False symlink False)
174 merging rev
174 merging rev
175 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
175 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
176 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
176 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
177 (branch merge, don't forget to commit)
177 (branch merge, don't forget to commit)
178 --------------
178 --------------
179 M b
179 M b
180 a
180 a
181 --------------
181 --------------
182
182
183 $ tm "nm a b" "up a " " " "4 get remote change to b"
183 $ tm "nm a b" "up a " " " "4 get remote change to b"
184 created new head
184 created new head
185 --------------
185 --------------
186 test L:nm a b R:up a W: - 4 get remote change to b
186 test L:nm a b R:up a W: - 4 get remote change to b
187 --------------
187 --------------
188 searching for copies back to rev 1
188 searching for copies back to rev 1
189 unmatched files in local:
189 unmatched files in local:
190 b
190 b
191 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
191 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
192 src: 'a' -> dst: 'b' *
192 src: 'a' -> dst: 'b' *
193 checking for directory renames
193 checking for directory renames
194 resolving manifests
194 resolving manifests
195 overwrite: False, partial: False
195 overwrite: False, partial: False
196 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
196 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
197 b: local copied/moved to a -> m
197 b: local copied/moved to a -> m
198 rev: versions differ -> m
198 rev: versions differ -> m
199 preserving b for resolve of b
199 preserving b for resolve of b
200 preserving rev for resolve of rev
200 preserving rev for resolve of rev
201 updating: b 1/2 files (50.00%)
201 updating: b 1/2 files (50.00%)
202 picked tool 'python ../merge' for b (binary False symlink False)
202 picked tool 'python ../merge' for b (binary False symlink False)
203 merging b and a to b
203 merging b and a to b
204 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
204 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
205 premerge successful
205 premerge successful
206 updating: rev 2/2 files (100.00%)
206 updating: rev 2/2 files (100.00%)
207 picked tool 'python ../merge' for rev (binary False symlink False)
207 picked tool 'python ../merge' for rev (binary False symlink False)
208 merging rev
208 merging rev
209 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
209 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
210 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
210 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
211 (branch merge, don't forget to commit)
211 (branch merge, don't forget to commit)
212 --------------
212 --------------
213 M b
213 M b
214 a
214 a
215 --------------
215 --------------
216
216
217 $ tm " " "nc a b" " " "5 get b"
217 $ tm " " "nc a b" " " "5 get b"
218 created new head
218 created new head
219 --------------
219 --------------
220 test L: R:nc a b W: - 5 get b
220 test L: R:nc a b W: - 5 get b
221 --------------
221 --------------
222 searching for copies back to rev 1
222 searching for copies back to rev 1
223 unmatched files in other:
223 unmatched files in other:
224 b
224 b
225 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
225 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
226 src: 'a' -> dst: 'b'
226 src: 'a' -> dst: 'b'
227 checking for directory renames
227 checking for directory renames
228 resolving manifests
228 resolving manifests
229 overwrite: False, partial: False
229 overwrite: False, partial: False
230 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
230 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
231 rev: versions differ -> m
231 rev: versions differ -> m
232 b: remote created -> g
232 b: remote created -> g
233 preserving rev for resolve of rev
233 preserving rev for resolve of rev
234 updating: b 1/2 files (50.00%)
234 updating: b 1/2 files (50.00%)
235 getting b
235 getting b
236 updating: rev 2/2 files (100.00%)
236 updating: rev 2/2 files (100.00%)
237 picked tool 'python ../merge' for rev (binary False symlink False)
237 picked tool 'python ../merge' for rev (binary False symlink False)
238 merging rev
238 merging rev
239 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
239 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
240 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
240 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
241 (branch merge, don't forget to commit)
241 (branch merge, don't forget to commit)
242 --------------
242 --------------
243 M b
243 M b
244 C a
244 C a
245 --------------
245 --------------
246
246
247 $ tm "nc a b" " " " " "6 nothing"
247 $ tm "nc a b" " " " " "6 nothing"
248 created new head
248 created new head
249 --------------
249 --------------
250 test L:nc a b R: W: - 6 nothing
250 test L:nc a b R: W: - 6 nothing
251 --------------
251 --------------
252 searching for copies back to rev 1
252 searching for copies back to rev 1
253 unmatched files in local:
253 unmatched files in local:
254 b
254 b
255 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
255 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
256 src: 'a' -> dst: 'b'
256 src: 'a' -> dst: 'b'
257 checking for directory renames
257 checking for directory renames
258 resolving manifests
258 resolving manifests
259 overwrite: False, partial: False
259 overwrite: False, partial: False
260 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
260 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
261 rev: versions differ -> m
261 rev: versions differ -> m
262 preserving rev for resolve of rev
262 preserving rev for resolve of rev
263 updating: rev 1/1 files (100.00%)
263 updating: rev 1/1 files (100.00%)
264 picked tool 'python ../merge' for rev (binary False symlink False)
264 picked tool 'python ../merge' for rev (binary False symlink False)
265 merging rev
265 merging rev
266 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
266 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
267 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
267 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
268 (branch merge, don't forget to commit)
268 (branch merge, don't forget to commit)
269 --------------
269 --------------
270 C a
270 C a
271 C b
271 C b
272 --------------
272 --------------
273
273
274 $ tm " " "nm a b" " " "7 get b"
274 $ tm " " "nm a b" " " "7 get b"
275 created new head
275 created new head
276 --------------
276 --------------
277 test L: R:nm a b W: - 7 get b
277 test L: R:nm a b W: - 7 get b
278 --------------
278 --------------
279 searching for copies back to rev 1
279 searching for copies back to rev 1
280 unmatched files in other:
280 unmatched files in other:
281 b
281 b
282 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
282 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
283 src: 'a' -> dst: 'b'
283 src: 'a' -> dst: 'b'
284 checking for directory renames
284 checking for directory renames
285 resolving manifests
285 resolving manifests
286 overwrite: False, partial: False
286 overwrite: False, partial: False
287 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
287 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
288 a: other deleted -> r
288 a: other deleted -> r
289 rev: versions differ -> m
289 rev: versions differ -> m
290 b: remote created -> g
290 b: remote created -> g
291 preserving rev for resolve of rev
291 preserving rev for resolve of rev
292 updating: a 1/3 files (33.33%)
292 updating: a 1/3 files (33.33%)
293 removing a
293 removing a
294 updating: b 2/3 files (66.67%)
294 updating: b 2/3 files (66.67%)
295 getting b
295 getting b
296 updating: rev 3/3 files (100.00%)
296 updating: rev 3/3 files (100.00%)
297 picked tool 'python ../merge' for rev (binary False symlink False)
297 picked tool 'python ../merge' for rev (binary False symlink False)
298 merging rev
298 merging rev
299 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
299 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
300 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
300 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
301 (branch merge, don't forget to commit)
301 (branch merge, don't forget to commit)
302 --------------
302 --------------
303 M b
303 M b
304 --------------
304 --------------
305
305
306 $ tm "nm a b" " " " " "8 nothing"
306 $ tm "nm a b" " " " " "8 nothing"
307 created new head
307 created new head
308 --------------
308 --------------
309 test L:nm a b R: W: - 8 nothing
309 test L:nm a b R: W: - 8 nothing
310 --------------
310 --------------
311 searching for copies back to rev 1
311 searching for copies back to rev 1
312 unmatched files in local:
312 unmatched files in local:
313 b
313 b
314 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
314 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
315 src: 'a' -> dst: 'b'
315 src: 'a' -> dst: 'b'
316 checking for directory renames
316 checking for directory renames
317 resolving manifests
317 resolving manifests
318 overwrite: False, partial: False
318 overwrite: False, partial: False
319 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
319 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
320 rev: versions differ -> m
320 rev: versions differ -> m
321 preserving rev for resolve of rev
321 preserving rev for resolve of rev
322 updating: rev 1/1 files (100.00%)
322 updating: rev 1/1 files (100.00%)
323 picked tool 'python ../merge' for rev (binary False symlink False)
323 picked tool 'python ../merge' for rev (binary False symlink False)
324 merging rev
324 merging rev
325 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
325 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
326 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
326 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
327 (branch merge, don't forget to commit)
327 (branch merge, don't forget to commit)
328 --------------
328 --------------
329 C b
329 C b
330 --------------
330 --------------
331
331
332 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
332 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
333 created new head
333 created new head
334 --------------
334 --------------
335 test L:um a b R:um a b W: - 9 do merge with ancestor in a
335 test L:um a b R:um a b W: - 9 do merge with ancestor in a
336 --------------
336 --------------
337 searching for copies back to rev 1
337 searching for copies back to rev 1
338 resolving manifests
338 resolving manifests
339 overwrite: False, partial: False
339 overwrite: False, partial: False
340 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
340 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
341 b: versions differ -> m
341 b: versions differ -> m
342 rev: versions differ -> m
342 rev: versions differ -> m
343 preserving b for resolve of b
343 preserving b for resolve of b
344 preserving rev for resolve of rev
344 preserving rev for resolve of rev
345 updating: b 1/2 files (50.00%)
345 updating: b 1/2 files (50.00%)
346 picked tool 'python ../merge' for b (binary False symlink False)
346 picked tool 'python ../merge' for b (binary False symlink False)
347 merging b
347 merging b
348 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
348 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
349 updating: rev 2/2 files (100.00%)
349 updating: rev 2/2 files (100.00%)
350 picked tool 'python ../merge' for rev (binary False symlink False)
350 picked tool 'python ../merge' for rev (binary False symlink False)
351 merging rev
351 merging rev
352 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
352 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
353 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
353 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
354 (branch merge, don't forget to commit)
354 (branch merge, don't forget to commit)
355 --------------
355 --------------
356 M b
356 M b
357 --------------
357 --------------
358
358
359
359
360 m "um a c" "um x c" " " "10 do merge with no ancestor"
360 m "um a c" "um x c" " " "10 do merge with no ancestor"
361
361
362 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
362 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
363 created new head
363 created new head
364 --------------
364 --------------
365 test L:nm a b R:nm a c W: - 11 get c, keep b
365 test L:nm a b R:nm a c W: - 11 get c, keep b
366 --------------
366 --------------
367 searching for copies back to rev 1
367 searching for copies back to rev 1
368 unmatched files in local:
368 unmatched files in local:
369 b
369 b
370 unmatched files in other:
370 unmatched files in other:
371 c
371 c
372 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
372 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
373 src: 'a' -> dst: 'b' !
373 src: 'a' -> dst: 'c' !
374 src: 'a' -> dst: 'c' !
374 src: 'a' -> dst: 'b' !
375 checking for directory renames
375 checking for directory renames
376 a: divergent renames -> dr
376 a: divergent renames -> dr
377 resolving manifests
377 resolving manifests
378 overwrite: False, partial: False
378 overwrite: False, partial: False
379 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
379 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
380 rev: versions differ -> m
380 rev: versions differ -> m
381 c: remote created -> g
381 c: remote created -> g
382 preserving rev for resolve of rev
382 preserving rev for resolve of rev
383 updating: a 1/3 files (33.33%)
383 updating: a 1/3 files (33.33%)
384 note: possible conflict - a was renamed multiple times to:
384 note: possible conflict - a was renamed multiple times to:
385 b
385 b
386 c
386 c
387 updating: c 2/3 files (66.67%)
387 updating: c 2/3 files (66.67%)
388 getting c
388 getting c
389 updating: rev 3/3 files (100.00%)
389 updating: rev 3/3 files (100.00%)
390 picked tool 'python ../merge' for rev (binary False symlink False)
390 picked tool 'python ../merge' for rev (binary False symlink False)
391 merging rev
391 merging rev
392 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
392 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
393 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
393 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
394 (branch merge, don't forget to commit)
394 (branch merge, don't forget to commit)
395 --------------
395 --------------
396 M c
396 M c
397 C b
397 C b
398 --------------
398 --------------
399
399
400 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
400 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
401 created new head
401 created new head
402 --------------
402 --------------
403 test L:nc a b R:up b W: - 12 merge b no ancestor
403 test L:nc a b R:up b W: - 12 merge b no ancestor
404 --------------
404 --------------
405 searching for copies back to rev 1
405 searching for copies back to rev 1
406 resolving manifests
406 resolving manifests
407 overwrite: False, partial: False
407 overwrite: False, partial: False
408 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
408 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
409 b: versions differ -> m
409 b: versions differ -> m
410 rev: versions differ -> m
410 rev: versions differ -> m
411 preserving b for resolve of b
411 preserving b for resolve of b
412 preserving rev for resolve of rev
412 preserving rev for resolve of rev
413 updating: b 1/2 files (50.00%)
413 updating: b 1/2 files (50.00%)
414 picked tool 'python ../merge' for b (binary False symlink False)
414 picked tool 'python ../merge' for b (binary False symlink False)
415 merging b
415 merging b
416 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
416 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
417 updating: rev 2/2 files (100.00%)
417 updating: rev 2/2 files (100.00%)
418 picked tool 'python ../merge' for rev (binary False symlink False)
418 picked tool 'python ../merge' for rev (binary False symlink False)
419 merging rev
419 merging rev
420 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
420 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
421 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
421 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
422 (branch merge, don't forget to commit)
422 (branch merge, don't forget to commit)
423 --------------
423 --------------
424 M b
424 M b
425 C a
425 C a
426 --------------
426 --------------
427
427
428 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
428 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
429 created new head
429 created new head
430 --------------
430 --------------
431 test L:up b R:nm a b W: - 13 merge b no ancestor
431 test L:up b R:nm a b W: - 13 merge b no ancestor
432 --------------
432 --------------
433 searching for copies back to rev 1
433 searching for copies back to rev 1
434 resolving manifests
434 resolving manifests
435 overwrite: False, partial: False
435 overwrite: False, partial: False
436 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
436 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
437 a: other deleted -> r
437 a: other deleted -> r
438 b: versions differ -> m
438 b: versions differ -> m
439 rev: versions differ -> m
439 rev: versions differ -> m
440 preserving b for resolve of b
440 preserving b for resolve of b
441 preserving rev for resolve of rev
441 preserving rev for resolve of rev
442 updating: a 1/3 files (33.33%)
442 updating: a 1/3 files (33.33%)
443 removing a
443 removing a
444 updating: b 2/3 files (66.67%)
444 updating: b 2/3 files (66.67%)
445 picked tool 'python ../merge' for b (binary False symlink False)
445 picked tool 'python ../merge' for b (binary False symlink False)
446 merging b
446 merging b
447 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
447 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
448 updating: rev 3/3 files (100.00%)
448 updating: rev 3/3 files (100.00%)
449 picked tool 'python ../merge' for rev (binary False symlink False)
449 picked tool 'python ../merge' for rev (binary False symlink False)
450 merging rev
450 merging rev
451 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
451 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
452 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
452 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
453 (branch merge, don't forget to commit)
453 (branch merge, don't forget to commit)
454 --------------
454 --------------
455 M b
455 M b
456 --------------
456 --------------
457
457
458 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
458 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
459 created new head
459 created new head
460 --------------
460 --------------
461 test L:nc a b R:up a b W: - 14 merge b no ancestor
461 test L:nc a b R:up a b W: - 14 merge b no ancestor
462 --------------
462 --------------
463 searching for copies back to rev 1
463 searching for copies back to rev 1
464 resolving manifests
464 resolving manifests
465 overwrite: False, partial: False
465 overwrite: False, partial: False
466 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
466 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
467 a: remote is newer -> g
467 a: remote is newer -> g
468 b: versions differ -> m
468 b: versions differ -> m
469 rev: versions differ -> m
469 rev: versions differ -> m
470 preserving b for resolve of b
470 preserving b for resolve of b
471 preserving rev for resolve of rev
471 preserving rev for resolve of rev
472 updating: a 1/3 files (33.33%)
472 updating: a 1/3 files (33.33%)
473 getting a
473 getting a
474 updating: b 2/3 files (66.67%)
474 updating: b 2/3 files (66.67%)
475 picked tool 'python ../merge' for b (binary False symlink False)
475 picked tool 'python ../merge' for b (binary False symlink False)
476 merging b
476 merging b
477 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
477 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
478 updating: rev 3/3 files (100.00%)
478 updating: rev 3/3 files (100.00%)
479 picked tool 'python ../merge' for rev (binary False symlink False)
479 picked tool 'python ../merge' for rev (binary False symlink False)
480 merging rev
480 merging rev
481 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
481 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
482 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
482 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
483 (branch merge, don't forget to commit)
483 (branch merge, don't forget to commit)
484 --------------
484 --------------
485 M a
485 M a
486 M b
486 M b
487 --------------
487 --------------
488
488
489 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
489 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
490 created new head
490 created new head
491 --------------
491 --------------
492 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
492 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
493 --------------
493 --------------
494 searching for copies back to rev 1
494 searching for copies back to rev 1
495 resolving manifests
495 resolving manifests
496 overwrite: False, partial: False
496 overwrite: False, partial: False
497 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
497 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
498 a: other deleted -> r
498 a: other deleted -> r
499 b: versions differ -> m
499 b: versions differ -> m
500 rev: versions differ -> m
500 rev: versions differ -> m
501 preserving b for resolve of b
501 preserving b for resolve of b
502 preserving rev for resolve of rev
502 preserving rev for resolve of rev
503 updating: a 1/3 files (33.33%)
503 updating: a 1/3 files (33.33%)
504 removing a
504 removing a
505 updating: b 2/3 files (66.67%)
505 updating: b 2/3 files (66.67%)
506 picked tool 'python ../merge' for b (binary False symlink False)
506 picked tool 'python ../merge' for b (binary False symlink False)
507 merging b
507 merging b
508 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
508 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
509 updating: rev 3/3 files (100.00%)
509 updating: rev 3/3 files (100.00%)
510 picked tool 'python ../merge' for rev (binary False symlink False)
510 picked tool 'python ../merge' for rev (binary False symlink False)
511 merging rev
511 merging rev
512 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
512 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
513 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
513 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
514 (branch merge, don't forget to commit)
514 (branch merge, don't forget to commit)
515 --------------
515 --------------
516 M b
516 M b
517 --------------
517 --------------
518
518
519 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
519 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
520 created new head
520 created new head
521 --------------
521 --------------
522 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
522 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
523 --------------
523 --------------
524 searching for copies back to rev 1
524 searching for copies back to rev 1
525 resolving manifests
525 resolving manifests
526 overwrite: False, partial: False
526 overwrite: False, partial: False
527 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
527 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
528 a: remote is newer -> g
528 a: remote is newer -> g
529 b: versions differ -> m
529 b: versions differ -> m
530 rev: versions differ -> m
530 rev: versions differ -> m
531 preserving b for resolve of b
531 preserving b for resolve of b
532 preserving rev for resolve of rev
532 preserving rev for resolve of rev
533 updating: a 1/3 files (33.33%)
533 updating: a 1/3 files (33.33%)
534 getting a
534 getting a
535 updating: b 2/3 files (66.67%)
535 updating: b 2/3 files (66.67%)
536 picked tool 'python ../merge' for b (binary False symlink False)
536 picked tool 'python ../merge' for b (binary False symlink False)
537 merging b
537 merging b
538 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
538 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
539 updating: rev 3/3 files (100.00%)
539 updating: rev 3/3 files (100.00%)
540 picked tool 'python ../merge' for rev (binary False symlink False)
540 picked tool 'python ../merge' for rev (binary False symlink False)
541 merging rev
541 merging rev
542 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
542 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
543 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
543 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
544 (branch merge, don't forget to commit)
544 (branch merge, don't forget to commit)
545 --------------
545 --------------
546 M a
546 M a
547 M b
547 M b
548 --------------
548 --------------
549
549
550 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
550 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
551 created new head
551 created new head
552 --------------
552 --------------
553 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
553 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
554 --------------
554 --------------
555 searching for copies back to rev 1
555 searching for copies back to rev 1
556 resolving manifests
556 resolving manifests
557 overwrite: False, partial: False
557 overwrite: False, partial: False
558 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
558 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
559 b: versions differ -> m
559 b: versions differ -> m
560 rev: versions differ -> m
560 rev: versions differ -> m
561 preserving b for resolve of b
561 preserving b for resolve of b
562 preserving rev for resolve of rev
562 preserving rev for resolve of rev
563 updating: b 1/2 files (50.00%)
563 updating: b 1/2 files (50.00%)
564 picked tool 'python ../merge' for b (binary False symlink False)
564 picked tool 'python ../merge' for b (binary False symlink False)
565 merging b
565 merging b
566 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
566 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
567 updating: rev 2/2 files (100.00%)
567 updating: rev 2/2 files (100.00%)
568 picked tool 'python ../merge' for rev (binary False symlink False)
568 picked tool 'python ../merge' for rev (binary False symlink False)
569 merging rev
569 merging rev
570 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
570 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
571 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
571 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
572 (branch merge, don't forget to commit)
572 (branch merge, don't forget to commit)
573 --------------
573 --------------
574 M b
574 M b
575 C a
575 C a
576 --------------
576 --------------
577
577
578 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
578 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
579 created new head
579 created new head
580 --------------
580 --------------
581 test L:nm a b R:up a b W: - 18 merge b no ancestor
581 test L:nm a b R:up a b W: - 18 merge b no ancestor
582 --------------
582 --------------
583 searching for copies back to rev 1
583 searching for copies back to rev 1
584 resolving manifests
584 resolving manifests
585 overwrite: False, partial: False
585 overwrite: False, partial: False
586 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
586 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
587 b: versions differ -> m
587 b: versions differ -> m
588 rev: versions differ -> m
588 rev: versions differ -> m
589 remote changed a which local deleted
589 remote changed a which local deleted
590 use (c)hanged version or leave (d)eleted? c
590 use (c)hanged version or leave (d)eleted? c
591 a: prompt recreating -> g
591 a: prompt recreating -> g
592 preserving b for resolve of b
592 preserving b for resolve of b
593 preserving rev for resolve of rev
593 preserving rev for resolve of rev
594 updating: a 1/3 files (33.33%)
594 updating: a 1/3 files (33.33%)
595 getting a
595 getting a
596 updating: b 2/3 files (66.67%)
596 updating: b 2/3 files (66.67%)
597 picked tool 'python ../merge' for b (binary False symlink False)
597 picked tool 'python ../merge' for b (binary False symlink False)
598 merging b
598 merging b
599 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
599 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
600 updating: rev 3/3 files (100.00%)
600 updating: rev 3/3 files (100.00%)
601 picked tool 'python ../merge' for rev (binary False symlink False)
601 picked tool 'python ../merge' for rev (binary False symlink False)
602 merging rev
602 merging rev
603 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
603 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
604 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
604 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
605 (branch merge, don't forget to commit)
605 (branch merge, don't forget to commit)
606 --------------
606 --------------
607 M a
607 M a
608 M b
608 M b
609 --------------
609 --------------
610
610
611 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
611 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
612 created new head
612 created new head
613 --------------
613 --------------
614 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
614 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
615 --------------
615 --------------
616 searching for copies back to rev 1
616 searching for copies back to rev 1
617 resolving manifests
617 resolving manifests
618 overwrite: False, partial: False
618 overwrite: False, partial: False
619 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
619 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
620 local changed a which remote deleted
620 local changed a which remote deleted
621 use (c)hanged version or (d)elete? c
621 use (c)hanged version or (d)elete? c
622 a: prompt keep -> a
622 a: prompt keep -> a
623 b: versions differ -> m
623 b: versions differ -> m
624 rev: versions differ -> m
624 rev: versions differ -> m
625 preserving b for resolve of b
625 preserving b for resolve of b
626 preserving rev for resolve of rev
626 preserving rev for resolve of rev
627 updating: a 1/3 files (33.33%)
627 updating: a 1/3 files (33.33%)
628 updating: b 2/3 files (66.67%)
628 updating: b 2/3 files (66.67%)
629 picked tool 'python ../merge' for b (binary False symlink False)
629 picked tool 'python ../merge' for b (binary False symlink False)
630 merging b
630 merging b
631 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
631 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
632 updating: rev 3/3 files (100.00%)
632 updating: rev 3/3 files (100.00%)
633 picked tool 'python ../merge' for rev (binary False symlink False)
633 picked tool 'python ../merge' for rev (binary False symlink False)
634 merging rev
634 merging rev
635 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
635 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
636 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
636 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
637 (branch merge, don't forget to commit)
637 (branch merge, don't forget to commit)
638 --------------
638 --------------
639 M b
639 M b
640 C a
640 C a
641 --------------
641 --------------
642
642
643 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
643 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
644 created new head
644 created new head
645 --------------
645 --------------
646 test L:up a R:um a b W: - 20 merge a and b to b, remove a
646 test L:up a R:um a b W: - 20 merge a and b to b, remove a
647 --------------
647 --------------
648 searching for copies back to rev 1
648 searching for copies back to rev 1
649 unmatched files in other:
649 unmatched files in other:
650 b
650 b
651 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
651 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
652 src: 'a' -> dst: 'b' *
652 src: 'a' -> dst: 'b' *
653 checking for directory renames
653 checking for directory renames
654 resolving manifests
654 resolving manifests
655 overwrite: False, partial: False
655 overwrite: False, partial: False
656 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
656 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
657 rev: versions differ -> m
657 rev: versions differ -> m
658 a: remote moved to b -> m
658 a: remote moved to b -> m
659 preserving a for resolve of b
659 preserving a for resolve of b
660 preserving rev for resolve of rev
660 preserving rev for resolve of rev
661 removing a
661 removing a
662 updating: a 1/2 files (50.00%)
662 updating: a 1/2 files (50.00%)
663 picked tool 'python ../merge' for b (binary False symlink False)
663 picked tool 'python ../merge' for b (binary False symlink False)
664 merging a and b to b
664 merging a and b to b
665 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
665 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
666 updating: rev 2/2 files (100.00%)
666 updating: rev 2/2 files (100.00%)
667 picked tool 'python ../merge' for rev (binary False symlink False)
667 picked tool 'python ../merge' for rev (binary False symlink False)
668 merging rev
668 merging rev
669 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
669 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
670 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
670 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
671 (branch merge, don't forget to commit)
671 (branch merge, don't forget to commit)
672 --------------
672 --------------
673 M b
673 M b
674 a
674 a
675 --------------
675 --------------
676
676
677 $ tm "um a b" "up a " " " "21 merge a and b to b"
677 $ tm "um a b" "up a " " " "21 merge a and b to b"
678 created new head
678 created new head
679 --------------
679 --------------
680 test L:um a b R:up a W: - 21 merge a and b to b
680 test L:um a b R:up a W: - 21 merge a and b to b
681 --------------
681 --------------
682 searching for copies back to rev 1
682 searching for copies back to rev 1
683 unmatched files in local:
683 unmatched files in local:
684 b
684 b
685 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
685 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
686 src: 'a' -> dst: 'b' *
686 src: 'a' -> dst: 'b' *
687 checking for directory renames
687 checking for directory renames
688 resolving manifests
688 resolving manifests
689 overwrite: False, partial: False
689 overwrite: False, partial: False
690 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
690 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
691 b: local copied/moved to a -> m
691 b: local copied/moved to a -> m
692 rev: versions differ -> m
692 rev: versions differ -> m
693 preserving b for resolve of b
693 preserving b for resolve of b
694 preserving rev for resolve of rev
694 preserving rev for resolve of rev
695 updating: b 1/2 files (50.00%)
695 updating: b 1/2 files (50.00%)
696 picked tool 'python ../merge' for b (binary False symlink False)
696 picked tool 'python ../merge' for b (binary False symlink False)
697 merging b and a to b
697 merging b and a to b
698 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
698 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
699 updating: rev 2/2 files (100.00%)
699 updating: rev 2/2 files (100.00%)
700 picked tool 'python ../merge' for rev (binary False symlink False)
700 picked tool 'python ../merge' for rev (binary False symlink False)
701 merging rev
701 merging rev
702 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
702 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
703 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
703 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
704 (branch merge, don't forget to commit)
704 (branch merge, don't forget to commit)
705 --------------
705 --------------
706 M b
706 M b
707 a
707 a
708 --------------
708 --------------
709
709
710
710
711 m "nm a b" "um x a" " " "22 get a, keep b"
711 m "nm a b" "um x a" " " "22 get a, keep b"
712
712
713 $ tm "nm a b" "up a c" " " "23 get c, keep b"
713 $ tm "nm a b" "up a c" " " "23 get c, keep b"
714 created new head
714 created new head
715 --------------
715 --------------
716 test L:nm a b R:up a c W: - 23 get c, keep b
716 test L:nm a b R:up a c W: - 23 get c, keep b
717 --------------
717 --------------
718 searching for copies back to rev 1
718 searching for copies back to rev 1
719 unmatched files in local:
719 unmatched files in local:
720 b
720 b
721 unmatched files in other:
721 unmatched files in other:
722 c
722 c
723 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
723 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
724 src: 'a' -> dst: 'b' *
724 src: 'a' -> dst: 'b' *
725 checking for directory renames
725 checking for directory renames
726 resolving manifests
726 resolving manifests
727 overwrite: False, partial: False
727 overwrite: False, partial: False
728 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
728 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
729 b: local copied/moved to a -> m
729 b: local copied/moved to a -> m
730 rev: versions differ -> m
730 rev: versions differ -> m
731 c: remote created -> g
731 c: remote created -> g
732 preserving b for resolve of b
732 preserving b for resolve of b
733 preserving rev for resolve of rev
733 preserving rev for resolve of rev
734 updating: b 1/3 files (33.33%)
734 updating: b 1/3 files (33.33%)
735 picked tool 'python ../merge' for b (binary False symlink False)
735 picked tool 'python ../merge' for b (binary False symlink False)
736 merging b and a to b
736 merging b and a to b
737 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
737 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
738 premerge successful
738 premerge successful
739 updating: c 2/3 files (66.67%)
739 updating: c 2/3 files (66.67%)
740 getting c
740 getting c
741 updating: rev 3/3 files (100.00%)
741 updating: rev 3/3 files (100.00%)
742 picked tool 'python ../merge' for rev (binary False symlink False)
742 picked tool 'python ../merge' for rev (binary False symlink False)
743 merging rev
743 merging rev
744 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
744 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
745 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
745 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
746 (branch merge, don't forget to commit)
746 (branch merge, don't forget to commit)
747 --------------
747 --------------
748 M b
748 M b
749 a
749 a
750 M c
750 M c
751 --------------
751 --------------
752
752
753
753
754 $ cd ..
754 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now