##// END OF EJS Templates
merge: give hint as to how to discover uncommitted changes...
Steve Borho -
r8545:3682a19b default
parent child Browse files
Show More
@@ -1,503 +1,504 b''
1 1 # merge.py - directory-level update/merge handling for Mercurial
2 2 #
3 3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2, incorporated herein by reference.
7 7
8 8 from node import nullid, nullrev, hex, bin
9 9 from i18n import _
10 10 import util, filemerge, copies
11 11 import errno, os, shutil
12 12
13 13 class mergestate(object):
14 14 '''track 3-way merge state of individual files'''
15 15 def __init__(self, repo):
16 16 self._repo = repo
17 17 self._read()
18 18 def reset(self, node=None):
19 19 self._state = {}
20 20 if node:
21 21 self._local = node
22 22 shutil.rmtree(self._repo.join("merge"), True)
23 23 def _read(self):
24 24 self._state = {}
25 25 try:
26 26 localnode = None
27 27 f = self._repo.opener("merge/state")
28 28 for i, l in enumerate(f):
29 29 if i == 0:
30 30 localnode = l[:-1]
31 31 else:
32 32 bits = l[:-1].split("\0")
33 33 self._state[bits[0]] = bits[1:]
34 34 self._local = bin(localnode)
35 35 except IOError, err:
36 36 if err.errno != errno.ENOENT:
37 37 raise
38 38 def _write(self):
39 39 f = self._repo.opener("merge/state", "w")
40 40 f.write(hex(self._local) + "\n")
41 41 for d, v in self._state.iteritems():
42 42 f.write("\0".join([d] + v) + "\n")
43 43 def add(self, fcl, fco, fca, fd, flags):
44 44 hash = util.sha1(fcl.path()).hexdigest()
45 45 self._repo.opener("merge/" + hash, "w").write(fcl.data())
46 46 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
47 47 hex(fca.filenode()), fco.path(), flags]
48 48 self._write()
49 49 def __contains__(self, dfile):
50 50 return dfile in self._state
51 51 def __getitem__(self, dfile):
52 52 return self._state[dfile][0]
53 53 def __iter__(self):
54 54 l = self._state.keys()
55 55 l.sort()
56 56 for f in l:
57 57 yield f
58 58 def mark(self, dfile, state):
59 59 self._state[dfile][0] = state
60 60 self._write()
61 61 def resolve(self, dfile, wctx, octx):
62 62 if self[dfile] == 'r':
63 63 return 0
64 64 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
65 65 f = self._repo.opener("merge/" + hash)
66 66 self._repo.wwrite(dfile, f.read(), flags)
67 67 fcd = wctx[dfile]
68 68 fco = octx[ofile]
69 69 fca = self._repo.filectx(afile, fileid=anode)
70 70 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
71 71 if not r:
72 72 self.mark(dfile, 'r')
73 73 return r
74 74
75 75 def _checkunknown(wctx, mctx):
76 76 "check for collisions between unknown files and files in mctx"
77 77 for f in wctx.unknown():
78 78 if f in mctx and mctx[f].cmp(wctx[f].data()):
79 79 raise util.Abort(_("untracked file in working directory differs"
80 80 " from file in requested revision: '%s'") % f)
81 81
82 82 def _checkcollision(mctx):
83 83 "check for case folding collisions in the destination context"
84 84 folded = {}
85 85 for fn in mctx:
86 86 fold = fn.lower()
87 87 if fold in folded:
88 88 raise util.Abort(_("case-folding collision between %s and %s")
89 89 % (fn, folded[fold]))
90 90 folded[fold] = fn
91 91
92 92 def _forgetremoved(wctx, mctx, branchmerge):
93 93 """
94 94 Forget removed files
95 95
96 96 If we're jumping between revisions (as opposed to merging), and if
97 97 neither the working directory nor the target rev has the file,
98 98 then we need to remove it from the dirstate, to prevent the
99 99 dirstate from listing the file when it is no longer in the
100 100 manifest.
101 101
102 102 If we're merging, and the other revision has removed a file
103 103 that is not present in the working directory, we need to mark it
104 104 as removed.
105 105 """
106 106
107 107 action = []
108 108 state = branchmerge and 'r' or 'f'
109 109 for f in wctx.deleted():
110 110 if f not in mctx:
111 111 action.append((f, state))
112 112
113 113 if not branchmerge:
114 114 for f in wctx.removed():
115 115 if f not in mctx:
116 116 action.append((f, "f"))
117 117
118 118 return action
119 119
120 120 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
121 121 """
122 122 Merge p1 and p2 with ancestor ma and generate merge action list
123 123
124 124 overwrite = whether we clobber working files
125 125 partial = function to filter file lists
126 126 """
127 127
128 128 repo.ui.note(_("resolving manifests\n"))
129 129 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
130 130 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
131 131
132 132 m1 = p1.manifest()
133 133 m2 = p2.manifest()
134 134 ma = pa.manifest()
135 135 backwards = (pa == p2)
136 136 action = []
137 137 copy, copied, diverge = {}, {}, {}
138 138
139 139 def fmerge(f, f2=None, fa=None):
140 140 """merge flags"""
141 141 if not f2:
142 142 f2 = f
143 143 fa = f
144 144 a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
145 145 if m == n: # flags agree
146 146 return m # unchanged
147 147 if m and n: # flags are set but don't agree
148 148 if not a: # both differ from parent
149 149 r = repo.ui.prompt(
150 150 _(" conflicting flags for %s\n"
151 151 "(n)one, e(x)ec or sym(l)ink?") % f,
152 152 (_("&None"), _("E&xec"), _("Sym&link")), _("n"))
153 153 return r != _("n") and r or ''
154 154 if m == a:
155 155 return n # changed from m to n
156 156 return m # changed from n to m
157 157 if m and m != a: # changed from a to m
158 158 return m
159 159 if n and n != a: # changed from a to n
160 160 return n
161 161 return '' # flag was cleared
162 162
163 163 def act(msg, m, f, *args):
164 164 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
165 165 action.append((f, m) + args)
166 166
167 167 if pa and not (backwards or overwrite):
168 168 if repo.ui.configbool("merge", "followcopies", True):
169 169 dirs = repo.ui.configbool("merge", "followdirs", True)
170 170 copy, diverge = copies.copies(repo, p1, p2, pa, dirs)
171 171 copied = set(copy.values())
172 172 for of, fl in diverge.iteritems():
173 173 act("divergent renames", "dr", of, fl)
174 174
175 175 # Compare manifests
176 176 for f, n in m1.iteritems():
177 177 if partial and not partial(f):
178 178 continue
179 179 if f in m2:
180 180 if overwrite or backwards:
181 181 rflags = m2.flags(f)
182 182 else:
183 183 rflags = fmerge(f)
184 184 # are files different?
185 185 if n != m2[f]:
186 186 a = ma.get(f, nullid)
187 187 # are we clobbering?
188 188 if overwrite:
189 189 act("clobbering", "g", f, rflags)
190 190 # or are we going back in time and clean?
191 191 elif backwards:
192 192 if not n[20:] or not p2[f].cmp(p1[f].data()):
193 193 act("reverting", "g", f, rflags)
194 194 # are both different from the ancestor?
195 195 elif n != a and m2[f] != a:
196 196 act("versions differ", "m", f, f, f, rflags, False)
197 197 # is remote's version newer?
198 198 elif m2[f] != a:
199 199 act("remote is newer", "g", f, rflags)
200 200 # local is newer, not overwrite, check mode bits
201 201 elif m1.flags(f) != rflags:
202 202 act("update permissions", "e", f, rflags)
203 203 # contents same, check mode bits
204 204 elif m1.flags(f) != rflags:
205 205 act("update permissions", "e", f, rflags)
206 206 elif f in copied:
207 207 continue
208 208 elif f in copy:
209 209 f2 = copy[f]
210 210 if f2 not in m2: # directory rename
211 211 act("remote renamed directory to " + f2, "d",
212 212 f, None, f2, m1.flags(f))
213 213 elif f2 in m1: # case 2 A,B/B/B
214 214 act("local copied to " + f2, "m",
215 215 f, f2, f, fmerge(f, f2, f2), False)
216 216 else: # case 4,21 A/B/B
217 217 act("local moved to " + f2, "m",
218 218 f, f2, f, fmerge(f, f2, f2), False)
219 219 elif f in ma:
220 220 if n != ma[f] and not overwrite:
221 221 if repo.ui.prompt(
222 222 _(" local changed %s which remote deleted\n"
223 223 "use (c)hanged version or (d)elete?") % f,
224 224 (_("&Changed"), _("&Delete")), _("c")) == _("d"):
225 225 act("prompt delete", "r", f)
226 226 act("prompt keep", "a", f)
227 227 else:
228 228 act("other deleted", "r", f)
229 229 elif overwrite and n[20:] == "a": # do not erase the working copy
230 230 act("remote deleted", "f", f)
231 231 else:
232 232 # file is created on branch or in working directory
233 233 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
234 234 act("remote deleted", "r", f)
235 235
236 236 for f, n in m2.iteritems():
237 237 if partial and not partial(f):
238 238 continue
239 239 if f in m1:
240 240 continue
241 241 if f in copied:
242 242 continue
243 243 if f in copy:
244 244 f2 = copy[f]
245 245 if f2 not in m1: # directory rename
246 246 act("local renamed directory to " + f2, "d",
247 247 None, f, f2, m2.flags(f))
248 248 elif f2 in m2: # rename case 1, A/A,B/A
249 249 act("remote copied to " + f, "m",
250 250 f2, f, f, fmerge(f2, f, f2), False)
251 251 else: # case 3,20 A/B/A
252 252 act("remote moved to " + f, "m",
253 253 f2, f, f, fmerge(f2, f, f2), True)
254 254 elif f in ma:
255 255 if overwrite or backwards:
256 256 act("recreating", "g", f, m2.flags(f))
257 257 elif n != ma[f]:
258 258 if repo.ui.prompt(
259 259 _("remote changed %s which local deleted\n"
260 260 "use (c)hanged version or leave (d)eleted?") % f,
261 261 (_("&Changed"), _("&Deleted")), _("c")) == _("c"):
262 262 act("prompt recreating", "g", f, m2.flags(f))
263 263 else:
264 264 act("remote created", "g", f, m2.flags(f))
265 265
266 266 return action
267 267
268 268 def actionkey(a):
269 269 return a[1] == 'r' and -1 or 0, a
270 270
271 271 def applyupdates(repo, action, wctx, mctx):
272 272 "apply the merge action list to the working directory"
273 273
274 274 updated, merged, removed, unresolved = 0, 0, 0, 0
275 275 ms = mergestate(repo)
276 276 ms.reset(wctx.parents()[0].node())
277 277 moves = []
278 278 action.sort(key=actionkey)
279 279
280 280 # prescan for merges
281 281 for a in action:
282 282 f, m = a[:2]
283 283 if m == 'm': # merge
284 284 f2, fd, flags, move = a[2:]
285 285 repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd))
286 286 fcl = wctx[f]
287 287 fco = mctx[f2]
288 288 fca = fcl.ancestor(fco) or repo.filectx(f, fileid=nullrev)
289 289 ms.add(fcl, fco, fca, fd, flags)
290 290 if f != fd and move:
291 291 moves.append(f)
292 292
293 293 # remove renamed files after safely stored
294 294 for f in moves:
295 295 if util.lexists(repo.wjoin(f)):
296 296 repo.ui.debug(_("removing %s\n") % f)
297 297 os.unlink(repo.wjoin(f))
298 298
299 299 audit_path = util.path_auditor(repo.root)
300 300
301 301 for a in action:
302 302 f, m = a[:2]
303 303 if f and f[0] == "/":
304 304 continue
305 305 if m == "r": # remove
306 306 repo.ui.note(_("removing %s\n") % f)
307 307 audit_path(f)
308 308 try:
309 309 util.unlink(repo.wjoin(f))
310 310 except OSError, inst:
311 311 if inst.errno != errno.ENOENT:
312 312 repo.ui.warn(_("update failed to remove %s: %s!\n") %
313 313 (f, inst.strerror))
314 314 removed += 1
315 315 elif m == "m": # merge
316 316 f2, fd, flags, move = a[2:]
317 317 r = ms.resolve(fd, wctx, mctx)
318 318 if r > 0:
319 319 unresolved += 1
320 320 else:
321 321 if r is None:
322 322 updated += 1
323 323 else:
324 324 merged += 1
325 325 util.set_flags(repo.wjoin(fd), 'l' in flags, 'x' in flags)
326 326 if f != fd and move and util.lexists(repo.wjoin(f)):
327 327 repo.ui.debug(_("removing %s\n") % f)
328 328 os.unlink(repo.wjoin(f))
329 329 elif m == "g": # get
330 330 flags = a[2]
331 331 repo.ui.note(_("getting %s\n") % f)
332 332 t = mctx.filectx(f).data()
333 333 repo.wwrite(f, t, flags)
334 334 updated += 1
335 335 elif m == "d": # directory rename
336 336 f2, fd, flags = a[2:]
337 337 if f:
338 338 repo.ui.note(_("moving %s to %s\n") % (f, fd))
339 339 t = wctx.filectx(f).data()
340 340 repo.wwrite(fd, t, flags)
341 341 util.unlink(repo.wjoin(f))
342 342 if f2:
343 343 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
344 344 t = mctx.filectx(f2).data()
345 345 repo.wwrite(fd, t, flags)
346 346 updated += 1
347 347 elif m == "dr": # divergent renames
348 348 fl = a[2]
349 349 repo.ui.warn(_("warning: detected divergent renames of %s to:\n") % f)
350 350 for nf in fl:
351 351 repo.ui.warn(" %s\n" % nf)
352 352 elif m == "e": # exec
353 353 flags = a[2]
354 354 util.set_flags(repo.wjoin(f), 'l' in flags, 'x' in flags)
355 355
356 356 return updated, merged, removed, unresolved
357 357
358 358 def recordupdates(repo, action, branchmerge):
359 359 "record merge actions to the dirstate"
360 360
361 361 for a in action:
362 362 f, m = a[:2]
363 363 if m == "r": # remove
364 364 if branchmerge:
365 365 repo.dirstate.remove(f)
366 366 else:
367 367 repo.dirstate.forget(f)
368 368 elif m == "a": # re-add
369 369 if not branchmerge:
370 370 repo.dirstate.add(f)
371 371 elif m == "f": # forget
372 372 repo.dirstate.forget(f)
373 373 elif m == "e": # exec change
374 374 repo.dirstate.normallookup(f)
375 375 elif m == "g": # get
376 376 if branchmerge:
377 377 repo.dirstate.normaldirty(f)
378 378 else:
379 379 repo.dirstate.normal(f)
380 380 elif m == "m": # merge
381 381 f2, fd, flag, move = a[2:]
382 382 if branchmerge:
383 383 # We've done a branch merge, mark this file as merged
384 384 # so that we properly record the merger later
385 385 repo.dirstate.merge(fd)
386 386 if f != f2: # copy/rename
387 387 if move:
388 388 repo.dirstate.remove(f)
389 389 if f != fd:
390 390 repo.dirstate.copy(f, fd)
391 391 else:
392 392 repo.dirstate.copy(f2, fd)
393 393 else:
394 394 # We've update-merged a locally modified file, so
395 395 # we set the dirstate to emulate a normal checkout
396 396 # of that file some time in the past. Thus our
397 397 # merge will appear as a normal local file
398 398 # modification.
399 399 repo.dirstate.normallookup(fd)
400 400 if move:
401 401 repo.dirstate.forget(f)
402 402 elif m == "d": # directory rename
403 403 f2, fd, flag = a[2:]
404 404 if not f2 and f not in repo.dirstate:
405 405 # untracked file moved
406 406 continue
407 407 if branchmerge:
408 408 repo.dirstate.add(fd)
409 409 if f:
410 410 repo.dirstate.remove(f)
411 411 repo.dirstate.copy(f, fd)
412 412 if f2:
413 413 repo.dirstate.copy(f2, fd)
414 414 else:
415 415 repo.dirstate.normal(fd)
416 416 if f:
417 417 repo.dirstate.forget(f)
418 418
419 419 def update(repo, node, branchmerge, force, partial):
420 420 """
421 421 Perform a merge between the working directory and the given node
422 422
423 423 branchmerge = whether to merge between branches
424 424 force = whether to force branch merging or file overwriting
425 425 partial = a function to filter file lists (dirstate not updated)
426 426 """
427 427
428 428 wlock = repo.wlock()
429 429 try:
430 430 wc = repo[None]
431 431 if node is None:
432 432 # tip of current branch
433 433 try:
434 434 node = repo.branchtags()[wc.branch()]
435 435 except KeyError:
436 436 if wc.branch() == "default": # no default branch!
437 437 node = repo.lookup("tip") # update to tip
438 438 else:
439 439 raise util.Abort(_("branch %s not found") % wc.branch())
440 440 overwrite = force and not branchmerge
441 441 pl = wc.parents()
442 442 p1, p2 = pl[0], repo[node]
443 443 pa = p1.ancestor(p2)
444 444 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
445 445 fastforward = False
446 446
447 447 ### check phase
448 448 if not overwrite and len(pl) > 1:
449 449 raise util.Abort(_("outstanding uncommitted merges"))
450 450 if branchmerge:
451 451 if pa == p2:
452 452 raise util.Abort(_("can't merge with ancestor"))
453 453 elif pa == p1:
454 454 if p1.branch() != p2.branch():
455 455 fastforward = True
456 456 else:
457 457 raise util.Abort(_("nothing to merge (use 'hg update'"
458 458 " or check 'hg heads')"))
459 459 if not force and (wc.files() or wc.deleted()):
460 raise util.Abort(_("outstanding uncommitted changes"))
460 raise util.Abort(_("outstanding uncommitted changes "
461 "(use 'hg status' to list changes)"))
461 462 elif not overwrite:
462 463 if pa == p1 or pa == p2: # linear
463 464 pass # all good
464 465 elif p1.branch() == p2.branch():
465 466 if wc.files() or wc.deleted():
466 467 raise util.Abort(_("crosses branches (use 'hg merge' or "
467 468 "'hg update -C' to discard changes)"))
468 469 raise util.Abort(_("crosses branches (use 'hg merge' "
469 470 "or 'hg update -C')"))
470 471 elif wc.files() or wc.deleted():
471 472 raise util.Abort(_("crosses named branches (use "
472 473 "'hg update -C' to discard changes)"))
473 474 else:
474 475 # Allow jumping branches if there are no changes
475 476 overwrite = True
476 477
477 478 ### calculate phase
478 479 action = []
479 480 if not force:
480 481 _checkunknown(wc, p2)
481 482 if not util.checkcase(repo.path):
482 483 _checkcollision(p2)
483 484 action += _forgetremoved(wc, p2, branchmerge)
484 485 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
485 486
486 487 ### apply phase
487 488 if not branchmerge: # just jump to the new rev
488 489 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
489 490 if not partial:
490 491 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
491 492
492 493 stats = applyupdates(repo, action, wc, p2)
493 494
494 495 if not partial:
495 496 recordupdates(repo, action, branchmerge)
496 497 repo.dirstate.setparents(fp1, fp2)
497 498 if not branchmerge and not fastforward:
498 499 repo.dirstate.setbranch(p2.branch())
499 500 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
500 501
501 502 return stats
502 503 finally:
503 504 wlock.release()
@@ -1,11 +1,11 b''
1 1 created new head
2 2 % local deleted a file, remote removed
3 abort: outstanding uncommitted changes
3 abort: outstanding uncommitted changes (use 'hg status' to list changes)
4 4 resolving manifests
5 5 removing a
6 6 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
7 7 (branch merge, don't forget to commit)
8 8 % should show a as removed
9 9 R a
10 10 % manifest. should not have a:
11 11 b
@@ -1,69 +1,69 b''
1 1 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2 2 created new head
3 3 %% no merges expected
4 4 changeset: 0:98e00378acd0
5 5 user: test
6 6 date: Mon Jan 12 13:46:40 1970 +0000
7 7 summary: commit #0
8 8
9 9 changeset: 1:4ee19afe4659
10 10 user: test
11 11 date: Mon Jan 12 13:46:40 1970 +0000
12 12 summary: commit #1
13 13
14 14 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 15 (branch merge, don't forget to commit)
16 16 diff -r d9e5953b9dec b
17 17 --- /dev/null
18 18 +++ b/b
19 19 @@ -0,0 +1,1 @@
20 20 +This is file b1
21 21 M b
22 22 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
23 23 created new head
24 24 %% merge should fail
25 25 abort: untracked file in working directory differs from file in requested revision: 'b'
26 26 %% merge of b expected
27 27 merging for b
28 28 merging b
29 29 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
30 30 (branch merge, don't forget to commit)
31 31 diff -r d9e5953b9dec b
32 32 --- /dev/null
33 33 +++ b/b
34 34 @@ -0,0 +1,1 @@
35 35 +This is file b2
36 36 M b
37 37 %%
38 38 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
39 39 created new head
40 40 Contents of b should be "this is file b1"
41 41 This is file b1
42 42 %% merge fails
43 abort: outstanding uncommitted changes
43 abort: outstanding uncommitted changes (use 'hg status' to list changes)
44 44 %% merge expected!
45 45 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
46 46 (branch merge, don't forget to commit)
47 47 diff -r c1dd73cbf59f b
48 48 --- a/b
49 49 +++ b/b
50 50 @@ -1,1 +1,1 @@
51 51 -This is file b1
52 52 +This is file b22
53 53 M b
54 54 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 55 created new head
56 56 %% merge of b should fail
57 abort: outstanding uncommitted changes
57 abort: outstanding uncommitted changes (use 'hg status' to list changes)
58 58 %% merge of b expected
59 59 merging for b
60 60 merging b
61 61 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
62 62 (branch merge, don't forget to commit)
63 63 diff -r c1dd73cbf59f b
64 64 --- a/b
65 65 +++ b/b
66 66 @@ -1,1 +1,1 @@
67 67 -This is file b1
68 68 +This is file b33
69 69 M b
@@ -1,153 +1,153 b''
1 1 adding a
2 2 updating working directory
3 3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 4 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
5 5 diff -r 33aaa84a386b a
6 6 --- a/a
7 7 +++ b/a
8 8 @@ -1,1 +1,1 @@
9 9 -a
10 10 +abc
11 11 adding b
12 12 M a
13 13 changeset: 0:33aaa84a386b
14 14 user: test
15 15 date: Mon Jan 12 13:46:40 1970 +0000
16 16 summary: 1
17 17
18 18 resolving manifests
19 19 overwrite False partial False
20 20 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
21 21 searching for copies back to rev 1
22 22 unmatched files in other:
23 23 b
24 24 a: versions differ -> m
25 25 b: remote created -> g
26 26 preserving a for resolve of a
27 27 picked tool 'true' for a (binary False symlink False)
28 28 merging a
29 29 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
30 30 getting b
31 31 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
32 32 changeset: 1:802f095af299
33 33 tag: tip
34 34 user: test
35 35 date: Mon Jan 12 13:46:40 1970 +0000
36 36 summary: 2
37 37
38 38 resolving manifests
39 39 overwrite False partial False
40 40 ancestor 33aaa84a386b local 802f095af299+ remote 33aaa84a386b
41 41 b: remote deleted -> r
42 42 removing b
43 43 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
44 44 changeset: 0:33aaa84a386b
45 45 user: test
46 46 date: Mon Jan 12 13:46:40 1970 +0000
47 47 summary: 1
48 48
49 49 abort: there is nothing to merge - use "hg update" instead
50 50 failed
51 51 changeset: 0:33aaa84a386b
52 52 user: test
53 53 date: Mon Jan 12 13:46:40 1970 +0000
54 54 summary: 1
55 55
56 56 resolving manifests
57 57 overwrite False partial False
58 58 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
59 59 searching for copies back to rev 1
60 60 unmatched files in other:
61 61 b
62 62 a: versions differ -> m
63 63 b: remote created -> g
64 64 preserving a for resolve of a
65 65 picked tool 'true' for a (binary False symlink False)
66 66 merging a
67 67 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
68 68 getting b
69 69 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
70 70 changeset: 1:802f095af299
71 71 tag: tip
72 72 user: test
73 73 date: Mon Jan 12 13:46:40 1970 +0000
74 74 summary: 2
75 75
76 76 changeset: 1:802f095af299
77 77 tag: tip
78 78 user: test
79 79 date: Mon Jan 12 13:46:40 1970 +0000
80 80 files: a b
81 81 description:
82 82 2
83 83
84 84
85 85 changeset: 0:33aaa84a386b
86 86 user: test
87 87 date: Mon Jan 12 13:46:40 1970 +0000
88 88 files: a
89 89 description:
90 90 1
91 91
92 92
93 93 diff -r 802f095af299 a
94 94 --- a/a
95 95 +++ b/a
96 96 @@ -1,1 +1,1 @@
97 97 -a2
98 98 +abc
99 99 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
100 100 adding b
101 101 created new head
102 102 M a
103 103 changeset: 1:802f095af299
104 104 user: test
105 105 date: Mon Jan 12 13:46:40 1970 +0000
106 106 summary: 2
107 107
108 108 abort: crosses branches (use 'hg merge' or 'hg update -C' to discard changes)
109 109 failed
110 abort: outstanding uncommitted changes
110 abort: outstanding uncommitted changes (use 'hg status' to list changes)
111 111 failed
112 112 resolving manifests
113 113 overwrite False partial False
114 114 ancestor 33aaa84a386b local 802f095af299+ remote 030602aee63d
115 115 searching for copies back to rev 1
116 116 a: versions differ -> m
117 117 b: versions differ -> m
118 118 preserving a for resolve of a
119 119 preserving b for resolve of b
120 120 picked tool 'true' for a (binary False symlink False)
121 121 merging a
122 122 my a@802f095af299+ other a@030602aee63d ancestor a@33aaa84a386b
123 123 picked tool 'true' for b (binary False symlink False)
124 124 merging b
125 125 my b@802f095af299+ other b@030602aee63d ancestor b@000000000000
126 126 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
127 127 (branch merge, don't forget to commit)
128 128 changeset: 1:802f095af299
129 129 user: test
130 130 date: Mon Jan 12 13:46:40 1970 +0000
131 131 summary: 2
132 132
133 133 changeset: 2:030602aee63d
134 134 tag: tip
135 135 parent: 0:33aaa84a386b
136 136 user: test
137 137 date: Mon Jan 12 13:46:40 1970 +0000
138 138 summary: 3
139 139
140 140 diff -r 802f095af299 a
141 141 --- a/a
142 142 +++ b/a
143 143 @@ -1,1 +1,1 @@
144 144 -a2
145 145 +abc
146 146 adding a
147 147 pulling from ../a
148 148 requesting all changes
149 149 adding changesets
150 150 adding manifests
151 151 adding file changes
152 152 added 1 changesets with 1 changes to 1 files
153 153 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