##// END OF EJS Templates
merge: add debug diagnostics for findcopies
Matt Mackall -
r5371:17ed9b9a default
parent child Browse files
Show More
@@ -1,636 +1,659 b''
1 # merge.py - directory-level update/merge handling for Mercurial
1 # merge.py - directory-level update/merge handling for Mercurial
2 #
2 #
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from node import *
8 from node import *
9 from i18n import _
9 from i18n import _
10 import errno, util, os, tempfile, context, heapq
10 import errno, util, os, tempfile, context, heapq
11
11
12 def filemerge(repo, fw, fd, fo, wctx, mctx):
12 def filemerge(repo, fw, fd, fo, wctx, mctx):
13 """perform a 3-way merge in the working directory
13 """perform a 3-way merge in the working directory
14
14
15 fw = original filename in the working directory
15 fw = original filename in the working directory
16 fd = destination filename in the working directory
16 fd = destination filename in the working directory
17 fo = filename in other parent
17 fo = filename in other parent
18 wctx, mctx = working and merge changecontexts
18 wctx, mctx = working and merge changecontexts
19 """
19 """
20
20
21 def temp(prefix, ctx):
21 def temp(prefix, ctx):
22 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
22 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
23 (fd, name) = tempfile.mkstemp(prefix=pre)
23 (fd, name) = tempfile.mkstemp(prefix=pre)
24 data = repo.wwritedata(ctx.path(), ctx.data())
24 data = repo.wwritedata(ctx.path(), ctx.data())
25 f = os.fdopen(fd, "wb")
25 f = os.fdopen(fd, "wb")
26 f.write(data)
26 f.write(data)
27 f.close()
27 f.close()
28 return name
28 return name
29
29
30 fcm = wctx.filectx(fw)
30 fcm = wctx.filectx(fw)
31 fcmdata = wctx.filectx(fd).data()
31 fcmdata = wctx.filectx(fd).data()
32 fco = mctx.filectx(fo)
32 fco = mctx.filectx(fo)
33
33
34 if not fco.cmp(fcmdata): # files identical?
34 if not fco.cmp(fcmdata): # files identical?
35 return None
35 return None
36
36
37 fca = fcm.ancestor(fco)
37 fca = fcm.ancestor(fco)
38 if not fca:
38 if not fca:
39 fca = repo.filectx(fw, fileid=nullrev)
39 fca = repo.filectx(fw, fileid=nullrev)
40 a = repo.wjoin(fd)
40 a = repo.wjoin(fd)
41 b = temp("base", fca)
41 b = temp("base", fca)
42 c = temp("other", fco)
42 c = temp("other", fco)
43
43
44 if fw != fo:
44 if fw != fo:
45 repo.ui.status(_("merging %s and %s\n") % (fw, fo))
45 repo.ui.status(_("merging %s and %s\n") % (fw, fo))
46 else:
46 else:
47 repo.ui.status(_("merging %s\n") % fw)
47 repo.ui.status(_("merging %s\n") % fw)
48
48
49 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
49 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
50
50
51 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
51 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
52 or "hgmerge")
52 or "hgmerge")
53 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
53 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
54 environ={'HG_FILE': fd,
54 environ={'HG_FILE': fd,
55 'HG_MY_NODE': str(wctx.parents()[0]),
55 'HG_MY_NODE': str(wctx.parents()[0]),
56 'HG_OTHER_NODE': str(mctx)})
56 'HG_OTHER_NODE': str(mctx)})
57 if r:
57 if r:
58 repo.ui.warn(_("merging %s failed!\n") % fd)
58 repo.ui.warn(_("merging %s failed!\n") % fd)
59
59
60 os.unlink(b)
60 os.unlink(b)
61 os.unlink(c)
61 os.unlink(c)
62 return r
62 return r
63
63
64 def checkunknown(wctx, mctx):
64 def checkunknown(wctx, mctx):
65 "check for collisions between unknown files and files in mctx"
65 "check for collisions between unknown files and files in mctx"
66 man = mctx.manifest()
66 man = mctx.manifest()
67 for f in wctx.unknown():
67 for f in wctx.unknown():
68 if f in man:
68 if f in man:
69 if mctx.filectx(f).cmp(wctx.filectx(f).data()):
69 if mctx.filectx(f).cmp(wctx.filectx(f).data()):
70 raise util.Abort(_("untracked local file '%s' differs"
70 raise util.Abort(_("untracked local file '%s' differs"
71 " from remote version") % f)
71 " from remote version") % f)
72
72
73 def checkcollision(mctx):
73 def checkcollision(mctx):
74 "check for case folding collisions in the destination context"
74 "check for case folding collisions in the destination context"
75 folded = {}
75 folded = {}
76 for fn in mctx.manifest():
76 for fn in mctx.manifest():
77 fold = fn.lower()
77 fold = fn.lower()
78 if fold in folded:
78 if fold in folded:
79 raise util.Abort(_("case-folding collision between %s and %s")
79 raise util.Abort(_("case-folding collision between %s and %s")
80 % (fn, folded[fold]))
80 % (fn, folded[fold]))
81 folded[fold] = fn
81 folded[fold] = fn
82
82
83 def forgetremoved(wctx, mctx):
83 def forgetremoved(wctx, mctx):
84 """
84 """
85 Forget removed files
85 Forget removed files
86
86
87 If we're jumping between revisions (as opposed to merging), and if
87 If we're jumping between revisions (as opposed to merging), and if
88 neither the working directory nor the target rev has the file,
88 neither the working directory nor the target rev has the file,
89 then we need to remove it from the dirstate, to prevent the
89 then we need to remove it from the dirstate, to prevent the
90 dirstate from listing the file when it is no longer in the
90 dirstate from listing the file when it is no longer in the
91 manifest.
91 manifest.
92 """
92 """
93
93
94 action = []
94 action = []
95 man = mctx.manifest()
95 man = mctx.manifest()
96 for f in wctx.deleted() + wctx.removed():
96 for f in wctx.deleted() + wctx.removed():
97 if f not in man:
97 if f not in man:
98 action.append((f, "f"))
98 action.append((f, "f"))
99
99
100 return action
100 return action
101
101
102 def findcopies(repo, m1, m2, ma, limit):
102 def findcopies(repo, m1, m2, ma, limit):
103 """
103 """
104 Find moves and copies between m1 and m2 back to limit linkrev
104 Find moves and copies between m1 and m2 back to limit linkrev
105 """
105 """
106
106
107 def nonoverlap(d1, d2, d3):
107 def nonoverlap(d1, d2, d3):
108 "Return list of elements in d1 not in d2 or d3"
108 "Return list of elements in d1 not in d2 or d3"
109 l = [d for d in d1 if d not in d3 and d not in d2]
109 l = [d for d in d1 if d not in d3 and d not in d2]
110 l.sort()
110 l.sort()
111 return l
111 return l
112
112
113 def dirname(f):
113 def dirname(f):
114 s = f.rfind("/")
114 s = f.rfind("/")
115 if s == -1:
115 if s == -1:
116 return ""
116 return ""
117 return f[:s]
117 return f[:s]
118
118
119 def dirs(files):
119 def dirs(files):
120 d = {}
120 d = {}
121 for f in files:
121 for f in files:
122 f = dirname(f)
122 f = dirname(f)
123 while f not in d:
123 while f not in d:
124 d[f] = True
124 d[f] = True
125 f = dirname(f)
125 f = dirname(f)
126 return d
126 return d
127
127
128 wctx = repo.workingctx()
128 wctx = repo.workingctx()
129
129
130 def makectx(f, n):
130 def makectx(f, n):
131 if len(n) == 20:
131 if len(n) == 20:
132 return repo.filectx(f, fileid=n)
132 return repo.filectx(f, fileid=n)
133 return wctx.filectx(f)
133 return wctx.filectx(f)
134 ctx = util.cachefunc(makectx)
134 ctx = util.cachefunc(makectx)
135
135
136 def findold(fctx):
136 def findold(fctx):
137 "find files that path was copied from, back to linkrev limit"
137 "find files that path was copied from, back to linkrev limit"
138 old = {}
138 old = {}
139 seen = {}
139 seen = {}
140 orig = fctx.path()
140 orig = fctx.path()
141 visit = [fctx]
141 visit = [fctx]
142 while visit:
142 while visit:
143 fc = visit.pop()
143 fc = visit.pop()
144 s = str(fc)
144 s = str(fc)
145 if s in seen:
145 if s in seen:
146 continue
146 continue
147 seen[s] = 1
147 seen[s] = 1
148 if fc.path() != orig and fc.path() not in old:
148 if fc.path() != orig and fc.path() not in old:
149 old[fc.path()] = 1
149 old[fc.path()] = 1
150 if fc.rev() < limit:
150 if fc.rev() < limit:
151 continue
151 continue
152 visit += fc.parents()
152 visit += fc.parents()
153
153
154 old = old.keys()
154 old = old.keys()
155 old.sort()
155 old.sort()
156 return old
156 return old
157
157
158 copy = {}
158 copy = {}
159 fullcopy = {}
159 fullcopy = {}
160 diverge = {}
160 diverge = {}
161
161
162 def checkcopies(c, man, aman):
162 def checkcopies(c, man, aman):
163 '''check possible copies for filectx c'''
163 '''check possible copies for filectx c'''
164 for of in findold(c):
164 for of in findold(c):
165 fullcopy[c.path()] = of # remember for dir rename detection
165 fullcopy[c.path()] = of # remember for dir rename detection
166 if of not in man: # original file not in other manifest?
166 if of not in man: # original file not in other manifest?
167 if of in ma:
167 if of in ma:
168 diverge.setdefault(of, []).append(c.path())
168 diverge.setdefault(of, []).append(c.path())
169 continue
169 continue
170 # if the original file is unchanged on the other branch,
170 # if the original file is unchanged on the other branch,
171 # no merge needed
171 # no merge needed
172 if man[of] == aman.get(of):
172 if man[of] == aman.get(of):
173 continue
173 continue
174 c2 = ctx(of, man[of])
174 c2 = ctx(of, man[of])
175 ca = c.ancestor(c2)
175 ca = c.ancestor(c2)
176 if not ca: # unrelated?
176 if not ca: # unrelated?
177 continue
177 continue
178 # named changed on only one side?
178 # named changed on only one side?
179 if ca.path() == c.path() or ca.path() == c2.path():
179 if ca.path() == c.path() or ca.path() == c2.path():
180 if c == ca or c2 == ca: # no merge needed, ignore copy
180 if c == ca or c2 == ca: # no merge needed, ignore copy
181 continue
181 continue
182 copy[c.path()] = of
182 copy[c.path()] = of
183
183
184 if not repo.ui.configbool("merge", "followcopies", True):
184 if not repo.ui.configbool("merge", "followcopies", True):
185 return {}, {}
185 return {}, {}
186
186
187 # avoid silly behavior for update from empty dir
187 # avoid silly behavior for update from empty dir
188 if not m1 or not m2 or not ma:
188 if not m1 or not m2 or not ma:
189 return {}, {}
189 return {}, {}
190
190
191 repo.ui.debug(_(" searching for copies back to rev %d\n") % limit)
192
191 u1 = nonoverlap(m1, m2, ma)
193 u1 = nonoverlap(m1, m2, ma)
192 u2 = nonoverlap(m2, m1, ma)
194 u2 = nonoverlap(m2, m1, ma)
193
195
196 if u1:
197 repo.ui.debug(_(" unmatched files in local:\n %s\n")
198 % "\n ".join(u1))
199 if u2:
200 repo.ui.debug(_(" unmatched files in other:\n %s\n")
201 % "\n ".join(u2))
202
194 for f in u1:
203 for f in u1:
195 checkcopies(ctx(f, m1[f]), m2, ma)
204 checkcopies(ctx(f, m1[f]), m2, ma)
196
205
197 for f in u2:
206 for f in u2:
198 checkcopies(ctx(f, m2[f]), m1, ma)
207 checkcopies(ctx(f, m2[f]), m1, ma)
199
208
200 d2 = {}
209 d2 = {}
201 for of, fl in diverge.items():
210 for of, fl in diverge.items():
202 for f in fl:
211 for f in fl:
203 fo = list(fl)
212 fo = list(fl)
204 fo.remove(f)
213 fo.remove(f)
205 d2[f] = (of, fo)
214 d2[f] = (of, fo)
206
215
216 if fullcopy:
217 repo.ui.debug(_(" all copies found (* = to merge, ! = divergent):\n"))
218 for f in fullcopy:
219 note = ""
220 if f in copy: note += "*"
221 if f in diverge: note += "!"
222 repo.ui.debug(_(" %s -> %s %s\n") % (f, fullcopy[f], note))
223
207 if not fullcopy or not repo.ui.configbool("merge", "followdirs", True):
224 if not fullcopy or not repo.ui.configbool("merge", "followdirs", True):
208 return copy, diverge
225 return copy, diverge
209
226
227 repo.ui.debug(_(" checking for directory renames\n"))
228
210 # generate a directory move map
229 # generate a directory move map
211 d1, d2 = dirs(m1), dirs(m2)
230 d1, d2 = dirs(m1), dirs(m2)
212 invalid = {}
231 invalid = {}
213 dirmove = {}
232 dirmove = {}
214
233
215 # examine each file copy for a potential directory move, which is
234 # examine each file copy for a potential directory move, which is
216 # when all the files in a directory are moved to a new directory
235 # when all the files in a directory are moved to a new directory
217 for dst, src in fullcopy.items():
236 for dst, src in fullcopy.items():
218 dsrc, ddst = dirname(src), dirname(dst)
237 dsrc, ddst = dirname(src), dirname(dst)
219 if dsrc in invalid:
238 if dsrc in invalid:
220 # already seen to be uninteresting
239 # already seen to be uninteresting
221 continue
240 continue
222 elif dsrc in d1 and ddst in d1:
241 elif dsrc in d1 and ddst in d1:
223 # directory wasn't entirely moved locally
242 # directory wasn't entirely moved locally
224 invalid[dsrc] = True
243 invalid[dsrc] = True
225 elif dsrc in d2 and ddst in d2:
244 elif dsrc in d2 and ddst in d2:
226 # directory wasn't entirely moved remotely
245 # directory wasn't entirely moved remotely
227 invalid[dsrc] = True
246 invalid[dsrc] = True
228 elif dsrc in dirmove and dirmove[dsrc] != ddst:
247 elif dsrc in dirmove and dirmove[dsrc] != ddst:
229 # files from the same directory moved to two different places
248 # files from the same directory moved to two different places
230 invalid[dsrc] = True
249 invalid[dsrc] = True
231 else:
250 else:
232 # looks good so far
251 # looks good so far
233 dirmove[dsrc + "/"] = ddst + "/"
252 dirmove[dsrc + "/"] = ddst + "/"
234
253
235 for i in invalid:
254 for i in invalid:
236 if i in dirmove:
255 if i in dirmove:
237 del dirmove[i]
256 del dirmove[i]
238
257
239 del d1, d2, invalid
258 del d1, d2, invalid
240
259
241 if not dirmove:
260 if not dirmove:
242 return copy, diverge
261 return copy, diverge
243
262
263 for d in dirmove:
264 repo.ui.debug(_(" dir %s -> %s\n") % (d, dirmove[d]))
265
244 # check unaccounted nonoverlapping files against directory moves
266 # check unaccounted nonoverlapping files against directory moves
245 for f in u1 + u2:
267 for f in u1 + u2:
246 if f not in fullcopy:
268 if f not in fullcopy:
247 for d in dirmove:
269 for d in dirmove:
248 if f.startswith(d):
270 if f.startswith(d):
249 # new file added in a directory that was moved, move it
271 # new file added in a directory that was moved, move it
250 copy[f] = dirmove[d] + f[len(d):]
272 copy[f] = dirmove[d] + f[len(d):]
273 repo.ui.debug(_(" file %s -> %s\n") % (f, copy[f]))
251 break
274 break
252
275
253 return copy, diverge
276 return copy, diverge
254
277
255 def symmetricdifference(repo, rev1, rev2):
278 def symmetricdifference(repo, rev1, rev2):
256 """symmetric difference of the sets of ancestors of rev1 and rev2
279 """symmetric difference of the sets of ancestors of rev1 and rev2
257
280
258 I.e. revisions that are ancestors of rev1 or rev2, but not both.
281 I.e. revisions that are ancestors of rev1 or rev2, but not both.
259 """
282 """
260 # basic idea:
283 # basic idea:
261 # - mark rev1 and rev2 with different colors
284 # - mark rev1 and rev2 with different colors
262 # - walk the graph in topological order with the help of a heap;
285 # - walk the graph in topological order with the help of a heap;
263 # for each revision r:
286 # for each revision r:
264 # - if r has only one color, we want to return it
287 # - if r has only one color, we want to return it
265 # - add colors[r] to its parents
288 # - add colors[r] to its parents
266 #
289 #
267 # We keep track of the number of revisions in the heap that
290 # We keep track of the number of revisions in the heap that
268 # we may be interested in. We stop walking the graph as soon
291 # we may be interested in. We stop walking the graph as soon
269 # as this number reaches 0.
292 # as this number reaches 0.
270 WHITE = 1
293 WHITE = 1
271 BLACK = 2
294 BLACK = 2
272 ALLCOLORS = WHITE | BLACK
295 ALLCOLORS = WHITE | BLACK
273 colors = {rev1: WHITE, rev2: BLACK}
296 colors = {rev1: WHITE, rev2: BLACK}
274
297
275 cl = repo.changelog
298 cl = repo.changelog
276
299
277 visit = [-rev1, -rev2]
300 visit = [-rev1, -rev2]
278 heapq.heapify(visit)
301 heapq.heapify(visit)
279 n_wanted = len(visit)
302 n_wanted = len(visit)
280 ret = []
303 ret = []
281
304
282 while n_wanted:
305 while n_wanted:
283 r = -heapq.heappop(visit)
306 r = -heapq.heappop(visit)
284 wanted = colors[r] != ALLCOLORS
307 wanted = colors[r] != ALLCOLORS
285 n_wanted -= wanted
308 n_wanted -= wanted
286 if wanted:
309 if wanted:
287 ret.append(r)
310 ret.append(r)
288
311
289 for p in cl.parentrevs(r):
312 for p in cl.parentrevs(r):
290 if p == nullrev:
313 if p == nullrev:
291 continue
314 continue
292 if p not in colors:
315 if p not in colors:
293 # first time we see p; add it to visit
316 # first time we see p; add it to visit
294 n_wanted += wanted
317 n_wanted += wanted
295 colors[p] = colors[r]
318 colors[p] = colors[r]
296 heapq.heappush(visit, -p)
319 heapq.heappush(visit, -p)
297 elif colors[p] != ALLCOLORS and colors[p] != colors[r]:
320 elif colors[p] != ALLCOLORS and colors[p] != colors[r]:
298 # at first we thought we wanted p, but now
321 # at first we thought we wanted p, but now
299 # we know we don't really want it
322 # we know we don't really want it
300 n_wanted -= 1
323 n_wanted -= 1
301 colors[p] |= colors[r]
324 colors[p] |= colors[r]
302
325
303 del colors[r]
326 del colors[r]
304
327
305 return ret
328 return ret
306
329
307 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
330 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
308 """
331 """
309 Merge p1 and p2 with ancestor ma and generate merge action list
332 Merge p1 and p2 with ancestor ma and generate merge action list
310
333
311 overwrite = whether we clobber working files
334 overwrite = whether we clobber working files
312 partial = function to filter file lists
335 partial = function to filter file lists
313 """
336 """
314
337
315 repo.ui.note(_("resolving manifests\n"))
338 repo.ui.note(_("resolving manifests\n"))
316 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
339 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
317 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
340 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
318
341
319 m1 = p1.manifest()
342 m1 = p1.manifest()
320 m2 = p2.manifest()
343 m2 = p2.manifest()
321 ma = pa.manifest()
344 ma = pa.manifest()
322 backwards = (pa == p2)
345 backwards = (pa == p2)
323 action = []
346 action = []
324 copy = {}
347 copy = {}
325 diverge = {}
348 diverge = {}
326
349
327 def fmerge(f, f2=None, fa=None):
350 def fmerge(f, f2=None, fa=None):
328 """merge flags"""
351 """merge flags"""
329 if not f2:
352 if not f2:
330 f2 = f
353 f2 = f
331 fa = f
354 fa = f
332 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
355 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
333 if ((a^b) | (a^c)) ^ a:
356 if ((a^b) | (a^c)) ^ a:
334 return 'x'
357 return 'x'
335 a, b, c = ma.linkf(fa), m1.linkf(f), m2.linkf(f2)
358 a, b, c = ma.linkf(fa), m1.linkf(f), m2.linkf(f2)
336 if ((a^b) | (a^c)) ^ a:
359 if ((a^b) | (a^c)) ^ a:
337 return 'l'
360 return 'l'
338 return ''
361 return ''
339
362
340 def act(msg, m, f, *args):
363 def act(msg, m, f, *args):
341 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
364 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
342 action.append((f, m) + args)
365 action.append((f, m) + args)
343
366
344 if not (backwards or overwrite):
367 if not (backwards or overwrite):
345 rev1 = p1.rev()
368 rev1 = p1.rev()
346 if rev1 is None:
369 if rev1 is None:
347 # p1 is a workingctx
370 # p1 is a workingctx
348 rev1 = p1.parents()[0].rev()
371 rev1 = p1.parents()[0].rev()
349 limit = min(symmetricdifference(repo, rev1, p2.rev()))
372 limit = min(symmetricdifference(repo, rev1, p2.rev()))
350 copy, diverge = findcopies(repo, m1, m2, ma, limit)
373 copy, diverge = findcopies(repo, m1, m2, ma, limit)
351
374
352 for of, fl in diverge.items():
375 for of, fl in diverge.items():
353 act("divergent renames", "dr", of, fl)
376 act("divergent renames", "dr", of, fl)
354
377
355 copied = dict.fromkeys(copy.values())
378 copied = dict.fromkeys(copy.values())
356
379
357 # Compare manifests
380 # Compare manifests
358 for f, n in m1.iteritems():
381 for f, n in m1.iteritems():
359 if partial and not partial(f):
382 if partial and not partial(f):
360 continue
383 continue
361 if f in m2:
384 if f in m2:
362 # are files different?
385 # are files different?
363 if n != m2[f]:
386 if n != m2[f]:
364 a = ma.get(f, nullid)
387 a = ma.get(f, nullid)
365 # are both different from the ancestor?
388 # are both different from the ancestor?
366 if not overwrite and n != a and m2[f] != a:
389 if not overwrite and n != a and m2[f] != a:
367 act("versions differ", "m", f, f, f, fmerge(f), False)
390 act("versions differ", "m", f, f, f, fmerge(f), False)
368 # are we clobbering?
391 # are we clobbering?
369 # is remote's version newer?
392 # is remote's version newer?
370 # or are we going back in time and clean?
393 # or are we going back in time and clean?
371 elif overwrite or m2[f] != a or (backwards and not n[20:]):
394 elif overwrite or m2[f] != a or (backwards and not n[20:]):
372 act("remote is newer", "g", f, m2.flags(f))
395 act("remote is newer", "g", f, m2.flags(f))
373 # local is newer, not overwrite, check mode bits
396 # local is newer, not overwrite, check mode bits
374 elif fmerge(f) != m1.flags(f):
397 elif fmerge(f) != m1.flags(f):
375 act("update permissions", "e", f, m2.flags(f))
398 act("update permissions", "e", f, m2.flags(f))
376 # contents same, check mode bits
399 # contents same, check mode bits
377 elif m1.flags(f) != m2.flags(f):
400 elif m1.flags(f) != m2.flags(f):
378 if overwrite or fmerge(f) != m1.flags(f):
401 if overwrite or fmerge(f) != m1.flags(f):
379 act("update permissions", "e", f, m2.flags(f))
402 act("update permissions", "e", f, m2.flags(f))
380 elif f in copied:
403 elif f in copied:
381 continue
404 continue
382 elif f in copy:
405 elif f in copy:
383 f2 = copy[f]
406 f2 = copy[f]
384 if f2 not in m2: # directory rename
407 if f2 not in m2: # directory rename
385 act("remote renamed directory to " + f2, "d",
408 act("remote renamed directory to " + f2, "d",
386 f, None, f2, m1.flags(f))
409 f, None, f2, m1.flags(f))
387 elif f2 in m1: # case 2 A,B/B/B
410 elif f2 in m1: # case 2 A,B/B/B
388 act("local copied to " + f2, "m",
411 act("local copied to " + f2, "m",
389 f, f2, f, fmerge(f, f2, f2), False)
412 f, f2, f, fmerge(f, f2, f2), False)
390 else: # case 4,21 A/B/B
413 else: # case 4,21 A/B/B
391 act("local moved to " + f2, "m",
414 act("local moved to " + f2, "m",
392 f, f2, f, fmerge(f, f2, f2), False)
415 f, f2, f, fmerge(f, f2, f2), False)
393 elif f in ma:
416 elif f in ma:
394 if n != ma[f] and not overwrite:
417 if n != ma[f] and not overwrite:
395 if repo.ui.prompt(
418 if repo.ui.prompt(
396 (_(" local changed %s which remote deleted\n") % f) +
419 (_(" local changed %s which remote deleted\n") % f) +
397 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
420 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
398 act("prompt delete", "r", f)
421 act("prompt delete", "r", f)
399 else:
422 else:
400 act("other deleted", "r", f)
423 act("other deleted", "r", f)
401 else:
424 else:
402 # file is created on branch or in working directory
425 # file is created on branch or in working directory
403 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
426 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
404 act("remote deleted", "r", f)
427 act("remote deleted", "r", f)
405
428
406 for f, n in m2.iteritems():
429 for f, n in m2.iteritems():
407 if partial and not partial(f):
430 if partial and not partial(f):
408 continue
431 continue
409 if f in m1:
432 if f in m1:
410 continue
433 continue
411 if f in copied:
434 if f in copied:
412 continue
435 continue
413 if f in copy:
436 if f in copy:
414 f2 = copy[f]
437 f2 = copy[f]
415 if f2 not in m1: # directory rename
438 if f2 not in m1: # directory rename
416 act("local renamed directory to " + f2, "d",
439 act("local renamed directory to " + f2, "d",
417 None, f, f2, m2.flags(f))
440 None, f, f2, m2.flags(f))
418 elif f2 in m2: # rename case 1, A/A,B/A
441 elif f2 in m2: # rename case 1, A/A,B/A
419 act("remote copied to " + f, "m",
442 act("remote copied to " + f, "m",
420 f2, f, f, fmerge(f2, f, f2), False)
443 f2, f, f, fmerge(f2, f, f2), False)
421 else: # case 3,20 A/B/A
444 else: # case 3,20 A/B/A
422 act("remote moved to " + f, "m",
445 act("remote moved to " + f, "m",
423 f2, f, f, fmerge(f2, f, f2), True)
446 f2, f, f, fmerge(f2, f, f2), True)
424 elif f in ma:
447 elif f in ma:
425 if overwrite or backwards:
448 if overwrite or backwards:
426 act("recreating", "g", f, m2.flags(f))
449 act("recreating", "g", f, m2.flags(f))
427 elif n != ma[f]:
450 elif n != ma[f]:
428 if repo.ui.prompt(
451 if repo.ui.prompt(
429 (_("remote changed %s which local deleted\n") % f) +
452 (_("remote changed %s which local deleted\n") % f) +
430 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
453 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
431 act("prompt recreating", "g", f, m2.flags(f))
454 act("prompt recreating", "g", f, m2.flags(f))
432 else:
455 else:
433 act("remote created", "g", f, m2.flags(f))
456 act("remote created", "g", f, m2.flags(f))
434
457
435 return action
458 return action
436
459
437 def applyupdates(repo, action, wctx, mctx):
460 def applyupdates(repo, action, wctx, mctx):
438 "apply the merge action list to the working directory"
461 "apply the merge action list to the working directory"
439
462
440 updated, merged, removed, unresolved = 0, 0, 0, 0
463 updated, merged, removed, unresolved = 0, 0, 0, 0
441 action.sort()
464 action.sort()
442 # prescan for copy/renames
465 # prescan for copy/renames
443 for a in action:
466 for a in action:
444 f, m = a[:2]
467 f, m = a[:2]
445 if m == 'm': # merge
468 if m == 'm': # merge
446 f2, fd, flags, move = a[2:]
469 f2, fd, flags, move = a[2:]
447 if f != fd:
470 if f != fd:
448 repo.ui.debug(_("copying %s to %s\n") % (f, fd))
471 repo.ui.debug(_("copying %s to %s\n") % (f, fd))
449 repo.wwrite(fd, repo.wread(f), flags)
472 repo.wwrite(fd, repo.wread(f), flags)
450
473
451 audit_path = util.path_auditor(repo.root)
474 audit_path = util.path_auditor(repo.root)
452
475
453 for a in action:
476 for a in action:
454 f, m = a[:2]
477 f, m = a[:2]
455 if f and f[0] == "/":
478 if f and f[0] == "/":
456 continue
479 continue
457 if m == "r": # remove
480 if m == "r": # remove
458 repo.ui.note(_("removing %s\n") % f)
481 repo.ui.note(_("removing %s\n") % f)
459 audit_path(f)
482 audit_path(f)
460 try:
483 try:
461 util.unlink(repo.wjoin(f))
484 util.unlink(repo.wjoin(f))
462 except OSError, inst:
485 except OSError, inst:
463 if inst.errno != errno.ENOENT:
486 if inst.errno != errno.ENOENT:
464 repo.ui.warn(_("update failed to remove %s: %s!\n") %
487 repo.ui.warn(_("update failed to remove %s: %s!\n") %
465 (f, inst.strerror))
488 (f, inst.strerror))
466 removed += 1
489 removed += 1
467 elif m == "m": # merge
490 elif m == "m": # merge
468 f2, fd, flags, move = a[2:]
491 f2, fd, flags, move = a[2:]
469 r = filemerge(repo, f, fd, f2, wctx, mctx)
492 r = filemerge(repo, f, fd, f2, wctx, mctx)
470 if r > 0:
493 if r > 0:
471 unresolved += 1
494 unresolved += 1
472 else:
495 else:
473 if r is None:
496 if r is None:
474 updated += 1
497 updated += 1
475 else:
498 else:
476 merged += 1
499 merged += 1
477 util.set_exec(repo.wjoin(fd), "x" in flags)
500 util.set_exec(repo.wjoin(fd), "x" in flags)
478 if f != fd and move and util.lexists(repo.wjoin(f)):
501 if f != fd and move and util.lexists(repo.wjoin(f)):
479 repo.ui.debug(_("removing %s\n") % f)
502 repo.ui.debug(_("removing %s\n") % f)
480 os.unlink(repo.wjoin(f))
503 os.unlink(repo.wjoin(f))
481 elif m == "g": # get
504 elif m == "g": # get
482 flags = a[2]
505 flags = a[2]
483 repo.ui.note(_("getting %s\n") % f)
506 repo.ui.note(_("getting %s\n") % f)
484 t = mctx.filectx(f).data()
507 t = mctx.filectx(f).data()
485 repo.wwrite(f, t, flags)
508 repo.wwrite(f, t, flags)
486 updated += 1
509 updated += 1
487 elif m == "d": # directory rename
510 elif m == "d": # directory rename
488 f2, fd, flags = a[2:]
511 f2, fd, flags = a[2:]
489 if f:
512 if f:
490 repo.ui.note(_("moving %s to %s\n") % (f, fd))
513 repo.ui.note(_("moving %s to %s\n") % (f, fd))
491 t = wctx.filectx(f).data()
514 t = wctx.filectx(f).data()
492 repo.wwrite(fd, t, flags)
515 repo.wwrite(fd, t, flags)
493 util.unlink(repo.wjoin(f))
516 util.unlink(repo.wjoin(f))
494 if f2:
517 if f2:
495 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
518 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
496 t = mctx.filectx(f2).data()
519 t = mctx.filectx(f2).data()
497 repo.wwrite(fd, t, flags)
520 repo.wwrite(fd, t, flags)
498 updated += 1
521 updated += 1
499 elif m == "dr": # divergent renames
522 elif m == "dr": # divergent renames
500 fl = a[2]
523 fl = a[2]
501 repo.ui.warn("warning: detected divergent renames of %s to:\n" % f)
524 repo.ui.warn("warning: detected divergent renames of %s to:\n" % f)
502 for nf in fl:
525 for nf in fl:
503 repo.ui.warn(" %s\n" % nf)
526 repo.ui.warn(" %s\n" % nf)
504 elif m == "e": # exec
527 elif m == "e": # exec
505 flags = a[2]
528 flags = a[2]
506 util.set_exec(repo.wjoin(f), flags)
529 util.set_exec(repo.wjoin(f), flags)
507
530
508 return updated, merged, removed, unresolved
531 return updated, merged, removed, unresolved
509
532
510 def recordupdates(repo, action, branchmerge):
533 def recordupdates(repo, action, branchmerge):
511 "record merge actions to the dirstate"
534 "record merge actions to the dirstate"
512
535
513 for a in action:
536 for a in action:
514 f, m = a[:2]
537 f, m = a[:2]
515 if m == "r": # remove
538 if m == "r": # remove
516 if branchmerge:
539 if branchmerge:
517 repo.dirstate.remove(f)
540 repo.dirstate.remove(f)
518 else:
541 else:
519 repo.dirstate.forget(f)
542 repo.dirstate.forget(f)
520 elif m == "f": # forget
543 elif m == "f": # forget
521 repo.dirstate.forget(f)
544 repo.dirstate.forget(f)
522 elif m in "ge": # get or exec change
545 elif m in "ge": # get or exec change
523 if branchmerge:
546 if branchmerge:
524 repo.dirstate.normaldirty(f)
547 repo.dirstate.normaldirty(f)
525 else:
548 else:
526 repo.dirstate.normal(f)
549 repo.dirstate.normal(f)
527 elif m == "m": # merge
550 elif m == "m": # merge
528 f2, fd, flag, move = a[2:]
551 f2, fd, flag, move = a[2:]
529 if branchmerge:
552 if branchmerge:
530 # We've done a branch merge, mark this file as merged
553 # We've done a branch merge, mark this file as merged
531 # so that we properly record the merger later
554 # so that we properly record the merger later
532 repo.dirstate.merge(fd)
555 repo.dirstate.merge(fd)
533 if f != f2: # copy/rename
556 if f != f2: # copy/rename
534 if move:
557 if move:
535 repo.dirstate.remove(f)
558 repo.dirstate.remove(f)
536 if f != fd:
559 if f != fd:
537 repo.dirstate.copy(f, fd)
560 repo.dirstate.copy(f, fd)
538 else:
561 else:
539 repo.dirstate.copy(f2, fd)
562 repo.dirstate.copy(f2, fd)
540 else:
563 else:
541 # We've update-merged a locally modified file, so
564 # We've update-merged a locally modified file, so
542 # we set the dirstate to emulate a normal checkout
565 # we set the dirstate to emulate a normal checkout
543 # of that file some time in the past. Thus our
566 # of that file some time in the past. Thus our
544 # merge will appear as a normal local file
567 # merge will appear as a normal local file
545 # modification.
568 # modification.
546 repo.dirstate.normallookup(fd)
569 repo.dirstate.normallookup(fd)
547 if move:
570 if move:
548 repo.dirstate.forget(f)
571 repo.dirstate.forget(f)
549 elif m == "d": # directory rename
572 elif m == "d": # directory rename
550 f2, fd, flag = a[2:]
573 f2, fd, flag = a[2:]
551 if not f2 and f not in repo.dirstate:
574 if not f2 and f not in repo.dirstate:
552 # untracked file moved
575 # untracked file moved
553 continue
576 continue
554 if branchmerge:
577 if branchmerge:
555 repo.dirstate.add(fd)
578 repo.dirstate.add(fd)
556 if f:
579 if f:
557 repo.dirstate.remove(f)
580 repo.dirstate.remove(f)
558 repo.dirstate.copy(f, fd)
581 repo.dirstate.copy(f, fd)
559 if f2:
582 if f2:
560 repo.dirstate.copy(f2, fd)
583 repo.dirstate.copy(f2, fd)
561 else:
584 else:
562 repo.dirstate.normal(fd)
585 repo.dirstate.normal(fd)
563 if f:
586 if f:
564 repo.dirstate.forget(f)
587 repo.dirstate.forget(f)
565
588
566 def update(repo, node, branchmerge, force, partial):
589 def update(repo, node, branchmerge, force, partial):
567 """
590 """
568 Perform a merge between the working directory and the given node
591 Perform a merge between the working directory and the given node
569
592
570 branchmerge = whether to merge between branches
593 branchmerge = whether to merge between branches
571 force = whether to force branch merging or file overwriting
594 force = whether to force branch merging or file overwriting
572 partial = a function to filter file lists (dirstate not updated)
595 partial = a function to filter file lists (dirstate not updated)
573 """
596 """
574
597
575 wlock = repo.wlock()
598 wlock = repo.wlock()
576 try:
599 try:
577 wc = repo.workingctx()
600 wc = repo.workingctx()
578 if node is None:
601 if node is None:
579 # tip of current branch
602 # tip of current branch
580 try:
603 try:
581 node = repo.branchtags()[wc.branch()]
604 node = repo.branchtags()[wc.branch()]
582 except KeyError:
605 except KeyError:
583 raise util.Abort(_("branch %s not found") % wc.branch())
606 raise util.Abort(_("branch %s not found") % wc.branch())
584 overwrite = force and not branchmerge
607 overwrite = force and not branchmerge
585 forcemerge = force and branchmerge
608 forcemerge = force and branchmerge
586 pl = wc.parents()
609 pl = wc.parents()
587 p1, p2 = pl[0], repo.changectx(node)
610 p1, p2 = pl[0], repo.changectx(node)
588 pa = p1.ancestor(p2)
611 pa = p1.ancestor(p2)
589 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
612 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
590 fastforward = False
613 fastforward = False
591
614
592 ### check phase
615 ### check phase
593 if not overwrite and len(pl) > 1:
616 if not overwrite and len(pl) > 1:
594 raise util.Abort(_("outstanding uncommitted merges"))
617 raise util.Abort(_("outstanding uncommitted merges"))
595 if pa == p1 or pa == p2: # is there a linear path from p1 to p2?
618 if pa == p1 or pa == p2: # is there a linear path from p1 to p2?
596 if branchmerge:
619 if branchmerge:
597 if p1.branch() != p2.branch() and pa != p2:
620 if p1.branch() != p2.branch() and pa != p2:
598 fastforward = True
621 fastforward = True
599 else:
622 else:
600 raise util.Abort(_("there is nothing to merge, just use "
623 raise util.Abort(_("there is nothing to merge, just use "
601 "'hg update' or look at 'hg heads'"))
624 "'hg update' or look at 'hg heads'"))
602 elif not (overwrite or branchmerge):
625 elif not (overwrite or branchmerge):
603 raise util.Abort(_("update spans branches, use 'hg merge' "
626 raise util.Abort(_("update spans branches, use 'hg merge' "
604 "or 'hg update -C' to lose changes"))
627 "or 'hg update -C' to lose changes"))
605 if branchmerge and not forcemerge:
628 if branchmerge and not forcemerge:
606 if wc.files():
629 if wc.files():
607 raise util.Abort(_("outstanding uncommitted changes"))
630 raise util.Abort(_("outstanding uncommitted changes"))
608
631
609 ### calculate phase
632 ### calculate phase
610 action = []
633 action = []
611 if not force:
634 if not force:
612 checkunknown(wc, p2)
635 checkunknown(wc, p2)
613 if not util.checkfolding(repo.path):
636 if not util.checkfolding(repo.path):
614 checkcollision(p2)
637 checkcollision(p2)
615 if not branchmerge:
638 if not branchmerge:
616 action += forgetremoved(wc, p2)
639 action += forgetremoved(wc, p2)
617 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
640 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
618
641
619 ### apply phase
642 ### apply phase
620 if not branchmerge: # just jump to the new rev
643 if not branchmerge: # just jump to the new rev
621 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
644 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
622 if not partial:
645 if not partial:
623 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
646 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
624
647
625 stats = applyupdates(repo, action, wc, p2)
648 stats = applyupdates(repo, action, wc, p2)
626
649
627 if not partial:
650 if not partial:
628 recordupdates(repo, action, branchmerge)
651 recordupdates(repo, action, branchmerge)
629 repo.dirstate.setparents(fp1, fp2)
652 repo.dirstate.setparents(fp1, fp2)
630 if not branchmerge and not fastforward:
653 if not branchmerge and not fastforward:
631 repo.dirstate.setbranch(p2.branch())
654 repo.dirstate.setbranch(p2.branch())
632 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
655 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
633
656
634 return stats
657 return stats
635 finally:
658 finally:
636 del wlock
659 del wlock
@@ -1,23 +1,31 b''
1 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
2 resolving manifests
2 resolving manifests
3 overwrite None partial False
3 overwrite None partial False
4 ancestor 583c7b748052 local fb3948d97f07+ remote 40da226db0f0
4 ancestor 583c7b748052 local fb3948d97f07+ remote 40da226db0f0
5 searching for copies back to rev 1
6 unmatched files in other:
7 b
8 c
9 all copies found (* = to merge, ! = divergent):
10 c -> a *
11 b -> a *
12 checking for directory renames
5 a: remote moved to c -> m
13 a: remote moved to c -> m
6 a: remote moved to b -> m
14 a: remote moved to b -> m
7 copying a to b
15 copying a to b
8 copying a to c
16 copying a to c
9 merging a and b
17 merging a and b
10 my a@fb3948d97f07+ other b@40da226db0f0 ancestor a@583c7b748052
18 my a@fb3948d97f07+ other b@40da226db0f0 ancestor a@583c7b748052
11 removing a
19 removing a
12 merging a and c
20 merging a and c
13 my a@fb3948d97f07+ other c@40da226db0f0 ancestor a@583c7b748052
21 my a@fb3948d97f07+ other c@40da226db0f0 ancestor a@583c7b748052
14 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
22 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
15 (branch merge, don't forget to commit)
23 (branch merge, don't forget to commit)
16 -- b --
24 -- b --
17 0
25 0
18 1
26 1
19 2
27 2
20 -- c --
28 -- c --
21 0
29 0
22 1
30 1
23 2
31 2
@@ -1,20 +1,26 b''
1 resolving manifests
1 resolving manifests
2 overwrite None partial False
2 overwrite None partial False
3 ancestor 310fd17130da local 2092631ce82b+ remote 7731dad1c2b9
3 ancestor 310fd17130da local 2092631ce82b+ remote 7731dad1c2b9
4 searching for copies back to rev 1
5 unmatched files in other:
6 bar
7 all copies found (* = to merge, ! = divergent):
8 bar -> foo *
9 checking for directory renames
4 foo: versions differ -> m
10 foo: versions differ -> m
5 foo: remote copied to bar -> m
11 foo: remote copied to bar -> m
6 copying foo to bar
12 copying foo to bar
7 merging foo and bar
13 merging foo and bar
8 my foo@2092631ce82b+ other bar@7731dad1c2b9 ancestor foo@310fd17130da
14 my foo@2092631ce82b+ other bar@7731dad1c2b9 ancestor foo@310fd17130da
9 merging foo
15 merging foo
10 my foo@2092631ce82b+ other foo@7731dad1c2b9 ancestor foo@310fd17130da
16 my foo@2092631ce82b+ other foo@7731dad1c2b9 ancestor foo@310fd17130da
11 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
17 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
12 (branch merge, don't forget to commit)
18 (branch merge, don't forget to commit)
13 -- foo --
19 -- foo --
14 line 0
20 line 0
15 line 1
21 line 1
16 line 2-1
22 line 2-1
17 -- bar --
23 -- bar --
18 line 0
24 line 0
19 line 1
25 line 1
20 line 2-2
26 line 2-2
@@ -1,17 +1,20 b''
1 reverting foo
1 reverting foo
2 changeset 2:4d9e78aaceee backs out changeset 1:b515023e500e
2 changeset 2:4d9e78aaceee backs out changeset 1:b515023e500e
3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 resolving manifests
4 resolving manifests
5 overwrite None partial False
5 overwrite None partial False
6 ancestor bbd179dfa0a7 local 71766447bdbb+ remote 4d9e78aaceee
6 ancestor bbd179dfa0a7 local 71766447bdbb+ remote 4d9e78aaceee
7 searching for copies back to rev 1
8 unmatched files in local:
9 bar
7 foo: remote is newer -> g
10 foo: remote is newer -> g
8 getting foo
11 getting foo
9 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
10 (branch merge, don't forget to commit)
13 (branch merge, don't forget to commit)
11 n 0 -2 unset foo
14 n 0 -2 unset foo
12 M foo
15 M foo
13 c6fc755d7e68f49f880599da29f15add41f42f5a 644 foo
16 c6fc755d7e68f49f880599da29f15add41f42f5a 644 foo
14 rev offset length base linkrev nodeid p1 p2
17 rev offset length base linkrev nodeid p1 p2
15 0 0 5 0 0 2ed2a3912a0b 000000000000 000000000000
18 0 0 5 0 0 2ed2a3912a0b 000000000000 000000000000
16 1 5 9 1 1 6f4310b00b9a 2ed2a3912a0b 000000000000
19 1 5 9 1 1 6f4310b00b9a 2ed2a3912a0b 000000000000
17 2 14 5 2 2 c6fc755d7e68 6f4310b00b9a 000000000000
20 2 14 5 2 2 c6fc755d7e68 6f4310b00b9a 000000000000
@@ -1,33 +1,51 b''
1 adding 1
1 adding 1
2 adding 2
2 adding 2
3 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
3 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
4 resolving manifests
4 resolving manifests
5 overwrite None partial False
5 overwrite None partial False
6 ancestor 81f4b099af3d local c64f439569a9+ remote 2f8037f47a5c
6 ancestor 81f4b099af3d local c64f439569a9+ remote 2f8037f47a5c
7 searching for copies back to rev 1
8 unmatched files in other:
9 1a
10 all copies found (* = to merge, ! = divergent):
11 1a -> 1
12 checking for directory renames
7 1: other deleted -> r
13 1: other deleted -> r
8 1a: remote created -> g
14 1a: remote created -> g
9 removing 1
15 removing 1
10 getting 1a
16 getting 1a
11 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
17 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
12 (branch merge, don't forget to commit)
18 (branch merge, don't forget to commit)
13 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
19 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
14 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
20 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
15 resolving manifests
21 resolving manifests
16 overwrite None partial False
22 overwrite None partial False
17 ancestor c64f439569a9 local ac7575e3c052+ remote 746e9549ea96
23 ancestor c64f439569a9 local ac7575e3c052+ remote 746e9549ea96
24 searching for copies back to rev 1
25 unmatched files in local:
26 1a
27 all copies found (* = to merge, ! = divergent):
28 1a -> 1 *
29 checking for directory renames
18 1a: local moved to 1 -> m
30 1a: local moved to 1 -> m
19 merging 1a and 1
31 merging 1a and 1
20 my 1a@ac7575e3c052+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
32 my 1a@ac7575e3c052+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
21 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
33 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
22 (branch merge, don't forget to commit)
34 (branch merge, don't forget to commit)
23 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
35 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
24 resolving manifests
36 resolving manifests
25 overwrite None partial False
37 overwrite None partial False
26 ancestor c64f439569a9 local 746e9549ea96+ remote ac7575e3c052
38 ancestor c64f439569a9 local 746e9549ea96+ remote ac7575e3c052
39 searching for copies back to rev 1
40 unmatched files in other:
41 1a
42 all copies found (* = to merge, ! = divergent):
43 1a -> 1 *
44 checking for directory renames
27 1: remote moved to 1a -> m
45 1: remote moved to 1a -> m
28 copying 1 to 1a
46 copying 1 to 1a
29 merging 1 and 1a
47 merging 1 and 1a
30 my 1@746e9549ea96+ other 1a@2f8037f47a5c ancestor 1@81f4b099af3d
48 my 1@746e9549ea96+ other 1a@2f8037f47a5c ancestor 1@81f4b099af3d
31 removing 1
49 removing 1
32 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
50 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
33 (branch merge, don't forget to commit)
51 (branch merge, don't forget to commit)
@@ -1,83 +1,85 b''
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 merging bar and foo
2 merging bar and foo
3 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
3 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4 (branch merge, don't forget to commit)
4 (branch merge, don't forget to commit)
5 % contents of bar should be line0 line1 line2
5 % contents of bar should be line0 line1 line2
6 line0
6 line0
7 line1
7 line1
8 line2
8 line2
9 rev offset length base linkrev nodeid p1 p2
9 rev offset length base linkrev nodeid p1 p2
10 0 0 77 0 2 da78c0659611 000000000000 000000000000
10 0 0 77 0 2 da78c0659611 000000000000 000000000000
11 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
11 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
12 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
12 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
13 rev offset length base linkrev nodeid p1 p2
13 rev offset length base linkrev nodeid p1 p2
14 0 0 7 0 0 690b295714ae 000000000000 000000000000
14 0 0 7 0 0 690b295714ae 000000000000 000000000000
15 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000
15 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17 4:2d2f9a22c82b 2:0a3ab4856510
17 4:2d2f9a22c82b 2:0a3ab4856510
18 3:7d3b554bfdf1 2:0a3ab4856510 1:5cd961e4045d
18 3:7d3b554bfdf1 2:0a3ab4856510 1:5cd961e4045d
19 2:0a3ab4856510 0:2665aaee66e9
19 2:0a3ab4856510 0:2665aaee66e9
20 1:5cd961e4045d
20 1:5cd961e4045d
21 0:2665aaee66e9
21 0:2665aaee66e9
22 % this should use bar@rev2 as the ancestor
22 % this should use bar@rev2 as the ancestor
23 resolving manifests
23 resolving manifests
24 overwrite None partial False
24 overwrite None partial False
25 ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 7d3b554bfdf1
25 ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 7d3b554bfdf1
26 searching for copies back to rev 1
26 bar: versions differ -> m
27 bar: versions differ -> m
27 merging bar
28 merging bar
28 my bar@2d2f9a22c82b+ other bar@7d3b554bfdf1 ancestor bar@0a3ab4856510
29 my bar@2d2f9a22c82b+ other bar@7d3b554bfdf1 ancestor bar@0a3ab4856510
29 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
30 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
30 (branch merge, don't forget to commit)
31 (branch merge, don't forget to commit)
31 % contents of bar should be line1 line2
32 % contents of bar should be line1 line2
32 line1
33 line1
33 line2
34 line2
34 rev offset length base linkrev nodeid p1 p2
35 rev offset length base linkrev nodeid p1 p2
35 0 0 77 0 2 da78c0659611 000000000000 000000000000
36 0 0 77 0 2 da78c0659611 000000000000 000000000000
36 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
37 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
37 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000
38 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000
38 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b
39 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b
39
40
40
41
41 requesting all changes
42 requesting all changes
42 adding changesets
43 adding changesets
43 adding manifests
44 adding manifests
44 adding file changes
45 adding file changes
45 added 3 changesets with 3 changes to 2 files (+1 heads)
46 added 3 changesets with 3 changes to 2 files (+1 heads)
46 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
47 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
47 merging foo and bar
48 merging foo and bar
48 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
49 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
49 (branch merge, don't forget to commit)
50 (branch merge, don't forget to commit)
50 % contents of bar should be line0 line1 line2
51 % contents of bar should be line0 line1 line2
51 line0
52 line0
52 line1
53 line1
53 line2
54 line2
54 rev offset length base linkrev nodeid p1 p2
55 rev offset length base linkrev nodeid p1 p2
55 0 0 77 0 2 da78c0659611 000000000000 000000000000
56 0 0 77 0 2 da78c0659611 000000000000 000000000000
56 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
57 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
57 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
58 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
58 rev offset length base linkrev nodeid p1 p2
59 rev offset length base linkrev nodeid p1 p2
59 0 0 7 0 0 690b295714ae 000000000000 000000000000
60 0 0 7 0 0 690b295714ae 000000000000 000000000000
60 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000
61 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000
61 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 4:2d2f9a22c82b 2:0a3ab4856510
63 4:2d2f9a22c82b 2:0a3ab4856510
63 3:96ab80c60897 1:5cd961e4045d 2:0a3ab4856510
64 3:96ab80c60897 1:5cd961e4045d 2:0a3ab4856510
64 2:0a3ab4856510 0:2665aaee66e9
65 2:0a3ab4856510 0:2665aaee66e9
65 1:5cd961e4045d
66 1:5cd961e4045d
66 0:2665aaee66e9
67 0:2665aaee66e9
67 % this should use bar@rev2 as the ancestor
68 % this should use bar@rev2 as the ancestor
68 resolving manifests
69 resolving manifests
69 overwrite None partial False
70 overwrite None partial False
70 ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 96ab80c60897
71 ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 96ab80c60897
72 searching for copies back to rev 1
71 bar: versions differ -> m
73 bar: versions differ -> m
72 merging bar
74 merging bar
73 my bar@2d2f9a22c82b+ other bar@96ab80c60897 ancestor bar@0a3ab4856510
75 my bar@2d2f9a22c82b+ other bar@96ab80c60897 ancestor bar@0a3ab4856510
74 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
76 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
75 (branch merge, don't forget to commit)
77 (branch merge, don't forget to commit)
76 % contents of bar should be line1 line2
78 % contents of bar should be line1 line2
77 line1
79 line1
78 line2
80 line2
79 rev offset length base linkrev nodeid p1 p2
81 rev offset length base linkrev nodeid p1 p2
80 0 0 77 0 2 da78c0659611 000000000000 000000000000
82 0 0 77 0 2 da78c0659611 000000000000 000000000000
81 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
83 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
82 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000
84 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000
83 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b
85 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b
@@ -1,77 +1,78 b''
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 pulling from ../test-a
2 pulling from ../test-a
3 searching for changes
3 searching for changes
4 adding changesets
4 adding changesets
5 adding manifests
5 adding manifests
6 adding file changes
6 adding file changes
7 added 1 changesets with 1 changes to 1 files (+1 heads)
7 added 1 changesets with 1 changes to 1 files (+1 heads)
8 (run 'hg heads' to see heads, 'hg merge' to merge)
8 (run 'hg heads' to see heads, 'hg merge' to merge)
9 warning: conflicts during merge.
9 warning: conflicts during merge.
10 merging test.txt
10 merging test.txt
11 merging test.txt failed!
11 merging test.txt failed!
12 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
12 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
13 There are unresolved merges, you can redo the full merge using:
13 There are unresolved merges, you can redo the full merge using:
14 hg update -C 1
14 hg update -C 1
15 hg merge 2
15 hg merge 2
16 pulling from ../test-a
16 pulling from ../test-a
17 searching for changes
17 searching for changes
18 adding changesets
18 adding changesets
19 adding manifests
19 adding manifests
20 adding file changes
20 adding file changes
21 added 1 changesets with 1 changes to 1 files (+1 heads)
21 added 1 changesets with 1 changes to 1 files (+1 heads)
22 (run 'hg heads' to see heads, 'hg merge' to merge)
22 (run 'hg heads' to see heads, 'hg merge' to merge)
23 warning: conflicts during merge.
23 warning: conflicts during merge.
24 resolving manifests
24 resolving manifests
25 overwrite None partial False
25 overwrite None partial False
26 ancestor faaea63e63a9 local 451c744aabcc+ remote a070d41e8360
26 ancestor faaea63e63a9 local 451c744aabcc+ remote a070d41e8360
27 searching for copies back to rev 1
27 test.txt: versions differ -> m
28 test.txt: versions differ -> m
28 merging test.txt
29 merging test.txt
29 my test.txt@451c744aabcc+ other test.txt@a070d41e8360 ancestor test.txt@faaea63e63a9
30 my test.txt@451c744aabcc+ other test.txt@a070d41e8360 ancestor test.txt@faaea63e63a9
30 merging test.txt failed!
31 merging test.txt failed!
31 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
32 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
32 There are unresolved merges, you can redo the full merge using:
33 There are unresolved merges, you can redo the full merge using:
33 hg update -C 3
34 hg update -C 3
34 hg merge 4
35 hg merge 4
35 one
36 one
36 <<<<<<< my
37 <<<<<<< my
37 two-point-five
38 two-point-five
38 =======
39 =======
39 two-point-one
40 two-point-one
40 >>>>>>> other
41 >>>>>>> other
41 three
42 three
42 rev offset length base linkrev nodeid p1 p2
43 rev offset length base linkrev nodeid p1 p2
43 0 0 7 0 0 01365c4cca56 000000000000 000000000000
44 0 0 7 0 0 01365c4cca56 000000000000 000000000000
44 1 7 9 1 1 7b013192566a 01365c4cca56 000000000000
45 1 7 9 1 1 7b013192566a 01365c4cca56 000000000000
45 2 16 15 2 2 8fe46a3eb557 01365c4cca56 000000000000
46 2 16 15 2 2 8fe46a3eb557 01365c4cca56 000000000000
46 3 31 27 2 3 fc3148072371 7b013192566a 8fe46a3eb557
47 3 31 27 2 3 fc3148072371 7b013192566a 8fe46a3eb557
47 4 58 25 4 4 d40249267ae3 8fe46a3eb557 000000000000
48 4 58 25 4 4 d40249267ae3 8fe46a3eb557 000000000000
48 changeset: 4:a070d41e8360
49 changeset: 4:a070d41e8360
49 tag: tip
50 tag: tip
50 parent: 2:faaea63e63a9
51 parent: 2:faaea63e63a9
51 user: test
52 user: test
52 date: Mon Jan 12 13:46:40 1970 +0000
53 date: Mon Jan 12 13:46:40 1970 +0000
53 summary: two -> two-point-one
54 summary: two -> two-point-one
54
55
55 changeset: 3:451c744aabcc
56 changeset: 3:451c744aabcc
56 parent: 1:e409be6afcc0
57 parent: 1:e409be6afcc0
57 parent: 2:faaea63e63a9
58 parent: 2:faaea63e63a9
58 user: test
59 user: test
59 date: Mon Jan 12 13:46:40 1970 +0000
60 date: Mon Jan 12 13:46:40 1970 +0000
60 summary: Merge 1
61 summary: Merge 1
61
62
62 changeset: 2:faaea63e63a9
63 changeset: 2:faaea63e63a9
63 parent: 0:095c92b91f1a
64 parent: 0:095c92b91f1a
64 user: test
65 user: test
65 date: Mon Jan 12 13:46:40 1970 +0000
66 date: Mon Jan 12 13:46:40 1970 +0000
66 summary: Numbers as words
67 summary: Numbers as words
67
68
68 changeset: 1:e409be6afcc0
69 changeset: 1:e409be6afcc0
69 user: test
70 user: test
70 date: Mon Jan 12 13:46:40 1970 +0000
71 date: Mon Jan 12 13:46:40 1970 +0000
71 summary: 2 -> 2.5
72 summary: 2 -> 2.5
72
73
73 changeset: 0:095c92b91f1a
74 changeset: 0:095c92b91f1a
74 user: test
75 user: test
75 date: Mon Jan 12 13:46:40 1970 +0000
76 date: Mon Jan 12 13:46:40 1970 +0000
76 summary: Initial
77 summary: Initial
77
78
@@ -1,44 +1,68 b''
1 adding a/a
1 adding a/a
2 adding a/b
2 adding a/b
3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 copying a/a to b/a
4 copying a/a to b/a
5 copying a/b to b/b
5 copying a/b to b/b
6 removing a/a
6 removing a/a
7 removing a/b
7 removing a/b
8 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
8 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
9 resolving manifests
9 resolving manifests
10 overwrite None partial False
10 overwrite None partial False
11 ancestor f9b20c0d4c51 local ce36d17b18fb+ remote 55119e611c80
11 ancestor f9b20c0d4c51 local ce36d17b18fb+ remote 55119e611c80
12 searching for copies back to rev 1
13 unmatched files in local:
14 a/c
15 unmatched files in other:
16 b/a
17 b/b
18 all copies found (* = to merge, ! = divergent):
19 b/a -> a/a
20 b/b -> a/b
21 checking for directory renames
22 dir a/ -> b/
23 file a/c -> b/c
12 a/c: remote renamed directory to b/c -> d
24 a/c: remote renamed directory to b/c -> d
13 a/b: other deleted -> r
25 a/b: other deleted -> r
14 a/a: other deleted -> r
26 a/a: other deleted -> r
15 b/a: remote created -> g
27 b/a: remote created -> g
16 b/b: remote created -> g
28 b/b: remote created -> g
17 removing a/a
29 removing a/a
18 removing a/b
30 removing a/b
19 moving a/c to b/c
31 moving a/c to b/c
20 getting b/a
32 getting b/a
21 getting b/b
33 getting b/b
22 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
34 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
23 (branch merge, don't forget to commit)
35 (branch merge, don't forget to commit)
24 a/* b/a b/b b/c
36 a/* b/a b/b b/c
25 M b/a
37 M b/a
26 M b/b
38 M b/b
27 A b/c
39 A b/c
28 a/c
40 a/c
29 R a/a
41 R a/a
30 R a/b
42 R a/b
31 R a/c
43 R a/c
32 b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
44 b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
33 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
45 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
34 resolving manifests
46 resolving manifests
35 overwrite None partial False
47 overwrite None partial False
36 ancestor f9b20c0d4c51 local 55119e611c80+ remote ce36d17b18fb
48 ancestor f9b20c0d4c51 local 55119e611c80+ remote ce36d17b18fb
49 searching for copies back to rev 1
50 unmatched files in local:
51 b/a
52 b/b
53 unmatched files in other:
54 a/c
55 all copies found (* = to merge, ! = divergent):
56 b/a -> a/a
57 b/b -> a/b
58 checking for directory renames
59 dir a/ -> b/
60 file a/c -> b/c
37 None: local renamed directory to b/c -> d
61 None: local renamed directory to b/c -> d
38 getting a/c to b/c
62 getting a/c to b/c
39 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
40 (branch merge, don't forget to commit)
64 (branch merge, don't forget to commit)
41 a/* b/a b/b b/c
65 a/* b/a b/b b/c
42 A b/c
66 A b/c
43 a/c
67 a/c
44 b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
68 b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
@@ -1,29 +1,40 b''
1 checkout
1 checkout
2 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
2 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
3 merge
3 merge
4 resolving manifests
4 resolving manifests
5 overwrite None partial False
5 overwrite None partial False
6 ancestor af1939970a1c local f26ec4fc3fa3+ remote 8e765a822af2
6 ancestor af1939970a1c local f26ec4fc3fa3+ remote 8e765a822af2
7 searching for copies back to rev 1
8 unmatched files in local:
9 c2
10 unmatched files in other:
11 b
12 b2
13 all copies found (* = to merge, ! = divergent):
14 c2 -> a2
15 b -> a *
16 b2 -> a2
17 checking for directory renames
7 a2: divergent renames -> dr
18 a2: divergent renames -> dr
8 a: remote moved to b -> m
19 a: remote moved to b -> m
9 b2: remote created -> g
20 b2: remote created -> g
10 copying a to b
21 copying a to b
11 merging a and b
22 merging a and b
12 my a@f26ec4fc3fa3+ other b@8e765a822af2 ancestor a@af1939970a1c
23 my a@f26ec4fc3fa3+ other b@8e765a822af2 ancestor a@af1939970a1c
13 removing a
24 removing a
14 warning: detected divergent renames of a2 to:
25 warning: detected divergent renames of a2 to:
15 c2
26 c2
16 b2
27 b2
17 getting b2
28 getting b2
18 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
29 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
19 (branch merge, don't forget to commit)
30 (branch merge, don't forget to commit)
20 M b
31 M b
21 a
32 a
22 M b2
33 M b2
23 R a
34 R a
24 C c2
35 C c2
25 blahblah
36 blahblah
26 rev offset length base linkrev nodeid p1 p2
37 rev offset length base linkrev nodeid p1 p2
27 0 0 67 0 1 dc51707dfc98 000000000000 000000000000
38 0 0 67 0 1 dc51707dfc98 000000000000 000000000000
28 1 67 72 1 3 b2494a44f0a9 000000000000 dc51707dfc98
39 1 67 72 1 3 b2494a44f0a9 000000000000 dc51707dfc98
29 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
40 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
@@ -1,136 +1,143 b''
1 adding a
1 adding a
2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 diff -r 33aaa84a386b a
4 diff -r 33aaa84a386b a
5 --- a/a
5 --- a/a
6 +++ b/a
6 +++ b/a
7 @@ -1,1 +1,1 @@ a
7 @@ -1,1 +1,1 @@ a
8 -a
8 -a
9 +abc
9 +abc
10 adding b
10 adding b
11 M a
11 M a
12 changeset: 0:33aaa84a386b
12 changeset: 0:33aaa84a386b
13 user: test
13 user: test
14 date: Mon Jan 12 13:46:40 1970 +0000
14 date: Mon Jan 12 13:46:40 1970 +0000
15 summary: 1
15 summary: 1
16
16
17 resolving manifests
17 resolving manifests
18 overwrite False partial False
18 overwrite False partial False
19 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
19 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
20 searching for copies back to rev 1
21 unmatched files in other:
22 b
20 a: versions differ -> m
23 a: versions differ -> m
21 b: remote created -> g
24 b: remote created -> g
22 merging a
25 merging a
23 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
26 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
24 getting b
27 getting b
25 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
28 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
26 changeset: 1:802f095af299
29 changeset: 1:802f095af299
27 tag: tip
30 tag: tip
28 user: test
31 user: test
29 date: Mon Jan 12 13:46:40 1970 +0000
32 date: Mon Jan 12 13:46:40 1970 +0000
30 summary: 2
33 summary: 2
31
34
32 resolving manifests
35 resolving manifests
33 overwrite False partial False
36 overwrite False partial False
34 ancestor 33aaa84a386b local 802f095af299+ remote 33aaa84a386b
37 ancestor 33aaa84a386b local 802f095af299+ remote 33aaa84a386b
35 b: remote deleted -> r
38 b: remote deleted -> r
36 removing b
39 removing b
37 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
40 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
38 changeset: 0:33aaa84a386b
41 changeset: 0:33aaa84a386b
39 user: test
42 user: test
40 date: Mon Jan 12 13:46:40 1970 +0000
43 date: Mon Jan 12 13:46:40 1970 +0000
41 summary: 1
44 summary: 1
42
45
43 abort: there is nothing to merge - use "hg update" instead
46 abort: there is nothing to merge - use "hg update" instead
44 failed
47 failed
45 changeset: 0:33aaa84a386b
48 changeset: 0:33aaa84a386b
46 user: test
49 user: test
47 date: Mon Jan 12 13:46:40 1970 +0000
50 date: Mon Jan 12 13:46:40 1970 +0000
48 summary: 1
51 summary: 1
49
52
50 resolving manifests
53 resolving manifests
51 overwrite False partial False
54 overwrite False partial False
52 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
55 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
56 searching for copies back to rev 1
57 unmatched files in other:
58 b
53 a: versions differ -> m
59 a: versions differ -> m
54 b: remote created -> g
60 b: remote created -> g
55 merging a
61 merging a
56 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
62 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
57 getting b
63 getting b
58 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
64 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
59 changeset: 1:802f095af299
65 changeset: 1:802f095af299
60 tag: tip
66 tag: tip
61 user: test
67 user: test
62 date: Mon Jan 12 13:46:40 1970 +0000
68 date: Mon Jan 12 13:46:40 1970 +0000
63 summary: 2
69 summary: 2
64
70
65 changeset: 1:802f095af299
71 changeset: 1:802f095af299
66 tag: tip
72 tag: tip
67 user: test
73 user: test
68 date: Mon Jan 12 13:46:40 1970 +0000
74 date: Mon Jan 12 13:46:40 1970 +0000
69 files: a b
75 files: a b
70 description:
76 description:
71 2
77 2
72
78
73
79
74 changeset: 0:33aaa84a386b
80 changeset: 0:33aaa84a386b
75 user: test
81 user: test
76 date: Mon Jan 12 13:46:40 1970 +0000
82 date: Mon Jan 12 13:46:40 1970 +0000
77 files: a
83 files: a
78 description:
84 description:
79 1
85 1
80
86
81
87
82 diff -r 802f095af299 a
88 diff -r 802f095af299 a
83 --- a/a
89 --- a/a
84 +++ b/a
90 +++ b/a
85 @@ -1,1 +1,1 @@ a2
91 @@ -1,1 +1,1 @@ a2
86 -a2
92 -a2
87 +abc
93 +abc
88 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
94 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
89 adding b
95 adding b
90 M a
96 M a
91 changeset: 1:802f095af299
97 changeset: 1:802f095af299
92 user: test
98 user: test
93 date: Mon Jan 12 13:46:40 1970 +0000
99 date: Mon Jan 12 13:46:40 1970 +0000
94 summary: 2
100 summary: 2
95
101
96 abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
102 abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
97 failed
103 failed
98 abort: outstanding uncommitted changes
104 abort: outstanding uncommitted changes
99 failed
105 failed
100 resolving manifests
106 resolving manifests
101 overwrite False partial False
107 overwrite False partial False
102 ancestor 33aaa84a386b local 802f095af299+ remote 030602aee63d
108 ancestor 33aaa84a386b local 802f095af299+ remote 030602aee63d
109 searching for copies back to rev 1
103 a: versions differ -> m
110 a: versions differ -> m
104 b: versions differ -> m
111 b: versions differ -> m
105 merging a
112 merging a
106 my a@802f095af299+ other a@030602aee63d ancestor a@33aaa84a386b
113 my a@802f095af299+ other a@030602aee63d ancestor a@33aaa84a386b
107 merging b
114 merging b
108 my b@802f095af299+ other b@030602aee63d ancestor b@000000000000
115 my b@802f095af299+ other b@030602aee63d ancestor b@000000000000
109 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
116 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
110 (branch merge, don't forget to commit)
117 (branch merge, don't forget to commit)
111 changeset: 1:802f095af299
118 changeset: 1:802f095af299
112 user: test
119 user: test
113 date: Mon Jan 12 13:46:40 1970 +0000
120 date: Mon Jan 12 13:46:40 1970 +0000
114 summary: 2
121 summary: 2
115
122
116 changeset: 2:030602aee63d
123 changeset: 2:030602aee63d
117 tag: tip
124 tag: tip
118 parent: 0:33aaa84a386b
125 parent: 0:33aaa84a386b
119 user: test
126 user: test
120 date: Mon Jan 12 13:46:40 1970 +0000
127 date: Mon Jan 12 13:46:40 1970 +0000
121 summary: 3
128 summary: 3
122
129
123 diff -r 802f095af299 a
130 diff -r 802f095af299 a
124 --- a/a
131 --- a/a
125 +++ b/a
132 +++ b/a
126 @@ -1,1 +1,1 @@ a2
133 @@ -1,1 +1,1 @@ a2
127 -a2
134 -a2
128 +abc
135 +abc
129 adding a
136 adding a
130 pulling from ../a
137 pulling from ../a
131 requesting all changes
138 requesting all changes
132 adding changesets
139 adding changesets
133 adding manifests
140 adding manifests
134 adding file changes
141 adding file changes
135 added 1 changesets with 1 changes to 1 files
142 added 1 changesets with 1 changes to 1 files
136 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
143 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
General Comments 0
You need to be logged in to leave comments. Login now