##// END OF EJS Templates
merge: simplify actions with helper function
Matt Mackall -
r3121:2ef0b3aa default
parent child Browse files
Show More
@@ -1,345 +1,337 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 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006 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 gettext as _
9 from i18n import gettext as _
10 from demandload import *
10 from demandload import *
11 demandload(globals(), "errno util os tempfile")
11 demandload(globals(), "errno util os tempfile")
12
12
13 def merge3(repo, fn, my, other, p1, p2):
13 def merge3(repo, fn, my, other, p1, p2):
14 """perform a 3-way merge in the working directory"""
14 """perform a 3-way merge in the working directory"""
15
15
16 def temp(prefix, node):
16 def temp(prefix, node):
17 pre = "%s~%s." % (os.path.basename(fn), prefix)
17 pre = "%s~%s." % (os.path.basename(fn), prefix)
18 (fd, name) = tempfile.mkstemp(prefix=pre)
18 (fd, name) = tempfile.mkstemp(prefix=pre)
19 f = os.fdopen(fd, "wb")
19 f = os.fdopen(fd, "wb")
20 repo.wwrite(fn, fl.read(node), f)
20 repo.wwrite(fn, fl.read(node), f)
21 f.close()
21 f.close()
22 return name
22 return name
23
23
24 fl = repo.file(fn)
24 fl = repo.file(fn)
25 base = fl.ancestor(my, other)
25 base = fl.ancestor(my, other)
26 a = repo.wjoin(fn)
26 a = repo.wjoin(fn)
27 b = temp("base", base)
27 b = temp("base", base)
28 c = temp("other", other)
28 c = temp("other", other)
29
29
30 repo.ui.note(_("resolving %s\n") % fn)
30 repo.ui.note(_("resolving %s\n") % fn)
31 repo.ui.debug(_("file %s: my %s other %s ancestor %s\n") %
31 repo.ui.debug(_("file %s: my %s other %s ancestor %s\n") %
32 (fn, short(my), short(other), short(base)))
32 (fn, short(my), short(other), short(base)))
33
33
34 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
34 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
35 or "hgmerge")
35 or "hgmerge")
36 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
36 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
37 environ={'HG_FILE': fn,
37 environ={'HG_FILE': fn,
38 'HG_MY_NODE': p1,
38 'HG_MY_NODE': p1,
39 'HG_OTHER_NODE': p2,
39 'HG_OTHER_NODE': p2,
40 'HG_FILE_MY_NODE': hex(my),
40 'HG_FILE_MY_NODE': hex(my),
41 'HG_FILE_OTHER_NODE': hex(other),
41 'HG_FILE_OTHER_NODE': hex(other),
42 'HG_FILE_BASE_NODE': hex(base)})
42 'HG_FILE_BASE_NODE': hex(base)})
43 if r:
43 if r:
44 repo.ui.warn(_("merging %s failed!\n") % fn)
44 repo.ui.warn(_("merging %s failed!\n") % fn)
45
45
46 os.unlink(b)
46 os.unlink(b)
47 os.unlink(c)
47 os.unlink(c)
48 return r
48 return r
49
49
50 def checkunknown(repo, m2, status):
50 def checkunknown(repo, m2, status):
51 """
51 """
52 check for collisions between unknown files and files in m2
52 check for collisions between unknown files and files in m2
53 """
53 """
54 modified, added, removed, deleted, unknown = status[:5]
54 modified, added, removed, deleted, unknown = status[:5]
55 for f in unknown:
55 for f in unknown:
56 if f in m2:
56 if f in m2:
57 if repo.file(f).cmp(m2[f], repo.wread(f)):
57 if repo.file(f).cmp(m2[f], repo.wread(f)):
58 raise util.Abort(_("'%s' already exists in the working"
58 raise util.Abort(_("'%s' already exists in the working"
59 " dir and differs from remote") % f)
59 " dir and differs from remote") % f)
60
60
61 def workingmanifest(repo, man, status):
61 def workingmanifest(repo, man, status):
62 """
62 """
63 Update manifest to correspond to the working directory
63 Update manifest to correspond to the working directory
64 """
64 """
65
65
66 modified, added, removed, deleted, unknown = status[:5]
66 modified, added, removed, deleted, unknown = status[:5]
67 for i,l in (("a", added), ("m", modified), ("u", unknown)):
67 for i,l in (("a", added), ("m", modified), ("u", unknown)):
68 for f in l:
68 for f in l:
69 man[f] = man.get(f, nullid) + i
69 man[f] = man.get(f, nullid) + i
70 man.set(f, util.is_exec(repo.wjoin(f), man.execf(f)))
70 man.set(f, util.is_exec(repo.wjoin(f), man.execf(f)))
71
71
72 for f in deleted + removed:
72 for f in deleted + removed:
73 del man[f]
73 del man[f]
74
74
75 return man
75 return man
76
76
77 def forgetremoved(m2, status):
77 def forgetremoved(m2, status):
78 """
78 """
79 Forget removed files
79 Forget removed files
80
80
81 If we're jumping between revisions (as opposed to merging), and if
81 If we're jumping between revisions (as opposed to merging), and if
82 neither the working directory nor the target rev has the file,
82 neither the working directory nor the target rev has the file,
83 then we need to remove it from the dirstate, to prevent the
83 then we need to remove it from the dirstate, to prevent the
84 dirstate from listing the file when it is no longer in the
84 dirstate from listing the file when it is no longer in the
85 manifest.
85 manifest.
86 """
86 """
87
87
88 modified, added, removed, deleted, unknown = status[:5]
88 modified, added, removed, deleted, unknown = status[:5]
89 action = []
89 action = []
90
90
91 for f in deleted + removed:
91 for f in deleted + removed:
92 if f not in m2:
92 if f not in m2:
93 action.append((f, "f"))
93 action.append((f, "f"))
94
94
95 return action
95 return action
96
96
97 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial):
97 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial):
98 """
98 """
99 Merge manifest m1 with m2 using ancestor ma and generate merge action list
99 Merge manifest m1 with m2 using ancestor ma and generate merge action list
100 """
100 """
101
101
102 def fmerge(f):
102 def fmerge(f):
103 """merge executable flags"""
103 """merge executable flags"""
104 a, b, c = ma.execf(f), m1.execf(f), m2.execf(f)
104 a, b, c = ma.execf(f), m1.execf(f), m2.execf(f)
105 return ((a^b) | (a^c)) ^ a
105 return ((a^b) | (a^c)) ^ a
106
106
107 action = []
107 action = []
108
108
109 def act(msg, f, m, *args):
110 ui.debug(" %s: %s -> %s\n" % (f, msg, m))
111 action.append((f, m) + args)
112
109 # Filter manifests
113 # Filter manifests
110 if partial:
114 if partial:
111 for f in m1.keys():
115 for f in m1.keys():
112 if not partial(f): del m1[f]
116 if not partial(f): del m1[f]
113 for f in m2.keys():
117 for f in m2.keys():
114 if not partial(f): del m2[f]
118 if not partial(f): del m2[f]
115
119
116 # Compare manifests
120 # Compare manifests
117 for f, n in m1.iteritems():
121 for f, n in m1.iteritems():
118 if f in m2:
122 if f in m2:
119 # are files different?
123 # are files different?
120 if n != m2[f]:
124 if n != m2[f]:
121 a = ma.get(f, nullid)
125 a = ma.get(f, nullid)
122 # are both different from the ancestor?
126 # are both different from the ancestor?
123 if not overwrite and n != a and m2[f] != a:
127 if not overwrite and n != a and m2[f] != a:
124 ui.debug(_(" %s versions differ, resolve\n") % f)
128 act("versions differ", f, "m", fmerge(f), n[:20], m2[f])
125 action.append((f, "m", fmerge(f), n[:20], m2[f]))
126 # are we clobbering?
129 # are we clobbering?
127 # is remote's version newer?
130 # is remote's version newer?
128 # or are we going back in time and clean?
131 # or are we going back in time and clean?
129 elif overwrite or m2[f] != a or (backwards and not n[20:]):
132 elif overwrite or m2[f] != a or (backwards and not n[20:]):
130 ui.debug(_(" remote %s is newer, get\n") % f)
133 act("remote is newer", f, "g", m2.execf(f), m2[f])
131 action.append((f, "g", m2.execf(f), m2[f]))
132 # local is newer, not overwrite, check mode bits
134 # local is newer, not overwrite, check mode bits
133 elif fmerge(f) != m1.execf(f):
135 elif fmerge(f) != m1.execf(f):
134 ui.debug(_(" updating permissions for %s\n") % f)
136 act("update permissions", f, "e", m2.execf(f))
135 action.append((f, "e", m2.execf(f)))
136 # contents same, check mode bits
137 # contents same, check mode bits
137 elif m1.execf(f) != m2.execf(f):
138 elif m1.execf(f) != m2.execf(f):
138 if overwrite or fmerge(f) != m1.execf(f):
139 if overwrite or fmerge(f) != m1.execf(f):
139 ui.debug(_(" updating permissions for %s\n") % f)
140 act("update permissions", f, "e", m2.execf(f))
140 action.append((f, "e", m2.execf(f)))
141 del m2[f]
141 del m2[f]
142 elif f in ma:
142 elif f in ma:
143 if n != ma[f] and not overwrite:
143 if n != ma[f] and not overwrite:
144 if ui.prompt(
144 if ui.prompt(
145 (_(" local changed %s which remote deleted\n") % f) +
145 (_(" local changed %s which remote deleted\n") % f) +
146 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
146 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
147 action.append((f, "r"))
147 act("prompt delete", f, "r")
148 else:
148 else:
149 ui.debug(_("other deleted %s\n") % f)
149 act("other deleted", f, "r")
150 action.append((f, "r"))
151 else:
150 else:
152 # file is created on branch or in working directory
151 # file is created on branch or in working directory
153 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
152 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
154 ui.debug(_("remote deleted %s, clobbering\n") % f)
153 act("remote deleted", f, "r")
155 action.append((f, "r"))
156 else:
157 ui.debug(_("local created %s, keeping\n") % f)
158
154
159 for f, n in m2.iteritems():
155 for f, n in m2.iteritems():
160 if f in ma:
156 if f in ma:
161 if overwrite or backwards:
157 if overwrite or backwards:
162 ui.debug(_("local deleted %s, recreating\n") % f)
158 act("recreating", f, "g", m2.execf(f), n)
163 action.append((f, "g", m2.execf(f), n))
164 elif n != ma[f]:
159 elif n != ma[f]:
165 if ui.prompt(
160 if ui.prompt(
166 (_("remote changed %s which local deleted\n") % f) +
161 (_("remote changed %s which local deleted\n") % f) +
167 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
162 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
168 action.append((f, "g", m2.execf(f), n))
163 act("prompt recreating", f, "g", m2.execf(f), n)
169 else:
170 ui.debug(_("local deleted %s\n") % f)
171 else:
164 else:
172 ui.debug(_("remote created %s\n") % f)
165 act("remote created", f, "g", m2.execf(f), n)
173 action.append((f, "g", m2.execf(f), n))
174
166
175 return action
167 return action
176
168
177 def applyupdates(repo, action, xp1, xp2):
169 def applyupdates(repo, action, xp1, xp2):
178 updated, merged, removed, unresolved = 0, 0, 0, 0
170 updated, merged, removed, unresolved = 0, 0, 0, 0
179 action.sort()
171 action.sort()
180 for a in action:
172 for a in action:
181 f, m = a[:2]
173 f, m = a[:2]
182 if f[0] == "/":
174 if f[0] == "/":
183 continue
175 continue
184 if m == "r": # remove
176 if m == "r": # remove
185 repo.ui.note(_("removing %s\n") % f)
177 repo.ui.note(_("removing %s\n") % f)
186 util.audit_path(f)
178 util.audit_path(f)
187 try:
179 try:
188 util.unlink(repo.wjoin(f))
180 util.unlink(repo.wjoin(f))
189 except OSError, inst:
181 except OSError, inst:
190 if inst.errno != errno.ENOENT:
182 if inst.errno != errno.ENOENT:
191 repo.ui.warn(_("update failed to remove %s: %s!\n") %
183 repo.ui.warn(_("update failed to remove %s: %s!\n") %
192 (f, inst.strerror))
184 (f, inst.strerror))
193 removed +=1
185 removed +=1
194 elif m == "m": # merge
186 elif m == "m": # merge
195 flag, my, other = a[2:]
187 flag, my, other = a[2:]
196 repo.ui.status(_("merging %s\n") % f)
188 repo.ui.status(_("merging %s\n") % f)
197 if merge3(repo, f, my, other, xp1, xp2):
189 if merge3(repo, f, my, other, xp1, xp2):
198 unresolved += 1
190 unresolved += 1
199 util.set_exec(repo.wjoin(f), flag)
191 util.set_exec(repo.wjoin(f), flag)
200 merged += 1
192 merged += 1
201 elif m == "g": # get
193 elif m == "g": # get
202 flag, node = a[2:]
194 flag, node = a[2:]
203 repo.ui.note(_("getting %s\n") % f)
195 repo.ui.note(_("getting %s\n") % f)
204 t = repo.file(f).read(node)
196 t = repo.file(f).read(node)
205 repo.wwrite(f, t)
197 repo.wwrite(f, t)
206 util.set_exec(repo.wjoin(f), flag)
198 util.set_exec(repo.wjoin(f), flag)
207 updated += 1
199 updated += 1
208 elif m == "e": # exec
200 elif m == "e": # exec
209 flag = a[2:]
201 flag = a[2:]
210 util.set_exec(repo.wjoin(f), flag)
202 util.set_exec(repo.wjoin(f), flag)
211
203
212 return updated, merged, removed, unresolved
204 return updated, merged, removed, unresolved
213
205
214 def recordupdates(repo, action, branchmerge):
206 def recordupdates(repo, action, branchmerge):
215 for a in action:
207 for a in action:
216 f, m = a[:2]
208 f, m = a[:2]
217 if m == "r": # remove
209 if m == "r": # remove
218 if branchmerge:
210 if branchmerge:
219 repo.dirstate.update([f], 'r')
211 repo.dirstate.update([f], 'r')
220 else:
212 else:
221 repo.dirstate.forget([f])
213 repo.dirstate.forget([f])
222 elif m == "f": # forget
214 elif m == "f": # forget
223 repo.dirstate.forget([f])
215 repo.dirstate.forget([f])
224 elif m == "g": # get
216 elif m == "g": # get
225 if branchmerge:
217 if branchmerge:
226 repo.dirstate.update([f], 'n', st_mtime=-1)
218 repo.dirstate.update([f], 'n', st_mtime=-1)
227 else:
219 else:
228 repo.dirstate.update([f], 'n')
220 repo.dirstate.update([f], 'n')
229 elif m == "m": # merge
221 elif m == "m": # merge
230 flag, my, other = a[2:]
222 flag, my, other = a[2:]
231 if branchmerge:
223 if branchmerge:
232 # We've done a branch merge, mark this file as merged
224 # We've done a branch merge, mark this file as merged
233 # so that we properly record the merger later
225 # so that we properly record the merger later
234 repo.dirstate.update([f], 'm')
226 repo.dirstate.update([f], 'm')
235 else:
227 else:
236 # We've update-merged a locally modified file, so
228 # We've update-merged a locally modified file, so
237 # we set the dirstate to emulate a normal checkout
229 # we set the dirstate to emulate a normal checkout
238 # of that file some time in the past. Thus our
230 # of that file some time in the past. Thus our
239 # merge will appear as a normal local file
231 # merge will appear as a normal local file
240 # modification.
232 # modification.
241 fl = repo.file(f)
233 fl = repo.file(f)
242 f_len = fl.size(fl.rev(other))
234 f_len = fl.size(fl.rev(other))
243 repo.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1)
235 repo.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1)
244
236
245 def update(repo, node, branchmerge=False, force=False, partial=None,
237 def update(repo, node, branchmerge=False, force=False, partial=None,
246 wlock=None, show_stats=True, remind=True):
238 wlock=None, show_stats=True, remind=True):
247
239
248 overwrite = force and not branchmerge
240 overwrite = force and not branchmerge
249 forcemerge = force and branchmerge
241 forcemerge = force and branchmerge
250
242
251 if not wlock:
243 if not wlock:
252 wlock = repo.wlock()
244 wlock = repo.wlock()
253
245
254 ### check phase
246 ### check phase
255
247
256 pl = repo.dirstate.parents()
248 pl = repo.dirstate.parents()
257 if not overwrite and pl[1] != nullid:
249 if not overwrite and pl[1] != nullid:
258 raise util.Abort(_("outstanding uncommitted merges"))
250 raise util.Abort(_("outstanding uncommitted merges"))
259
251
260 p1, p2 = pl[0], node
252 p1, p2 = pl[0], node
261 pa = repo.changelog.ancestor(p1, p2)
253 pa = repo.changelog.ancestor(p1, p2)
262
254
263 # are we going backwards?
255 # are we going backwards?
264 backwards = (pa == p2)
256 backwards = (pa == p2)
265
257
266 # is there a linear path from p1 to p2?
258 # is there a linear path from p1 to p2?
267 if pa == p1 or pa == p2:
259 if pa == p1 or pa == p2:
268 if branchmerge:
260 if branchmerge:
269 raise util.Abort(_("there is nothing to merge, just use "
261 raise util.Abort(_("there is nothing to merge, just use "
270 "'hg update' or look at 'hg heads'"))
262 "'hg update' or look at 'hg heads'"))
271 elif not (overwrite or branchmerge):
263 elif not (overwrite or branchmerge):
272 raise util.Abort(_("update spans branches, use 'hg merge' "
264 raise util.Abort(_("update spans branches, use 'hg merge' "
273 "or 'hg update -C' to lose changes"))
265 "or 'hg update -C' to lose changes"))
274
266
275 status = repo.status()
267 status = repo.status()
276 modified, added, removed, deleted, unknown = status[:5]
268 modified, added, removed, deleted, unknown = status[:5]
277 if branchmerge and not forcemerge:
269 if branchmerge and not forcemerge:
278 if modified or added or removed:
270 if modified or added or removed:
279 raise util.Abort(_("outstanding uncommitted changes"))
271 raise util.Abort(_("outstanding uncommitted changes"))
280
272
281 m1 = repo.changectx(p1).manifest().copy()
273 m1 = repo.changectx(p1).manifest().copy()
282 m2 = repo.changectx(p2).manifest().copy()
274 m2 = repo.changectx(p2).manifest().copy()
283 ma = repo.changectx(pa).manifest()
275 ma = repo.changectx(pa).manifest()
284
276
285 # resolve the manifest to determine which files
277 # resolve the manifest to determine which files
286 # we care about merging
278 # we care about merging
287 repo.ui.note(_("resolving manifests\n"))
279 repo.ui.note(_("resolving manifests\n"))
288 repo.ui.debug(_(" overwrite %s branchmerge %s partial %s\n") %
280 repo.ui.debug(_(" overwrite %s branchmerge %s partial %s\n") %
289 (overwrite, branchmerge, bool(partial)))
281 (overwrite, branchmerge, bool(partial)))
290 repo.ui.debug(_(" ancestor %s local %s remote %s\n") %
282 repo.ui.debug(_(" ancestor %s local %s remote %s\n") %
291 (short(p1), short(p2), short(pa)))
283 (short(p1), short(p2), short(pa)))
292
284
293 action = []
285 action = []
294 m1 = workingmanifest(repo, m1, status)
286 m1 = workingmanifest(repo, m1, status)
295
287
296 if not force:
288 if not force:
297 checkunknown(repo, m2, status)
289 checkunknown(repo, m2, status)
298 if not branchmerge:
290 if not branchmerge:
299 action += forgetremoved(m2, status)
291 action += forgetremoved(m2, status)
300 action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial)
292 action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial)
301 del m1, m2, ma
293 del m1, m2, ma
302
294
303 ### apply phase
295 ### apply phase
304
296
305 if not branchmerge:
297 if not branchmerge:
306 # we don't need to do any magic, just jump to the new rev
298 # we don't need to do any magic, just jump to the new rev
307 p1, p2 = p2, nullid
299 p1, p2 = p2, nullid
308
300
309 xp1, xp2 = hex(p1), hex(p2)
301 xp1, xp2 = hex(p1), hex(p2)
310 if p2 == nullid: xp2 = ''
302 if p2 == nullid: xp2 = ''
311
303
312 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
304 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
313
305
314 updated, merged, removed, unresolved = applyupdates(repo, action, xp1, xp2)
306 updated, merged, removed, unresolved = applyupdates(repo, action, xp1, xp2)
315
307
316 # update dirstate
308 # update dirstate
317 if not partial:
309 if not partial:
318 repo.dirstate.setparents(p1, p2)
310 repo.dirstate.setparents(p1, p2)
319 recordupdates(repo, action, branchmerge)
311 recordupdates(repo, action, branchmerge)
320
312
321 if show_stats:
313 if show_stats:
322 stats = ((updated, _("updated")),
314 stats = ((updated, _("updated")),
323 (merged - unresolved, _("merged")),
315 (merged - unresolved, _("merged")),
324 (removed, _("removed")),
316 (removed, _("removed")),
325 (unresolved, _("unresolved")))
317 (unresolved, _("unresolved")))
326 note = ", ".join([_("%d files %s") % s for s in stats])
318 note = ", ".join([_("%d files %s") % s for s in stats])
327 repo.ui.status("%s\n" % note)
319 repo.ui.status("%s\n" % note)
328 if not partial:
320 if not partial:
329 if branchmerge:
321 if branchmerge:
330 if unresolved:
322 if unresolved:
331 repo.ui.status(_("There are unresolved merges,"
323 repo.ui.status(_("There are unresolved merges,"
332 " you can redo the full merge using:\n"
324 " you can redo the full merge using:\n"
333 " hg update -C %s\n"
325 " hg update -C %s\n"
334 " hg merge %s\n"
326 " hg merge %s\n"
335 % (repo.changelog.rev(p1),
327 % (repo.changelog.rev(p1),
336 repo.changelog.rev(p2))))
328 repo.changelog.rev(p2))))
337 elif remind:
329 elif remind:
338 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
330 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
339 elif unresolved:
331 elif unresolved:
340 repo.ui.status(_("There are unresolved merges with"
332 repo.ui.status(_("There are unresolved merges with"
341 " locally modified files.\n"))
333 " locally modified files.\n"))
342
334
343 repo.hook('update', parent1=xp1, parent2=xp2, error=unresolved)
335 repo.hook('update', parent1=xp1, parent2=xp2, error=unresolved)
344 return unresolved
336 return unresolved
345
337
@@ -1,78 +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 merge: warning: conflicts during merge
9 merge: 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 merge: warning: conflicts during merge
23 merge: warning: conflicts during merge
24 resolving manifests
24 resolving manifests
25 overwrite None branchmerge True partial False
25 overwrite None branchmerge True partial False
26 ancestor 451c744aabcc local a070d41e8360 remote faaea63e63a9
26 ancestor 451c744aabcc local a070d41e8360 remote faaea63e63a9
27 test.txt versions differ, resolve
27 test.txt: versions differ -> m
28 merging test.txt
28 merging test.txt
29 resolving test.txt
29 resolving test.txt
30 file test.txt: my fc3148072371 other d40249267ae3 ancestor 8fe46a3eb557
30 file test.txt: my fc3148072371 other d40249267ae3 ancestor 8fe46a3eb557
31 merging test.txt failed!
31 merging test.txt failed!
32 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
33 There are unresolved merges, you can redo the full merge using:
33 There are unresolved merges, you can redo the full merge using:
34 hg update -C 3
34 hg update -C 3
35 hg merge 4
35 hg merge 4
36 one
36 one
37 <<<<<<<
37 <<<<<<<
38 two-point-five
38 two-point-five
39 =======
39 =======
40 two-point-one
40 two-point-one
41 >>>>>>>
41 >>>>>>>
42 three
42 three
43 rev offset length base linkrev nodeid p1 p2
43 rev offset length base linkrev nodeid p1 p2
44 0 0 7 0 0 01365c4cca56 000000000000 000000000000
44 0 0 7 0 0 01365c4cca56 000000000000 000000000000
45 1 7 9 1 1 7b013192566a 01365c4cca56 000000000000
45 1 7 9 1 1 7b013192566a 01365c4cca56 000000000000
46 2 16 15 2 2 8fe46a3eb557 01365c4cca56 000000000000
46 2 16 15 2 2 8fe46a3eb557 01365c4cca56 000000000000
47 3 31 27 2 3 fc3148072371 7b013192566a 8fe46a3eb557
47 3 31 27 2 3 fc3148072371 7b013192566a 8fe46a3eb557
48 4 58 25 4 4 d40249267ae3 8fe46a3eb557 000000000000
48 4 58 25 4 4 d40249267ae3 8fe46a3eb557 000000000000
49 changeset: 4:a070d41e8360
49 changeset: 4:a070d41e8360
50 tag: tip
50 tag: tip
51 parent: 2:faaea63e63a9
51 parent: 2:faaea63e63a9
52 user: test
52 user: test
53 date: Mon Jan 12 13:46:40 1970 +0000
53 date: Mon Jan 12 13:46:40 1970 +0000
54 summary: two -> two-point-one
54 summary: two -> two-point-one
55
55
56 changeset: 3:451c744aabcc
56 changeset: 3:451c744aabcc
57 parent: 1:e409be6afcc0
57 parent: 1:e409be6afcc0
58 parent: 2:faaea63e63a9
58 parent: 2:faaea63e63a9
59 user: test
59 user: test
60 date: Mon Jan 12 13:46:40 1970 +0000
60 date: Mon Jan 12 13:46:40 1970 +0000
61 summary: Merge 1
61 summary: Merge 1
62
62
63 changeset: 2:faaea63e63a9
63 changeset: 2:faaea63e63a9
64 parent: 0:095c92b91f1a
64 parent: 0:095c92b91f1a
65 user: test
65 user: test
66 date: Mon Jan 12 13:46:40 1970 +0000
66 date: Mon Jan 12 13:46:40 1970 +0000
67 summary: Numbers as words
67 summary: Numbers as words
68
68
69 changeset: 1:e409be6afcc0
69 changeset: 1:e409be6afcc0
70 user: test
70 user: test
71 date: Mon Jan 12 13:46:40 1970 +0000
71 date: Mon Jan 12 13:46:40 1970 +0000
72 summary: 2 -> 2.5
72 summary: 2 -> 2.5
73
73
74 changeset: 0:095c92b91f1a
74 changeset: 0:095c92b91f1a
75 user: test
75 user: test
76 date: Mon Jan 12 13:46:40 1970 +0000
76 date: Mon Jan 12 13:46:40 1970 +0000
77 summary: Initial
77 summary: Initial
78
78
@@ -1,141 +1,141 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 branchmerge False partial False
18 overwrite False branchmerge False partial False
19 ancestor 33aaa84a386b local 802f095af299 remote 33aaa84a386b
19 ancestor 33aaa84a386b local 802f095af299 remote 33aaa84a386b
20 a versions differ, resolve
20 a: versions differ -> m
21 remote created b
21 b: remote created -> g
22 merging a
22 merging a
23 resolving a
23 resolving a
24 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
24 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
25 getting b
25 getting b
26 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
26 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
27 changeset: 1:802f095af299
27 changeset: 1:802f095af299
28 tag: tip
28 tag: tip
29 user: test
29 user: test
30 date: Mon Jan 12 13:46:40 1970 +0000
30 date: Mon Jan 12 13:46:40 1970 +0000
31 summary: 2
31 summary: 2
32
32
33 resolving manifests
33 resolving manifests
34 overwrite False branchmerge False partial False
34 overwrite False branchmerge False partial False
35 ancestor 802f095af299 local 33aaa84a386b remote 33aaa84a386b
35 ancestor 802f095af299 local 33aaa84a386b remote 33aaa84a386b
36 remote deleted b, clobbering
36 b: remote deleted -> r
37 removing b
37 removing b
38 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
38 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
39 changeset: 0:33aaa84a386b
39 changeset: 0:33aaa84a386b
40 user: test
40 user: test
41 date: Mon Jan 12 13:46:40 1970 +0000
41 date: Mon Jan 12 13:46:40 1970 +0000
42 summary: 1
42 summary: 1
43
43
44 abort: there is nothing to merge - use "hg update" instead
44 abort: there is nothing to merge - use "hg update" instead
45 failed
45 failed
46 changeset: 0:33aaa84a386b
46 changeset: 0:33aaa84a386b
47 user: test
47 user: test
48 date: Mon Jan 12 13:46:40 1970 +0000
48 date: Mon Jan 12 13:46:40 1970 +0000
49 summary: 1
49 summary: 1
50
50
51 resolving manifests
51 resolving manifests
52 overwrite False branchmerge False partial False
52 overwrite False branchmerge False partial False
53 ancestor 33aaa84a386b local 802f095af299 remote 33aaa84a386b
53 ancestor 33aaa84a386b local 802f095af299 remote 33aaa84a386b
54 a versions differ, resolve
54 a: versions differ -> m
55 remote created b
55 b: remote created -> g
56 merging a
56 merging a
57 resolving a
57 resolving a
58 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
58 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
59 getting b
59 getting b
60 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
60 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
61 changeset: 1:802f095af299
61 changeset: 1:802f095af299
62 tag: tip
62 tag: tip
63 user: test
63 user: test
64 date: Mon Jan 12 13:46:40 1970 +0000
64 date: Mon Jan 12 13:46:40 1970 +0000
65 summary: 2
65 summary: 2
66
66
67 changeset: 1:802f095af299
67 changeset: 1:802f095af299
68 tag: tip
68 tag: tip
69 user: test
69 user: test
70 date: Mon Jan 12 13:46:40 1970 +0000
70 date: Mon Jan 12 13:46:40 1970 +0000
71 files: a b
71 files: a b
72 description:
72 description:
73 2
73 2
74
74
75
75
76 changeset: 0:33aaa84a386b
76 changeset: 0:33aaa84a386b
77 user: test
77 user: test
78 date: Mon Jan 12 13:46:40 1970 +0000
78 date: Mon Jan 12 13:46:40 1970 +0000
79 files: a
79 files: a
80 description:
80 description:
81 1
81 1
82
82
83
83
84 diff -r 802f095af299 a
84 diff -r 802f095af299 a
85 --- a/a
85 --- a/a
86 +++ b/a
86 +++ b/a
87 @@ -1,1 +1,1 @@ a2
87 @@ -1,1 +1,1 @@ a2
88 -a2
88 -a2
89 +abc
89 +abc
90 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
90 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
91 adding b
91 adding b
92 M a
92 M a
93 changeset: 1:802f095af299
93 changeset: 1:802f095af299
94 user: test
94 user: test
95 date: Mon Jan 12 13:46:40 1970 +0000
95 date: Mon Jan 12 13:46:40 1970 +0000
96 summary: 2
96 summary: 2
97
97
98 abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
98 abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
99 failed
99 failed
100 abort: outstanding uncommitted changes
100 abort: outstanding uncommitted changes
101 failed
101 failed
102 resolving manifests
102 resolving manifests
103 overwrite False branchmerge True partial False
103 overwrite False branchmerge True partial False
104 ancestor 802f095af299 local 030602aee63d remote 33aaa84a386b
104 ancestor 802f095af299 local 030602aee63d remote 33aaa84a386b
105 a versions differ, resolve
105 a: versions differ -> m
106 b versions differ, resolve
106 b: versions differ -> m
107 merging a
107 merging a
108 resolving a
108 resolving a
109 file a: my d730145abbf9 other 13e0d5f949fa ancestor b789fdd96dc2
109 file a: my d730145abbf9 other 13e0d5f949fa ancestor b789fdd96dc2
110 merging b
110 merging b
111 resolving b
111 resolving b
112 file b: my 1e88685f5dde other 61de8c7723ca ancestor 000000000000
112 file b: my 1e88685f5dde other 61de8c7723ca ancestor 000000000000
113 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
113 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
114 (branch merge, don't forget to commit)
114 (branch merge, don't forget to commit)
115 changeset: 1:802f095af299
115 changeset: 1:802f095af299
116 user: test
116 user: test
117 date: Mon Jan 12 13:46:40 1970 +0000
117 date: Mon Jan 12 13:46:40 1970 +0000
118 summary: 2
118 summary: 2
119
119
120 changeset: 2:030602aee63d
120 changeset: 2:030602aee63d
121 tag: tip
121 tag: tip
122 parent: 0:33aaa84a386b
122 parent: 0:33aaa84a386b
123 user: test
123 user: test
124 date: Mon Jan 12 13:46:40 1970 +0000
124 date: Mon Jan 12 13:46:40 1970 +0000
125 summary: 3
125 summary: 3
126
126
127 diff -r 802f095af299 a
127 diff -r 802f095af299 a
128 --- a/a
128 --- a/a
129 +++ b/a
129 +++ b/a
130 @@ -1,1 +1,1 @@ a2
130 @@ -1,1 +1,1 @@ a2
131 -a2
131 -a2
132 +abc
132 +abc
133 adding a
133 adding a
134 pulling from ../a
134 pulling from ../a
135 requesting all changes
135 requesting all changes
136 adding changesets
136 adding changesets
137 adding manifests
137 adding manifests
138 adding file changes
138 adding file changes
139 added 1 changesets with 1 changes to 1 files
139 added 1 changesets with 1 changes to 1 files
140 merging a
140 merging a
141 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
141 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
@@ -1,54 +1,54 b''
1 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2 Main should be gone
2 Main should be gone
3 a
3 a
4 changeset: 3:ded32b0db104
4 changeset: 3:ded32b0db104
5 tag: tip
5 tag: tip
6 user: test
6 user: test
7 date: Mon Jan 12 13:46:40 1970 +0000
7 date: Mon Jan 12 13:46:40 1970 +0000
8 summary: Added side2
8 summary: Added side2
9
9
10 changeset: 2:92a816cea698
10 changeset: 2:92a816cea698
11 parent: 0:537353581d3d
11 parent: 0:537353581d3d
12 user: test
12 user: test
13 date: Mon Jan 12 13:46:40 1970 +0000
13 date: Mon Jan 12 13:46:40 1970 +0000
14 summary: Added side1
14 summary: Added side1
15
15
16 changeset: 1:221226fb2bd8
16 changeset: 1:221226fb2bd8
17 user: test
17 user: test
18 date: Mon Jan 12 13:46:40 1970 +0000
18 date: Mon Jan 12 13:46:40 1970 +0000
19 summary: Added main
19 summary: Added main
20
20
21 changeset: 0:537353581d3d
21 changeset: 0:537353581d3d
22 user: test
22 user: test
23 date: Mon Jan 12 13:46:40 1970 +0000
23 date: Mon Jan 12 13:46:40 1970 +0000
24 summary: Added a
24 summary: Added a
25
25
26 Should have two heads, side2 and main
26 Should have two heads, side2 and main
27 changeset: 3:ded32b0db104
27 changeset: 3:ded32b0db104
28 tag: tip
28 tag: tip
29 user: test
29 user: test
30 date: Mon Jan 12 13:46:40 1970 +0000
30 date: Mon Jan 12 13:46:40 1970 +0000
31 summary: Added side2
31 summary: Added side2
32
32
33 changeset: 1:221226fb2bd8
33 changeset: 1:221226fb2bd8
34 user: test
34 user: test
35 date: Mon Jan 12 13:46:40 1970 +0000
35 date: Mon Jan 12 13:46:40 1970 +0000
36 summary: Added main
36 summary: Added main
37
37
38 Should show a side1 side2
38 Should show a side1 side2
39 a
39 a
40 side1
40 side1
41 side2
41 side2
42 resolving manifests
42 resolving manifests
43 overwrite True branchmerge False partial False
43 overwrite True branchmerge False partial False
44 ancestor ded32b0db104 local 221226fb2bd8 remote 537353581d3d
44 ancestor ded32b0db104 local 221226fb2bd8 remote 537353581d3d
45 remote deleted side2, clobbering
45 side2: remote deleted -> r
46 remote deleted side1, clobbering
46 side1: remote deleted -> r
47 remote created main
47 main: remote created -> g
48 getting main
48 getting main
49 removing side1
49 removing side1
50 removing side2
50 removing side2
51 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
51 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
52 Should only show a main
52 Should only show a main
53 a
53 a
54 main
54 main
General Comments 0
You need to be logged in to leave comments. Login now