Show More
@@ -0,0 +1,32 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | mkdir t | |||
|
4 | cd t | |||
|
5 | hg init | |||
|
6 | ||||
|
7 | mkdir a | |||
|
8 | echo foo > a/a | |||
|
9 | echo bar > a/b | |||
|
10 | ||||
|
11 | hg add a | |||
|
12 | hg ci -m "0" -d "0 0" | |||
|
13 | ||||
|
14 | hg co -C 0 | |||
|
15 | hg mv a b | |||
|
16 | hg ci -m "1 mv a/ b/" -d "0 0" | |||
|
17 | ||||
|
18 | hg co -C 0 | |||
|
19 | echo baz > a/c | |||
|
20 | hg add a/c | |||
|
21 | hg ci -m "2 add a/c" -d "0 0" | |||
|
22 | ||||
|
23 | hg merge --debug 1 | |||
|
24 | ls a/ b/ | |||
|
25 | hg st -C | |||
|
26 | hg ci -m "3 merge 2+1" -d "0 0" | |||
|
27 | ||||
|
28 | hg co -C 1 | |||
|
29 | hg merge --debug 2 | |||
|
30 | ls a/ b/ | |||
|
31 | hg st -C | |||
|
32 | hg ci -m "4 merge 1+2" -d "0 0" |
@@ -553,9 +553,11 b' class localrepository(repo.repository):' | |||||
553 | fp2 = nullid |
|
553 | fp2 = nullid | |
554 | elif fp2 != nullid: # copied on remote side |
|
554 | elif fp2 != nullid: # copied on remote side | |
555 | meta["copyrev"] = hex(manifest1.get(cp, nullid)) |
|
555 | meta["copyrev"] = hex(manifest1.get(cp, nullid)) | |
556 |
el |
|
556 | elif fp1 != nullid: # copied on local side, reversed | |
557 | meta["copyrev"] = hex(manifest2.get(cp)) |
|
557 | meta["copyrev"] = hex(manifest2.get(cp)) | |
558 | fp2 = nullid |
|
558 | fp2 = nullid | |
|
559 | else: # directory rename | |||
|
560 | meta["copyrev"] = hex(manifest1.get(cp, nullid)) | |||
559 | self.ui.debug(_(" %s: copy %s:%s\n") % |
|
561 | self.ui.debug(_(" %s: copy %s:%s\n") % | |
560 | (fn, cp, meta["copyrev"])) |
|
562 | (fn, cp, meta["copyrev"])) | |
561 | fp1 = nullid |
|
563 | fp1 = nullid |
@@ -122,11 +122,20 b' def findcopies(repo, m1, m2, ma, limit):' | |||||
122 | return |
|
122 | return | |
123 | c2 = ctx(of, man[of]) |
|
123 | c2 = ctx(of, man[of]) | |
124 | ca = c.ancestor(c2) |
|
124 | ca = c.ancestor(c2) | |
125 |
if not ca |
|
125 | if not ca: # unrelated | |
126 | return |
|
126 | return | |
127 | if ca.path() == c.path() or ca.path() == c2.path(): |
|
127 | if ca.path() == c.path() or ca.path() == c2.path(): | |
|
128 | fullcopy[c.path()] = of | |||
|
129 | if c == ca or c2 == ca: # no merge needed, ignore copy | |||
|
130 | return | |||
128 | copy[c.path()] = of |
|
131 | copy[c.path()] = of | |
129 |
|
132 | |||
|
133 | def dirs(files): | |||
|
134 | d = {} | |||
|
135 | for f in files: | |||
|
136 | d[os.path.dirname(f)] = True | |||
|
137 | return d | |||
|
138 | ||||
130 | if not repo.ui.configbool("merge", "followcopies", True): |
|
139 | if not repo.ui.configbool("merge", "followcopies", True): | |
131 | return {} |
|
140 | return {} | |
132 |
|
141 | |||
@@ -136,6 +145,7 b' def findcopies(repo, m1, m2, ma, limit):' | |||||
136 |
|
145 | |||
137 | dcopies = repo.dirstate.copies() |
|
146 | dcopies = repo.dirstate.copies() | |
138 | copy = {} |
|
147 | copy = {} | |
|
148 | fullcopy = {} | |||
139 | u1 = nonoverlap(m1, m2, ma) |
|
149 | u1 = nonoverlap(m1, m2, ma) | |
140 | u2 = nonoverlap(m2, m1, ma) |
|
150 | u2 = nonoverlap(m2, m1, ma) | |
141 | ctx = util.cachefunc(lambda f, n: repo.filectx(f, fileid=n[:20])) |
|
151 | ctx = util.cachefunc(lambda f, n: repo.filectx(f, fileid=n[:20])) | |
@@ -146,6 +156,38 b' def findcopies(repo, m1, m2, ma, limit):' | |||||
146 | for f in u2: |
|
156 | for f in u2: | |
147 | checkcopies(ctx(f, m2[f]), m1) |
|
157 | checkcopies(ctx(f, m2[f]), m1) | |
148 |
|
158 | |||
|
159 | if not fullcopy or not repo.ui.configbool("merge", "followdirs", True): | |||
|
160 | return copy | |||
|
161 | ||||
|
162 | # generate a directory move map | |||
|
163 | d1, d2 = dirs(m1), dirs(m2) | |||
|
164 | invalid = {} | |||
|
165 | dirmove = {} | |||
|
166 | ||||
|
167 | for dst, src in fullcopy.items(): | |||
|
168 | dsrc, ddst = os.path.dirname(src), os.path.dirname(dst) | |||
|
169 | if dsrc in invalid: | |||
|
170 | continue | |||
|
171 | elif (dsrc in d1 and ddst in d1) or (dsrc in d2 and ddst in d2): | |||
|
172 | invalid[dsrc] = True | |||
|
173 | elif dsrc in dirmove and dirmove[dsrc] != ddst: | |||
|
174 | invalid[dsrc] = True | |||
|
175 | del dirmove[dsrc] | |||
|
176 | else: | |||
|
177 | dirmove[dsrc] = ddst | |||
|
178 | ||||
|
179 | del d1, d2, invalid | |||
|
180 | ||||
|
181 | if not dirmove: | |||
|
182 | return copy | |||
|
183 | ||||
|
184 | # check unaccounted nonoverlapping files | |||
|
185 | for f in u1 + u2: | |||
|
186 | if f not in fullcopy: | |||
|
187 | d = os.path.dirname(f) | |||
|
188 | if d in dirmove: | |||
|
189 | copy[f] = dirmove[d] + "/" + os.path.basename(f) | |||
|
190 | ||||
149 | return copy |
|
191 | return copy | |
150 |
|
192 | |||
151 | def manifestmerge(repo, p1, p2, pa, overwrite, partial): |
|
193 | def manifestmerge(repo, p1, p2, pa, overwrite, partial): | |
@@ -210,7 +252,10 b' def manifestmerge(repo, p1, p2, pa, over' | |||||
210 | continue |
|
252 | continue | |
211 | elif f in copy: |
|
253 | elif f in copy: | |
212 | f2 = copy[f] |
|
254 | f2 = copy[f] | |
213 |
if f2 in m |
|
255 | if f2 not in m2: # directory rename | |
|
256 | act("remote renamed directory to " + f2, "d", | |||
|
257 | f, None, f2, m1.execf(f)) | |||
|
258 | elif f2 in m1: # case 2 A,B/B/B | |||
214 | act("local copied to " + f2, "m", |
|
259 | act("local copied to " + f2, "m", | |
215 | f, f2, f, fmerge(f, f2, f2), False) |
|
260 | f, f2, f, fmerge(f, f2, f2), False) | |
216 | else: # case 4,21 A/B/B |
|
261 | else: # case 4,21 A/B/B | |
@@ -238,7 +283,10 b' def manifestmerge(repo, p1, p2, pa, over' | |||||
238 | continue |
|
283 | continue | |
239 | if f in copy: |
|
284 | if f in copy: | |
240 | f2 = copy[f] |
|
285 | f2 = copy[f] | |
241 |
if f2 in m |
|
286 | if f2 not in m1: # directory rename | |
|
287 | act("local renamed directory to " + f2, "d", | |||
|
288 | None, f, f2, m2.execf(f)) | |||
|
289 | elif f2 in m2: # rename case 1, A/A,B/A | |||
242 | act("remote copied to " + f, "m", |
|
290 | act("remote copied to " + f, "m", | |
243 | f2, f, f, fmerge(f2, f, f2), False) |
|
291 | f2, f, f, fmerge(f2, f, f2), False) | |
244 | else: # case 3,20 A/B/A |
|
292 | else: # case 3,20 A/B/A | |
@@ -264,7 +312,7 b' def applyupdates(repo, action, wctx, mct' | |||||
264 | action.sort() |
|
312 | action.sort() | |
265 | for a in action: |
|
313 | for a in action: | |
266 | f, m = a[:2] |
|
314 | f, m = a[:2] | |
267 | if f[0] == "/": |
|
315 | if f and f[0] == "/": | |
268 | continue |
|
316 | continue | |
269 | if m == "r": # remove |
|
317 | if m == "r": # remove | |
270 | repo.ui.note(_("removing %s\n") % f) |
|
318 | repo.ui.note(_("removing %s\n") % f) | |
@@ -300,6 +348,20 b' def applyupdates(repo, action, wctx, mct' | |||||
300 | repo.wwrite(f, t) |
|
348 | repo.wwrite(f, t) | |
301 | util.set_exec(repo.wjoin(f), flag) |
|
349 | util.set_exec(repo.wjoin(f), flag) | |
302 | updated += 1 |
|
350 | updated += 1 | |
|
351 | elif m == "d": # directory rename | |||
|
352 | f2, fd, flag = a[2:] | |||
|
353 | if f: | |||
|
354 | repo.ui.note(_("moving %s to %s\n") % (f, fd)) | |||
|
355 | t = wctx.filectx(f).data() | |||
|
356 | repo.wwrite(fd, t) | |||
|
357 | util.set_exec(repo.wjoin(fd), flag) | |||
|
358 | util.unlink(repo.wjoin(f)) | |||
|
359 | if f2: | |||
|
360 | repo.ui.note(_("getting %s to %s\n") % (f2, fd)) | |||
|
361 | t = mctx.filectx(f2).data() | |||
|
362 | repo.wwrite(fd, t) | |||
|
363 | util.set_exec(repo.wjoin(fd), flag) | |||
|
364 | updated += 1 | |||
303 | elif m == "e": # exec |
|
365 | elif m == "e": # exec | |
304 | flag = a[2] |
|
366 | flag = a[2] | |
305 | util.set_exec(repo.wjoin(f), flag) |
|
367 | util.set_exec(repo.wjoin(f), flag) | |
@@ -345,6 +407,19 b' def recordupdates(repo, action, branchme' | |||||
345 | repo.dirstate.update([fd], 'n', st_size=-1, st_mtime=-1) |
|
407 | repo.dirstate.update([fd], 'n', st_size=-1, st_mtime=-1) | |
346 | if move: |
|
408 | if move: | |
347 | repo.dirstate.forget([f]) |
|
409 | repo.dirstate.forget([f]) | |
|
410 | elif m == "d": # directory rename | |||
|
411 | f2, fd, flag = a[2:] | |||
|
412 | if branchmerge: | |||
|
413 | repo.dirstate.update([fd], 'a') | |||
|
414 | if f: | |||
|
415 | repo.dirstate.update([f], 'r') | |||
|
416 | repo.dirstate.copy(f, fd) | |||
|
417 | if f2: | |||
|
418 | repo.dirstate.copy(f2, fd) | |||
|
419 | else: | |||
|
420 | repo.dirstate.update([fd], 'n') | |||
|
421 | if f: | |||
|
422 | repo.dirstate.forget([f]) | |||
348 |
|
423 | |||
349 | def update(repo, node, branchmerge, force, partial, wlock): |
|
424 | def update(repo, node, branchmerge, force, partial, wlock): | |
350 | """ |
|
425 | """ |
General Comments 0
You need to be logged in to leave comments.
Login now