124 def findcopies(repo, m1, m2, limit): |
131 def findcopies(repo, m1, m2, limit): |
125 """ |
132 """ |
126 Find moves and copies between m1 and m2 back to limit linkrev |
133 Find moves and copies between m1 and m2 back to limit linkrev |
127 """ |
134 """ |
128 |
135 |
|
136 if not repo.ui.config("merge", "followcopies"): |
|
137 return {} |
|
138 |
129 # avoid silly behavior for update from empty dir |
139 # avoid silly behavior for update from empty dir |
130 if not m1: |
140 if not m1: |
131 return {} |
141 return {} |
132 |
142 |
133 dcopies = repo.dirstate.copies() |
143 dcopies = repo.dirstate.copies() |
162 for mf in match[of]: |
172 for mf in match[of]: |
163 checkpair(c, mf, m1) |
173 checkpair(c, mf, m1) |
164 |
174 |
165 return copy |
175 return copy |
166 |
176 |
167 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial): |
177 def manifestmerge(ui, m1, m2, ma, copy, overwrite, backwards, partial): |
168 """ |
178 """ |
169 Merge manifest m1 with m2 using ancestor ma and generate merge action list |
179 Merge manifest m1 with m2 using ancestor ma and generate merge action list |
170 """ |
180 """ |
171 |
181 |
172 def fmerge(f): |
182 def fmerge(f, f2=None, fa=None): |
173 """merge executable flags""" |
183 """merge executable flags""" |
174 a, b, c = ma.execf(f), m1.execf(f), m2.execf(f) |
184 if not f2: |
|
185 f2 = f |
|
186 fa = f |
|
187 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2) |
175 return ((a^b) | (a^c)) ^ a |
188 return ((a^b) | (a^c)) ^ a |
176 |
189 |
177 action = [] |
190 action = [] |
178 |
191 |
179 def act(msg, f, m, *args): |
192 def act(msg, f, m, *args): |
201 act("update permissions", f, "e", m2.execf(f)) |
214 act("update permissions", f, "e", m2.execf(f)) |
202 # contents same, check mode bits |
215 # contents same, check mode bits |
203 elif m1.execf(f) != m2.execf(f): |
216 elif m1.execf(f) != m2.execf(f): |
204 if overwrite or fmerge(f) != m1.execf(f): |
217 if overwrite or fmerge(f) != m1.execf(f): |
205 act("update permissions", f, "e", m2.execf(f)) |
218 act("update permissions", f, "e", m2.execf(f)) |
|
219 elif f in copy: |
|
220 f2 = copy[f] |
|
221 if f in ma: # case 3,20 A/B/A |
|
222 act("remote moved", |
|
223 f, "c", f2, f2, m1[f], m2[f2], fmerge(f, f2, f), True) |
|
224 else: |
|
225 if f2 in m1: # case 2 A,B/B/B |
|
226 act("local copied", |
|
227 f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False) |
|
228 else: # case 4,21 A/B/B |
|
229 act("local moved", |
|
230 f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False) |
206 elif f in ma: |
231 elif f in ma: |
207 if n != ma[f] and not overwrite: |
232 if n != ma[f] and not overwrite: |
208 if ui.prompt( |
233 if ui.prompt( |
209 (_(" local changed %s which remote deleted\n") % f) + |
234 (_(" local changed %s which remote deleted\n") % f) + |
210 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"): |
235 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"): |
219 for f, n in m2.iteritems(): |
244 for f, n in m2.iteritems(): |
220 if partial and not partial(f): |
245 if partial and not partial(f): |
221 continue |
246 continue |
222 if f in m1: |
247 if f in m1: |
223 continue |
248 continue |
224 if f in ma: |
249 if f in copy: |
|
250 f2 = copy[f] |
|
251 if f2 in ma or f2 in m1: # already seen |
|
252 continue |
|
253 # rename case 1, A/A,B/A |
|
254 act("remote copied", |
|
255 f, "c", f2, f, m1[f2], m2[f], fmerge(f2, f, f2), False) |
|
256 elif f in ma: |
225 if overwrite or backwards: |
257 if overwrite or backwards: |
226 act("recreating", f, "g", m2.execf(f), n) |
258 act("recreating", f, "g", m2.execf(f), n) |
227 elif n != ma[f]: |
259 elif n != ma[f]: |
228 if ui.prompt( |
260 if ui.prompt( |
229 (_("remote changed %s which local deleted\n") % f) + |
261 (_("remote changed %s which local deleted\n") % f) + |
249 except OSError, inst: |
281 except OSError, inst: |
250 if inst.errno != errno.ENOENT: |
282 if inst.errno != errno.ENOENT: |
251 repo.ui.warn(_("update failed to remove %s: %s!\n") % |
283 repo.ui.warn(_("update failed to remove %s: %s!\n") % |
252 (f, inst.strerror)) |
284 (f, inst.strerror)) |
253 removed +=1 |
285 removed +=1 |
|
286 elif m == "c": # copy |
|
287 f2, fd, my, other, flag, remove = a[2:] |
|
288 if filemerge(repo, f, f2, fd, my, other, xp1, xp2, remove): |
|
289 unresolved += 1 |
|
290 util.set_exec(repo.wjoin(fd), flag) |
|
291 merged += 1 |
254 elif m == "m": # merge |
292 elif m == "m": # merge |
255 flag, my, other = a[2:] |
293 flag, my, other = a[2:] |
256 repo.ui.status(_("merging %s\n") % f) |
294 repo.ui.status(_("merging %s\n") % f) |
257 if filemerge(repo, f, f, f, my, other, xp1, xp2, False): |
295 if filemerge(repo, f, f, f, my, other, xp1, xp2, False): |
258 unresolved += 1 |
296 unresolved += 1 |
356 if not branchmerge: |
394 if not branchmerge: |
357 action += forgetremoved(m2, wc) |
395 action += forgetremoved(m2, wc) |
358 if not (backwards or overwrite): |
396 if not (backwards or overwrite): |
359 copy = findcopies(repo, m1, m2, pa.rev()) |
397 copy = findcopies(repo, m1, m2, pa.rev()) |
360 |
398 |
361 action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial) |
399 action += manifestmerge(repo.ui, m1, m2, ma, copy, |
|
400 overwrite, backwards, partial) |
362 |
401 |
363 ### apply phase |
402 ### apply phase |
364 |
403 |
365 if not branchmerge: |
404 if not branchmerge: |
366 # we don't need to do any magic, just jump to the new rev |
405 # we don't need to do any magic, just jump to the new rev |