Show More
@@ -45,11 +45,11 b' class mergestate(object):' | |||
|
45 | 45 | f.write("\0".join([d] + v) + "\n") |
|
46 | 46 | f.close() |
|
47 | 47 | self._dirty = False |
|
48 |
def add(self, fcl, fco, fca, fd |
|
|
48 | def add(self, fcl, fco, fca, fd): | |
|
49 | 49 | hash = util.sha1(fcl.path()).hexdigest() |
|
50 | 50 | self._repo.opener.write("merge/" + hash, fcl.data()) |
|
51 | 51 | self._state[fd] = ['u', hash, fcl.path(), fca.path(), |
|
52 | hex(fca.filenode()), fco.path(), flags] | |
|
52 | hex(fca.filenode()), fco.path(), fcl.flags()] | |
|
53 | 53 | self._dirty = True |
|
54 | 54 | def __contains__(self, dfile): |
|
55 | 55 | return dfile in self._state |
@@ -67,12 +67,22 b' class mergestate(object):' | |||
|
67 | 67 | if self[dfile] == 'r': |
|
68 | 68 | return 0 |
|
69 | 69 | state, hash, lfile, afile, anode, ofile, flags = self._state[dfile] |
|
70 | fcd = wctx[dfile] | |
|
71 | fco = octx[ofile] | |
|
72 | fca = self._repo.filectx(afile, fileid=anode) | |
|
73 | # "premerge" x flags | |
|
74 | flo = fco.flags() | |
|
75 | fla = fca.flags() | |
|
76 | if 'x' in flags + flo + fla and 'l' not in flags + flo + fla: | |
|
77 | if fca.node() == nullid: | |
|
78 | self._repo.ui.warn(_('warning: cannot merge flags for %s\n') % | |
|
79 | afile) | |
|
80 | elif flags == fla: | |
|
81 | flags = flo | |
|
82 | # restore local | |
|
70 | 83 | f = self._repo.opener("merge/" + hash) |
|
71 | 84 | self._repo.wwrite(dfile, f.read(), flags) |
|
72 | 85 | f.close() |
|
73 | fcd = wctx[dfile] | |
|
74 | fco = octx[ofile] | |
|
75 | fca = self._repo.filectx(afile, fileid=anode) | |
|
76 | 86 | r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca) |
|
77 | 87 | if r is None: |
|
78 | 88 | # no real conflict |
@@ -183,32 +193,6 b' def manifestmerge(repo, p1, p2, pa, over' | |||
|
183 | 193 | partial = function to filter file lists |
|
184 | 194 | """ |
|
185 | 195 | |
|
186 | def fmerge(f, f2, fa): | |
|
187 | """merge flags""" | |
|
188 | a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2) | |
|
189 | if m == n: # flags agree | |
|
190 | return m # unchanged | |
|
191 | if m and n and not a: # flags set, don't agree, differ from parent | |
|
192 | r = repo.ui.promptchoice( | |
|
193 | _(" conflicting flags for %s\n" | |
|
194 | "(n)one, e(x)ec or sym(l)ink?") % f, | |
|
195 | (_("&None"), _("E&xec"), _("Sym&link")), 0) | |
|
196 | if r == 1: | |
|
197 | return "x" # Exec | |
|
198 | if r == 2: | |
|
199 | return "l" # Symlink | |
|
200 | return "" | |
|
201 | if m and m != a: # changed from a to m | |
|
202 | return m | |
|
203 | if n and n != a: # changed from a to n | |
|
204 | if (n == 'l' or a == 'l') and m1.get(f) != ma.get(f): | |
|
205 | # can't automatically merge symlink flag when there | |
|
206 | # are file-level conflicts here, let filemerge take | |
|
207 | # care of it | |
|
208 | return m | |
|
209 | return n | |
|
210 | return '' # flag was cleared | |
|
211 | ||
|
212 | 196 | def act(msg, m, f, *args): |
|
213 | 197 | repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) |
|
214 | 198 | actions.append((f, m) + args) |
@@ -248,17 +232,25 b' def manifestmerge(repo, p1, p2, pa, over' | |||
|
248 | 232 | if partial and not partial(f): |
|
249 | 233 | continue |
|
250 | 234 | if f in m2: |
|
251 | rflags = fmerge(f, f, f) | |
|
235 | n2 = m2[f] | |
|
236 | fl1, fl2, fla = m1.flags(f), m2.flags(f), ma.flags(f) | |
|
237 | nol = 'l' not in fl1 + fl2 + fla | |
|
252 | 238 | a = ma.get(f, nullid) |
|
253 | if n == m2[f] or m2[f] == a: # same or local newer | |
|
254 | # is file locally modified or flags need changing? | |
|
255 | # dirstate flags may need to be made current | |
|
256 | if m1.flags(f) != rflags or n[20:]: | |
|
257 | act("update permissions", "e", f, rflags) | |
|
258 | elif n == a: # remote newer | |
|
259 |
act(" |
|
|
260 |
else: |
|
|
261 |
act(" |
|
|
239 | if n == n2 and fl1 == fl2: | |
|
240 | pass # same - keep local | |
|
241 | elif n2 == a and fl2 == fla: | |
|
242 | pass # remote unchanged - keep local | |
|
243 | elif n == a and fl1 == fla: # local unchanged - use remote | |
|
244 | if n == n2: # optimization: keep local content | |
|
245 | act("update permissions", "e", f, fl2) | |
|
246 | else: | |
|
247 | act("remote is newer", "g", f, fl2) | |
|
248 | elif nol and n2 == a: # remote only changed 'x' | |
|
249 | act("update permissions", "e", f, fl2) | |
|
250 | elif nol and n == a: # local only changed 'x' | |
|
251 | act("remote is newer", "g", f, fl) | |
|
252 | else: # both changed something | |
|
253 | act("versions differ", "m", f, f, f, False) | |
|
262 | 254 | elif f in copied: # files we'll deal with on m2 side |
|
263 | 255 | pass |
|
264 | 256 | elif f in movewithdir: # directory rename |
@@ -267,8 +259,7 b' def manifestmerge(repo, p1, p2, pa, over' | |||
|
267 | 259 | m1.flags(f)) |
|
268 | 260 | elif f in copy: # case 2 A,B/B/B or case 4,21 A/B/B |
|
269 | 261 | f2 = copy[f] |
|
270 | act("local copied/moved to " + f2, "m", f, f2, f, | |
|
271 | fmerge(f, f2, f2), False) | |
|
262 | act("local copied/moved to " + f2, "m", f, f2, f, False) | |
|
272 | 263 | elif f in ma: # clean, a different, no remote |
|
273 | 264 | if n != ma[f]: |
|
274 | 265 | if repo.ui.promptchoice( |
@@ -296,16 +287,15 b' def manifestmerge(repo, p1, p2, pa, over' | |||
|
296 | 287 | f2 = copy[f] |
|
297 | 288 | if f2 in m2: # rename case 1, A/A,B/A |
|
298 | 289 | act("remote copied to " + f, "m", |
|
299 |
f2, f, f, |
|
|
290 | f2, f, f, False) | |
|
300 | 291 | else: # case 3,20 A/B/A |
|
301 | 292 | act("remote moved to " + f, "m", |
|
302 |
f2, f, f, |
|
|
293 | f2, f, f, True) | |
|
303 | 294 | elif f not in ma: |
|
304 | 295 | if (not overwrite |
|
305 | 296 | and _checkunknownfile(repo, p1, p2, f)): |
|
306 | rflags = fmerge(f, f, f) | |
|
307 | 297 | act("remote differs from untracked local", |
|
308 |
"m", f, f, f, |
|
|
298 | "m", f, f, f, False) | |
|
309 | 299 | else: |
|
310 | 300 | act("remote created", "g", f, m2.flags(f)) |
|
311 | 301 | elif n != ma[f]: |
@@ -341,7 +331,7 b' def applyupdates(repo, actions, wctx, mc' | |||
|
341 | 331 | for a in actions: |
|
342 | 332 | f, m = a[:2] |
|
343 | 333 | if m == "m": # merge |
|
344 |
f2, fd |
|
|
334 | f2, fd, move = a[2:] | |
|
345 | 335 | if fd == '.hgsubstate': # merged internally |
|
346 | 336 | continue |
|
347 | 337 | repo.ui.debug("preserving %s for resolve of %s\n" % (f, fd)) |
@@ -356,7 +346,7 b' def applyupdates(repo, actions, wctx, mc' | |||
|
356 | 346 | fca = fcl.ancestor(fco, actx) |
|
357 | 347 | if not fca: |
|
358 | 348 | fca = repo.filectx(f, fileid=nullrev) |
|
359 |
ms.add(fcl, fco, fca, fd |
|
|
349 | ms.add(fcl, fco, fca, fd) | |
|
360 | 350 | if f != fd and move: |
|
361 | 351 | moves.append(f) |
|
362 | 352 | |
@@ -390,7 +380,7 b' def applyupdates(repo, actions, wctx, mc' | |||
|
390 | 380 | subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), |
|
391 | 381 | overwrite) |
|
392 | 382 | continue |
|
393 |
f2, fd |
|
|
383 | f2, fd, move = a[2:] | |
|
394 | 384 | audit(fd) |
|
395 | 385 | r = ms.resolve(fd, wctx, mctx) |
|
396 | 386 | if r is not None and r > 0: |
@@ -484,7 +474,7 b' def recordupdates(repo, actions, branchm' | |||
|
484 | 474 | else: |
|
485 | 475 | repo.dirstate.normal(f) |
|
486 | 476 | elif m == "m": # merge |
|
487 |
f2, fd |
|
|
477 | f2, fd, move = a[2:] | |
|
488 | 478 | if branchmerge: |
|
489 | 479 | # We've done a branch merge, mark this file as merged |
|
490 | 480 | # so that we properly record the merger later |
@@ -34,16 +34,28 b' Symlink is local parent, executable is o' | |||
|
34 | 34 | resolving manifests |
|
35 | 35 | overwrite: False, partial: False |
|
36 | 36 | ancestor: c334dc3be0da, local: 521a1e40188f+, remote: 3574f3e69b1c |
|
37 | conflicting flags for a | |
|
38 | (n)one, e(x)ec or sym(l)ink? n | |
|
39 | a: update permissions -> e | |
|
37 | a: versions differ -> m | |
|
38 | preserving a for resolve of a | |
|
40 | 39 | updating: a 1/1 files (100.00%) |
|
41 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
42 | (branch merge, don't forget to commit) | |
|
40 | picked tool 'internal:merge' for a (binary False symlink True) | |
|
41 | merging a | |
|
42 | my a@521a1e40188f+ other a@3574f3e69b1c ancestor a@c334dc3be0da | |
|
43 | warning: internal:merge cannot merge symlinks for a | |
|
44 | merging a incomplete! (edit conflicts, then use 'hg resolve --mark') | |
|
45 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved | |
|
46 | use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon | |
|
47 | [1] | |
|
43 | 48 | |
|
44 | 49 | $ tellmeabout a |
|
45 | a is a plain file with content: | |
|
46 | symlink (no-eol) | |
|
50 | a is a symlink: | |
|
51 | a -> symlink | |
|
52 | $ hg resolve a --tool internal:other | |
|
53 | $ tellmeabout a | |
|
54 | a is an executable file with content: | |
|
55 | a | |
|
56 | $ hg st | |
|
57 | M a | |
|
58 | ? a.orig | |
|
47 | 59 | |
|
48 | 60 | Symlink is other parent, executable is local: |
|
49 | 61 | |
@@ -55,17 +67,21 b' Symlink is other parent, executable is l' | |||
|
55 | 67 | resolving manifests |
|
56 | 68 | overwrite: False, partial: False |
|
57 | 69 | ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f |
|
58 | conflicting flags for a | |
|
59 | (n)one, e(x)ec or sym(l)ink? n | |
|
60 | a: remote is newer -> g | |
|
70 | a: versions differ -> m | |
|
71 | preserving a for resolve of a | |
|
61 | 72 | updating: a 1/1 files (100.00%) |
|
62 | getting a | |
|
63 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
64 | (branch merge, don't forget to commit) | |
|
73 | picked tool 'internal:merge' for a (binary False symlink True) | |
|
74 | merging a | |
|
75 | my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da | |
|
76 | warning: internal:merge cannot merge symlinks for a | |
|
77 | merging a incomplete! (edit conflicts, then use 'hg resolve --mark') | |
|
78 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved | |
|
79 | use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon | |
|
80 | [1] | |
|
65 | 81 | |
|
66 | 82 |
$ |
|
67 |
a is a |
|
|
68 | symlink (no-eol) | |
|
83 | a is an executable file with content: | |
|
84 | a | |
|
69 | 85 | |
|
70 | 86 | Update to link without local change should get us a symlink (issue3316): |
|
71 | 87 | |
@@ -74,6 +90,7 b' Update to link without local change shou' | |||
|
74 | 90 | $ hg up |
|
75 | 91 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
76 | 92 | $ hg st |
|
93 | ? a.orig | |
|
77 | 94 | |
|
78 | 95 | Update to link with local change should cause a merge prompt (issue3200): |
|
79 | 96 | |
@@ -119,18 +136,24 b' where that was what happened.' | |||
|
119 | 136 | $ ln -s base f |
|
120 | 137 | $ hg ci -qm2 |
|
121 | 138 | $ hg merge |
|
122 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
123 | (branch merge, don't forget to commit) | |
|
139 | merging f | |
|
140 | warning: internal:merge cannot merge symlinks for f | |
|
141 | merging f incomplete! (edit conflicts, then use 'hg resolve --mark') | |
|
142 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved | |
|
143 | use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon | |
|
144 | [1] | |
|
124 | 145 | $ tellmeabout f |
|
125 | 146 | f is a symlink: |
|
126 |
f -> |
|
|
127 | content | |
|
128 | ||
|
147 | f -> base | |
|
129 | 148 | |
|
130 | 149 | $ hg up -Cqr1 |
|
131 | 150 | $ hg merge |
|
132 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
133 | (branch merge, don't forget to commit) | |
|
151 | merging f | |
|
152 | warning: internal:merge cannot merge symlinks for f | |
|
153 | merging f incomplete! (edit conflicts, then use 'hg resolve --mark') | |
|
154 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved | |
|
155 | use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon | |
|
156 | [1] | |
|
134 | 157 |
$ |
|
135 | 158 | f is a plain file with content: |
|
136 | 159 | file |
@@ -152,19 +175,27 b" Test removed 'x' flag merged with change" | |||
|
152 | 175 | $ ln -s dangling f |
|
153 | 176 | $ hg ci -qm2 |
|
154 | 177 | $ hg merge |
|
155 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
156 | (branch merge, don't forget to commit) | |
|
178 | merging f | |
|
179 | warning: internal:merge cannot merge symlinks for f | |
|
180 | merging f incomplete! (edit conflicts, then use 'hg resolve --mark') | |
|
181 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved | |
|
182 | use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon | |
|
183 | [1] | |
|
157 | 184 | $ tellmeabout f |
|
158 | 185 | f is a symlink: |
|
159 | 186 | f -> dangling |
|
160 | 187 | |
|
161 | 188 | $ hg up -Cqr1 |
|
162 | 189 | $ hg merge |
|
163 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
164 | (branch merge, don't forget to commit) | |
|
190 | merging f | |
|
191 | warning: internal:merge cannot merge symlinks for f | |
|
192 | merging f incomplete! (edit conflicts, then use 'hg resolve --mark') | |
|
193 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved | |
|
194 | use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon | |
|
195 | [1] | |
|
165 | 196 |
$ |
|
166 | f is a symlink: | |
|
167 | f -> dangling | |
|
197 | f is a plain file with content: | |
|
198 | f | |
|
168 | 199 | |
|
169 | 200 | $ cd .. |
|
170 | 201 | |
@@ -210,13 +241,10 b' h: l vs l, different' | |||
|
210 | 241 | $ hg ci -Aqm2 |
|
211 | 242 | |
|
212 | 243 | $ hg merge |
|
213 | conflicting flags for e | |
|
214 | (n)one, e(x)ec or sym(l)ink? n | |
|
215 | conflicting flags for d | |
|
216 | (n)one, e(x)ec or sym(l)ink? n | |
|
217 | 244 | merging a |
|
218 | 245 | warning: conflicts during merge. |
|
219 | 246 | merging a incomplete! (edit conflicts, then use 'hg resolve --mark') |
|
247 | warning: cannot merge flags for b | |
|
220 | 248 | merging b |
|
221 | 249 | warning: conflicts during merge. |
|
222 | 250 | merging b incomplete! (edit conflicts, then use 'hg resolve --mark') |
@@ -229,7 +257,7 b' h: l vs l, different' | |||
|
229 | 257 | merging h |
|
230 | 258 | warning: internal:merge cannot merge symlinks for h |
|
231 | 259 | merging h incomplete! (edit conflicts, then use 'hg resolve --mark') |
|
232 |
|
|
|
260 | 3 files updated, 0 files merged, 0 files removed, 5 files unresolved | |
|
233 | 261 | use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon |
|
234 | 262 | [1] |
|
235 | 263 | $ hg resolve -l |
@@ -246,21 +274,21 b' h: l vs l, different' | |||
|
246 | 274 | 1 |
|
247 | 275 | >>>>>>> other |
|
248 | 276 | $ tellmeabout b |
|
249 |
b is a |
|
|
277 | b is a plain file with content: | |
|
250 | 278 | <<<<<<< local |
|
251 | 279 | 2 |
|
252 | 280 | ======= |
|
253 | 281 | 1 |
|
254 | 282 | >>>>>>> other |
|
255 | 283 | $ tellmeabout c |
|
256 |
c is a |
|
|
284 | c is a plain file with content: | |
|
257 | 285 | x |
|
258 | 286 | $ tellmeabout d |
|
259 | d is a plain file with content: | |
|
260 | 2 (no-eol) | |
|
287 | d is a symlink: | |
|
288 | d -> 2 | |
|
261 | 289 | $ tellmeabout e |
|
262 | e is a plain file with content: | |
|
263 | x (no-eol) | |
|
290 | e is a symlink: | |
|
291 | e -> x | |
|
264 | 292 | $ tellmeabout f |
|
265 | 293 | f is a symlink: |
|
266 | 294 | f -> 2 |
@@ -273,13 +301,10 b' h: l vs l, different' | |||
|
273 | 301 | |
|
274 | 302 | $ hg up -Cqr1 |
|
275 | 303 | $ hg merge |
|
276 | conflicting flags for e | |
|
277 | (n)one, e(x)ec or sym(l)ink? n | |
|
278 | conflicting flags for d | |
|
279 | (n)one, e(x)ec or sym(l)ink? n | |
|
280 | 304 | merging a |
|
281 | 305 | warning: conflicts during merge. |
|
282 | 306 | merging a incomplete! (edit conflicts, then use 'hg resolve --mark') |
|
307 | warning: cannot merge flags for b | |
|
283 | 308 | merging b |
|
284 | 309 | warning: conflicts during merge. |
|
285 | 310 | merging b incomplete! (edit conflicts, then use 'hg resolve --mark') |
@@ -292,7 +317,7 b' h: l vs l, different' | |||
|
292 | 317 | merging h |
|
293 | 318 | warning: internal:merge cannot merge symlinks for h |
|
294 | 319 | merging h incomplete! (edit conflicts, then use 'hg resolve --mark') |
|
295 |
|
|
|
320 | 3 files updated, 0 files merged, 0 files removed, 5 files unresolved | |
|
296 | 321 | use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon |
|
297 | 322 | [1] |
|
298 | 323 | $ tellmeabout a |
@@ -310,13 +335,13 b' h: l vs l, different' | |||
|
310 | 335 | 2 |
|
311 | 336 | >>>>>>> other |
|
312 | 337 | $ tellmeabout c |
|
313 |
c is a |
|
|
338 | c is a plain file with content: | |
|
314 | 339 | x |
|
315 | 340 | $ tellmeabout d |
|
316 |
d is a |
|
|
341 | d is an executable file with content: | |
|
317 | 342 | 1 |
|
318 | 343 | $ tellmeabout e |
|
319 |
e is a |
|
|
344 | e is an executable file with content: | |
|
320 | 345 | x (no-eol) |
|
321 | 346 | $ tellmeabout f |
|
322 | 347 | f is a plain file with content: |
General Comments 0
You need to be logged in to leave comments.
Login now