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 | 553 | fp2 = nullid |
|
554 | 554 | elif fp2 != nullid: # copied on remote side |
|
555 | 555 | meta["copyrev"] = hex(manifest1.get(cp, nullid)) |
|
556 |
el |
|
|
556 | elif fp1 != nullid: # copied on local side, reversed | |
|
557 | 557 | meta["copyrev"] = hex(manifest2.get(cp)) |
|
558 | 558 | fp2 = nullid |
|
559 | else: # directory rename | |
|
560 | meta["copyrev"] = hex(manifest1.get(cp, nullid)) | |
|
559 | 561 | self.ui.debug(_(" %s: copy %s:%s\n") % |
|
560 | 562 | (fn, cp, meta["copyrev"])) |
|
561 | 563 | fp1 = nullid |
@@ -122,11 +122,20 b' def findcopies(repo, m1, m2, ma, limit):' | |||
|
122 | 122 | return |
|
123 | 123 | c2 = ctx(of, man[of]) |
|
124 | 124 | ca = c.ancestor(c2) |
|
125 |
if not ca |
|
|
125 | if not ca: # unrelated | |
|
126 | 126 | return |
|
127 | 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 | 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 | 139 | if not repo.ui.configbool("merge", "followcopies", True): |
|
131 | 140 | return {} |
|
132 | 141 | |
@@ -136,6 +145,7 b' def findcopies(repo, m1, m2, ma, limit):' | |||
|
136 | 145 | |
|
137 | 146 | dcopies = repo.dirstate.copies() |
|
138 | 147 | copy = {} |
|
148 | fullcopy = {} | |
|
139 | 149 | u1 = nonoverlap(m1, m2, ma) |
|
140 | 150 | u2 = nonoverlap(m2, m1, ma) |
|
141 | 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 | 156 | for f in u2: |
|
147 | 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 | 191 | return copy |
|
150 | 192 | |
|
151 | 193 | def manifestmerge(repo, p1, p2, pa, overwrite, partial): |
@@ -210,7 +252,10 b' def manifestmerge(repo, p1, p2, pa, over' | |||
|
210 | 252 | continue |
|
211 | 253 | elif f in copy: |
|
212 | 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 | 259 | act("local copied to " + f2, "m", |
|
215 | 260 | f, f2, f, fmerge(f, f2, f2), False) |
|
216 | 261 | else: # case 4,21 A/B/B |
@@ -238,7 +283,10 b' def manifestmerge(repo, p1, p2, pa, over' | |||
|
238 | 283 | continue |
|
239 | 284 | if f in copy: |
|
240 | 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 | 290 | act("remote copied to " + f, "m", |
|
243 | 291 | f2, f, f, fmerge(f2, f, f2), False) |
|
244 | 292 | else: # case 3,20 A/B/A |
@@ -264,7 +312,7 b' def applyupdates(repo, action, wctx, mct' | |||
|
264 | 312 | action.sort() |
|
265 | 313 | for a in action: |
|
266 | 314 | f, m = a[:2] |
|
267 | if f[0] == "/": | |
|
315 | if f and f[0] == "/": | |
|
268 | 316 | continue |
|
269 | 317 | if m == "r": # remove |
|
270 | 318 | repo.ui.note(_("removing %s\n") % f) |
@@ -300,6 +348,20 b' def applyupdates(repo, action, wctx, mct' | |||
|
300 | 348 | repo.wwrite(f, t) |
|
301 | 349 | util.set_exec(repo.wjoin(f), flag) |
|
302 | 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 | 365 | elif m == "e": # exec |
|
304 | 366 | flag = a[2] |
|
305 | 367 | util.set_exec(repo.wjoin(f), flag) |
@@ -345,6 +407,19 b' def recordupdates(repo, action, branchme' | |||
|
345 | 407 | repo.dirstate.update([fd], 'n', st_size=-1, st_mtime=-1) |
|
346 | 408 | if move: |
|
347 | 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 | 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